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

Python Okenní aplikace Upomínač narozenin v PyQt - Logická vrstva

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

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 dnenší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

Pokračovat budeme zas v příští lekci, Upomínač narozenin v PyQt - Dokončení aplikace, kdy aplikaci zprovozníme.


 

 

Článek pro vás napsal MQ .
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor je srdcem Pythonista.
Aktivity (9)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!