4. gyakorlat¶
Warning
Figyelem! A héten kiadásra kerül a második beadandó, 8 pontért! Bővebb információ CooSpace-en.
A gyakorlat anyaga¶
Dátumok kezelése¶
A datetime
modul néhány részét nézzük meg az órán, azonban mindenkit arra bíztatunk, hogy nyugodtan fedezze fel a modulban rejlő egyéb lehetőségeket is: https://docs.python.org/3/library/datetime.html
Dátum objektumok¶
A dátumok a datetime
modul date
osztályában találhatóak. Létrehozása: datetime.date(év, hónap, nap)
.
Ezekhez tartozó fontosabb metódusok és attribútumok:
Metódus | Leírás |
---|---|
today() |
visszaadja a mai napot date objektumként |
fromisoformat() |
paraméterként egy string -et vár (YYYY-MM-DD alakban), és ezt alakítja át date objektummá |
weekday() |
visszaadja a hét adott napját egy egész számként, ahol hétfő indexe 0, a vasárnap indexe 6 |
isoweekday() |
visszaadja a hét adott napját egy egész számként, ahol hétfő indexe 1, a vasárnap indexe 7 |
Attribútum | Leírás |
---|---|
year |
visszaadja az évet |
month |
visszaadja a hónapot |
day |
visszaadja a napot |
import datetime
def fn_date():
ma = datetime.date.today() # Class method, ami visszaadja a mai napot date objektumként
print(ma)
print(type(ma))
print("--")
egy_nap = datetime.date(2021, 3, 10)
print(egy_nap)
egy_nap2 = datetime.date.fromisoformat("2021-03-08")
print(egy_nap)
egy_nap3 = datetime.datetime.strptime("2021 (év) 03 (hó) 10. (nap)", "%Y (év) %m (hó) %d. (nap)")
print(egy_nap)
print(egy_nap.strftime("Év: %Y, hónap: %m, nap: %d"))
print(egy_nap.year)
print(egy_nap.month)
print(egy_nap.day)
print("operátorok")
print("<", egy_nap2 < egy_nap)
print(">", egy_nap2 > egy_nap)
print("==", egy_nap2 == egy_nap)
if datetime.date(2020, 12, 31) < datetime.date.today() < datetime.date(2021, 4, 1):
print("2021 első negyedévében vagyunk.")
print("--")
Idő objektumok¶
A idő a datetime
modul time
osztályában találhatóak. Létrehozása: datetime.time(óra, perc, másodperc, mikroszekundum)
, amennyiben valamelyiket paramétert kihagyjuk, 0-lesz az alapértelmezett értéke.
- 0 <= óra < 24
- 0 <= perc < 60
- 0 <= másodperc < 60
- 0 <= mikroszekundum < 1000000
Hozzá tartozó fontosabb metódusok és attribútumok:
Metódus | Leírás |
---|---|
fromisoformat() |
paraméterként egy string -et vár (HH:MM:SS.ffffff vagy HH:MM:SS alakban), és ezt alakítja át time objektummá |
Attribútum | Leírás |
---|---|
hour |
visszaadja az órát |
minute |
visszaadja a percet |
second |
visszaadja a másodpercet |
microsecond |
visszaadja a mikroszekundumot (a másodperc egymilliomod része) |
min |
visszaadja a legkisebb időt ami a time(0, 0, 0, 0) |
max |
visszaadja a legnagyobb időt ami a time(23, 59, 59, 999999) |
import datetime
def fn_time():
# time - csak az ido kezelesere (a datum nem szamit)
# egy_idopillanat = datetime.time(12)
# egy_idopillanat = datetime.time(12, 00)
# egy_idopillanat = datetime.time(12, 0, 0)
# egy_idopillanat = datetime.time(12, 00, 00, 123)
egy_idopillanat = datetime.time(12, 10, 12, 123, datetime.timezone.utc)
print("time", egy_idopillanat)
print(egy_idopillanat.hour)
# Vigyázat! A min az a lehető legkisebb értéke az objektumnak!
print("min", egy_idopillanat.min)
print("max", egy_idopillanat.max)
print(egy_idopillanat.minute)
print(egy_idopillanat.second)
print(egy_idopillanat.microsecond)
print("--")
Dátum és idő objektumok¶
A datetime
modul datetime
osztályában találhatóak. Létrehozása: datetime.datetime(year, month, day, hour, minute, second, microsecond, tzinfo)
, amennyiben valamelyiket paramétert kihagyjuk, 0-lesz az alapértelmezett értéke.
Kötelező: year
, month
, day
Hozzá tartozó fontosabb metódusok és attribútumok:
Metódus | Leírás |
---|---|
now() |
visszaadja a mostani dátumot és időt (megadható neki paraméternek időzóna tz ) datetime objektumként |
fromisoformat() |
paraméterként egy string -et vár (ISO formátumban) és ezt alakítja át datetime objektummá |
strptime() |
paraméterként egy testszőlegesstring -et vár és ezt alakítja át datetime objektummá |
weekday() |
visszaadja a hét adott napját egy egész számként, ahol Monday az 0 és a Sunday az 6 |
isoweekday() |
visszaadja a hét adott napját egy egész számként, ahol Monday az 1 és a Sunday az 7 |
datetime.combine() |
paramétere egy date és egy time ebből hoz létre egy datetime -ot |
Attribútum | Leírás |
---|---|
year |
visszaadja az évet |
month |
visszaadja a hónapot (számként) |
day |
visszaadja a napot (számként) |
hour |
visszaadja az órát |
minute |
visszaadja a percet |
second |
visszaadja a másodpercet |
microsecond |
visszaadja a mikroszekundumot (a másodperc egymilliomod része) |
min |
visszaadja a legkisebb időt ami a time(0, 0, 0, 0) |
max |
visszaadja a legnagyobb időt ami a time(23, 59, 59, 999999) |
tzinfo |
időzóna` |
strptime() format kód |
Leírás |
---|---|
%d |
nap számmal (01, 02, ..., 31) |
%b |
hónap neve röviden (Jan, Feb, ..., Dec) |
%B |
hónap neve hosszan (January, February, ..., December) |
%m |
hónap számmal 01, 02, ..., 12 |
%y |
év számmal röviden (00, 01, ..., 99) |
%Y |
év 4 jegyű számként (0001, 0002, ..., 9999) |
%H |
óra 24-órás felbontásban (00, 01, ..., 23) |
%I |
óra 12-órás felbontásban (01, 02, ..., 12) |
%S |
másodperc számmal (00, 01, ..., 59) |
%f |
mikroszekundum számmal (000000, 000001, ..., 999999) |
import datetime
def fn_datetime():
most = datetime.datetime.now()
egy_nap = datetime.date(2021, 3, 10)
egy_idopillanat = datetime.time(12, 10, 12, 123, datetime.timezone.utc)
valamikor = datetime.datetime.combine(egy_nap, egy_idopillanat)
print(most)
print(valamikor)
print(most.year)
print(most.month)
print(most.day)
print(most.hour)
print(most.minute)
print(most.second)
print(most.microsecond)
print(most.tzinfo)
# 0 - Monday 1 - Tuesday 2 - Wednesday 3 - Thursday 4 - Friday 5 - Saturday 6 - Sunday
print(most.weekday())
# 1 - Monday 2 - Tuesday 3 - Wednesday 4 - Thursday 5 - Friday 6 - Saturday 7 - Sunday
print(most.isoweekday())
print("--")
Különbség¶
A timedelta
objektum 2 date vagy time közötti különbséget reprezentálja. Csak a napok, másodpercek, mikroszekundumok tárolódnak, a többit átalakítja.
- 1 millisecond -> 1000 microseconds
- 1 minute -> 60 seconds
- 1 hour -> 3600 seconds
- 1 week -> 7 days
Lehetséges értékek: - 0 <= mikroszekundumok < 1000000 - 0 <= másodpercek < 3600*24 - 999999999 <= napok <= 999999999
import datetime
def fn_timedelta():
most = datetime.datetime.now()
regebben = datetime.datetime(2021, 1, 1, 13, 33, 45, 10)
delta = datetime.timedelta(days=10, hours=1, minutes=10, seconds=5, microseconds=100, milliseconds=98)
print(most + delta)
print(most - delta)
print(delta.days)
print(delta.seconds)
print(delta.microseconds)
delta = most - regebben
print(delta)
print(type(delta))
print(type(delta))
Naptár¶
A calendar
modulról részletesebben: https://docs.python.org/3/library/calendar.html
Fontosabb metódusai:
Metódus | Leírás |
---|---|
month() |
Visszaad egy havi naptárat, paramétere: év, hónap |
calendar() |
3 oszlopos naptárat ad vissza, paramétere: év, hónap |
isleap() |
Igazat ad, ha a paraméterben érkezett év szökőév, egyébként hamisat |
leapdays() |
A 2 kapott paraméter (év) között visszaadja, hány darab szökőév volt |
monthcalendar() |
Egy mátrix alapú naptárat ad vissza, 2 paramétere van: év, hónap |
import calendar
import datetime
if __name__ == '__main__':
most = datetime.datetime.now()
naptar = calendar.month(most.year, most.month)
print(naptar)
print(calendar.calendar(most.year, 2, 2, 6, 3))
# Hasznos funkciók
print("Szökőév?", calendar.isleap(most.year))
print("Szökőévek száma 2000 és 2020 között:", calendar.leapdays(2000, 2020))
print(f"Mai nap: {calendar.day_name[most.weekday()]}")
print("A jelenlegi hónap hetei")
print(calendar.monthcalendar(most.year, most.month))
CSV kezelés¶
A csv
modulról részletesen: https://docs.python.org/3/library/csv.html
Leírás | |
---|---|
writer() |
csv fájl író létrehozása |
reader() |
csv fájl olvasó létrehozása |
DictReader() |
csv fájból dict -be olvas be |
encoding |
karakterkódolás beállítása |
delimiter |
elválasztójel beállítása |
writerow() |
A kapott paramétert a writer fájl objektumába írja |
Olvasás¶
import csv
import os
with open(os.path.join("kesesek.csv"), encoding="utf8") as fp:
csv_reader = csv.reader(fp, delimiter=",")
for row in csv_reader:
print([r.strip() for r in row])
Ez a megoldás gyakorlatilag nem sokkal jobb, mintha mi magunk írtunk volna meg a beolvasást egy, felturbózva egy egyszerű split
-tel.
import csv
import os
with open(os.path.join("hf2", "kesesek.csv"), encoding="utf8") as fp:
csv_reader = csv.DictReader(fp, delimiter=",")
for row in csv_reader:
print(row)
Írás¶
import csv
import os
with open('kutyak.csv', mode='w') as kutya_adatok:
kutya_writer = csv.writer(kutya_adatok, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
kutya_writer.writerow(['Bloki', 'labrador', 'fekete', 'soha'])
kutya_writer.writerow(['Cukika', 'palotapincsi', 'feher', 'nyaron']
Hasonló a probléma, mint fentebb. Azonban itt is létezik jobb megoldás.
import csv
import os
with open('kutyak_jobb.csv', mode='w') as kutya_adatok:
fieldnames = ['nev', 'fajta', 'szine', 'szor_hullas']
kutya_writer = csv.DictWriter(kutya_adatok, fieldnames=fieldnames, lineterminator="\n")
kutya_writer.writeheader()
kutya_writer.writerow({'nev': 'Bloki', 'fajta': 'labrador', 'szine': 'fekete', 'szor_hullas': 'soha'})
kutya_writer.writerow({'nev': 'Cukika', 'fajta': 'palotapincsi', 'szine': 'feher', 'szor_hullas': 'nyaron'})
kutyak = [
{'nev': 'Bloki', 'fajta': 'labrador', 'szine': 'fekete', 'szor_hullas': 'soha'},
{'nev': 'Cukika', 'fajta': 'palotapincsi', 'szine': 'feher', 'szor_hullas': 'nyaron'}
]
with open('kutyak_jobb2.csv', mode='w') as kutya_adatok:
kutya_writer = csv.DictWriter(kutya_adatok, fieldnames=kutyak[0].keys(), lineterminator="\n")
kutya_writer.writeheader()
for k in kutyak:
kutya_writer.writerow(k)
Egyszerű glob¶
import glob
import os
# for file_name in glob.glob('csv_fajlok/netflix_yearly_data/**/*.csv'):
for file_name in glob.glob('csv_fajlok/netflix_yearly_data/*.csv'):
print(file_name)
print(os.path.abspath(file_name))
# szetvalasztas evtizedekre
Pathlib¶
import os
import pathlib
netflix_data_folder = os.path.join("csv_fajlok", "netflix_yearly_data")
p = pathlib.Path(netflix_data_folder)
print("p:", p)
print("abszolút útvonal:", p.absolute())
print("név:", p.name)
print("szülő:", p.parent)
print("nagyszülő:", p.parent.parent)
print("létezik:", p.exists())
print("cwd:", p.cwd())
print("posix:", p.as_posix())
print("uri:", p.absolute().as_uri())
for fajl in p.glob("**/*.csv"):
print(fajl)
# összeolvasztás
p = p.parent
foka = p.joinpath("teszt_foka.txt")
print("létezik:", foka.exists())
with foka.open("w") as fp:
fp.write("Seals can sleep underwater and usually only come on land to escape predators like whales and sharks, as well as to mate, give birth, feed and moult.")
print("létezik:", foka.exists())
# A teljes útvonal megadása szükséges
# foka.rename("foka_teny.txt")
Reguláris kifejezések¶
import os
import re
# Amire szükség lesz: basic regex ismeretek
# Help: https://regex101.com/
text = """Akkor nem kell!
Akkor nem kell!!!!!
Akkor nem kell!!
Akkor nem kell!!444!4!4!!!!
Akkor nem kell!!444!4!4!4!4!
"""
# Alap keresés regex segítségével
# Flagek:
# re.I == re.IGNORECASE
# re.M == re.MULTILINE
# re.S == re.DOTALL
# re.X == re.VERBOSE
# re.U == re.UNICODE
# re.L == re.LOCALE
# re.DEBUG
match = re.search(r".+!{2,}$", text, flags=re.MULTILINE | re.IGNORECASE)
print(match)
if match:
print("Van találat!")
print(match.groups())
match = re.search(r".+!{100,}$", text, flags=re.MULTILINE | re.IGNORECASE)
if match:
print("Van találat!")
# Kiegészíteni a regexet
# EMAIL_REGEX = re.compile("^\\S+@\\S+\\.\\S+$")
# EMAIL_REGEX = re.compile(r"^\S+@\S+\.\S+$")
EMAIL_REGEX = re.compile(r"\S+@\S+\.\S+$")
CIMEK = ["Alma@kukac.hamm", "jajj@gmail.com", "cica@vagyok.hu", "kutya.vagyok.hu", "nem tudom mi ez @gmail.com",
"nem értem", "denever@eset.hu", "Asszem valami cipofuzo23@gmail.com"]
print("---")
for email in CIMEK:
print(email, "valid:", "igen" if EMAIL_REGEX.search(email) else "nem")
print("---")
for email in CIMEK:
print(email, "valid:", "igen" if EMAIL_REGEX.match(email) else "nem")
print("---")
with open(os.path.join("szoveg", "cirmatlan_cica.txt"), encoding="utf8") as fp:
cica_mese = fp.read()
# Csak egy találatot ad vissza
print(re.search("tényle{2,}g", cica_mese, flags=re.U | re.I))
for talalat in re.findall("ténylee+g", cica_mese, re.U | re.I):
print(talalat)
for talalat in re.finditer("ténylee+g", cica_mese, re.U | re.I):
print("találat", talalat)
print("---")
# re.sub házi feladat
EMAIL_REGEX = re.compile(r"^(\S+)@(\S+)\.(\S+)$")
for email in CIMEK:
match = EMAIL_REGEX.match(email)
if match:
print(match.groups())
print(match.group(0))
print(match.group(1))
print(match.group(2))
print(match.group(3))
Órai feladatok¶
Megjegyzés
Az órai feladatok alatt lévő feladat(sor)ok azok a feladat(sor)ok, amelyek megoldása beleszámít a zh javításért megoldandó feladatok közé. Ezen feladat(sor)okból 6 darab megoldása szükséges ahhoz, hogy egy zh javíthatóvá váljon. Ha külön nem jelezzük, a teljes feladatsor megoldása esetén jár a zh javításért szerezhető pont.
Info
A teljes feladatsor megoldása szükséges a zh javításért járó pont megszerzéséért.
Nőnap¶
Készíts egy statisztikát arról, hogy az utóbbi 30 évben milyen napokra esett a Nemzetközi nőnap (március 8). A függvény térjen vissza egy dictionary objektummal.
Ennek visszatérési értéke (példa):
Péntek 13¶
Számoljuk ki, hogy az elmúlt 5 évben hányszor volt pénteken a hónap 13. napja. A függvény írja ki a péntek 13-i dátumokat, majd térjen vissza a darabszámmal. Egészítsd ki, hogy a felhasználótól kérje be, hogy az utóbbi hány évre kíváncsi.
Szétbontás évtizedekre¶
A csv_fajlok
mappában lévő netflix_yearly_data
mappa mellé készítsünk még egy mappát (Python kódból), netflix_decade_data
néven, amibe legyenek berendezve a csv
fájlok évtizedek szerint, például: 1910_1920
, 1920_1930
, stb.
Tipp
Használd a glob
modult, az shutil
modullal együtt! Vagy pedig a pathlib
modul Path
osztályát!
Idegroncs detektor advanced edition¶
Egészítsd ki az órai példát, hogy ne csak a "!!+" regex szerint találja meg a felkiáltójel helytelen használóit, hanem a felkiáltójelek között tetszőlegesen, tetszőleges darabszámban elhelyezett "4" karakterekkel is felismerje azt, amikor valaki idegességében írt egy mondatot.
Adatösszevonás¶
Vond össze az összes fájlt egyetlen nagy csv fájlba a csv_fajlok
mappában lévő netflix_yearly_data
mappából.
Házi feladat¶
Csere¶
Önállóan feldolgozni a re.sub
függvényt az alábbi oldalról: https://docs.python.org/3/library/re.html#re.sub