Alapvető vezérlési utasítások a programozásban


In [1]:
%pylab inline
Populating the interactive namespace from numpy and matplotlib

If (elágázás, feltétel vizsgálat)

Ha azt szeretnénk, hogy valami akkor történjen, ha megfelel vagy épp nem felel meg valamilyen feltételnek (valami egyenlő-e valamivel, nagyobb-e, ...) akkor feltétel vizsgálatot kell végezni és az eredmény szerinti feladatot elvégezni.

Például, ha gyököt akarunk vonni egy beadott számból szükséges lehet ilyen vizsgálat. Ugyanis ha pozitív a szám semmi gond, ha viszont negatív, akkor ezt kezelni kell, mondjuk szorozzuk meg -1-el.

Ez a kérdés magyarul hogy is szól: Ha a szám nagyobb (vagy egyenlő) mint 0 akkor vonjunk gyököt, ha pedig nem akkor szorozzuk meg mínusz eggyel és utána vonjunk gyököt belőle. Lehet érzeni a mondatban, mit mikor kell elvégezni.

Ennek a műveleteknek az elvégzésére több paranccsal is alkalmas, de a leggyakoribb az if-else parancs. Ez lényegében egy elágazás, ami azt teszik, hogy ha igaz az állítás, akkor megcsinál valamit, ha meg hamis, akkor mást.

Szerkezete:

if (feltétel vizsgálat):
   utasítás1
else:
   utasítás2

Megjegyzés: Nem kötelező mindkét ágban utasítást adni, ilyenkor csakis a feltétel teljesülésekor hajtódik végre utasítás.

Tehát a következő parancs is értelmes:

if "élet értelme" == 42:
    print("Naná")  # És itt nem adunk meg else ágat

Példák

In [2]:
var1 = 100
if var1:
   print("A változónak van értéke")
   print(var1)
else:
   print("A változónak nincs értéke")
   print(var1)
A változónak van értéke
100
In [3]:
var1 = "cica"
if var1:
   print("A változónak van értéke")
   print(var1)
else:
   print("A változónak nincs értéke")
   print(var1)
A változónak van értéke
cica
In [4]:
var1 = ""
if var1:
   print("A változónak van értéke")
   print(var1)
else:
   print("A változónak nincs értéke")
   print(var1)
A változónak nincs értéke

Adjunk magyarázatot a kovetkezőre:

In [5]:
var1 = 0
if var1:
   print("A változónak van értéke")
   print(var1)
else:
   print("A változónak nincs értéke")
   print(var1)
A változónak nincs értéke
0

Többszörös elágazások (if-elif-else)

Az elágazások egymásba fűzhetőek két módon. Vagy egy már nyitott elágazásban helyezünk el újabb elágazást, vagy többszörös feltételvizsgálatot végzünk az elágazásunkon. Lássuk most az első esetet:

In [6]:
szam=1 #Ide írj be egy számot

if szam > 0:
    if szam%2 == 0:
        print("A megadott szám páros pozitív")
    else: 
        print("A megadott szám páratlan pozitív")
else: 
    if szam%2 == 0:
        print("A megadott szám páros negatív")
    else: 
        print("A megadott szám páratlan negatív")
A megadott szám páratlan pozitív

Ha nem egymásba akarunk teljesen eltérő feltételeket vizsgálni, hanem összefüggően, több feltételt külön-külön vizsgálni (több elágazásunk van), akkor használjuk az if-elif-else szerkezetet:

In [7]:
szam=1 #Ide írj be egy számot

if szam == 0:
    print("nulla")
elif szam > 0:
    print("pozitív")
else:
    print("negatív")
pozitív

Megjegyzés: Törekedjünk a lehető legkevesebb új elágazás használatára. Mivel a sok elágazás átláthatatlanná teszi a program működését. Azaz szerencsésebb az if-elif-else használata, mint sok önálló if-else.

Diákok napja (feladat)

Írjunk egy if tömböt amely a nap és az óra változók megadott értékei alapján eldönti, hogy épp az adott időben a diák mit csinál. Az if tömb válasza az alábbiak szerint osztandó ki:

  • A fiúk is és a lányok is hétköznap délelőtt tanulnak.
  • 12-től fociznak.
  • Hétvégén mindenki kirándul.
  • Mindennap mindenki 8-kor megy aludni, és reggel 8 kor kel.
In [8]:
# Megoldás helye

For-loop (ciklus)

