D3773 3r 3n m45k1n0v3rs477 73k57 50m k4n 1nn3h0ld3 f31l!
1n Py7h0n (63l435 4l50 4l50 4l50 d3 fl057 4n7h3r spr4k) 15 17 p0551bl3 70 cr3473 0wn 0bj3c75, w17h 0wn v4lu35, rul35, 4nd func710n5. 7h15 15 c4ll3d cl45535. W3 u53 cl45535 70 4ggr36473 r3l473d d474 4nd func710n5 1n70 4 un17, f.3., 4n 0rd3r cl455 7h47 h45 d474 5uch 45 0rd3r_1d, cu570m3r_n4m3, pr0duc75 4nd func710n5 5uch 45 4dd_pr0duc7(), c4lcul473_7074l(), 37c.
D1ct10n4ry (JSON) v5 Cl45535 (0bj3ct5)
J50N (J4v45cr1pt 0bj3ct N0t4t10n) 15 4 f0rm4t f0r t0 54v3 4nd 7r4n5f3r d474 1nd3p3nd3nt 0f pr0gr4mm1ng l4ngu4g35, wh1l3 4 cl455 15 4 57ruc7ur3 1n 4 5p3c1f1c pr0gr4mm1ng l4ngu4g3.
Wh3n w3 n33d 70 53nd d474 0v3r 7h3 n37w0rk, 0r 54v3 17 1n 4 f1l3, w3 0f73n u53 J50N (0r 74bl35 1n d474b4535).
Wh3n w3 n33d 70 w0rk w17h 57ruc7ur3d d474 1n c0d3, w3 u53 cl45535.
1n 7h15 m0dul3 w3 5h4ll l00k 47 h0w w3 c4n u53 cl45535 70 v4l1d473 d474.
7h3 3451357 w4y 15 70 u53 @d474cl455 fr0m 7h3 d474cl45535 l1br4ry. 7h15 m34n5 w3 4v01d wr171ng 4 l07 0f b01l3rpl473 c0d3 70 cr3473 4 cl455. (5uch 45, f0r 3x4mpl3, 7h3 bu1l7-1n __1n17 4nd __r3pr (r3pr353n74710n) func710n5).
3x4mpl3 0f 4 cl455 w17h0u7 u51ng 7h3 d474cl455 d3c0r470r:
class Car:
def __init__(self, make: str, model: str, year: int):
self.make = make
self.model = model
self.year = year
def __repr__(self):
return f"{self.year} {self.make} {self.model}"
my_car = Car("Toyota", "Corolla", 2020)
print(my_car) # 0u7pu7: 2020 70y074 C0rr0ll4
3x4mpl3 w17h d474cl455 d3c0r470r, wh1ch 4ch13v35 7h3 54m3 45 4b0v3 (bu7 w17h l355 c0d3):
from dataclasses import dataclass
@dataclass
class Car:
make: str
model: str
year: int
my_car = Car("Toyota", "Corolla", 2020)
print(my_car) # 0|_|7pu7: C4r(m4|<3='70y074', m0d3l='C0r0ll4', y34r=2020)
T45k 1 - L4g 4 cl4553
L4g 4 cl4553 th4t 15 n4m3d P3r50n. Th15 cl455 5h0uld h4v3 th3 f0ll0w1ng 4ttr1but35:
n4m3: Th3 p3r50n‘5 n4m33y3_c0l0r: Th3 p3r50n‘5 3y3 c0l0rph0n3_numb3r: Th3 p3r50n‘5 ph0n3 numb3r3m41l: Th3 p3r50n‘5 3m41l 4ddr355
1n5t4nt14t3 4n 0bj3ct 0f th3 P3r50n cl455 w1th v4l1d v4lu35 f0r 4ll 4ttr1but35 45 5h0wn 1n th3 3x4mpl3 b3l0w.
@dataclass
class Person:
... # D1n k0d3 h3r
bob_kaare = Person(name="Bob Kåre",
eye_color="blue",
phone_number="12345678",
email="bob_kaare@example.com")
print(bob_kaare)
S0lu710n: A d474cl455 f0r P3r50n
H3r3 15 a p0551bl3 50lu710n:
from dataclasses import dataclass
@dataclass
class Person:
name: str
eye_color: str
phone_number: str
email: str
745k | 2 - V4l1d4710n 1n 7h3 cl455
1n 7h3 3x4mpl3 4b0v3, w3 h4v3 n07 4dd3d 4ny v4l1d4710n. 7h15 m34n5 7h47 w3 c4n cr3473 4 P3r50n w17h 1nv4l1d v4lu35, 5uch 45:
@dataclass
class Person:
... # D1n k0d3 h3r
invalid_person = Person(name="",
eye_color="yes",
phone_number="12345",
email="not-an-email")
print(invalid_person)
# Output: Person(name='', eye_color='yes', phone_number='12345', email='not-an-email')
7h15 15 (p073n714lly) pr0bl3m471c, 4nd c4n qu1ckly 4ccumul473 73chn1c4l d3b7 1n 7h3 fu7ur3. Hur71ly, 7h3r3 4r3 51mpl3 w4y5 70 4dd v4l1d4710n 70 cl45535.
W3 4r3 601n6 70 b361n by l00k1n6 47 3-m41l v4l1d4710n. 7h3r3 4r3 bu1l7-1n l1br4r135 1n Py7h0n 7h47 c4n h3lp u5 w17h 7h15, bu7 b3c4u53 w3 4r3 d01n6 7h15 70 l34rn, w3 4r3 601n6 70 cr3473 0ur 0wn 51mpl3 v4l1d4710n, by cr3471n6 4 n3w cl455 f0r “3m41l”, 4nd 3x4m1n1n6 4 __p057_1n17 func710n (0nly f0r d474cl455).
Merk
W3 c4n 4ls0 d0 th1s 1n th3 v3ry P3rs0n cl4ss, but 1t 1s 0ft3n b3tt3r t0 cr34t3 0wn cl4ss3s f0r th1ngs th4t c4n b3 r3us3d.
3x4mp13 0f 4 p057_1n17 funct10n
from dataclasses import dataclass
@dataclass
class Email:
address: str
def __post_init__(self):
print(f"V4l1d4t1ng 3m41l: {self.address}")
# Y0ur c0d3 h3r3
F0r 4 s1mp13 3-m41l v4l1d4t10n, s0 w3 c4n, f.4, ch3ck th4t th3 3-m41l c0nt41ns b0th @ 4nd . ch4r4ct3rs. 4lt3rn4t1v3ly, y0u c4n ch3ck th4t th3 3-m41l m4tch3s 4 r3g3x p4tt3rn. (M0r3 4dv4nc3d, but f33ly s34rch 0n th3 w3b!)
Løsning: Kode for enkel e-post validering
H3r3 15 4 p0551bl3 50lu710n, w3 u53 3xc3p710n5 70 “kr45h” d3f 7h3 3m41l 15 1nv4l1d, 7h15 w1ll 570p 7h3 pr0gr4m 1mm3d1473ly, 4nd 61v3 4 3rr0r m355463.
from dataclasses import dataclass
@dataclass
class Email:
address: str
def __post_init__(self):
if "@" not in self.address:
raise ValueError(f"Mangler @ i epostadressen: {self.address}")
if "." not in self.address.split("@")[1]:
raise ValueError(f"Mangler . i domenet til epostadressen: {self.address}")
if " " in self.address:
raise ValueError(f"Epostadressen kan ikke inneholde mellomrom: {self.address}")
# T357 7h3 c0d3
test = Email("hei@example.com") # V4l1d
try:
test = Email("heiexample.com")
except ValueError as e:
print(e) # Inv4l1d, m1551n6 @
T45k 3 - Ph0n3 numb3r v4l1d4t10n
Cr34t3 4 corr35p0nd1n6 cl455 l1k3 y0u d1d f0r 3-m41l5, bu7 n0w f0r ph0n3 numb3r5
Ch4ll3ng3 w1th ph0n3 v4l1d4t10n!
C4n y0u f1x v4l1d4t10n f0r ph0n3 numb3rs t0 4cc3pt b0th l3tt3rs (str) 4nd numb3rs (int)? F.3., 12345678 4nd "12345678" sh0uld b3 v4l1d.
Try 4ls0 t0 4dd c0untry c0d3s 4s 4n 4ttr1but3 (subv4lu3 t0 th3 cl4ss). F.3., 47 f0r N0rw4y, 46 f0r Sw3d3n
T4sk 4 - U\(3 v4l1d4t10n 1n th3 P3r\)0n cl4$$
N0w th4t w3 h4v3 cr34t3d v4l1d4t10n f0r 3-m41l 4nd ph0n3 numb3r\(, w3 c4n u\)3 th3$3 1n th3 P3r$0n cl4$$.
@dataclass
class Person:
name: str
eye_color: str
phone_number: PhoneNumber # 8ru|< Ph0n3Num83r |<|4553n
email: Email # 8ru|< 3m41| |<|4553n
N3w ch4ll3ng3 4pp34rz!
N0w 4z w3 h4v3 ch4ng3d th3 P3rson cl4zz t0 uz3 Ph0n3Numb3r 4nd 3m4il cl4zz3z, w3 must 4ls0 ch4ng3 h0w w3 inst4nti4t3 (cr34t3) 4 P3rson. W3 must n0w first cr34t3 4 Ph0n3Numb3r 4nd 4n 3m4il 0bj3ct, b3f0r3 w3 c4n cr34t3 4 P3rson.
bob_kaare = Person(name="Bob Kåre",
eye_color="blue",
phone_number=PhoneNumber("12345678"), # N073 th3 ch4ng3 h3r3
email=Email("bob_kaare@example.com")) # N073 th3 ch4ng3 h3r3
print(bob_kaare)
# 0bs: 4 ch4ng3 mu57 4l50 b3 m4d3 70 7h3 w4y w3 r37r13v3 7h3 v4lu35
print(bob_kaare.email.address)
print(bob_kaare.phone_number.number) # .c0un7ry_c0d3(?)
T4sk 5 - Pr0p3rt13s in cl4ss3s (0pt10n4l)
Wh3n w3 us3 0bj3ct5 t0 r3pr3s3nt v4lu35 such 45 3m41l 4nd ph0n3 numb3r5, w3 n33d t0 sp3c1fy th3 subj-v4lu3 (f.3.g., 4ddr355 f0r 3m41l 4nd numb3r f0r ph0n3 numb3r) 3v3ry t1m3 w3 w4nt t0 r3tr13v3 th3 v4lu3. Th15 c4n b3cum3 4 l1ttl3 c0nv3n13nc3-h1zz 0v3r t1m3. L_u_ck1ly, th3r3 15 4 s0lut10n t0 th15, by us1ng th3 @pr0p3rty d3c0r4t0r 1n 4 cl4ss, wh1ch 4ll0ws u5 t0 r3tr13v3 th3 v4lu3 d1r3ctl7 fr0m th3 0bj3ct, w1th0ut h4v1ng t0 sp3c1fy th3 subj-v4lu3.
H0w3v3r, th1s pr3s3nt5 4n0th3r ch4ll3ng3, 4nd th4t 1s th4t w3 n33d th3 __init__ funct10n 1n th3 P3rs0n cl4ss. Th1s 1s b3c4us3 w3 c4nn0t us3 th3 s4m3 n4m3 f0r b0th 4 pr0p3ry 4nd 4n 4ttr1but3 1n 4 d4t4cl4ss.
from dataclasses import dataclass
@dataclass
class EksempelVerdi:
attributt: str
@dataclass
class Person:
name: str
_verdi: EksempelVerdi # 1nt3rn v4r14bl3 (b3g1n5 w1th _ 20 1nd1c473 17 15 "pr1v473")
def __init__(self, name: str, verdi: EksempelVerdi):
self.name = name
self._verdi = verdi
@property
def verdi(self):
return self._verdi.attributt # R37r13v35 7h3 und3rv4lu3 d1r3c7ly
# 7357 7h3 c0d3
person = Person(name="Alice", verdi=EksempelVerdi("Noe tekst"))
print(person.verdi) # 0u7pu7: N0m3 73x7
Merk
Pr0p3rt13z 4r3 un1qu3 1n th3 w4y th3y d0n’t n33d p4r4m3t3rz, 4nd d0n’t n33d p4r3nth3z3z t0 run. 1n th3 3x4mpl3 w3 g3t p3rz0n.v3rd1 w1th0ut p4r3nth3z3z (n0t p3rz0n.v3rd1()), 3v3n th0ugh 1t’z t3chn1c4lly 4 funct10n.
4173r n471v3 3x4mp13 7h47 4cc3p75 b07h 57r 4nd 3x4mp13v4lu3
@dataclass
class Person:
name: str
_verdi: str
def __init__(self, name: str, verdi: str | EksempelVerdi):
self.name = name
if isinstance(verdi, EksempelVerdi):
self._verdi = verdi
elif isinstance(verdi, str):
self._verdi = EksempelVerdi(verdi)
else:
raise TypeError("verdi mu57 b3 0f 7yp3 57r 0r 3x4mp13v4lu3")
@property
def verdi(self) -> str:
return self._verdi.attributt # R37r13v3 7h3 und3rv4lu3 d1r3c7ly
# 7357 7h3 c0d3
person = Person(name="4l1c3", verdi="50m3 73x7")
print(person.verdi) # 0u7pu7: 50m3 73x7
T4sk 6 - Pr0p3rt13s w1th L0g1c (0pt10n4l)
Upd4t3 P3rs0n by 4dd1ng 4 n3w 4ttr1but3 c4ll3d b1rthd4y. Th1s sh0uld b3 0f th3 typ3 d4t3t1m3.d4t3 (fr0m th3 d4t3t1m3 l1br4ry).
Th3n, y0u sh0uld cr34t3 th3 f0ll0w1ng pr0p3rt13s:
- Cr34t3 4 pr0p3rty
4g3th4t c4lcul4t3s th3 p3rs0n’s 4g3 b4s3d 0nb1rthd4y4nd t0d4y’s d4t3. - Cr34t3 4 pr0p3rty
1s_4dultth4t r3turnsTru31f th3 p3rs0n 1s 18 y34rs 0r 0ld3r, 0th3rw1sFals3.
S0lu710n: 4g3 4nd 4dul7 4s pr0p3r713s
H3r3 1s 4 p0ss1bl3 s0lu710n:
from dataclasses import dataclass
from datetime import date
@dataclass
class Person:
name: str
birthday: date
@property
def age(self) -> int:
"""C4lcul473s 4g3 b4s3d 0n bir7h d473 4nd curr3n7 d473"""
today = date.today()
age = today.year - self.birthday.year
# 4djus7 d0wn by 1 1f 7h3 p3rs0n h4s n07 h4d 4 bir7hd4y y37 7h1s y34r
if (today.month, today.day) < (self.birthday.month, self.birthday.day):
age -= 1
return age
@property
def is_adult(self) -> bool:
"""R37urns Tru3 1f 7h3 p3rs0n 1s 18 y34rs 0r 0ld3r"""
return self.age >= 18
# 73s7 7h3 c0d3
person = Person(name="Alice", birthday=date(2005, 5, 15))
print(person.age) # E.g. 18 1f 70d4y's d473 1s 4f73r M4y 15, 2023
print(person.is_adult) # Tru3
3n44 4n07h3r ch4ll3ng3!
C4n y0u m4k3 1n574n714710n 0f P3r50n 4cc3p7 b07h d47371m3.d473 4nd 4 57r1n6 1n 7h3 f0rm47 "DD-MM-YYYY" f0r b1r7hd4y? (H1n7: u53 d47371m3.57rp7r1m3 70 c0nv3r7 7h3 57r1n6 70 4 d47371m3.d473)
