Python kezdőknek kurzus 6. lecke

A Ubuwiki wikiből


Függvények és szótárak

A mostani leckében megtudjuk, hogyan írhatunk saját függvényeket és megismerjük a nagyon hasznos szótár típust.

Függvények

A függvény eszméje egyszerű: ez egy kis programrészlet, ami valami specifikus feladatot végez el. A függvényeket használhatjuk arra, hogy csoportosítsuk a kódunkat, ami így olvashatóbbá válik, vagy csak különálló részekre bontjuk, melyeket különböző helyeken hívhatunk meg (indíthatunk el).

Így hozhatunk létre függvényt:

Python 2.x Python 3.x
def hello() :
    print "Hello vilag!"
def hello():
    print(“Hello vilag!”)

A def kulcsszó mondja azt, hogy függvényt szeretnénk definiálni (létrehozni); a függvényen belül minden sort beljebb kezdünk. A fent definiált függvényt a programkódban hello() formában lehet meghívni.

A hello() függvény csak kiír valamit. A legtöbb esetben viszont azt szeretnénk, hogy a függvény valamit kiszámoljon és adja vissza az eredményt.

def szavak_szama(s) :
    return len(s.split())    # visszaadja a szavak szamat az s sztringben

Ebben az esetben így használható a fenti függvény:

Python 2.x Python 3.x
sajat_sztring = "Ez egy nagyon hosszu mondat tele szavakkal"
print "A sztring", szavak_szama(sajat_sztring), "szót tartalmaz"
sajat_sztring = "Ez egy nagyon hosszu mondat tele szavakkal"
print("A sztring", szavak_szama(sajat_sztring), "szót tartalmaz")

Amikor meghívjuk a szavak_szama(sajat_sztring)et, a Python fogja a sajat_sztringet és átadja a szavak_szama függvénynek, de a függvényen belül a sztring már nem sajat_sztring névvel rendelkezik, hanem az ssel. A függvény végrehajtja, amit végre kell hajtania, kiszámolja az eredményt és visszatérési értékként ezt adja vissza a kód azon részén, ahol meghívjuk.

Az s-t a szavak_szama függvényben “argumentumnak” (vagy paraméternek) hívjuk. Egy függvénynek bármennyi paramétere lehet. Például ha írunk egy url-készítő függvényt, az lehet ilyen:

def url_keszites(sema, domain, utvonal) :
    return sema + "://" + domain + "/" + utvonal

url_keszites("http", "mailman.linuxchix.org", "pipermail/courses/")
'http://mailman.linuxchix.org/pipermail/courses/'

Többszörös visszatérési érték: tuples

Függvény visszatérési értéke bármilyen Python típus lehet, nem csak szám. Lehet sztring, lista, vagy bármi más. Sőt akár több értékkel is visszatérhetünk:

def sorok_es_szavak_szamolasa(fajlnev) :
    sorok = 0
   szavak = 0
   fajl = open(fajlnev)
    for sor in fajl :
        sorok += 1
       szavak += len(sor.split())
    return (sorok, szavak)

A fenti függvényt így hívhatjuk meg:

(sorok, szavak) = sorok_es_szavak_szamolasa("sajat_fajl.txt")

Nem szükséges zárójeleket használni, írhatjuk úgy is

return sorok, szavak

és

sorok, szavak = sorok_es_szavak_szamolasa("sajat_fajl.txt")

de szerintem a zárójelekkel áttekinthetőbbé válik, hogy mi is történik. Csak azért említem ezt, mert mindkét módszerrel találkozhatsz Python programokban.

Az ilyen zárójelezett dolgokat, mint a (sorok, szavak) vagy (42, "foo"), sornak (tuple) hívjuk Pythonban. A sor sok szempontból hasonlít a listára. Például használhatjuk így

>>> sajat_sor = sorok_es_szavak_szamolasa("/etc/hosts")
>>> sajat_sor
(17, 34)
>>> len(sajat_sor)
2
>>> sajat_sor[0]
17
>>> sorok_es_szavak_szamolasa("/etc/hosts")[0]
17

A fentiek alapján eléggé hasonlít a listákra, nem? Akkor tulajdonképpen mi is a különbség? A sor esetén nem változtathatjuk meg az értékét, miután létrehoztuk. Így a sor alapvetően akkor hasznos, amikor értéket szeretnénk átadni, vagy (esetleg több értékkel) vissza szeretnénk térni egy függvényből.


Szótárak

A Pythonban van még egy “dolgok gyűjteménye” adattípus, amiről érdemes tudni: ez a szótár.

Néha, amikor programot írunk, nem tudjuk előre hány elemet (adatot) szeretnénk tárolni, vagy milyen sorrendben. Csak azt tudjuk, hogy szükséges lesz neveket rendelni az értékekhez. Ilyenkor használhatjuk a szótár típust, amit { } kapcsos zárójelek közt adhatunk meg.

Például, ha szervezetek nevét szeretnénk társítani az URL-jükkel:

