Kihagyás

2. gyakorlat

A gyakorlat anyaga

Ezen a gyakorlaton elkészítjük a legelső Python szkriptünket. Ezt követően megismerkedünk a Python vezérlési szerkezeteivel (szelekciós vezérlés, ciklusok). Szó lesz a függvényekről, valamint a string adattípusról szóló ismereteinket is bővíteni fogjuk.

Python szkriptek és futtatásuk

Az előző gyakorlaton a parancssori értelmező segítségével hajtottunk végre Python utasításokat. A gyakorlatban viszont a Python kódunkat általában egy fájlba szoktuk kiszervezni. Az ilyen fájlokat szkripteknek nevezzük. A Python szkriptjeink kiterjesztése .py lesz.

Hozzunk létre egy fájlt test.py néven, és írjuk bele az alábbi kódot:

1
2
3
print("Ez az első Python szkriptem")
szam = 40 + 2
print("Az élet értelme:", szam)

Mentsük el a szkriptet, majd parancssorban navigáljunk el abba a mappába, ahol a fájl található. Ebben a mappában a python test.py (szükség esetén python3 test.py) parancs kiadásával futtassuk a megírt szkriptünket.

A futtatás után a Python értelmező sorról sorra értelmezi és végrehajtja a szkriptünkben szereplő utasításokat. A programunk kimenete:

Kimenet

Ez az első Python szkriptem Az élet értelme: 42

A Python blokkszintaxisa

C-ben és Javában kapcsos zárójelek ({...}) között adhattunk meg utasításblokkokat (pl. vezérlési szerkezetek, függvények esetén).

Pythonban viszont kapcsos zárójelek helyett az úgynevezett indentálás (beljebb igazítás) dönti el, hogy mely utasítások mely blokkokhoz tartoznak. Tehát az egyes blokkokhoz tartozó kódrészeket mindig beljebb kell igazítanunk.

Figyeljük meg a Pythonra jellemző blokkszintaxist az alábbi kódban!

1
2
3
4
5
6
7
8
9
pontszamok = [81, 96, 56, 100, 89]
otosok_szama = 0

for pontszam in pontszamok:
    if pontszam >= 89:        # 1. indentálási szint
        otosok_szama += 1     # 2. indentálási szint
        print("Találtunk egy ötöst!")

print("Összesen", otosok_szama, "hallgató kapott ötöst.")
  • Az if szerkezet közvetlenül a for utasítás blokkjába tartozik (1. indentálási szint)
  • A for-on belüli if utasítás blokkjába két utasítás tartozik (2. indentálási szint)

Figyelem

Fontos, hogy egy blokkon belül mindig ugyanannyi helyközt használjunk az indentálásra (pl. mindenhol 4 darab szóközt)! Ellenkező esetben IndentationError hibaüzenetet kapunk.

A Python vezérlési szerkezetei

Szelekciós vezérlés

Pythonban a szelekciós vezérlés megvalósítására az if, else és elif utasítások használatosak. Az elif a C-ből és Javából ismerős else if Pythonos megfelelője. A másik két utasítás ugyanazt a célt szolgálja, mint C-ben vagy Javában.

Használatuk szintaxisa (a szögletes zárójelek közötti részek elhagyhatók):

1
2
3
4
5
6
if feltetel:
    csinalunk_valamit()
[elif feltetel:
    csinalunk_valami_mast()]
[else:
    csinalunk_valami_teljesen_mast()]

Amint láthatjuk, a szelekciós vezérlési ágaknál használjuk az imént megismert blokkszintaxist - egy adott vezérlési ághoz tartozó utasítás-sorozatot beljebb igazítunk.

A feltételek megadásakor használható fontosabb feltételes és logikai operátorok:

Operátor Müködése
a == b Igaz, ha a és b értéke megegyezik
a != b Igaz, ha a és b értéke nem egyezik meg
a < b Igaz, ha a kisebb, mint b
a <= b Igaz, ha a kisebb vagy egyenlő, mint b
a > b Igaz, ha a nagyobb, mint b
a >= b Igaz, ha a nagyobb vagy egyenlő, mint b
a and b Igaz, ha a és b értéke egyaránt igaz (logikai ÉS)
a or b Igaz, ha legalább az egyik operandus értéke igaz (logikai VAGY)
not a Igaz, ha a értéke hamis (logikai tagadás)

