02. MODUL · PYTHON

Feltételes utasítások.

if, elif, else – döntések a programban

1. fejezet

Döntések a programban

Az eddigi programjaink minden sort végrehajtottak, fentről lefelé. A valódi programok viszont döntenek: ha a jelszó helyes, beengednek; ha a pontszám 50 alatti, „elégtelen”-t írnak ki. Az ilyen útelágazást feltételes utasításnak vagy elágazásnak nevezzük.

Feltétel

A feltétel egy kifejezés; a program az értéke alapján dönti el, melyik utat járja be. Leggyakrabban összehasonlítás (kor >= 18), amelynek eredménye logikai (bool) érték: True (igaz) vagy False (hamis). Feltétel lehet egy logikai változó, ezek kombinációja, sőt bármilyen érték is: a 0, az üres szöveg (""), a None és az üres gyűjtemények (például a 4. modul üres listája) hamisnak számítanak, minden más igaznak.

kor = int(input("Hány éves vagy? "))
if kor >= 18:
    print("Beléphetsz.")
else:
    print("Sajnos még nem léphetsz be.")
print("Viszlát!")

Futtasd többször, különböző életkorral (16, 18, 30), majd kövesd Lépésenként: a Kiértékelés részben látod, hogyan lesz a kor >= 18-ból 16 >= 18, majd False – és hogy emiatt melyik sor marad ki. Az utolsó print nincs beljebb kezdve, ezért az elágazástól függetlenül mindig lefut.

2. fejezet

Összehasonlító műveletek

JelJelentésPéldaÉrték
==egyenlő5 == 5True
!=nem egyenlő5 != 3True
<kisebb3 < 5True
<=kisebb vagy egyenlő5 <= 5True
>nagyobb3 > 5False
>=nagyobb vagy egyenlő4 >= 5False

Az összehasonlítás eredménye maga is egy érték, amelyet ki lehet írni vagy változóba lehet tenni:

x = 7
print(x > 5)
print(x == 10)
nagykoru = x >= 18
print(nagykoru, type(nagykoru))
print("alma" == "alma", "alma" == "Alma")

= vagy ==? Az egy egyenlőségjel értékadás („legyen”), a kettő összehasonlítás („egyenlő-e?”). Ha egyenlőséget vizsgálsz, == kell; az if x = 5: szintaktikai hiba.

Mit ír ki?

print(5 == 5.0, "5" == 5)
  1. True True
  2. True False
  3. False False

Az egész 5 és a valós 5.0 ugyanazt a számot jelenti, ezért egyenlők. A "5" viszont szöveg, a szöveg és a szám sosem egyenlő – ezért kell az input() eredményét átalakítani, mielőtt számmal hasonlítjuk össze.

Szövegeket is lehet <-tel és >-vel hasonlítani: a Python karakterenként, a karakterek kódja szerint dönt ("alma" < "banán" igaz). A kis- és nagybetű különbözik ("Zebra" < "alma" is igaz, mert a nagybetűk kódja kisebb), és az ékezetes betűk nem a magyar ábécé szerint sorolódnak. Szöveges egyezésnél gyakran mindkét oldalt kisbetűsre alakítjuk: valasz.lower() == "igen" (a ponttal kapcsolódó .lower() a szöveg metódusa: a kisbetűs változatát adja).

Valós számokat ne ==-vel hasonlíts. Az 1. modulban láttuk, hogy a 0.1 + 0.2 nem pontosan 0,3 – ezért a 0.1 + 0.2 == 0.3 értéke False. Valós számoknál tűréssel vizsgáljuk az egyezést: abs(a - b) < 1e-9.

a = 0.1 + 0.2
print(a == 0.3)
print(abs(a - 0.3) < 1e-9)

3. fejezet

Az if utasítás

if feltétel:
    utasítás1    # ezek csak akkor futnak le,
    utasítás2    # ha a feltétel igaz
