IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 6 - Upomínač narozenin v PyQt - Logická vrstva

V minulé lekci, Upomínač narozenin v PyQt - Dokončení návrhu formulářů, jsme navrhli kompletně formuláře pro naši PyQt aplikaci pro upomínání narozenin osob.

V dnešním Python tutoriálu se budeme zabývat návrhem logické vrstvy, tedy tříd, které obsahují logiku aplikace.

Osoba

V naší aplikaci budou zcela jistě figurovat osoby, vytvořme jim tedy novou třídu. Další třídy budeme nyní přidávat nad třídu App.

Vlastnosti

Osoba bude mít 2 vlastnosti: jméno a narozeniny. Tyto vlastnosti nastavíme pomocí konstruktoru.

class Osoba():
    def __init__(self, jmeno, narozeniny):
        self.jmeno = jmeno
        self.narozeniny = narozeniny

Metody

Kromě konstruktoru bude třída disponovat metodami spocti_vek() a zbyva_dni().

spocti_vek()

Metoda vypočítá a vrátí aktuální věk osoby v celých letech, výpočet věku tedy provedeme následujícím způsobem:

  • Získáme si aktuální datum (bez času) pomocí datetime.datetime.now().date(). Právě zavolání date() vrátí pouze datum z aktuálního data a času.
  • Věk spočítáme jako rozdíl roků v aktuálním datu a datu narozenin. Asi je vám jasné, že tento věk není přesný. Pokud jsme se narodili 1.2.1990 a je 1.1.2020, není nám 30 let, ale jen 29. Z toho důvodu provedeme korekci.
  • V případě, že je aktuální datum menší (dříve) než datum narození po přidání námi vypočítaných let, nastal výše uvedený případ a my věk o rok snížíme.
  • Hotový věk vrátíme.

Kód metody bude následující:

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()

Metoda nám vrátí kolik dní zbývá do narozenin osoby. To zjistíme následujícím způsobem:

  • Získáme si aktuální datum (opět bez času).
  • Získáme datum dalších narozenin přičtením věku + 1 k datu narození.
  • Data odečteme a celkový rozdíl ve dnech vrátíme.
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

Přičtení roků provedeme přes funkci relativedelta(). Tu si naimportujte pomocí řádku:

from dateutil.relativedelta import relativedelta

Řáde umístíme mezi importy na začátek souboru.

__str__()

Jelikož budeme osoby vypisovat, vytvoříme metodu __str__() tak, aby vracela jméno osoby:

def __str__(self):
    return self.jmeno

Správce osob

Další logickou komponentou aplikace bude správce osob. Třída se bude starat o osoby, bude je umět přidávat, odebírat a jejich seznam ukládat do souboru a opětovně načíst. Konečně bude umět mezi osobami vyhledat tu, která má nejbližší narozeniny.

Všimněte si, jak je i za úlohu spravování osob zodpovědná oddělená třída a tyto metody nemícháme s metodami GUI. V kalkulačce jsme tuto návrhovou praktiku zanedbali, protože to byla naše první aplikace a byla také velmi jednoduchá. Odteď budeme ovšem do GUI psát vždy jen obsluhu uživatelského rozhraní a jakoukoli logiku vždy oddělíme do samostatných tříd.

Vlastnosti a atributy

Jedinou vlastností třídy je seznam osob. Seznam osob bude pouze obyčejný list/pole, do kterého budeme osoby přidávat.

Třída zatím vypadá takto:

class SpravceOsob():
    osoby = []

Metody

Kromě přidávání a odebírání bude třída umět i nalézt osobu s nejbližšími narozeninami. Ukládání a načítání osob do/ze souboru necháme na později.

pridej()

Metoda přidá novou osobu do pole/listu. Jelikož osobu přidáváme formulářem, hodí se nám, aby metoda brala v parametrech vlastnosti osoby a na jejich základě vytvořila novou instanci. Z data narození uložíme pouze část s datem, tedy bez času.

Zde zadané datum ošetřovat nemusíme, jelikož uživatel nemá možnost zadat datum v budoucnosti díky vygenerovaným hodnotám.

def pridej(self, jmeno, datum_narozeni):
    osoba = Osoba(jmeno, datum_narozeni)
    self.osoby.append(osoba)

odeber()

Metoda odebere osobu z pole/listu. Protože vždy budeme chtít odebírat již hotovou osobu, bere metoda v parametru právě tu.

def odeber(self, osoba):
    self.osoby.remove(osoba)

najdi_nejblizsi()

Metoda najde a vrátí osobu, která má nejbližší narozeniny. K vyhledání osoby v listu použijeme funkci `sorted(), která vrátí osoby uspořádané podle klíče. V našem případě klíčem bude kolik dní zbývá do jejich narozenin.

def najdi_nejblizsi(self):
    if len(self.osoby) > 0:
        serazene = sorted(self.osoby, key = lambda item: item.zbyva_dni())
        return serazene[0]
    return None

V další lekci, Upomínač narozenin v PyQt - Dokončení aplikace, dokončíme aplikaci Upomínač narozenin.


 

Předchozí článek
Upomínač narozenin v PyQt - Dokončení návrhu formulářů
Všechny články v sekci
PyQt - Okenní aplikace v Pythonu
Přeskočit článek
(nedoporučujeme)
Upomínač narozenin v PyQt - Dokončení aplikace
Článek pro vás napsal MQ .
Avatar
Uživatelské hodnocení:
22 hlasů
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity