Skip to content

Commit 002a78b

Browse files
committed
Sprint 5 Prep exercises.
1 parent 407b010 commit 002a78b

File tree

9 files changed

+353
-0
lines changed

9 files changed

+353
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
node_modules
2+
implement-cowsay/.venv
3+
**/package.json
4+
**/package-lock.json
5+
implement-cowsay/requirements.txt
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'''
2+
Run it through mypy - notice that no errors are reported - mypy understands
3+
that Person has a property named age so is happy with the function.
4+
Write a new function in the file that accepts a Person as a parameter
5+
and tries to access a property that doesn't exist. Run it through mypy
6+
and check that it does report an error.
7+
'''
8+
9+
class Person:
10+
def __init__(self, name: str, age: int, preferred_operating_system: str):
11+
self.name = name
12+
self.age = age
13+
self.preferred_operating_system = preferred_operating_system
14+
15+
imran = Person("Imran", 22, "Ubuntu")
16+
print(imran.name)
17+
#print(imran.address)
18+
19+
eliza = Person("Eliza", 34, "Arch Linux")
20+
print(eliza.name)
21+
#print(eliza.address)
22+
23+
def is_adult(person: Person) -> bool:
24+
return person.age >= 18
25+
26+
print(is_adult(imran))
27+
28+
''' adding the function:'''
29+
def read_genre(person: Person) -> str:
30+
if person.genre == "M":
31+
return "Male"
32+
else:
33+
return "Female"
34+
35+
''' returns:
36+
cyf@cyfs-MacBook-Pro prep-sprint5 % mypy class-object-person.py
37+
class-object-person.py:29: error: "Person" has no attribute "genre" [attr-defined]
38+
Found 1 error in 1 file (checked 1 source file)
39+
40+
'''

prep-sprint5/dataclass-person.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'''Write a Person class using @datatype which uses a datetime.date for date of birth,
2+
rather than an int for age.
3+
Re-add the is_adult method to it.'''
4+
from dataclasses import dataclass
5+
from datetime import date
6+
7+
@dataclass(frozen=True)
8+
class Person:
9+
name: str
10+
date_of_birth: date
11+
preferred_operating_system: str
12+
13+
def is_adult(self) -> bool:
14+
today_year = date.today().year
15+
birth_year = self.date_of_birth.year
16+
age = today_year - birth_year
17+
18+
if date.today().month > self.date_of_birth.month:
19+
return age >= 18
20+
elif date.today().month == self.date_of_birth.month:
21+
return date.today().day >= self.date_of_birth.day and age >= 18
22+
else:
23+
return age - 1 >= 18
24+
25+
imran = Person("Imran", date(2002, 9, 21), "Ubuntu")
26+
print(imran)
27+
print("Is adult?", imran.is_adult())

