Python gyerekeknek - ciklusok

Kategória: Python gyerekeknek.

Áttekintés

Ha valamit ismételten többször végre kell hajtani, akkor ahhoz ciklust használhatunk. Két fő ciklusfajta létezik: a for és a while; ezeket nézzük most meg.

Először nézzünk egy bevezető példát! Tegyük fel, hogy egy szám faktoriálisát szeretnénk kiszámolni! A faktoriális a számok szorzata 1-től addig a számig. Például az 5 faktoriálisa az alábbi:

>>> 1*2*3*4*5
120

Láthatjuk, hogy a szorzás művelet ismételten előfordul, többször egymás után. Nem lehetne ezt csak egyszer leírni és utána ismételni?

A for ciklus

Elmélet

A for ciklus segítségével elemeken tudunk végiglépkedni, és mindegyiken valamilyen műveletet végrehajtani. Erre a későbbiekben még látunk majd példát, most egy szakasz elemeit vizsgáljuk meg. Először nézzünk egy példát!

for i in range(5):
    print('alma')

Kiírja ötször azt, hogy alma. Az alábbiakat figyeljük meg:

  • for a sor elején.
  • i: ez az ún. ciklusváltozó, amiről még lesz szó.
  • in: arra utal, hogy valamin lépkedünk végig.
  • range(5): ötször hajtjuk végre.
  • : a végén.
  • A belseje beljebb húzva (ez lehetne több utasítás is).

Ehhez hasonló a Scratch-ben (bár ott nem túl látványos):

for.png

De mi is az a range()? Tekintsük az alábbi kódot!

for i in range(5):
    print(i)

Lefuttatva azt tapasztaljuk, hogy kiírja a számokat 0-tól 4-ig. A paraméter tehát eggyel több, mint ameddig a szakasz tart. Ennek az az oka, hogy a sorszámozás 0-tól indul.

A range()-nek nemcsak egy, hanem két paramétert is megadhatunk. Ekkor az első paraméter az, hogy honnan számoljon, a második pedig az, hogy meddig, mínusz 1:

for i in range(1, 6):
    print(i)

Ez tehát a számokat íjra ki 1-től 5-ig. Ehhez hasonló a Scratch-ben:

fori.png

Végül a range() 3 paramétert is tartalmazhat; a harmadik a lépték. Kettesével a következőképpen léphetünk (melynek eredménye 1, 3 és 5 lesz):

for i in range(1, 6, 2):
    print(i)

Most már tudjuk, hogy hogyan tudunk egyesével végiglépkedni 1-től 5-ig; valósítsuk meg a faktoriálist!

faktorialis = 1
for i in range(1, 6):
    faktorialis = faktorialis * i
print(faktorialis)

Az elején a faktorialis változót 1-re állítottuk, majd összeszoroztuk 1-től 5-ig a számokat, minden lépésben eggyel, végül kiírattuk a végeredményt, ami 120. Ugyanez Scratch-ben:

faktorialis.png

Feladat

Három számra akkor mondjuk, hogy Pitagorasz számhármas, ha azokat külön-külön négyzetre emelve, majd kettőt közülük összeadva megkapjuk a harmadikat. Például a 3, a 4 és az 5 Pitagorasz számhármas, mert $3^2 + 4^2 = 5^2$. Írjunk programot, amely 1-től 20-ig megkeresi az összes Pitagorasz számhármast!

Vajon hogyan tudjuk egymásba ágyazni a ciklusokat? Hogyan tudjuk kombinálni a feltételkezeléssel?

for a in range(1, 21):
    for b in range(1, 21):
        for c in range(1, 21):
            if a*a + b*b == c*c:
                print(str(a) + ', ' + str(b) + ', ' + str(c))

Ez így működik, de ugyanazokat többször is kiírja. Oldjuk meg azt, hogy minden megoldást csak egyszer írjon ki!

for a in range(1, 19):
    for b in range(a, 20):
        for c in range(b, 21):
            if a*a + b*b == c*c:
                print(str(a) + ', ' + str(b) + ', ' + str(c))

Önálló feladat

Írjuk ki az olyan számhármasokat 1-től 10-ig, melyre igaz az, hogy $a\cdot b = c^2$, és mindhárom szám különböző.

Teszt

1. feladat

Mit ír ki az alábbi kód?

for i in range(6):
    print(i)

A 1, 2, 3, 4, 5, 6
B 1, 2, 3, 4, 5
C 0, 1, 2, 3, 4, 5, 6
D 0, 1, 2, 3, 4, 5

2. feladat

Milyen számokat ír ki az alábbi kód?

a = 0
b = 1
for i in range(10):
    temp = b
    b = a + b
    a = temp
    print(a)

3. feladat

Mit csinál az alábbi kód?

import math
 
for i in range(2, 19):
    p = True
    for j in range(2, round(math.sqrt(i))+1):
        if i % j == 0:
            p = False
    if p:
        print(i)

A while ciklus

Elmélet

A while ciklus ún. elöltesztelő ciklus. Ott nem konkrét elemeken lépked végig, hanem addig tart, amíg egy feltétel igaz. A számokat 1-től 5-ig a következőképpen írathatjuk ki:

i = 1
while i <= 5:
    print(i)
    i = i + 1

Figyeljük meg az alábbiakat:

  • while: ezzel kezdődik,
  • utána jön a feltétel,
  • : a végén.

Ez egy példa arra is, hogy a belseje több (jelen esetben kettő) utasítást is tartalmazhat.

