Kihagyás

4. gyakorlat

A gyakorlat anyaga

Saját fájlokból modulok

  • Modulok készítése
  • Almodul, __init__.py szerepe
  • __init__.py import, minden importálás, átnevezése
  • A csillagos import hibájának fixálása __all__ segítségével

Functools

  • Órai cache jobban
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import functools

from contextlib import contextmanager
import time


# https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)
@functools.lru_cache(50)
# @functools.lru_cache(None)
def factorial(n):
    r = 1
    i = 2
    while i <= n:
        r *= i
        i += 1
    return r


@contextmanager
def timed():
    start_time = time.time()
    yield
    end_time = time.time()
    print("Total execution time: {}".format(end_time - start_time))


def main():
    with timed():
        for i in range(5000):
            factorial(3000 + (i % 50))


if __name__ == '__main__':
    main()

Cached property

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import functools
from contextlib import contextmanager
import time


@contextmanager
def timed():
    start_time = time.time()
    yield
    end_time = time.time()
    print("Total execution time: {}".format(end_time - start_time))


# def factorial(n):
#     return n * factorial(n - 1) if n else 1

def factorial(n):
    r = 1
    i = 2
    while i <= n:
        r *= i
        i += 1
    return r


class SzamStatisztika:

    def __init__(self, szam):
        self.szam = szam

    def jegyek_szama(self):
        return len(str(self.szam))

    @functools.cached_property
    # @property
    def faktorialis(self):
        return factorial(self.szam)


if __name__ == '__main__':
    szam1 = SzamStatisztika(30)
    print(szam1.faktorialis)

    with timed():
        szam2 = SzamStatisztika(80000)
        szam2.faktorialis
        szam2.faktorialis

Partial

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import functools


def termek_adatok(kategoria, termek_neve, ar, leiras):
    print("Termék neve:", termek_neve)
    print("Kategória:", kategoria)
    print(f"Ára: {ar} Ft")
    print(leiras)
    print("---")

termek_adatok("Plüss micimackó", "plüss", 1200, "A legjobb plüss Micimackó")

# Partial, első paraméterek megadása
szamitogep_adatok = functools.partial(termek_adatok, "Szamitogep")
szamitogep_adatok("Acer Predator", 250000, "Nagyon komoly gamer laptop, Minecraft 120 fps!!!")

# Partial, az utolsó paraméterek megadása
leiras_nelkuli_termek = functools.partial(termek_adatok, leiras="Nincs leírás")
leiras_nelkuli_termek("plüss", "Malacka plüss", 1000)

# Partial, első és utolsó paraméterek megadása
szamitogep_leiras_nelkuli_termek = functools.partial(termek_adatok, "Szamitogep", leiras="Nincs leírás")
szamitogep_leiras_nelkuli_termek("Acer Predator", 250000)

Total ordering

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import functools


@functools.total_ordering
class Teglalap:
    def __init__(self, a, b=0):
        self.a = a
        self.b = (b if b > 0 else a)

    def terulet(self):
        return self.a * self.b

    def kerulet(self):
        return 2 * self.a + 2 * self.b

    def __eq__(self, other):
        if isinstance(other, Teglalap):
            return self.terulet() == other.terulet()
        return False

    def __lt__(self, other):
        if isinstance(other, Teglalap):
            return self.terulet() < other.terulet()
        return False


if __name__ == '__main__':
    t1 = Teglalap(6, 5)
    print(t1.terulet())
    print(t1.kerulet())

    t2 = Teglalap(5, 6)
    t3 = Teglalap(3, 10)
    print("---")

    print(t1 == t2)
    print(t1 < t2)
    print(t1 <= t2)
    print(t1 > t2)
    print(t1 >= t2)
    print(t1 != t2)
    print("---")

    print(t1 == t3)
    print(t1 < t3)
    print(t1 <= t3)
    print(t1 > t3)
    print(t1 >= t3)
    print(t1 != t3)
    print("---")

    t4 = Teglalap(8)
    print(t2 > t4)
    print(t2 <= t4)

