Skip to content

Commit d2cb996

Browse files
committed
completed prep exercises
1 parent 3100694 commit d2cb996

10 files changed

Lines changed: 320 additions & 0 deletions
722 Bytes
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Person:
2+
def __init__(self, name: str, age: int, preferred_operating_system: str):
3+
self.name = name
4+
self.age = age
5+
self.preferred_operating_system = preferred_operating_system
6+
7+
8+
def is_adult(person: Person) -> bool:
9+
return person.age >= 18
10+
11+
12+
imran = Person("Imran", 22, "Ubuntu")
13+
print(imran.name)
14+
# print(imran.address)
15+
# Person doesn't have address attribute
16+
17+
eliza = Person("Eliza", 34, "Arch Linux")
18+
print(eliza.name)
19+
# print(eliza.address)
20+
# Person doesn't have address attribute
21+
22+
# def favorite_song(person: Person) -> str:
23+
# return person.song
24+
# error because person doesn't have song attribute
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from dataclasses import dataclass
2+
import datetime as dt
3+
4+
@dataclass(frozen=True)
5+
class Person:
6+
name: str
7+
age: dt.date
8+
preferred_operating_system: str
9+
10+
def is_adult(self) -> bool:
11+
today = dt.datetime.today()
12+
13+
age_in_year = today.year - self.age.year
14+
15+
if (today.month, today.day) < (self.age.month, self.age.day):
16+
age_in_year -= 1
17+
return age_in_year >= 18
18+
19+
imran = Person("Imran", dt.date.fromisoformat("2002-08-05"), "Ubuntu")
20+
print(imran)
21+
22+
imran2 = Person("Imran", dt.date.fromisoformat("2002-08-05"), "Ubuntu")
23+
print(imran == imran2)
24+
25+
print(f'{imran.name} is adult: {imran.is_adult()}')

prep-exercises/enums.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from dataclasses import dataclass
2+
from enum import Enum
3+
from typing import List, Dict
4+
import sys
5+
6+
class OperatingSystem(Enum):
7+
MACOS = "macOS"
8+
ARCH = "Arch Linux"
9+
UBUNTU = "Ubuntu"
10+
11+
@dataclass(frozen=True)
12+
class Person:
13+
name: str
14+
age: int
15+
preferred_operating_system: OperatingSystem
16+
17+
18+
@dataclass(frozen=True)
19+
class Laptop:
20+
id: int
21+
manufacturer: str
22+
model: str
23+
screen_size_in_inches: float
24+
operating_system: OperatingSystem
25+
26+
27+
def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]:
28+
possible_laptops = []
29+
for laptop in laptops:
30+
if laptop.operating_system == person.preferred_operating_system:
31+
possible_laptops.append(laptop)
32+
return possible_laptops
33+
34+
laptops = [
35+
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH),
36+
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
37+
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
38+
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
39+
]
40+
41+
def user_register() -> Person:
42+
43+
user_name: str = input("Please enter your name: ")
44+
user_age_str: str = input("Please enter your age: ")
45+
46+
try:
47+
user_age: int = int(user_age_str)
48+
if user_age < 0:
49+
raise ValueError
50+
except ValueError:
51+
sys.stderr.write(f'Error: "{user_age_str}" is not a valid age. \n')
52+
sys.exit(1)
53+
54+
user_system_str = input("Please enter your preferred operating system - Arch Linux, Ubuntu, or macOS: ")
55+
56+
try:
57+
user_system = OperatingSystem(user_system_str)
58+
except ValueError:
59+
sys.stderr.write(f'Error: "{user_system_str}" is not a valid system. \n')
60+
sys.exit(1)
61+
62+
return Person(name=user_name, age=user_age, preferred_operating_system=user_system)
63+
64+
65+
def matching_laptop(new_user: Person = user_register()) -> None:
66+
possible_laptops = find_possible_laptops(laptops=laptops, person=new_user)
67+
68+
print(f'Library has {len(possible_laptops)} laptops have {new_user.preferred_operating_system.value}')
69+
70+
system_counts: Dict[OperatingSystem, int] = {}
71+
for laptop in laptops:
72+
system_counts[laptop.operating_system] = (system_counts.get(laptop.operating_system) or 0 ) + 1
73+
74+
most_available = max(system_counts, key=lambda name: system_counts[name])
75+
76+
if system_counts[most_available] > len(possible_laptops):
77+
print(f'if you are willing to accept {most_available.value} you are more likely to get a laptop.')
78+
79+
80+
matching_laptop()

prep-exercises/generics.py

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