A Scratch-ben ehhez hasonló utasítás az ismételd eddig, csakhogy sajnos ott picit más a logika: ott addig ismétli a belsejét, amíg igaz nem lesz a feltétel. Tehát ha a feltétel hamis, akkor hajtja végre az utasításokat. Talán elsőre nehéz lesz váltani erre a másik logikára, viszont megéri váltani, ugyanis a programozási nyelvek döntő többsége e tekintetben úgy működik, mint a Python. A Scratch kód:

while.png

Végtelen ciklust a while True: utasítással tudunk létrehozni, ami többé-kevésbé megfelel a Scratch mindig utasításának:

mindig.png

Tekintsük az alábbi "végtelen ciklus" Python kódot!

i = 1
while True:
    print(i)
    i = i + 1
    if i > 5:
        break

Vegyük észre az alábbiakat:

  • while True: az elején: végtelen ciklus.
  • if i > 5: feltétel a while cikluson belül. Mivel a while miatt önmagában be kell húzni az utasításokat, és az if miatt is, az azon belüli utasítást már kétszeresen be kell húzni. Mivel a feltételek és ciklusok tetszőlegesen egymásba ágyazhatóak (ill. vannak még olyan elemek, amelyeknél be kell húzni), elvileg tetszőleges mélységű lehet a behúzás.
  • break : ez egy új utasítás, ami azt jelenti, hogy lépj ki az aktuális ciklusból. Ebben a példában tehát a while True ténylegesen nem lesz végtelen; amint az i nagyobb lesz 5-nél, megszakad a végtelen ciklus.

A break utasítás nincs a Scratch-ben.

A break-hez hasonló a continue, ami pont ellentétes azzal: újrakezdi a ciklusmagot. Pl.:

print('Páros számok:')
i = 0
while i < 10:
    i = i + 1
    if i % 2 == 1:
        continue
    print(i)

Ez a kódrészlet a páros számokat írja ki. Nagy része már ismerős kell, hogy legyen; az új részek az alábbiak:

  • if i % 2 == 1: emlékezzünk vissza: az i % 2 a maradékos osztás maradéka. Itt azt kérdezzük, hogy ha az i értékét elosztjuk 2-vel, akkor 1 lesz-e a maradék? Ilyen számok pl. az 1, a 3, az 5, a 7 stb. Nem ilyen a 2, a 4, a 6, a 8 stb. Tehát máris meg vannak a páros számok!
  • continue: újraindul a ciklusmag, tehát a feltétel kiértékelése, majd ha az igaz, akkor az i = i + 1 sor, és nem hajtódik végre a print(i).

Ehhez hasonló sincs a Scratch-ben.

Feladat

Adjuk össze a számokat egyesével addig, amíg el nem érjük a 100-at. Amint elértük, álljunk le! Írjuk ki az utolsó számot, amit hozzá kellett adni, és az összeget is!

sum = 0
number = 0
while sum < 100:
    number = number + 1
    sum = sum + number
print('Utolsó szám: ' + str(number))
print('Összeg: ' + str(sum))

A következő feladatban csak a páros számokat adjuk össze!

sum = 0
number = 0
while sum < 100:
    number = number + 1
    if number % 2 == 1:
        continue
    sum = sum + number
print('Utolsó szám: ' + str(number))
print('Összeg: ' + str(sum))

Ugyanezt valósítsuk meg végtelen ciklussal

sum = 0
number = 0
while True:
    number = number + 1
    if number % 2 == 1:
        continue
    sum = sum + number
    if sum >= 100:
        break
print('Utolsó szám: ' + str(number))
print('Összeg: ' + str(sum))

Önálló feladat

A hárommal osztható számokat adjuk össze addig, amíg az összeg el nem éri a 200-at.

Teszt

1. feladat

Tekintsük az alábbi kódot!

while True:
    tipp = input('Mi Magyarország fővárosa? ')
    # A
    if tipp == 'Budapest':
        print('A válasz helyes!')
        # B
    else:
        print('A válasz helytelen!')
    # C

Azt szeretnénk elérni, hogy addig kérdezze a kérdést, amíg a felhasználó helyes választ nem ad. Mit kell módosítani a kódon ahhoz, hogy jól működjön?

  • A Az A helyre be kell írni azt, hogy continue.
  • B A B helyre be kell írni azt, hogy break.
  • C A C helyre be kell írni azt, hogy while.
  • D Nem kell beírni semmit; ez a kód pont azt csinálja, amit kell.

2. feladat

n = 42
tip = -1
tip_nr = 0
print('Gondoltam egy számra 1 és 100 között; találd ki!')
while tip != n: # A
    tip = int(input('Tipp: '))
    tip_nr = tip_nr + 1
    if n < tip:
        print('kisebb')
        # B
    elif n > tip:
        print('nagyobb')
        # B
    # C
print(f"Gratulálok, {tip_nr} lépésben eltaláltad!")

Azt szeretnénk elérni, hogy addig kérdezzen, amíg el nem találjuk a számot. Mit kell a kódon módosítani, hogy jól működjön?

  • A Meg kell fordítani a feltételt: n != tip.
  • B Erre a két helyre azt kell írni, hogy continue.
  • C Ide kell egy else ág, break utasítással.
  • D Nem kell beírni semmit; ez a kód pont azt csinálja, amit kell.

3. feladat

Mit csinál az alábbi kód?

a = 30
b = 12
while a != b:
    if a > b:
        a = a - b
    else:
        b = b - a
print(a)
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License