Skip to content

Commit 6dff387

Browse files
add lesson #11 slides, script
1 parent 5ed9ac9 commit 6dff387

File tree

3 files changed

+222
-0
lines changed

3 files changed

+222
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
06. [Потоки, процессы, IPC](lesson-06)
1111
07. [Асинхронное программирование](lesson-07)
1212
08. [Память, профилирование](lesson-08)
13+
09. [Логирование, отладка](lesson-09)
1314
10. [C-расширения](lesson-10)
15+
11. [Аннотация типов](lesson-11)
1416

1517

1618
## Правила оформления домашек на github

lesson-11/hints_check.py

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
from collections.abc import Iterable, Sequence
2+
from dataclasses import dataclass
3+
from typing import (
4+
Any,
5+
Generator,
6+
NewType,
7+
Protocol,
8+
runtime_checkable,
9+
TypeVar,
10+
TYPE_CHECKING,
11+
)
12+
13+
14+
type UserData = dict[str, str | int | None]
15+
type OptUserData = UserData | None
16+
17+
18+
@dataclass
19+
class User:
20+
user_id: str
21+
name: str
22+
age: int
23+
24+
def __bool__(self) -> bool:
25+
return not not self.user_id
26+
27+
28+
@dataclass
29+
class Student(User):
30+
pass
31+
32+
33+
def fetch_user(user_id: str) -> UserData:
34+
return {
35+
"user_id": user_id,
36+
"name": "Steve",
37+
"age": 99,
38+
}
39+
40+
41+
def get_user_data(user: User) -> OptUserData:
42+
if not user:
43+
return None
44+
45+
data = fetch_user(user.user_id)
46+
47+
return data
48+
49+
50+
def run_user() -> None:
51+
user = User("123", "steve", 99)
52+
res: OptUserData = get_user_data(user)
53+
print(f"111: {res=} for {user=}")
54+
55+
user = User("", "", 0)
56+
res = get_user_data(user)
57+
print(f"222: {res=} for {user=}")
58+
59+
user = Student("456", "stud", 239)
60+
res = get_user_data(user)
61+
print(f"333: {res=} for {user=}")
62+
63+
64+
Celcius = NewType("Celcius", float)
65+
Fareng = NewType("Fareng", float)
66+
67+
68+
def convert_celcius_to_fareng(temp: Celcius) -> Fareng:
69+
return Fareng(temp * 9 / 5 + 32)
70+
71+
72+
def gen_celcius_temps(start: Celcius) -> Generator[Celcius, None, str]:
73+
# if False:
74+
# yield start
75+
yield start
76+
yield Celcius(start + 7)
77+
yield Celcius(start + 10)
78+
79+
return "finished"
80+
81+
82+
# def get_max_temp(temps: tuple[Celcius, ...]) -> Celcius | None:
83+
84+
def get_max_temp(temps: Iterable[Celcius]) -> Celcius | None:
85+
if not temps:
86+
return None
87+
88+
return max(temps)
89+
90+
91+
def get_first_temp(temps: Sequence[Celcius]) -> Celcius | None:
92+
if not temps:
93+
return None
94+
95+
return temps[0]
96+
97+
98+
def run_temp() -> None:
99+
temp = Celcius(36.6)
100+
res: float = convert_celcius_to_fareng(temp)
101+
print(f"111: {res=} for {temp=}, {type(res)=}")
102+
103+
temp = Celcius(-40)
104+
res = convert_celcius_to_fareng(temp)
105+
print(f"222: {res=} for {temp=}, {type(res)=}")
106+
107+
temps: Iterable[Celcius] = [Celcius(-40), Celcius(5), Celcius(0)]
108+
max_temp = get_max_temp(temps)
109+
print(f"333: {max_temp=} for {temps=}")
110+
111+
temps = []
112+
max_temp = get_max_temp(temps)
113+
print(f"444: {max_temp=} for {temps=}")
114+
115+
temps = (Celcius(8), Celcius(5), Celcius(0))
116+
max_temp = get_max_temp(temps)
117+
print(f"555: {max_temp=} for {temps=}")
118+
119+
temps = gen_celcius_temps(Celcius(25))
120+
max_temp = get_max_temp(temps)
121+
print(f"666: {max_temp=} for {temps=}")
122+
123+
temps = [Celcius(-40), Celcius(5), Celcius(0)]
124+
first_temp = get_first_temp(temps)
125+
print(f"777: {first_temp=} for {temps=}")
126+
127+
# temps = gen_celcius_temps(Celcius(25))
128+
# first_temp = get_first_temp(temps)
129+
# print(f"888: {first_temp=} for {temps=}")
130+
131+
132+
@runtime_checkable
133+
class Comparable(Protocol):
134+
def __lt__(self: "T", other: "T") -> bool: ...
135+
def __gt__(self: "T", other: "T") -> bool: ...
136+
137+
138+
T = TypeVar("T", bound=Comparable)
139+
140+
141+
def get_max_temp_generic(temps: Iterable[T]) -> T | None:
142+
if not temps:
143+
return None
144+
145+
return max(temps)
146+
147+
148+
def get_first_temp_generic[V](temps: Sequence[V]) -> V | None:
149+
if not temps:
150+
return None
151+
152+
return temps[0]
153+
154+
155+
def run_generic() -> None:
156+
temps = [Celcius(-40), Celcius(5), Celcius(0)]
157+
max_temp = get_max_temp_generic(temps)
158+
print(f"111: {max_temp=} for Celcius {temps=}")
159+
160+
fareng_temps = [Fareng(-40), Fareng(5), Fareng(0)]
161+
max_f_temp = get_max_temp_generic(fareng_temps)
162+
print(f"222: {max_f_temp=} for Farengs {fareng_temps=}")
163+
164+
print(f"333: {isinstance(Celcius(-40), Comparable)=}, {isinstance('qwert', Comparable)=}")
165+
166+
temps = [Celcius(-40), Celcius(5), Celcius(0)]
167+
first_temp = get_first_temp_generic(temps)
168+
print(f"444: {first_temp=} for Celcius {temps=}")
169+
170+
fareng_temps = [Fareng(-40), Fareng(5), Fareng(0)]
171+
first_f_temp = get_first_temp_generic(fareng_temps)
172+
print(f"555: {first_f_temp=} for Farengs {fareng_temps=}")
173+
174+
175+
@runtime_checkable
176+
class Predictable(Protocol):
177+
def predict(self) -> float:
178+
pass
179+
180+
181+
class RandomForest:
182+
def predict(self) -> float:
183+
return 0.95
184+
185+
186+
class NoPredict:
187+
def no_predict(self) -> float:
188+
return 0.1
189+
190+
191+
def calc_prediction(model: Predictable) -> float:
192+
# return model.predict()
193+
return 0.5
194+
195+
196+
def run_protocol() -> None:
197+
model = RandomForest()
198+
score = calc_prediction(model)
199+
print(f"{score=}, {isinstance(model, Predictable)=}")
200+
201+
model2 = NoPredict()
202+
print(f"{isinstance(model2, Predictable)=}")
203+
score = calc_prediction(model2)
204+
205+
206+
if __name__ == "__main__":
207+
print(f"{TYPE_CHECKING=}")
208+
209+
run_user()
210+
print()
211+
212+
run_temp()
213+
print()
214+
215+
run_generic()
216+
print()
217+
218+
run_protocol()
219+
220+
print("ok")

lesson-11/lesson-11.pdf

584 KB
Binary file not shown.

0 commit comments

Comments
 (0)