Operációs rendszerrel/Fájlokkal kapcsolatos műveletek

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
import os
import shutil


def main():
    print(os.name)
    print(os.environ)
    print(os.sep)
    print(repr(os.linesep))
    print("---")
    print("Jelenlegi konyvtar", os.getcwd())
    print("Fájlok:")
    print(os.listdir("."))
    print("---")

    # Egy könyvtárral felmegyünk
    os.chdir("./sajat_mappa")
    print("Jelenlegi konyvtar", os.getcwd())
    print("Fájlok:")
    print(os.listdir("."))
    print("---")
    for f in os.listdir("."):
        print(f)
        # Fáj teljes útvonala
        print(os.path.abspath(f))
        # Fájl relatív útvonala (mindig az aktuális munkakönyvtárhoz viszonyítva)
        print(os.path.relpath(f))
        # print(os.stat(f))
        print(os.stat(f).st_size)  # bájt

    rossz_utvonal = "abc/asd"
    rossz_utvonal2 = r"alma\korte"
    # Útvonalak összefűzése (nem kell, hogy létező legyen!)
    jo_utvonal = os.path.join("asd", "edasdasdas")
    print(jo_utvonal)
    # Útvonalak létezőségének ellenőrzése
    print("Útvonal létezik?", os.path.exists(os.path.join(jo_utvonal)))
    print("Útvonal könyvtár?", os.path.isdir(os.path.join(jo_utvonal)))
    print("Útvonal fájl?", os.path.isfile(os.path.join(jo_utvonal)))

    # Így nem lehet teljes mappaszerkezetet létrehozni
    # Ez megfelel a sima mkdir parancsnak
    # os.mkdir(jo_utvonal)
    # Vigyázat! Ha létezik a mappa, hibát kapunk!
    os.mkdir("cicas_dolgok")
    os.mkdir("kutyas_dolgok")

    os.makedirs(jo_utvonal)
    print("Útvonal létezik?", os.path.exists(os.path.join(jo_utvonal)))
    print("Útvonal könyvtár?", os.path.isdir(os.path.join(jo_utvonal)))
    # Ez egy könyvtár kitörlésése használható, feltétele, hogy üres legyen a könyvtár
    os.rmdir(jo_utvonal)

    # print("Útvonal létezik?", os.path.exists(os.path.join(jo_utvonal)))
    # os.makedirs(jo_utvonal)
    # # Több könyvtár törlésése a removedirs() használható, ez is üres könyvtárakra működik
    # os.removedirs(jo_utvonal)

    # Fájl másolása
    shutil.copy("baby_seal.png", "my_favorite_seal.png")
    # Csak viccelek
    # 1 darab fájl törlése
    os.remove("my_favorite_seal.png")
    os.mkdir("seal")
    # Másolás átnevezéssel
    shutil.copy("baby_seal.png", os.path.join("seal", "my_favorite_seal.png"))
    # Fájl másolása egy könyvtárba
    shutil.copy("baby_seal.png", "seal")
    # A seal mappa már nem üres, így nem is lehet törölni az rmdir paranccsal.
    # Workaround: fájl(ok) törlése, mappa törlése
    # os.rmdir("seal")
    # Az rmtree kitörli a mappát a tartalmával együtt.
    shutil.rmtree("seal")

    # Bemásoljuk a kedvenc fókánkat
    os.mkdir("seal")
    # Másolás átnevezéssel
    shutil.copy("baby_seal.png", os.path.join("seal", "my_favorite_seal.png"))
    # Fájl másolása egy könyvtárba
    shutil.copy("baby_seal.png", "seal")
    # Teljes mappaszerkezet átmásolása
    shutil.copytree("seal", "favorite_selas")
    # Fájl/mappa átnevezése
    os.rename("favorite_selas", "favorite_seals")

    print(os.path.split(os.path.abspath("seal")))
    print(os.path.splitdrive(os.path.abspath("seal")))
    print(os.path.splitext(os.path.abspath("seal")))
    print(os.path.splitext(os.path.abspath("adult_seal.png")))
    print(os.path.splitext(os.path.abspath("adult_seal.tar.gz")))
    # Fájl név
    print(os.path.basename(os.path.abspath("adult_seal.tar.gz")))
    # Mappa név
    print(os.path.dirname(os.path.abspath("adult_seal.tar.gz")))