utasítás3        # ez mindig lefut
  • ifkulcsszó: „ha”
  • feltételkifejezés, amelyet a Python igaznak vagy hamisnak tekint – jellemzően True vagy False értékű
  • :a fejléc végét jelzi – kötelező
  • ····4 szóköz behúzás: ezek a sorok alkotják a blokkot

A behúzás a Pythonban a szerkezet része: ami az if alatt beljebb kezdődik, az az if blokkja, és csak igaz feltétel esetén fut. Az első nem behúzott sor már az elágazás után következik. Más nyelvek kapcsos zárójellel jelölik a blokkot – a Python a behúzással.

szam = int(input("Adj meg egy egész számot: "))
if szam < 0:
    print("Negatív számot adtál meg.")
    szam = -szam
print("A szám abszolút értéke:", szam)

Kövesd lépésenként két futással: egyszer negatív, egyszer pozitív számmal. Negatív számnál a blokk mindkét sora lefut, és a szam = -szam előjelet vált. Pozitívnál a teljes blokk kimarad.

A leggyakoribb hibák: hiányzó kettőspont (SyntaxError: expected ':'), hiányzó behúzás (IndentationError: expected an indented block), illetve a blokk sorai eltérő mértékben vannak beljebb kezdve. Próbáld ki: töröld ki a kettőspontot a fenti példából, és futtasd.

4. fejezet

Két ág: if – else

Az else („különben”) ág akkor fut le, ha a feltétel hamis. Az else-nek nincs feltétele, és mindig az elágazás utolsó ága. A két ág közül pontosan egy fut le – sosem mindkettő, és sosem egyik sem.

Példa: páros vagy páratlan?

Egy szám akkor páros, ha 2-vel osztva a maradék 0. A szam % 2 a 2-vel vett maradékot adja (0 vagy 1), a feltétel pedig azt vizsgálja, hogy ez a maradék 0-e.

szam = int(input("Adj meg egy egész számot: "))
if szam % 2 == 0:
    print(szam, "páros.")
else:
    print(szam, "páratlan.")
szam % 2 == 0→17 % 2 == 0→1 == 0→False

17 = 8 · 2 + 1, a maradék 1, ezért a feltétel hamis, és az else ág fut. Figyeld meg: nem azt vizsgáljuk, hogy „a szám nulla-e”, hanem hogy a maradék nulla-e.

Példa: felhasználónév hossza

felhasznalonev = input("Felhasználónév: ")
if len(felhasznalonev) >= 3:
    print(f"Üdv, {felhasznalonev}!")
else:
    print("Hiba: a név legalább 3 karakter legyen.")

5. fejezet

Több ág: elif

Ha kettőnél több lehetőség van, az elif („különben, ha”) ágakkal bővítjük az elágazást. A Python fentről lefelé vizsgálja a feltételeket, és az első igaz feltételhez tartozó ágat hajtja végre – a többit már meg sem nézi. Ha egyik sem igaz, az else fut (ha van).

pont = int(input("Elért pontszám (0–100): "))
if pont >= 85:
    jegy = 5
elif pont >= 70:
    jegy = 4
elif pont >= 55:
    jegy = 3
elif pont >= 40:
    jegy = 2
else:
    jegy = 1
print("Az érdemjegy:", jegy)

78 pontnál a pont >= 85 hamis, a pont >= 70 igaz – itt a vizsgálat véget ér, a jegy 4. Hogy a pont >= 55 is igaz lenne, már nem számít. Ezért elég az alsó határokat leírni: az elif pont >= 70 ágba csak olyan pontszám juthat el, amely 85 alatti.

A sorrend számít. Ha a feltételeket alulról kezdenénk (if pont >= 40 előre), minden legalább 40 pontos dolgozat 2-est kapna, mert ez az első igaz feltétel. Javítsd ki ezt a hibás programot, és ellenőrizd 90 ponttal:

pont = int(input("Pontszám: "))
if pont >= 40:
    jegy = 2
elif pont >= 55:
    jegy = 3
elif pont >= 70:
    jegy = 4
elif pont >= 85:
    jegy = 5
