Skip to content

Commit fefe921

Browse files
committed
Complete Sprint 5 exercises
1 parent 3f26722 commit fefe921

11 files changed

Lines changed: 451 additions & 0 deletions

Sprint-5/ExerSice10.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
2+
#enum exersice
3+
4+
from dataclasses import dataclass
5+
from typing import List
6+
import sys
7+
8+
9+
@dataclass(frozen=True)
10+
class Person:
11+
name: str
12+
age: int
13+
preferred_operating_system: str
14+
15+
16+
@dataclass(frozen=True)
17+
class Laptop:
18+
id: int
19+
manufacturer: str
20+
model: str
21+
screen_size_in_inches: float
22+
operating_system: str
23+
24+
25+
laptops = [
26+
Laptop(1, "Dell", "XPS", 13, "Ubuntu"),
27+
Laptop(2, "Dell", "XPS", 15, "Ubuntu"),
28+
Laptop(3, "Dell", "XPS", 15, "Arch Linux"),
29+
Laptop(4, "Apple", "MacBook", 13, "macOS"),
30+
Laptop(5, "Lenovo", "ThinkPad", 14, "Ubuntu"),
31+
]
32+
33+
34+
name = input("Enter your name: ")
35+
36+
try:
37+
age = int(input("Enter your age: "))
38+
except ValueError:
39+
print("Error: age must be a number.", file=sys.stderr)
40+
sys.exit(1)
41+
42+
43+
preferred_operating_system = input(
44+
"Enter your preferred operating system: "
45+
)
46+
47+
available_operating_systems = {
48+
laptop.operating_system for laptop in laptops
49+
}
50+
51+
if preferred_operating_system not in available_operating_systems:
52+
print(
53+
"Error: that operating system is not available.",
54+
file=sys.stderr
55+
)
56+
sys.exit(1)
57+
58+
59+
person = Person(
60+
name=name,
61+
age=age,
62+
preferred_operating_system=preferred_operating_system
63+
)
64+
65+
66+
matching_laptops = [
67+
laptop
68+
for laptop in laptops
69+
if laptop.operating_system == person.preferred_operating_system
70+
]
71+
72+
print(
73+
f"The library has {len(matching_laptops)} "
74+
f"laptop(s) with {person.preferred_operating_system}."
75+
)
76+
77+
78+
laptop_counts = {}
79+
80+
for laptop in laptops:
81+
laptop_counts[laptop.operating_system] = (
82+
laptop_counts.get(laptop.operating_system, 0) + 1
83+
)
84+
85+
86+
for operating_system, count in laptop_counts.items():
87+
if (
88+
operating_system != person.preferred_operating_system
89+
and count > len(matching_laptops)
90+
):
91+
print(
92+
f"The library has more {operating_system} laptops "
93+
f"({count}). You are more likely to get a laptop "
94+
f"if you are willing to use {operating_system}."
95+
)

Sprint-5/Exersice1.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
# Predict what double("22") will do. Then run the code and check. Did it do what you expected? Why did it return the value it did?
3+
4+
5+
# double("22") returns "2222".
6+
7+
# "22" is a string, so * 2 repeats the string twice.
8+
9+
10+
def half(value):
11+
return value / 2
12+
13+
def double(value):
14+
return value * 2
15+
16+
def second(value):
17+
return value[1]
18+
19+
print(double(22))
20+
print(double("hello"))
21+
print(double("22"))
22+
23+
print(second(22))
24+
print(second(0x16))
25+
print(second("hello"))
26+
print(second("22"))
27+

Sprint-5/Exersice11.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Inheritance exercise.
2+
3+
class Parent:
4+
def __init__(self, first_name: str, last_name: str):
5+
self.first_name = first_name
6+
self.last_name = last_name
7+
8+
def get_name(self) -> str:
9+
return f"{self.first_name} {self.last_name}"
10+
11+
12+
class Child(Parent):
13+
def __init__(self, first_name: str, last_name: str):
14+
super().__init__(first_name, last_name)
15+
self.previous_last_names = []
16+
17+
def change_last_name(self, last_name) -> None:
18+
self.previous_last_names.append(self.last_name)
19+
self.last_name = last_name
20+
21+
def get_full_name(self) -> str:
22+
suffix = ""
23+
if len(self.previous_last_names) > 0:
24+
suffix = f" (née {self.previous_last_names[0]})"
25+
return f"{self.first_name} {self.last_name}{suffix}"
26+
27+
28+
person1 = Child("Elizaveta", "Alekseeva")
29+
30+
print(person1.get_name())
31+
print(person1.get_full_name())
32+
33+
person1.change_last_name("Tyurina")
34+
35+
print(person1.get_name())
36+
print(person1.get_full_name())
37+
38+
39+
person2 = Parent("Elizaveta", "Alekseeva")
40+
41+
print(person2.get_name())
42+
43+
# Parent does not have get_full_name()
44+
# print(person2.get_full_name())
45+
46+
# Parent does not have change_last_name()
47+
# person2.change_last_name("Tyurina")
48+
49+
# These would work if the above line was not an error:
50+
# print(person2.get_name())
51+
# print(person2.get_full_name())

Sprint-5/Exersice2.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
# Read the above code and write down what the bug is. How would you fix it?
3+
4+
# The bug was that the function multiplied the number by 3.
5+
6+
# Since the function is called double, it should multiply the number by 2.
7+
8+
def double(number):
9+
return number * 2
10+
11+
print(double(10))
12+
13+