prep-exercises/inheritance.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from typing import List
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: List[str] = []
16+
17+
def change_last_name(self, last_name: str) -> 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+
person1 = Child("Elizaveta", "Alekseeva")
28+
print(person1.get_name())
29+
print(person1.get_full_name())
30+
person1.change_last_name("Tyurina")
31+
print(person1.get_name())
32+
print(person1.get_full_name())
33+
34+
person2 = Parent("Elizaveta", "Alekseeva")
35+
print(person2.get_name())
36+
# print(person2.get_full_name())
37+
# person2.change_last_name("Tyurina")
38+
print(person2.get_name())
39+
# print(person2.get_full_name())
40+
41+
42+
# Predictions:
43+
# person 1 should be able to print both name and full name as Elizaveta Alekseeva
44+
# and should be able to print both name Elizaveta Tyurina and full name Elizaveta Tyurina (née Alekseeva) after changing last name to Tyurina
45+
# because it was created in class Child which inherits get_name from class Parent
46+
#
47+
# In contracts, person 2 is able to print name as Elizaveta Alekseeva
48+
# but shouldn't be able to print full name as it was create in class Parent, which does not have method get_full_name
49+
# and couldn't be able to change last name to Tyurina, so the name stays the same Elizaveta Alekseeva
50+
# and it still won't be able to print full name even after the attempt of change last name

prep-exercises/methods.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Think of the advantages of using methods instead of free functions. Write them down in your notebook.
2+
# It is object oriented. The same method can be shared between the same class.
3+
# It is more obvious to understand the purpose of the methods than a free function
4+
5+
import datetime as dt
6+
7+
class Person:
8+
def __init__(self, name: str, date_of_birth: str, preferred_operating_system: str):
9+
self.name = name
10+
self.date_of_birth = dt.date.fromisoformat(date_of_birth)
11+
self.preferred_operating_system = preferred_operating_system
12+
13+
def is_adult(self) -> bool:
14+
today = dt.datetime.today()
15+
16+
age_in_year = today.year - self.date_of_birth.year
17+
18+
if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day):
19+
age_in_year -= 1
20+
return age_in_year >= 18
21+
22+
imran = Person("Imran", "2000-10-20", "Ubuntu")
23+
print(imran.is_adult())
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from typing import Dict
2+
3+
def open_account(balances: Dict[str, int], name: str, amount: int) -> None:
4+
balances[name] = amount
5+
6+
def sum_balances(accounts: Dict[str, int]) -> int:
7+
total = 0
8+
for name, pence in accounts.items():
9+
print(f"{name} had balance {pence}")
10+
total += pence
11+
return total
12+
13+
def format_pence_as_string(total_pence: int) -> str:
14+
if total_pence < 100:
15+
return f"{total_pence}p"
16+
pounds = int(total_pence / 100)
17+
pence = total_pence % 100
18+
return f"£{pounds}.{pence:02d}"
19+
20+
balances = {
21+
"Sima": 700,
22+
"Linn": 545,
23+
"Georg": 831,
24+
}
25+
26+
open_account(balances, "Tobi", 913)
27+
open_account(balances, "Olya", 713)
28+
29+
total_pence = sum_balances(balances)
30+
total_string = format_pence_as_string(total_pence)
31+
32+
print(f"The bank accounts total {total_string}")
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from dataclasses import dataclass
2+
from typing import List
3+
4+
@dataclass(frozen=True)
5+
class Person:
6+
name: str
7+
age: int
8+
preferred_operating_systems: List[str]
9+
10+
11+
@dataclass(frozen=True)
12+
class Laptop:
13+
id: int
14+
manufacturer: str
15+
model: str
16+
screen_size_in_inches: float
17+
operating_system: str
18+
19+
20+
def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]:
21+
possible_laptops = []
22+
for laptop in laptops:
23+
for system in person.preferred_operating_systems:
24+
if laptop.operating_system == system:
25+
possible_laptops.append(laptop)
26+
return possible_laptops
27+
28+
29+
people = [
30+
Person(name="Imran", age=22, preferred_operating_systems=["Ubuntu", "Arch Linux", "macOS", "Windows"]),
31+
Person(name="Eliza", age=34, preferred_operating_systems=["Arch Linux", "Ubuntu", "macOS", "Windows"]),
32+
]
33+
34+
laptops = [
35+
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system="Arch Linux"),
36+
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="Ubuntu"),
37+
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="ubuntu"),
38+
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system="macOS"),
39+
]
40+
41+
for person in people:
42+
possible_laptops = find_possible_laptops(laptops, person)
43+
print(f"Possible laptops for {person.name}: {possible_laptops}")
44+
45+
system_list = person.preferred_operating_systems
46+
preference_sentences: List[str] = ["prefers {} most of all", ", and then {}", ", but will not use {}"]
47+
statement: str = f'{person.name} '
48+
49+
if len(system_list) != 0:
50+
for index, system in enumerate(system_list):
51+
if index == 0:
52+
statement += preference_sentences[index].format(system)
53+
elif index == len(system_list) - 1:
54+
statement += preference_sentences[-1].format(system)
55+
else:
56+
statement += preference_sentences[1].format(system)
57+
print(statement)

prep-exercises/why_we_use_types.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def double(number: float) -> float:
2+
return number * 2
3+
4+
print(double(10))
5+
6+
# The code above was not defined with types for the function and variable
7+
# I should add the types to fix the code
8+
# Besides the function name did not reflect its return
9+
# I make the return as number * 2 instead

0 commit comments

Comments
 (0)