else:
    jegy = 1
print("Az érdemjegy:", jegy)

Miért nem három külön if?

Az egymás alatti, egymástól független if-ek mindegyike kiértékelődik, és több is lefuthat. Az if–elif lánc viszont egyetlen elágazás: legfeljebb egy ága fut le. Ha az esetek kizárják egymást (egy pontszám egy jegy), az elif a helyes eszköz.

homerseklet = 30
if homerseklet > 25:
    print("Meleg van.")
if homerseklet > 15:
    print("Kellemes idő van.")
if homerseklet > 5:
    print("Nem fagy.")

Itt mindhárom üzenet megjelenik. Írd át elif-re a második és harmadik if-et, és figyeld meg a különbséget.

6. fejezet

Összetett feltételek: and, or, not

and

és

Akkor igaz, ha mindkét oldala igaz.

or

vagy

Akkor igaz, ha legalább az egyik oldala igaz.

not

nem

Megfordítja az értéket: igazból hamis, hamisból igaz.

kor = int(input("Életkor: "))
jogsi = input("Van jogosítványod? (igen/nem) ")
van_jogsi = jogsi == "igen"
if kor >= 18 and van_jogsi:
    print("Vezethetsz.")
else:
    print("Nem vezethetsz.")

Rövidzár. Az and balról jobbra halad, és ha a bal oldal hamis, a jobb oldalt ki sem értékeli – az eredmény úgyis hamis. Az or igaz bal oldalnál áll meg. Ezt ki is használhatjuk: if oszto != 0 and szam % oszto == 0: nullával soha nem oszt, mert nulla osztónál a második rész már nem fut le. A Lépésenként nézet Kiértékelés részében látod, hol áll meg a kiértékelés.

Sorrend. Zárójel nélkül előbb a not, aztán az and, végül az or értékelődik ki: a or b and c jelentése a or (b and c). Ha bizonytalan vagy, zárójelezz – az olvasónak is segít.

Intervallum vizsgálata

Azt, hogy egy szám két határ közé esik-e, írhatjuk két összehasonlítással és and-del, vagy a Pythonban megengedett láncolt alakban:

pont = 73
print(0 <= pont and pont <= 100)
print(0 <= pont <= 100)
print(not (0 <= pont <= 100))

Példa: szerkeszthető-e a háromszög?

Három szakaszból akkor szerkeszthető háromszög, ha bármely két oldal összege nagyobb a harmadiknál (háromszög-egyenlőtlenség). Ha igen, a kerületet és – Hérón képletével – a területet is kiszámoljuk. A négyzetgyökhöz a math modul sqrt() függvényét használjuk; az import math sor teszi elérhetővé (a modulokról az 5. modulban lesz részletesen szó).

import math

a = float(input("a = "))
b = float(input("b = "))
c = float(input("c = "))
if a + b > c and a + c > b and b + c > a:
    kerulet = a + b + c
    s = kerulet / 2
    terulet = math.sqrt(s * (s - a) * (s - b) * (s - c))
    print(f"Szerkeszthető. Kerület: {kerulet:.2f}, terület: {terulet:.2f}")
else:
    print("Ebből a három szakaszból nem szerkeszthető háromszög.")

Próbáld ki az 1, 2, 3 bemenettel is: 1 + 2 nem nagyobb 3-nál, csak egyenlő – a három szakasz egy egyenesre esne.

Tartalmazás: in

Ha egy értéket több lehetőséggel kell összevetni, a hosszú or-lánc helyett az in művelet tömörebb: honap in (12, 1, 2) igaz, ha a hónap a felsorolt értékek egyike. (A zárójeles, vesszős felsorolás egy tuple – a 4. modulban lesz róla szó.) A not in az ellenkezőjét vizsgálja. Szövegnél az in részszöveget keres: "ma" in "alma" igaz.

honap = int(input("Hónap (1–12): "))
if honap in (12, 1, 2):
    print("Tél")
elif honap in (3, 4, 5):
    print("Tavasz")