Sprint-5/Exersice3.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# type checking
2+
3+
rom typing import Dict
4+
5+
def open_account(balances: Dict[str, int], name: str, amount: int) -> None:
6+
balances[name] = amount
7+
8+
def sum_balances(accounts: Dict[str, int]) -> int:
9+
total = 0
10+
for name, pence in accounts.items():
11+
print(f"{name} had balance {pence}")
12+
total += pence
13+
return total
14+
15+
def format_pence_as_string(total_pence: int) -> str:
16+
if total_pence < 100:
17+
return f"{total_pence}p"
18+
19+
```
20+
pounds = int(total_pence / 100)
21+
pence = total_pence % 100
22+
return f"£{pounds}.{pence:02d}"
23+
```
24+
25+
balances = {
26+
"Sima": 700,
27+
"Linn": 545,
28+
"Georg": 831,
29+
}
30+
31+
open_account(balances, "Tobi", 913)
32+
open_account(balances, "Olya", 713)
33+
34+
total_pence = sum_balances(balances)
35+
total_string = format_pence_as_string(total_pence)
36+
37+
print(f"The bank accounts total {total_string}")
38+
39+
# Answer:
40+
41+
# The type annotations tell mypy what types are expected.
42+
43+
# balances contains string names and integer balances.
44+
45+
# The account amounts are stored as pence, so £9.13 is 913
46+
47+
# and £7.13 is 713.
48+
49+
# format_pence_as_string returns a string.
50+
51+
# The original function call had the wrong function name:
52+
53+
# format_pence_as_str -> format_pence_as_string

Sprint-5/Exersice4.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Classes and objects
2+
3+
# Classes and objects
4+
5+
class Person:
6+
def __init__(self, name: str, age: int, preferred_operating_system: str):
7+
self.name = name
8+
self.age = age
9+
self.preferred_operating_system = preferred_operating_system
10+
11+
12+
imran = Person("Imran", 22, "Ubuntu")
13+
print(imran.name)
14+
# print(imran.address)
15+
16+
eliza = Person("Eliza", 34, "Arch Linux")
17+
print(eliza.name)
18+
# print(eliza.address)
19+
20+
21+
def is_adult(person: Person) -> bool:
22+
return person.age >= 18
23+
24+
25+
print(is_adult(imran))
26+
27+
28+
29+
30+
def is_developer(person: Person) -> bool:
31+
return person.is_developer
32+
33+
34+
print(is_developer(imran))
35+
36+
# there is an error because the is_developer attribute is not in the Person class.

Sprint-5/Exersice5.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# methods
2+
3+
# Think of the advantages of using methods
4+
5+
Encapsulation:
6+
Data and methods are kept together in one class, which controls how the data can be accessed or changed. It hides the implementation details and allows the implementation to change without affecting the user, as long as the interface stays the same.
7+
For example, a Person class can control how a person's data is modified.
8+
9+
10+
Ease of use:
11+
Users only need to know how to use the class's interface, not how it works internally. Methods can be easily accessed using dot notation and IDE autocomplete,
12+
for example person.is_adult().

Sprint-5/Exersice6.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
# Change the Person class to take a date of birth (using the standard library’s datetime.date class) and store it in a field instead of age.
3+
4+
import datetime as dt
5+
6+
class Person:
7+
def __init__(self, name: str, birthdate: dt.date, preferred_operating_system: str):
8+
self.name = name
9+
self.birthdate = birthdate
10+
self.preferred_operating_system = preferred_operating_system
11+
self.birthdate = birthdate
12+
13+
def is_adult(self) -> bool:
14+
today = dt.date.today()
15+
print(today)
16+
return today >= dt.date(self.birthdate.year +18, self.birthdate.month, self.birthdate.day)
17+
18+
imran = Person("Imran", dt.date(2008,8,6), "Ubuntu")
19+
print(imran.is_adult())

Sprint-5/Exersice7.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
# Write a Person class using @datatype which uses a datetime.date for date of birth, rather than an int for age.
3+
4+
from dataclasses import dataclass
5+
from datetime import date
6+
7+
8+
@dataclass
9+
class Person:
10+
name: str
11+
date_of_birth: date
12+
preferred_operating_system: str
13+
14+
def is_adult(self) -> bool:
15+
today = date.today()
16+
17+
years = today.year - self.date_of_birth.year
18+
19+
had_birthday_this_year = (
20+
(today.month, today.day)
21+
>= (self.date_of_birth.month, self.date_of_birth.day)
22+
)
23+
24+
age = years if had_birthday_this_year else years - 1
25+
26+
return age >= 18
27+
28+
29+
imran = Person(
30+
"Imran",
31+
date(2008, 8, 6),
32+
"Ubuntu"
33+
)
34+
35+
print(imran.is_adult())

Sprint-5/Exersice8.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Generic exersice
2+
3+
from dataclasses import dataclass
4+
from typing import List
5+
6+
7+
@dataclass(frozen=True)
8+
class Person:
9+
name: str
10+
age: int
11+
children: List["Person"]
12+
13+
14+
fatma = Person(name="Fatma", age=5, children=[])
15+
aisha = Person(name="Aisha", age=8, children=[])
16+
17+
imran = Person(name="Imran", age=35, children=[fatma, aisha])
18+
19+
20+
def print_family_tree(person: Person) -> None:
21+
print(person.name)
22+
for child in person.children:
23+
print(f"- {child.name} ({child.age})")
24+
25+
26+
print_family_tree(imran)

0 commit comments

Comments
 (0)