A számítógépek legfontosabb tulajdonságai közt szerepel az, hogy nagyon gyorsak és "fáradhatatlanok". Olyan feladatok megoldásában a leghatékonyabbak, amikor a feladatot kevés munkával meg lehet fogalmazni ("az alkotó pihen") de végrehajtása nagyon sok ismétlést, iterációt igényel ("a gép forog"). Az iteráció (angol: iterate) azt jelenti, hogy például egy lista elemein egyesével végigmegy a program, és műveleteket végez el rajtuk.

A Python-ban, az egyik erre használható utasítás a for parancs (magyarul kb. a ...-ra, azaz pl. a hét minden napjára, a lista minden elemére):

In [9]:
days_of_the_week = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
In [10]:
for day in days_of_the_week:
    print(day)
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Ez a kódrészlet a days_of_the_week listán megy végig és a meglátogatott elemet hozzárendeli a day változóhoz, amit ciklusváltozónak is neveznek. Ezek után mindent végrehajt amit a beljebb tabulált (angolul: indented) parancsblokkban írtunk (most csak egy print utasítás), amihez felhasználhatja a ciklusváltozót is. Miután vége a beljebb tabulált régiónak, kilép a ciklusból.

Szinte minden programnyelv használ hasonló ciklusokat. A C, C++, Java nyelvekben kapcsos zárójeleket {} használnak a ciklusok elkülönítésére, kb. így:

for (i=1..10) {print i}

A FORTRAN nyelvben az END szócska kiírása jelzi a ciklus végét. A pythonban a kettőspont (":"), majd szóközökkel beljebb írt sorok szolgálnak erre. Ha más programokból másolunk át részleteket figyeljünk arra hogy a behúzás helyett nem TAB-ot használ. (A TAB néhol megengedett de kerülendő. A modern python kódolási stílusirányzat minden behúzást 4 szóköznek javasol.)

Annak semmi jelentősége nincs, hogy a példában a day nevet adtunk az iterációban szereplő ciklusváltozónak. A program semmit se tud az emberi időszámításról, például, hogy a hétben napok vannak és nem kiscicák:

In [11]:
for macska in days_of_the_week:
    print(macska)
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

A ciklus utasításblokkja állhat több utasításból is:

In [12]:
for day in days_of_the_week:
    statement = "Today is " + day
    print(statement)
Today is Sunday
Today is Monday
Today is Tuesday
Today is Wednesday
Today is Thursday
Today is Friday
Today is Saturday

A range() parancs remekül használható ha a for ciklusban adott számú műveletet szeretnénk elvégezni:

In [13]:
for i in range(20):
    print("The square of ",i," is ",i*i)
The square of  0  is  0
The square of  1  is  1
The square of  2  is  4
The square of  3  is  9
The square of  4  is  16
The square of  5  is  25
The square of  6  is  36
The square of  7  is  49
The square of  8  is  64
The square of  9  is  81
The square of  10  is  100
The square of  11  is  121
The square of  12  is  144
The square of  13  is  169
The square of  14  is  196
The square of  15  is  225
The square of  16  is  256
The square of  17  is  289
The square of  18  is  324
The square of  19  is  361

Akkor válik mindez még érdekesebbé, ha az eddig tanult iterációt és feltétel vizsgálatot kombináljuk:

In [14]:
for day in days_of_the_week:
    statement = "Today is " + day
    print(statement)
    if day == "Sunday":
        print ("   Sleep in")
    elif day == "Saturday":
        print ("   Do chores")
    else:
        print ("   Go to work")
Today is Sunday
   Sleep in
Today is Monday
   Go to work
Today is Tuesday
   Go to work
Today is Wednesday
   Go to work
Today is Thursday
   Go to work
Today is Friday
   Go to work
Today is Saturday
   Do chores

Figyeljük meg a fenti példában hogy ágyazódik egymás alá a for és az if!

Példa a négyzetszámok előállítására:

A program 0-tól 9-ig kiszámolja a számok négyzetét, majd egy listában sorban egymás mögé fűzi.

In [15]:
dat=[];
for i in range(10):
    dat.append(i**2)
In [16]:
dat
Out[16]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Fibonacci sorozat (feladat)

A Fibonacci sorozat első két eleme 0 és 1, majd a következő elemet mindig az előző kettő összegéből számoljuk ki: 0,1,1,2,3,5,8,13,21,34,55,89,...

Ha nagyobb n értékekre is ki akarjuk számolni a sorozatot, ez kiváló feladat lehet egy fáradhatatlan és gyors számítógépnek!

Egy kis segítségképpen Nézzük végig lépésről lépésre! Először n értékét, azaz a kiszámolandó sorozat hosszát állítjuk be 10-re. A sorozatot majdan tároló listát sequence-nek neveztük el, és inicializáltuk az első két értékkel. A "kézi munka" után következhet a gép automatikus munkája, az iteráció.