elif honap in (6, 7, 8):
    print("Nyár")
elif honap in (9, 10, 11):
    print("Ősz")
else:
    print("Nincs ilyen hónap.")

Mit ír ki?

x = 15
if x % 3 == 0 and x % 5 == 0:
    print("A")
elif x % 3 == 0:
    print("B")
if x > 10 or x < 0:
    print("C")
  1. A
  2. A B C (külön sorokban)
  3. A és C (külön sorokban)
  4. B és C (külön sorokban)

A 15 osztható 3-mal és 5-tel is, ezért az első ág fut (A), az elif kimarad. A harmadik if egy új elágazás: 15 > 10 igaz, így C is megjelenik.

7. fejezet

Beágyazott elágazás

Egy ág blokkjában újabb elágazás is állhat – ilyenkor a belső if sorai még egy szinttel (újabb 4 szóközzel) beljebb kezdődnek. Akkor használjuk, ha a második kérdésnek csak az első válasz ismeretében van értelme.

Példa: egyszerű számológép

Az osztásnál külön meg kell vizsgálni, hogy az osztó nem nulla-e – ez a belső elágazás.

a = float(input("Első szám: "))
muvelet = input("Művelet (+, -, *, /): ")
b = float(input("Második szám: "))
if muvelet == "+":
    print("Eredmény:", a + b)
elif muvelet == "-":
    print("Eredmény:", a - b)
elif muvelet == "*":
    print("Eredmény:", a * b)
elif muvelet == "/":
    if b != 0:
        print("Eredmény:", a / b)
    else:
        print("Nullával nem lehet osztani!")
else:
    print("Ismeretlen művelet.")

Példa: bankautomata

Ez a program egyetlen tranzakciót kezel: előbb a PIN-kódot ellenőrzi, és csak helyes PIN esetén kérdez rá a műveletre, kivétnél pedig a fedezetre is. A három szint pontosan a döntések sorrendjét követi.

PIN = "1234"
egyenleg = 100000

pin = input("PIN-kód: ")
if pin == PIN:
    print("1 – Készpénzfelvétel")
    print("2 – Egyenleg lekérdezése")
    valasztas = input("Választás: ")
    if valasztas == "1":
        osszeg = int(input("Összeg (Ft): "))
        if osszeg <= 0:
            print("Az összegnek pozitívnak kell lennie.")
        elif osszeg > egyenleg:
            print("Nincs elegendő fedezet.")
        else:
            egyenleg = egyenleg - osszeg
            print(f"Vegye el a pénzt! Új egyenleg: {egyenleg} Ft")
    elif valasztas == "2":
        print(f"Egyenleg: {egyenleg} Ft")
    else:
        print("Érvénytelen választás.")
else:
    print("Hibás PIN-kód.")

A PIN nagybetűs neve azt jelzi, hogy állandónak szánt érték (konstans). A PIN-t szövegként tároljuk és hasonlítjuk, mert nem számolunk vele – így a 0123 kezdetű kód sem veszíti el a nulláját. A valódi automata természetesen ismétli a menüt; ehhez a következő modul ciklusai kellenek.

Túl mély beágyazás nehezen olvasható. Ha három-négy szintnél többre volna szükség, érdemes átgondolni: gyakran egy elif-lánc vagy egy összetett feltétel (and) ugyanazt egyszerűbben fejezi ki.

8. fejezet

Gyakorló feladatok

A kiírt szövegek legyenek pontosan olyanok, mint a mintában. Minden feladatnál próbáld ki a határeseteket is (egyenlő számok, 0, negatív szám) – az ellenőrzés is ezekkel tesztel.

Melyik a nagyobb?

Kérj be két egész számot, és írd ki, melyik a nagyobb – vagy hogy egyenlők:

Első szám: 5
Második szám: 8
A második szám a nagyobb.

A lehetséges kimenetek: Az első szám a nagyobb. · A második szám a nagyobb. · A két szám egyenlő.