Példa: Egy program, amely beolvas egy egész számot és kiírja, hogy az pozitív, nulla vagy negatív

1
2
3
4
5
6
7
8
9
szam = int(input("Adj meg egy számot: "))

if szam < 0:                        # "ha" ág
    print("A beírt szám negatív.")
    print("Abszolútértéke: " + str(abs(szam)))
elif szam == 0:                     # "egyébként ha" ág
    print("A beírt szám nulla.")
else:                               # "egyébként" ág
    print("A beírt szám pozitív.")

Példa: Logikai operátorok használata

1
2
3
4
# ...

if not gondolt_szam == 10:                      # logikai "NEM"
    print("A gondolt szám nem 10.")
1
2
3
4
# ...

if eletkor >= 18 and nem == "férfi":            # logikai "ÉS"
    print("Nagykorú férfi vagy.")
1
2
3
4
# ...

if homerseklet < -20 or homerseklet > 50:       # logikai "VAGY"
    print("Srácok, baj van...")

Ismétléses vezérlés (Ciklusok)

Pythonban a while és for utasításokat tudjuk használni ismétléses vezérlés megvalósításra. (Pythonban nincs beépített do... while szerkezet.)

A while utasítás

A while utasítás a klasszikus elöltesztelős ismétléses vezérlést valósítja meg. Szintaxisa:

1
2
while feltetel:
    csinalunk_valamit()

A már jól megszokott módon, a ciklusmag addig fut, amíg a vizsgált feltétel igaz.

Példa: Írassuk ki az egész számokat 1-től 10-ig, while utasítás segítségével.

1
2
3
4
5
i = 1

while i <= 10:
    print(i)
    i += 1   # emlékeztető: Pythonban nincs i++

A C-ben és Javában tanult break, illetve continue utasítások Pythonban is használhatók.

  • break: megszakítja az aktuális ismétlést és a szerkezetet követő utasítással folytatja
  • continue: megszakítja az aktuális ismétlést és a következő iterációval folytatja

Példa: A break és continue utasítások használata while ciklusban:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
count = 0

while True:         # végtelen ciklust indít
    count += 1

    if count > 5:   # megállási feltétel
        break

    if count == 3:  # a 3-as értéket átugorjuk
        continue

    print(count, "Python for life")

Kimenet

1 Python for life 2 Python for life 4 Python for life 5 Python for life

A for utasítás

Pythonban a for-ciklus a korábban tanultakkal ellentétben nem a klasszikus számlálásos ismétléses vezérlést valósítja meg. Pythonban ugyanis úgynevezett listaszerű for-ciklus van, ami egy elemsorozat bejárását valósítja meg. Ekkor a ciklusváltozó rendre felveszi a bejárni kívánt elemsorozat összes értékét.

Nézzünk néhány példát a for utasítás használatára!

Szövegek bejárása
1
2
for betu in "alma":
    print(betu)

A fenti példában a bejárni kívánt elemsorozatunk egy szöveg ("alma"). A szöveg karakterekből áll, ezeken a karaktereken iterálunk végig. A betu névre hallgató ciklusváltozónk minden iterációban felveszi az aktuális karakter értékét, amit kiírunk a konzolra.

Kimenet

a l m a

Listák bejárása

A for-ciklus egy másik gyakori használata a listák bejárása. A listákról a következő gyakorlaton tanulunk részletesebben, de tulajdonképpen tekinthetünk rájuk úgy, mint a tömbökre - ők is elemek sorozatát tárolják.

A lista elemeinek bejárása hasonlóképpen történik, mint a szövegek karaktereinek bejárása.

1
2
for szam in [12, 23, 34, 45]:
    print(szam)

Kimenet

12 23 34 45

Hagyományos for-ciklus szimulálása

Felmerülhet bennünk a kérdés, hogy van-e lehetőségünk Pythonban a for-ciklust a "hagyományos" módon, számlálásos ismétléses vezérlésre használnunk. A válasz igen.

Ahhoz, hogy a klasszikus módon tudjuk használni a for-ciklust, először egy számokból álló elemsorozatot kell generálnunk, aminek az elemein végig fogunk iterálni.