Az iterációt 2-vel kezdjük (ez ugye a 0-s indexelés miatt a 3. elem lesz, hisz az első kettőt már mi megadtuk) és n-ig, a megadott lista méretig számolunk.

A ciklus törzsében az addig kiszámolt lista végére hozzátűzzük (append) az előző két tag összegét. A ciklus vége után kiíratjuk az eredményt.

In [17]:
# Megoldás helye

WhileLoop (Elöltesztelő ciklus)

A while a hagyományos elöltesztelős ciklus (a for és az if ötvözete). A ciklus addig fut, amíg valamilyen általunk definiált feltétel teljesül. Lehetőség van kilépési ág megadására is, és ez az else-ága akkor fut le, ha a ciklusfeltétel nem teljesül (tehát a ciklus elhagyása után mindig, kivéve ha break utasítással hagyjuk el a ciklust).

Kiugrási lehetőségek a ciklusból (a feltétel teljesülése esetén):

  • break - rögtön a ciklus utáni utasításra kerül a vezérlés
  • continue - a ciklusfeltétel tesztelésére ugrik a vezérlés

Ezek a parancsok mindig 1 ciklusban hajtódnak végre, azaz nincs lehetőség egyszerre több ciklusból való kiugrásra.

Szerkezete:

while <feltétel>:
    utasítások
else:
    "végül" utasítások
In [18]:
# Erőnk
power = 5

# Addig dolgozunk amíg el nem fáradunk (az erőnk nagyobb, mint nulla)
while(power > 0):
    print("Még dolgozol, mert az erőd: "+str(power))
    # Minden körben fogy az erőnk:
    power = power - 1
else:
    print ("\nOh nem, az erőd 0-ra esett, elfáradtál.")
# "\n" string az új sor jele, azaz most létrehoz egy üres sort.
Még dolgozol, mert az erőd: 5
Még dolgozol, mert az erőd: 4
Még dolgozol, mert az erőd: 3
Még dolgozol, mert az erőd: 2
Még dolgozol, mert az erőd: 1

Oh nem, az erőd 0-ra esett, elfáradtál.

Függvények (function)

A számítógép-programozásban a függvény (function) egy nagyobb program forráskódjának egy viszonylag jól felismerhető része, amely egy adott feladatot hajt végre. A kód többi részétől viszonylag független egység, és többször felhasználható anélkül, hogy a program kódjának több példányban is tartalmaznia kellene, azaz többször, több helyen is hivatkozhatunk ugyanarra a függvényre. Hasonló fogalmat jelölnek a eljárás, szubrutin, metódus, procedúra vagy alprogram nevek is.

Függvények és eljárások használatnak előnyei

  • csökkenthető a kódismétlődés
  • ugyanaz a függvény más programban is használható
  • összetett problémák egyszerűbb részekre bonthatók, ami könnyebbé teszi a kód frissítését és bővítését
  • javítható a program olvashatósága
  • elrejthetők és szabályozhatók a program egyes részei

Az eddig megismert parancsokat felfoghatjuk már előre definiált függvényként. Például a exp parancs, olyan függvény, ami kiszámolja az e hatványait. Vagy a következő órán bemutatott plot egy olyan eljárás, ami ábrázolja az adatokat. Néhány programozási nyelvben szokás különbséget tenni eljárás és függvény között. A függvény egy csoportja az eljárások halmazának. Olyan speciális eljárások, melyeknek van valamilyen visszatérési értéke (csinál valami, és az eredményt visszaadja a programnak). Tehát a plot inkább csak szimpla eljárás, míg az exp, vagy sqrt igazi függvények. A C-ben és a pythonban a két fogalmat szinonimaként használhatjuk.

A következőkben bemutatjuk, hogyan lehet egyszerűen a függvények használni.

A függvények szintaktikájára jellemző, hogy 3 fő része van.

  • Beolvasott adatok, paraméterek
  • Műveletvégzés
  • A kész eredmény visszaadása a fő programnak (oda ahol megvolt hívva a függvény): return rész

A következő példában a func függvény kiszámolja a beadott szám reciprokát, majd az eredményt visszaadja meghívás helyének, ez esetben a plot parancs y adatsorának.

In [19]:
############################

def func(x): # A fügvényünk megkapja az "x" adatokat
    return 1/x # A visszadás és a művelevégézés ez esetben egybe van olvasztva

############################


x=arange(1,2,0.01)  # Geneáljuk az x adatokat

Lehet több függvényünk is: (f1 és f2 nevű)

In [20]:
########################################################
def f1(t):  # Egy "sima" koszinusz függvény
    y=cos(2*pi*t)
    return y
