5. diel - PRIPOMIENKOVÉ narodenín v PyQt - Logická vrstva
V minulej lekcii, PRIPOMIENKOVÉ narodenín v PyQt - Dokončenie návrhu formulárov , sme navrhli kompletne formuláre pre našu PyQt aplikáciu pre upomínania narodenín osôb. V dnenším Python tutoriálu sa budeme zaoberať návrhom logické vrstvy, teda tried, ktoré obsahujú logiku aplikácie.
Osoba
V našej aplikácii budú celkom iste figurovať osoby, vytvorme im teda
novú triedu. Ďalšie triedy budeme teraz pridávať nad triedu
App
.
Vlastnosti
Osoba bude mať 2 vlastnosti: meno a narodeniny. Tieto vlastnosti nastavíme pomocou konstruktoru.
class Osoba(): def __init__(self, jmeno, narozeniny): self.jmeno = jmeno self.narozeniny = narozeniny
Metódy
Okrem konstruktoru bude trieda disponovať metódami
spocti_vek()
a zbyva_dni()
.
Spocti_vek ()
Metóda vypočíta a vráti aktuálne vek osoby v celých rokoch, výpočet veku teda vykonáme nasledujúcim spôsobom:
- Získame si aktuálny dátum (bez času) pomocou
datetime.datetime.now().date()
. Práve zavolaniedate()
vráti len dátum z aktuálneho dátumu a času. - Vek spočítame ako rozdiel rokov v aktuálnom dátume a dátume narodenín. Asi je vám jasné, že tento vek nie je presný. Ak sme sa narodili 1.2.1990 a je 1.1.2020, nie je nám 30 rokov, ale len 29. Z toho dôvodu vykonáme korekciu.
- V prípade, že je aktuálny dátum menšia (skôr) ako dátum narodenia po pridaní nami vypočítaných rokov, nastal vyššie uvedený prípad a my vek o rok znížime.
- Hotový vek vrátime.
Kód metódy bude nasledujúci:
def spocti_vek(self): dnes = datetime.datetime.now() vek = dnes.year - self.narozeniny.year if dnes < self.narozeniny.replace(year=self.narozeniny.year + vek): vek -= 1 return vek
Zbyva_dni ()
Metóda nám vráti koľko dní zostáva do narodenín osoby. To zistíme nasledujúcim spôsobom:
- Získame si aktuálny dátum (opäť bez času).
- Získame dátum ďalších narodenín pripočítaním veku + 1 k dátumu narodenia.
- Dáta odčítame a celkový rozdiel v dňoch vrátime.
def zbyva_dni(self): dnes = datetime.datetime.now() dalsi_narozeniny = self.narozeniny + relativedelta(years = self.spocti_vek() + 1) rozdil = dalsi_narozeniny - dnes return rozdil.days
Pripočítanie rokov vykonáme cez funkciu relativedelta()
. Tú
si importujte pomocou riadku:
from dateutil.relativedelta import relativedelta
Radšej umiestnime medzi importy na začiatok súboru.
__str __ ()
Keďže budeme osoby vypisovať, vytvoríme metódu __str__()
tak, aby vracala meno osoby:
def __str__(self): return self.jmeno
Správca osôb
Ďalšie logickú komponentom aplikácia bude správca osôb. Trieda sa bude starať o osoby, bude ich vedieť pridávať, odoberať a ich zoznam ukladať do súboru a opätovne načítať. Konečne bude vedieť medzi osobami vyhľadať tú, ktorá má najbližšie narodeniny.
Všimnite si, ako je aj za úlohu spravovanie osôb zodpovedná oddelená trieda a tieto metódy nemiešame s metódami GUI. V kalkulačke sme túto návrhovú praktiku zanedbali, pretože to bola naša prvá aplikácia a bola tiež veľmi jednoduchá. Odteraz budeme však do GUI písať vždy len obsluhu používateľského rozhrania a akúkoľvek logiku vždy oddelíme do samostatných tried.
Vlastnosti a atribúty
Jedinou vlastnosťou triedy je zoznam osôb. Zoznam osôb bude iba obyčajný list / pole, do ktorého budeme osoby pridávať.
Trieda zatiaľ vyzerá takto:
class SpravceOsob():
osoby = []
Metódy
Okrem pridávanie a odoberanie bude trieda vedieť aj nájsť osobu s najbližšími narodeninami. Ukladanie a načítanie osôb do / zo súboru necháme na neskôr.
Pridajme ()
Metóda pridá novú osobu do poľa / listu. Keďže osobu pridávame formulárom, hodí sa nám, aby metóda brala v parametroch vlastnosti osoby a na ich základe vytvorila novú inštanciu. Z dátumu narodenia uložíme iba časť s dátumom, teda bez času.
Tu zadané dátum ošetrovať nemusíme, pretože používateľ nemá možnosť zadať dátum v budúcnosti vďaka vygenerovaným hodnotám.
def pridej(self, jmeno, datum_narozeni):
osoba = Osoba(jmeno, datum_narozeni)
self.osoby.append(osoba)
Odober ()
Metóda odoberie osobu z poľa / listu. Pretože vždy budeme chcieť odoberať už hotovú osobu, berie metóda v parametri práve tú.
def odeber(self, osoba):
self.osoby.remove(osoba)
Najdi_nejblizsi ()
Metóda nájde a vráti osobu, ktorá má najbližšie narodeniny. Na vyhľadanie osoby v liste použijeme funkciu `sorted (), ktorá vráti osoby usporiadané podľa kľúča. V našom prípade kľúčom bude koľko dní zostáva do ich narodenín.
def najdi_nejblizsi(self): if len(self.osoby) > 0: serazene = sorted(self.osoby, key = lambda item: item.zbyva_dni()) return serazene[0] return None
Pokračovať budeme zas v budúcej lekcii, PRIPOMIENKOVÉ narodenín v PyQt - Dokončenie aplikácie , kedy aplikáciu sprevádzkujeme.