urlek = { "LinuxChix"     : "http://linuxchix.org",
         "Ubuntu Women"  : "http://ubuntu-women.org/",
         "Debian Women"  : "http://women.debian.org/",
         "Geek Feminism" : "http://geekfeminism.wikia.com/"
       }

Megjegyzés: ez egyike azon eseteknek, amikor nem fontos a behúzás. A fenti példában csak a könnyebb olvashatóság miatt vannak beljebb egyes sorok, de akár egy sorba is írhatjuk az egészet behúzás nélkül.

Így akár kiadhatjuk az alábbi parancsot

Python 2.x Python 3.x
print "Tovább információk a LinuxChix oldalán:", urlek["LinuxChix"]
print ("Tovább információk a LinuxChix oldalán:", urlek["LinuxChix"])

Olyan, mintha listát indexelnénk, de a [] szögletes zárójelek közt nem szám, hanem sztring szerepel.

Az index értékeket a zárójelek közt (mint amilyen a "LinuxChix" is), kulcsnak hívjuk, a többit (az URL-eket) értékeknek. A kulcsok listáját a keys() függvénnyel kérhetjük le és ennek használatával végigjárhatjuk ciklussal a szótárat:

Python 2.x Python 3.x
for szerv in urlek.keys() :
    print "Tovább információ a", szerv, "szervezetről:", urlek[szerv]
for szerv in urlek.keys() :
    print ("Tovább információ a", szerv, "szervezetről:", urlek[szerv])

Talán észrevetted, hogy nem került vessző a szótárban az utolsó elem után (Geekfeminism). Néhány nyelv kényes erre, de a Python rugalmas: tehetünk az utolsó elem után vesszőt, de el is hagyhatjuk. Ha például egy hosszabb listát készítünk, egyszerűbb lehet, ha minden sor ugyanúgy néz ki, minden elem után van vessző.

Azután is adhatunk elemeket a szótárhoz, hogy létrehoztuk. Üres szótárat például az alábbi módon tölthetünk fel:


Python 2.x Python 3.x
urlek = {}     # egy üres szótár
while True :
    szerv = raw_input("Szervezet neve (vagy q a kilépéshez) ")
    if szerv == 'q' :
        break
    url = raw_input("URL? ")
    urlek[szerv] = url

print urlek
urlek = {}     # egy üres szótár
while True :
    szerv = input("Szervezet neve (vagy q a kilépéshez) ")
    if szerv == 'q' :
        break
    url = input("URL? ")
    urlek[szerv] = url

print(urlek)

A szótárak nagyon hasznosak, bizonyára idővel egyre többet fogod használni őket. Számomra sokáig zavaros volt a használatuk, hiszen {}t használsz létrehozáshoz, de [] segítségével indexeled őket, mint a listáknál és sosem emlékszel melyik melyik. Most viszont azt kívánom bár ne féltem volna és előbb kezdtem volna használni szótárakat.

Emlékeztetőként (érdemes felírni valahova)

[] üres lista
{} üres szótár
() üres sor (leggyakrabban függvény visszatérési értéke)

de mind [] zárójelekkel indexeljük, miután létrehoztuk őket.

Gyakorló feladatok

1. Írjunk egy függvényt, aminek egyik paramétere egy szótár és a másik egy véletlenszerűen választott kulcs a szótárból. A visszatérési érték legyen egy sor, melyben a kulcs és a hozzá tartozó érték szerepel.

Más szavakkal, ha a korábbi urlek szótárat használjuk, akkor, ha a "LinuxChix" a függvény egyik argumentuma, akkor a visszatérési érték ("LinuxChix", "http://linuxchix.org") lesz.

2. Használjuk az előző feladatban megírt függvényt tanulókártyás program készítésésre.

A tanulókártya bármilyen témájú lehet (akár vegyes témákból is összeállíthatod). Készítsünk el egy szótárat kérdésekből és a válaszokból - a kulcsok legyen a kérdések, a válaszok pedig az értékek. A függvényünk segítségével véletlenszerűen válasszunk egy kérdés/válasz párt, írjuk ki a kérdést és várjuk meg a felhasználó válaszát. Ezután írjuk ki a választ. (A felhasználónak kell ellenőriznie, hogy helyesen válaszolt-e)

Ha szükség van nem-ASCII karakterekre (például olyan tanulókártyákat szeretnénk, amiket nem angolul írunk így például ékezetes betűk is szerepelnek benne), megadhatjuk a karakterkódolást a programunk elején (például rögtön a shebang sor után), így:

# -*- coding: utf-8 -*-

3. Változtassuk meg a tanulókártyás programot úgy, hogy a program leellenőrzi, hogy helyes választ adott-e a felhasználó és tároljuk el, hány kérdést válaszolt meg helyesen és hányat helytelenül.

Megjegyzés: lehetséges, hogy ez a feladat idegesíteni fog, mert bármilyen typo vagy plusz szóköz kerül a válaszba, nem lesz érvényes. Van esetleg ötleted arra, hogy lehet rugalmasabbá tenni a játékot?

További leckék

Személyes eszközök