prep-sprint5/enums.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
'''
2+
Write a program which:
3+
1.Already has a list of Laptops that a library has to lend out.
4+
2.Accepts user input to create a new Person - it should use the input function to
5+
read a person's name, age, and preferred operating system.
6+
3.Tells the user how many laptops the library has that have that operating system.
7+
4.If there is an operating system that has more laptops available, tells the user
8+
that if they're willing to accept that operating system they're more likely to get a laptop.
9+
10+
You should convert the age and preferred operating system input from the user
11+
into more constrained types as quickly as possible, and should output errors to
12+
stderr and terminate the program with a non-zero exit code if the user input bad values.
13+
'''
14+
15+
from dataclasses import dataclass
16+
from enum import Enum
17+
from typing import List
18+
19+
class OperatingSystem(Enum):
20+
MACOS = "macOS"
21+
ARCH = "Arch Linux"
22+
UBUNTU = "Ubuntu"
23+
24+
@dataclass(frozen=True)
25+
class Person:
26+
name: str
27+
age: int
28+
preferred_operating_system: OperatingSystem
29+
30+
31+
@dataclass(frozen=True)
32+
class Laptop:
33+
id: int
34+
manufacturer: str
35+
model: str
36+
screen_size_in_inches: float
37+
operating_system: OperatingSystem
38+
39+
40+
def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]:
41+
possible_laptops = []
42+
for laptop in laptops:
43+
if laptop.operating_system == person.preferred_operating_system:
44+
possible_laptops.append(laptop)
45+
return possible_laptops
46+
47+
48+
people = [
49+
Person(name="Imran", age=22, preferred_operating_system=OperatingSystem.UBUNTU),
50+
Person(name="Eliza", age=34, preferred_operating_system=OperatingSystem.ARCH),
51+
]
52+
53+
laptops = [
54+
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH),
55+
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
56+
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
57+
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
58+
]
59+
60+
print("Library laptops:") # 1. list of laptops
61+
for laptop in laptops:
62+
print(f"- ID:{laptop.id} {laptop.operating_system.value} - {laptop.manufacturer} {laptop.model} Size: {laptop.screen_size_in_inches}")
63+
64+
# receiving values from input to create person:
65+
name = input("Enter your name: ")
66+
age = int(input("Enter your age: "))
67+
68+
print("Choose preferred operating system:")
69+
print("1. macOS")
70+
print("2. Arch Linux")
71+
print("3. Ubuntu")
72+
choice = input(">> ")
73+
74+
os_map = {
75+
"1": OperatingSystem.MACOS,
76+
"2": OperatingSystem.ARCH,
77+
"3": OperatingSystem.UBUNTU,
78+
}
79+
80+
preferred_os = os_map.get(choice)
81+
82+
person = Person(name=name, age=age, preferred_operating_system=preferred_os)
83+
84+
print("Created person:", person)
85+
# counts how many laptops there are with that OS
86+
matches_count = sum(
87+
1 for laptop in laptops
88+
if laptop.operating_system == person.preferred_operating_system
89+
)
90+
print(f"There are {matches_count} laptop(s) with {person.preferred_operating_system.value}.")
91+
92+
count_laptops_by_os = {
93+
os_type: sum(1 for laptop in laptops if laptop.operating_system == os_type)
94+
for os_type in OperatingSystem
95+
}
96+
97+
best_os = max(count_laptops_by_os, key = count_laptops_by_os.get)
98+
best_os_count = count_laptops_by_os[best_os]
99+
100+
if best_os != person.preferred_operating_system:
101+
print(
102+
f"There are more laptops available with {best_os.value} "
103+
f"({best_os_count} laptops). If you're willing to use that OS, "
104+
"you're more likely to get a laptop."
105+
)
106+
else:
107+
print("Good choice! Your preferred OS has the highest availability.")
108+

prep-sprint5/generics.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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=20, children=[])
11+
aisha = Person(name="Aisha", age=30, children=[])
12+
13+
imran = Person(name="Imran", age=50, children=[fatma, aisha])
14+
maria = Person(name="maria", age=38,children=[fatma])
15+
16+
def print_family_tree(person: Person) -> None:
17+
print(person.name)
18+
for child in person.children:
19+
print(f"- {child.name} ({child.age})")
20+
21+
print_family_tree(maria)

prep-sprint5/inheritance.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'''
2+
Play computer with this code. Predict what you expect each line will do.
3+
Then run the code and check your predictions. (If any lines cause errors,
4+
you may need to comment them out to check later lines).
5+
'''
6+
7+
class Parent:
8+
def __init__(self, first_name: str, last_name: str):
9+
self.first_name = first_name
10+
self.last_name = last_name
11+
12+
def get_name(self) -> str:
13+
return f"{self.first_name} {self.last_name}"
14+
15+
16+
class Child(Parent):
17+
def __init__(self, first_name: str, last_name: str):
18+
super().__init__(first_name, last_name)
19+
self.previous_last_names = []
20+
21+
def change_last_name(self, last_name) -> None:
22+
self.previous_last_names.append(self.last_name)
23+
self.last_name = last_name
24+
25+
def get_full_name(self) -> str:
26+
suffix = ""
27+
if len(self.previous_last_names) > 0:
28+
suffix = f" (née {self.previous_last_names[0]})"
29+
return f"{self.first_name} {self.last_name}{suffix}"
30+
31+
person1 = Child("Elizaveta", "Alekseeva")
32+
print(person1.get_name())
33+
print(person1.get_full_name())
34+
person1.change_last_name("Tyurina")
35+
print(person1.get_name())
36+
print(person1.get_full_name())
37+
38+
person2 = Parent("Elizaveta", "Alekseeva")
39+
print(person2.get_name())
40+
#print(person2.get_full_name())
41+
#person2.change_last_name("Tyurina")
42+
#print(person2.get_name())
43+
#print(person2.get_full_name())
44+
45+
# PREDICTION:
46+
# Printing from person1 (Child) will work fine, as the Child class inherits from the Parent class and has access to its own methods.
47+
# Printing from person2 (Parent) will get error because the Parent class does not have the methods get_full_name and change_last_name defined in the Child class.