A range(start, end, step) függvénnyel egyszerűen generálható ilyen számokból álló elemsorozat. Ez a függvény legyártja nekünk az egész számokat start-tól end-ig (az end már nincs benne az elemsorozatban), step lépésközzel.

A start, illetve step paraméterek elhagyhatók. Alapértelmezett módon 0-tól indulunk (start alapértéke), és 1-esével lépkedünk (step alapértéke).

A step értékeként negatív számot is meghatunk, ekkor "visszafelé lépkedünk".

Példa: Az egész számok kiíratása 0-tól 10-ig (a 10 már nincs benne)

1
2
for i in range(10):             # 0 1 2 ... 7 8 9
    print(i)

Példa: Az egész számok kiíratása 2-től 10-ig (a 10 már nincs benne)

1
2
for i in range(2, 10):          # 2 3 4 ... 7 8 9
    print(i)

Példa: Az egész számok kiíratása 1-től 100-ig, 3-as lépésközzel

1
2
for i in range(1, 100, 3):      # 1 4 7 ... 94 97
    print(i)

Példa: Az egész számok kiíratása 20-tól 10-ig ("visszafelé lépkedés")

1
2
for i in range(20, 10, -1):     # 20 19 18 ... 12 11
    print(i)
break, continue

Természetesen a for-ciklusban is használhatjuk a break és continue utasításokat.

Példa: Elkezdjük kiíratni az 1 és 100 közötti egész számokat, majd 42-nél kilépünk

1
2
3
4
5
6
for i in range(1, 100):
    print(i)

    if i == 42:
        print("Megtaláltuk az élet értelmét.")
        break

Példa: Kiíratjuk egy pizzafeltéteket tároló lista elemeit, viszont ha ananászt látunk, azt átugorjuk

1
2
3
4
5
6
print("A legjobb pizzafeltétek:")

for feltet in ["sajt", "bacon", "ananász", "pepperoni"]:
    if feltet == "ananász":
        continue
    print(feltet)

Függvények

Függvénydefiníció

Pythonban is lehetőségünk van saját függvényeket definiálnunk, majd ezeket később használnunk, meghívnunk.

A függvénydefiníció szintaxisa a következő (a szögletes zárójelek közötti részek elhagyhatók):

1
2
3
def fuggveny_neve([param1, param2, ...]):
    utasitasok
    [return visszateresi_ertek]

Itt is használjuk a Python blokkszintaxist, és a függvény törzsét beljebb indentáljuk.

A függvényeink vissza is térhetnek valamilyen értékkel. Ezt a visszatérési értéket a return kulcsszó után adhatjuk meg.

Függvényhívás

Ha egy függvényt meg szeretnénk hívni Pythonban, akkor azt az alábbi szintaxissal tehetjük meg:

1
fuggveny_neve([param1, param2, ...])

Ahogy azt már más nyelvekben megszokhattuk, a függvényhívás során átadjuk a függvénynek a bemeneti paramétereket (feltéve ha a kérdéses függvény vár paramétert).

Default paraméterek

Javában lehetőségünk volt több ugyanolyan nevű függvényt definiálni, feltéve ha eltérő volt azok paraméterezése. A függvényhívás során is a paraméterezés döntötte el, hogy az azonos nevű függvények közül melyik került meghívásra. Ezt neveztük function overload-nak.

A Python nem támogatja a function overload-ot (még eltérő paraméterezés esetén sem). Azonos nevű függvények esetén a kódban legkésőbb definiált függvény lesz hívható.

1
2
3
4
5
6
7
8
def hello():
    print("Hello World!")

def hello(nev):
    print("Hello " + nev + "!")

# hello()               # HIBA!!!
hello("Béla")

Kimenet

Hello Béla!

Mivel a fenti kódban két hello névre hallgató függvényünk is van, ezért a fentebb leírtak miatt a legutoljára definiált, 1 paramétert váró hello(nev) függvény lesz hívható. Ha a korábban definiált, 0 paraméteres hello() függvényt próbáljuk meghívni, hibát kapunk.

A gyakorlatban viszont sokszor felmerül az igény arra, hogy egy függvényt akár eltérő paraméterszámmal is meg tudjunk hívni. Szerencsére a Python biztosít erre egy megoldást, mégpedig a default függvényparamétereket.