a = int(input("Első szám: "))
b = int(input("Második szám: "))
if a > b:
    print("Az első szám a nagyobb.")
elif a < b:
    print("A második szám a nagyobb.")
else:
    print("A két szám egyenlő.")
Tipp

Három eset van, ezért if – elif – else kell. Az egyenlőséget hagyhatod az else-re: ha egyik sem nagyobb, csak egyenlők lehetnek.

Páros vagy páratlan

Kérj be egy egész számot, és írd ki, hogy páros vagy páratlan:

Szám: 14
A 14 páros.

Páratlan esetén: A 7 páratlan. (A névelővel most ne foglalkozz: mindig „A” legyen.)

szam = int(input("Szám: "))
if szam % 2 == 0:
    print(f"A {szam} páros.")
else:
    print(f"A {szam} páratlan.")
Tipp

A maradék vizsgálata: szam % 2 == 0. A 0 is páros, mert 0 % 2 == 0. Negatív számra is működik: Pythonban -3 % 2 értéke 1.

Belépőjegy

Egy múzeumban a belépő ára 6 éves kor alatt ingyenes, 6–17 éves korig 1200 Ft, 18–64 évesen 2500 Ft, 65 évtől 1200 Ft. Kérd be az életkort, és írd ki a jegy árát:

Életkor: 15
Jegyár: 1200 Ft

Ingyenes belépés esetén ezt írd ki: Jegyár: ingyenes

kor = int(input("Életkor: "))
if kor < 6:
    print("Jegyár: ingyenes")
elif kor < 18:
    print("Jegyár: 1200 Ft")
elif kor < 65:
    print("Jegyár: 2500 Ft")
else:
    print("Jegyár: 1200 Ft")
Tipp

Haladj alulról felfelé az elif-lánccal: kor < 6, kor < 18, kor < 65, a többi az else. A határokra figyelj: a 6 éves már fizet, a 18 éves már felnőttjegyet vesz.

Oszthatóság 3-mal és 5-tel

Kérj be egy egész számot, és írd ki a négy lehetséges üzenet közül a megfelelőt:

Szám: 15
Osztható 3-mal és 5-tel is.

A többi üzenet: Osztható 3-mal. · Osztható 5-tel. · Sem 3-mal, sem 5-tel nem osztható.

szam = int(input("Szám: "))
if szam % 3 == 0 and szam % 5 == 0:
    print("Osztható 3-mal és 5-tel is.")
elif szam % 3 == 0:
    print("Osztható 3-mal.")
elif szam % 5 == 0:
    print("Osztható 5-tel.")
else:
    print("Sem 3-mal, sem 5-tel nem osztható.")
Tipp

A „mindkettővel osztható” esetet kell először vizsgálni – különben a 15-re már a „3-mal osztható” ág lefutna. Ez ugyanaz a sorrend-csapda, mint az érdemjegyeknél.

Szökőév

Egy év szökőév, ha osztható 4-gyel, de a 100-zal osztható évek közül csak azok, amelyek 400-zal is oszthatók (az 1900 nem szökőév, a 2000 igen). Kérj be egy évszámot, és döntsd el:

Évszám: 2024
2024 szökőév.

Különben: 2023 nem szökőév.

ev = int(input("Évszám: "))
if (ev % 4 == 0 and ev % 100 != 0) or ev % 400 == 0:
    print(f"{ev} szökőév.")
else:
    print(f"{ev} nem szökőév.")
Tipp

Fogalmazd meg egy összetett feltétellel: „4-gyel osztható és 100-zal nem” vagy „400-zal osztható”. A zárójel segít, hogy a részek jól elkülönüljenek.

Egészszám-számológép

Kérj be két egész számot és közöttük egy műveleti jelet a következők közül: // (egészosztás), % (maradék), ** (hatványozás). Írd ki az eredményt így:

Első szám: 17
Művelet: //
Második szám: 5
17 // 5 = 3

Ha az egészosztás vagy a maradék osztója 0: Nullával nem lehet osztani. Negatív kitevőnél: A kitevő nem lehet negatív. Ismeretlen műveletnél: Ismeretlen művelet.