########################################################
########################################################
def f2(t):
    y=f1(t) * exp(-t) # Adjunk hozzá "exp(-t)" csillapítást
    return y
########################################################

t1 = arange(0.0, 5.0, 0.05)

print(f2(f1(t1))) # Egymásba is ágyazhatóak
[ 0.36787944  0.36820858  0.16136394 -0.47316863 -0.26604415  1.
 -0.49358559 -1.53306202  0.81378506  2.46701104  2.71828183  2.46701104
  0.81378506 -1.53306202 -0.49358559  1.         -0.26604415 -0.47316863
  0.16136394  0.36820858  0.36787944  0.36820858  0.16136394 -0.47316863
 -0.26604415  1.         -0.49358559 -1.53306202  0.81378506  2.46701104
  2.71828183  2.46701104  0.81378506 -1.53306202 -0.49358559  1.
 -0.26604415 -0.47316863  0.16136394  0.36820858  0.36787944  0.36820858
  0.16136394 -0.47316863 -0.26604415  1.         -0.49358559 -1.53306202
  0.81378506  2.46701104  2.71828183  2.46701104  0.81378506 -1.53306202
 -0.49358559  1.         -0.26604415 -0.47316863  0.16136394  0.36820858
  0.36787944  0.36820858  0.16136394 -0.47316863 -0.26604415  1.
 -0.49358559 -1.53306202  0.81378506  2.46701104  2.71828183  2.46701104
  0.81378506 -1.53306202 -0.49358559  1.         -0.26604415 -0.47316863
  0.16136394  0.36820858  0.36787944  0.36820858  0.16136394 -0.47316863
 -0.26604415  1.         -0.49358559 -1.53306202  0.81378506  2.46701104
  2.71828183  2.46701104  0.81378506 -1.53306202 -0.49358559  1.
 -0.26604415 -0.47316863  0.16136394  0.36820858]

Egy másik példa függvények használatára: Figyeljük meg, hogy a függvény hívásakor több paramétert is meg kell adni! (x,a,b-t is, ahol x egy vektor, míg a és b konstansok). A konstansok átadása a következő módon történik:

func(x, *(a,b))

In [21]:
def func(x,a,b):
    return (x**a)+b

x=arange(1,2,0.01)
zz=(2.5,100)
print(zz)
(2.5, 100)

A zz változó most egy speciális lista, úgynevezett tuple típusú változó. Ezeket a "listákat" nem lehet elemként kezelni, kivéve, ha kibontjuk őket. (Úgy szokták hívni a tuple-t, hogy nem módosítható lista.) Most bontsuk ki a paramétereket a függvény számára a `*()' használatával:

In [22]:
print(func(x, *(zz)))
[ 101.          101.02518781  101.05075249  101.07669591  101.1030199
  101.12972632  101.156817    101.18429377  101.21215844  101.24041282
  101.26905871  101.2980979   101.32753218  101.35736332  101.38759309
  101.41822325  101.44925555  101.48069174  101.51253356  101.54478272
  101.57744097  101.61051     101.64399153  101.67788727  101.7121989
  101.74692811  101.78207658  101.81764599  101.853638    101.89005428
  101.92689647  101.96416623  102.00186519  102.039995    102.07855727
  102.11755364  102.15698572  102.19685513  102.23716345  102.27791231
  102.31910327  102.36073795  102.40281791  102.44534474  102.48832
  102.53174526  102.57562208  102.61995201  102.66473661  102.70997741
  102.75567596  102.80183379  102.84845242  102.89553339  102.9430782
  102.99108838  103.03956543  103.08851085  103.13792614  103.18781281
  103.23817232  103.28900618  103.34031587  103.39210284  103.44436859
  103.49711457  103.55034225  103.60405307  103.65824851  103.71293
  103.76809899  103.82375692  103.87990523  103.93654534  103.99367869
  104.0513067   104.10943078  104.16805236  104.22717284  104.28679364
  104.34691615  104.40754177  104.46867191  104.53030795  104.59245128
  104.65510328  104.71826534  104.78193883  104.84612512  104.91082559
  104.9760416   105.04177451  105.10802568  105.17479646  105.24208821
  105.30990228  105.37824     105.44710272  105.51649178  105.58640852]

Háromszögszámokat előállító függvényt (feladat)

A Háromszögszámok azok a számok, amelyek előállnak az első valahány egymást követő természetes szám összegeként. A feladat, hogy legeneráljuk az első néhány ilyen számot függvényt használva.

Analitikus formában:

$$ x=\frac{n \cdot (n+1)}{2} $$
In [23]:
# Megoldás helye