if __name__ == '__main__':
    main()

Deep copy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import copy

weather_szeged = {
    'city': 'Szeged',
    'temp': 12,
}

weather_budapest = {
    'city': 'Budapest',
    'temp': 10,
}

weather_forecast_list = [weather_szeged, weather_budapest]

weather_copy = copy.copy(weather_forecast_list)
weather_copy = copy.deepcopy(weather_forecast_list)

weather_copy[0]['city'] = 'Swaged'

print('Eredeti lista', weather_forecast_list)
print('Másolat lista', weather_copy)
print('Eredeti Szegedi időjárás objektum', weather_szeged)

Feladatok

Partial method

A partial methodok megértése, kipróbálása: https://docs.python.org/3/library/functools.html#functools.partialmethod

Mappaváltó context manager

Készíts egy context managert, ami a blokkba kerüléskor mappát vált az adott mappára, majd visszatér az eredeti mappához a blokkból való távozáskor.

1
2
3
4
5
6
7
def change_dir(d):
    pass

print(os.getcwd())
with change_dir("../"):
    print(os.getcwd())
print(os.getcwd())

Egyszerű statisztika

Számoljunk statisztikát fájltípusok szerint. A jpg és JPG kiterjesztése ugyanaz. Számoljuk meg hány darab fájl van, és mi az összes, átlagos fájlméret.

1
2
def stats():
    pass

Okos kiterjesztés levágó

Az os.path.splitext sajnos a legutolsó pont utáni részt vágja csak le, azonban egy fájl "rendes" kiterjesztése az első pont utáni rész végig. Készítsd el a normal_splitext metódust, ami így vágja le a fájlok kiterjesztését. A visszatérési értéke egy tuple legyen.

1
2
def normal_splitext(f):
    pass

Rendezgetés vol. 1

Rendezzük a sajat_mappa fájljait a cicas_dolgok és kutyas_dolgok mappába. A fájlokban nézzük meg, hogy szerepel-e a "cat" vagy "dog" szó, és ezek szerint másoljuk a mappákba. Amennyiben egy fájlban egyik szó sem szerepel, azzal ne csináljunk semmit.

Rendezgetés vol. 2

Egészítsük ki az előző kódot: amennyiben egy fájlban egyik szó sem szerepel, kérdezzük meg a felhasználót, hogy mit szeretnénk kezdeni az adott fájllal:

  • Ha a felhasználó azt írja be, hogy "cica", másoljuk a "cicas_dolgok" mappába, és a fájlt nevezzük át "cica_[index]", az [index] helyére egy folyóindexet tegyünk.
  • Ha a felhasználó azt írja be, hogy "kutya", másoljuk a "kutyas_dolgok" mappába, és a fájlt nevezzük át "kutya_[index]", az [index] helyére egy folyóindexet tegyünk.
  • Minden más esetben pedig ne csináljunk semmit az adott fájllal.

Fact generátor

Készítsünk két random tény generátort. Ehhez olvassuk be soronként a "clean_cat_facts.txt" és "clean_dog_facts.txt" fájlt. Amennyiben nem létezik, hozzuk létre őket. Ehhez olvassuk be soronként a "cat-facts.txt" és "dog_facts.txt" fájlt. A fájlok nagyjából jók, azonban lehetnek benne üres sorok például, ezeket szűrjük ki belőle. Lehetnek a tények előtt sorszámok, ezeket is takarítsuk ki a "clean_" fájlokból. Amennyiben léteznek a fájlok, olvassuk be őket soronként, és adjunk vissza egy véletlenszerű sort.

Kapcsolódó linkek


Utolsó frissítés: 2021-03-11 10:44:56