prep-sprint5/methods-person.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
from datetime import date
3+
4+
class Person:
5+
def __init__(self, name: str, date_of_birth: date, preferred_operating_system: str):
6+
self.name = name
7+
self.date_of_birth = date_of_birth
8+
self.preferred_operating_system = preferred_operating_system
9+
10+
def is_adult(self) -> bool:
11+
today_year = date.today().year
12+
birth_year = self.date_of_birth.year
13+
age = today_year - birth_year
14+
15+
if date.today().month > self.date_of_birth.month:
16+
return age >= 18
17+
elif date.today().month == self.date_of_birth.month:
18+
return date.today().day >= self.date_of_birth.day and age >= 18
19+
else:
20+
return age - 1 >= 18
21+
22+
23+
imran = Person("Imran", date(2007,1,19), "Ubuntu")
24+
print(imran.is_adult())

prep-sprint5/mypy-checking.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
def open_account(balances:dict, name:str, amount:int) -> None:
2+
balances[name] = amount
3+
4+
def sum_balances(accounts) -> int:
5+
total = 0
6+
for name, pence in accounts.items():
7+
print(f"{name} had balance {pence}")
8+
total += pence
9+
return total
10+
11+
def format_pence_as_string(total_pence: int) -> str:
12+
if total_pence < 100:
13+
return f"{total_pence}p"
14+
pounds = int(total_pence / 100)
15+
pence = total_pence % 100
16+
return f"£{pounds}.{pence:02d}"
17+
18+
balances = {
19+
"Sima": 700,
20+
"Linn": 545,
21+
"Georg": 831,
22+
}
23+
24+
open_account(balances,"Tobi", int(9.13 * 100))
25+
open_account(balances,"Olya", int(7.13 * 100))
26+
27+
total_pence = sum_balances(balances)
28+
total_string = format_pence_as_string(total_pence)
29+
30+
print(f"The bank accounts total {total_string}")
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'''Try changing the type annotation of Person.preferred_operating_system from str to List[str].
2+
Run mypy on the code.
3+
It tells us different places that our code is now wrong, because we’re passing values of the wrong type.
4+
We probably also want to rename our field - lists are plural. Rename the field to preferred_operating_systems.
5+
Run mypy again.
6+
Fix all of the places that mypy tells you need changing. Make sure the program works as you’d expect.'''
7+
8+
from dataclasses import dataclass
9+
from typing import List
10+
11+
@dataclass(frozen=True)
12+
class Person:
13+
name: str
14+
age: int
15+
preferred_operating_systems: List[str]
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: str
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 in person.preferred_operating_systems:
31+
possible_laptops.append(laptop)
32+
return possible_laptops
33+
34+
35+
people = [
36+
Person(name="Imran", age=22, preferred_operating_systems=["Ubuntu", "Arch Linux"]),
37+
Person(name="Eliza", age=34, preferred_operating_systems=["Arch Linux"]),
38+
]
39+
40+
laptops = [
41+
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system="Arch Linux"),
42+
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="Ubuntu"),
43+
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="ubuntu"),
44+
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system="macOS"),
45+
]
46+
47+
for person in people:
48+
possible_laptops = find_possible_laptops(laptops, person)
49+
print(f"Possible laptops for {person.name}: ")
50+
for each in possible_laptops:
51+
print(f" - ID:{each.id} {each.manufacturer} {each.model} ({each.operating_system})")
52+
print()

0 commit comments

Comments
 (0)