A default paraméterek lényege, hogy a függvény bizonyos paramétereinek alapértelmezett értéket adunk a függvénydefiníció során. Ha a függvényhíváskor nem adjuk meg az adott paraméter értékét, akkor az az alapértelmezett értéket veszi fel.

1
2
3
4
5
def hello(nev="Senki"):
    print("Hello " + nev + "!")

hello()     
hello("Béla")                       

Kimenet

Hello Senki! Hello Béla!

A fenti kódban először paraméter nélkül hívjuk meg a hello függvényt. Mivel a paraméterváltozónknak nem adtunk át értékét, ezért az az alapértelmezett "Senki" szöveget fogja felvenni. A második függvényhívásnál már megadtuk a paraméter értékét ("Béla"), ebben az esetben természetesen ezt fogjuk használni a függvényen belül (nem a default értéket).

A default paraméterek kapcsán van egy fontos szabály, amit be kell tartanunk: ha nem minden függvényparaméternek adunk alapértelmezett értéket, akkor mindig az utolsó néhány paraméternek kell default értéket adnunk (azaz a default paraméterek mindig a paraméterlista jobb oldalán szerepelnek).

1
2
3
4
5
6
def osszead(a, b=0, c=0):
    return a + b + c

print(osszead(5))               # 5 + 0 + 0
print(osszead(5, 2))            # 5 + 2 + 0
print(osszead(5, 2, 3))         # 5 + 2 + 3

Kimenet

5 7 10

Nevesített paraméterátadás

Default paraméterek használata esetén lehetőségünk van nevesített paraméterátadásra. Ekkor az elhagyható paraméterek közül expliciten megmondjuk, hogy melyiknek az értékét akarjuk megadni (név=érték formában).

Ez alapvetően akkor lehet hasznos, ha nem olyan sorrendben szeretnénk megadni a paramétereket, mint ahogy azok a függvény paraméterlistájában szerepelnek.

1
2
3
4
5
6
7
def info(felhasznalonev, jelszo=None, szak=None):
    if jelszo is not None:      # ha megadtuk a jelszo paramétert...
        print(felhasznalonev, "jelszava:", jelszo)
    if szak is not None:        # ha megadtuk a szak paramétert...
        print(felhasznalonev, "szakja:", szak)

info("Károly", szak="proginfó")

Kimenet

Károly szakja: proginfó

A fenti példában a függvényhíváskor értéket adtunk az egyetlen kötelező paraméternek (felhasznalonev), majd nevesített paraméterátadással a legutolsó (szak) paraméternek az értékét állítottuk be. A középső (jelszo) paraméternek nem adtunk értéket, így az az alapértelmezett, None értéket veszi fel.

A None érték

A fenti példában szereplő None egy speciális beépített kulcsszó Pythonban. Ez az "üres érték", amit más nyelvekben gyakran null-nak neveznek.

Az értéket nem tároló változók (pl. nem megadott függvényparaméterek) értéke None lesz.

Stringek

Pythonban a stringek tetszőlegesen hosszú karaktersorozatok, szövegek.

Stringek megadása

A stringeket leggyakrabban aposztrófok ('...') vagy idézőjelek ("...") között szoktuk megadni. A két megadási mód között lényegi különbség nincs.

Több soros szövegkonstansokat három darab idézőjel között adhatunk meg.

1
2
3
4
tobb_soros_szoveg = """Egy, egy almafa
Kettő, két katica
Három, három kiskacsa
Egy, kettő, három"""

Stringek összefűzése

A stringek összefűzése a + (plusz) operátorral történik.

1
2
szoveg = "szkript" + "nyelvek"
print(szoveg)   

Kimenet

szkriptnyelvek

Emlékeztető: Pythonban stringet csak stringgel lehet összefűzni. A nem szöveges típusú adatokat először stringgé kell alakítanunk az str() függvénnyel.

1
2
szoveg = str(101) + " kiskutya"
print(szoveg)       

Kimenet

101 kiskutya

Stringek hossza

Pythonban a len() beépített függvény segítségével egyszerűen lekérdezhetjük egy tetszőleges string hosszát.

1
2
szoveg = "Python"
print(len(szoveg))

Kimenet

6