a = int(input("Első szám: "))
muvelet = input("Művelet: ")
b = int(input("Második szám: "))
if muvelet == "//" or muvelet == "%":
    if b == 0:
        print("Nullával nem lehet osztani.")
    elif muvelet == "//":
        print(f"{a} // {b} = {a // b}")
    else:
        print(f"{a} % {b} = {a % b}")
elif muvelet == "**":
    if b < 0:
        print("A kitevő nem lehet negatív.")
    else:
        print(f"{a} ** {b} = {a ** b}")
else:
    print("Ismeretlen művelet.")
Tipp

A műveleti jel szöveg: muvelet == "//". A két osztásos műveletet egy közös ágba is teheted (or), és ott egy beágyazott if vizsgálja az osztót. Az ellenőrzés sorrendje számít: előbb a nulla osztót nézd meg.

A legkisebb és a legnagyobb

Kérj be három egész számot, és írd ki a legkisebbet és a legnagyobbat. A min() és max() függvényt (6. modul) most ne használd – elágazásokkal oldd meg.

1. szám: 4
2. szám: 9
3. szám: -2
Legkisebb: -2
Legnagyobb: 9
a = int(input("1. szám: "))
b = int(input("2. szám: "))
c = int(input("3. szám: "))
legkisebb = a
if b < legkisebb:
    legkisebb = b
if c < legkisebb:
    legkisebb = c
legnagyobb = a
if b > legnagyobb:
    legnagyobb = b
if c > legnagyobb:
    legnagyobb = c
print("Legkisebb:", legkisebb)
print("Legnagyobb:", legnagyobb)
Tipp

Tegyük fel, hogy az első szám a legkisebb (legkisebb = a). Aztán nézd meg a többit egyenként: ha valamelyik kisebb ennél, az lesz az új legkisebb. Ugyanígy a legnagyobbal. Ez a „minimumkeresés” – a ciklusoknál sokszor visszatér.

Milyen háromszög?

Kérd be egy háromszög három oldalát (egész számok), és írd ki a típusát:

  • Nem szerkeszthető. – ha nem teljesül a háromszög-egyenlőtlenség (ez a 0 vagy negatív hosszú oldalt is kiszűri),
  • Egyenlő oldalú. – ha mindhárom oldal egyenlő,
  • Egyenlő szárú. – ha pontosan két oldal egyenlő,
  • Általános. – egyébként.
a = 5
b = 5
c = 8
Egyenlő szárú.
a = int(input("a = "))
b = int(input("b = "))
c = int(input("c = "))
if a + b <= c or a + c <= b or b + c <= a:
    print("Nem szerkeszthető.")
elif a == b == c:
    print("Egyenlő oldalú.")
elif a == b or b == c or a == c:
    print("Egyenlő szárú.")
else:
    print("Általános.")
Tipp

A szerkeszthetőséget kell először vizsgálni: a 2, 2, 9 két egyenlő oldala ellenére sem háromszög. Utána az egyenlő oldalút (mert az „egyenlő szárú” feltétele rá is igaz lenne), végül az egyenlő szárút.

9. fejezet

Összefoglalás

EszközLényeg
== != < <= > >=összehasonlítás; az eredmény True vagy False
if feltétel:a behúzott blokk csak igaz feltételnél fut le
else:az előző feltétel(ek) hamis volta esetén fut; nincs feltétele
elif feltétel:újabb feltétel; az első igaz ág fut, a többi kimarad – a sorrend számít
and, or, notösszetett feltétel; rövidzáras kiértékelés balról jobbra
x in (1, 2, 3)szerepel-e az érték a felsorolásban

Gyakorold tovább: írj programot, amely egy dolgozat pontszámából (0–40) és a jegyhatárokból (11, 18, 26, 31) kiírja az érdemjegyet. Előbb írd fel a határeseteket (10, 11, 30, 31, 40), számold ki a várt jegyet, és csak utána teszteld a programot.