A len() függvény egyébként nem csak stringek, hanem egyéb típusok (pl. lista, tuple, dictionary) hosszát is le tudja kérdezni. A len()-nel még a következő gyakorlaton is találkozunk.

Karakterek indexelése

Pythonban is lehetőségünk van a stringek karaktereinek az indexelésére. Erre a más nyelvekből ismerős szögletes zárójel operátort használjuk: szoveg[index].

A karakterek indexelése minden esetben 0-tól kezdődik (tehát a legelső karakter indexe itt is 0 lesz).

1
2
3
szoveg = "macskajancsi"
print("A 0. indexű karakter:", szoveg[0])   
print("A 4. indexű karakter:", szoveg[4])   

Kimenet

A 0. indexű karakter: m A 4. indexű karakter: k

Egy kis érdekesség, hogy a Python támogatja a negatív indexeket is. Ebben az esetben a string végétől kezdünk el számolni (tehát az utolsó karakter indexe -1, az utolsó előtti karakteré -2 stb.).

1
2
szoveg = "macskajancsi"
print("Az utolsó karakter:", szoveg[-1])

Kimenet

Az utolsó karakter: i

Ha Pythonban nem csak egyetlen karaktert, hanem egy komplett részstringet szeretnénk lekérdezni, akkor használjuk az intervallumos indexelést.

A szoveg[index] konstrukcióban most index helyén egy intervallumot adhatunk meg, mettől:meddig:lépésköz formában. A három, kettősponttal elválasztott érték közül bármelyik tetszőlegesen elhagyható: alapból a 0. karaktertől megyünk az utolsó karakterig, 1-es lépésközzel.

1
2
3
4
5
6
7
szoveg = "macskajancsi"
print(szoveg[1:8:2])    # 1-8. karakter, 2-es lépésközzel
print(szoveg[2:5])      # 2-5. karakter
print(szoveg[:5])       # 0-5. karakter
print(szoveg[5:])       # 5. karaktertől a string végéig
print(szoveg[:])        # a teljes szöveg
print(szoveg[::2])      # minden második karakter

Kimenet

asaa csk macsk ajancsi macskajancsi mckjns

String megfordítása

Pythonban ha egy stringet meg szeretnénk fordítani, akkor az intervallumos indexelést felhasználva ezt egyszerűen megtehetjük: vesszük a teljes szöveget, csak most nem előrefelé, hanem visszafelé lépkedve "olvassuk" azt (-1-es lépésköz).

1
2
szoveg = "macskajancsi"                     
print(szoveg[::-1])                 

Kimenet

iscnajakscam

Immutable adattípus

Pythonban minden string immutable. Ez azt jelenti, hogy a stringek kezdeti értéke nem változhat meg. Tehát Pythonban például nem csinálhatunk olyat, hogy egy szöveg adott karakterét módosítjuk. Ha ezt megpróbáljuk, hibaüzenetet kapunk.

1
2
3
4
szoveg = "Jaj, erre figyelni kell!"
szoveg[1] = 'u'

print(szoveg)

Kimenet

Traceback (most recent call last): File "main.py", line 2, in <module> szoveg[1] = 'u' TypeError: 'str' object does not support item assignment

Részstring előfordulása

Pythonban ha le akarjuk ellenőrizni, hogy egy szöveg részstringként szerepel-e egy másik szövegben, akkor ezt az in kulcsszóval egyszerűen meg tudjuk tenni.

Az s1 in s2 kifejezés igazat ad vissza, ha az s1 szöveg benne van az s2 szövegben.

Példa: Az in operátor használata

1
2
3
4
5
6
7
szoveg = "1, egy almafa; 2, két katica; 3, három kiskacsa; 1, 2, 3"

if "alma" in szoveg:
    print("Van a szövegben alma.")

if szoveg[0] in "0123456789":
    print("A szöveg egy számjeggyel kezdődik.")

Kimenet

Van a szövegben alma. A szöveg egy számjeggyel kezdődik.

Stringkezelő függvények

A Python rengeteg beépített stringkezelő függvényt biztosít számunkra. Ezek közül áttekintjük a kurzus szempontjából a legfontosabbakat.

  • s.lower(): csupa kisbetűssé alakítja az s stringet
  • s.upper(): csupa nagybetűssé alakítja az s stringet
  • s.startswith(v): igazat ad vissza, ha az s string a v értékkel kezdődik
  • s.endswith(v): igazat ad vissza, ha az s string a v értékre végződik
  • s.count(v): visszaadja, hogy az s stringben hányszor szerepel a v érték
  • s.strip(): eltávolítja az s string elején és végén lévő whitespace karaktereket
    • s.lstrip(): csak az s string elején lévő whitespace-t távolítja el (left strip)
    • s.rstrip(): csak az s string végén lévő whitespace-t távolítja el (right strip)
  • s.replace(old, new): lecseréli az s stringben az összes old részstringet new-ra
  • s.split(delim): feldarabolja az s stringet delim karakterek mentén (listát ad vissza)
  • s.isalpha(): igazat ad vissza, ha az s stringben csak betűk szerepelnek
  • s.isdigit(): igazat ad vissza, ha az s stringben csak számjegyek szerepelnek
  • ...

Példa: Stringkezelő függvények használata

1
2
3
4
5
6
7
8
9
szoveg = "   A füstölt szalonna a legjobb szalonna Béla szerint                "
szoveg = szoveg.strip()   # whitespace eltávolítása a szöveg elejéről és végéről

print(szoveg.lower())               # kisbetűsítés
print(szoveg.upper())               # nagybetűsítés
print(szoveg.endswith("szerint"))   # a "szerint" stringre végződik-e a szöveg
print(szoveg.count("a"))            # hány darab 'a' betű van a szövegben
print(szoveg.replace("szalonna", "kolbász"))  # lecserélés
print(szoveg.split(" "))            # feldarabolás szóközök mentén

Kimenet

a füstölt szalonna a legjobb szalonna béla szerint A FÜSTÖLT SZALONNA A LEGJOBB SZALONNA BÉLA SZERINT True 6 A füstölt kolbász a legjobb kolbász Béla szerint ['A', 'füstölt', 'szalonna', 'a', 'legjobb', 'szalonna', 'Béla', 'szerint']

Kiegészítés: Formázott kiíratás

Pythonban stringek formázott kiíratására több módszert is használhatunk:

  • format() metódus
  • %-formatting
  • f-stringek (Python 3.6-tól).

Nézzünk egy-egy példát ezek mindegyikére.

1
2
3
4
5
6
7
8
9
PI = 3.14159265359
print("A pí értéke: {}".format(PI))         # format() metódus

nev = "Béla"
eletkor = 21
print("Hello, %s vagyok, %d éves." % (nev, eletkor))  # %-formatting

elet_ertelme = 42
print(f"Az élet értelme: {elet_ertelme}")   # f-string

Kimenet

A pí értéke: 3.14159265359 Hello, Béla vagyok, 21 éves. Az élet értelme: 42

Feladatok

  1. Készíts egy piramis nevű függvényt, ami egy számot vár, és alábbi piramist rajzolja ki (mindig az aktuális számig, az még legyen benne a kiíratásban):

    1
    2
    3
    4
    5
    1
    2 2
    3 3 3
    4 4 4 4
    5 5 5 5 5
    
  2. Készíts egy szorzotabla nevű függvényt, ami kiírja a szorzótáblát 1-től 10-ig

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    1  2 3 4 5 6 7 8 9 10
    2  4 6 8 10 12 14 16 18 20
    3  6 9 12 15 18 21 24 27 30
    4  8 12 16 20 24 28 32 36 40
    5  10 15 20 25 30 35 40 45 50
    6  12 18 24 30 36 42 48 54 60
    7  14 21 28 35 42 49 56 63 70
    8  16 24 32 40 48 56 64 72 80
    9  18 27 36 45 54 63 72 81 90
    10 20 30 40 50 60 70 80 90 100
    
  3. Készíts egy programot, ami az alábbi fordított piramist írja ki:

    1
    2
    3
    4
    5
    * * * * *
    * * * *
    * * *
    * *
    *
    
  4. Készíts egy programot, ami bekér 3 számot, és a három szám alapján kiírja a felhasználónak, hogy a megadott három szám

    • számtani sorozatot alkot-e,
    • mértani sorozatot alkot-e,
    • nem alkot sem számtani, sem mértani sorozatot.

További gyakorló feladatok megoldással itt és itt


Utolsó frissítés: 2020-09-22 18:12:04