Ugrás a lényegre

Nyelvi dolgok és Vezérlési folyam

TL;DR Tartalom
Extra feladatok

Ezek nem kötelező feladatok, csak megoldásuk közben könyebb megtanulni a dolgokat

  • Készíts egy függvényt, egy kapott IP címből és MASZK-ból eldönti, hogy mi a hálózat amiben van.
    (Spoiler: .split('.'))
  • Implementálj egy szöveg rendezési algoritmust, mely a paraméterben bármennyi szót kaphat és azok alapján egy tömmbel tér vissza.
    A függvény ezután legyen képes akár listákat is elfogadni a paraméterében.
  • Dokumentálj egy függvényt.

Változók

Az előző fejezetben láttál pár változót, viszont még részletesebben nem meséltem róluk.

>>> width = 20
>>> height = 5 * 9

Észreveheted, hogy semmi típus definíciónk nincs a változónál. Sőt, ezt a típust menet közben cserélhetjük is.

>>> test = 1
>>> test
1
>>> test = "alma"
>>> test
'alma'

Ez egy kényelmi része annak, hogy interpretált nyelv a Python.
Menet közben képes rá az interpreter, hogy eldobja az előző értéket, majd kicserélje egy teljesen újra típustól függetlenül.

TypeError go brrr

Ez a kényelem azt is jelenti, hogy gyakran futhatunk típus hibákba.
Például feltételezzük, hogy egy változó szám és mégis sztring lesz, akkor egy osztás műveletnél elszáll a programunk.
Próbáld ki! De csak saját felelősségre

Mi van akkor, ha egy változóra többé nincs szükségünk?
A del segítségével azt ki tudjuk törölni.

>>> test = "alma"
>>> test
'alma'
>>> del test
>>> test
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'test' is not defined

Sőt akár egy listából is ki tudunk venni a del segítségével.

>>> # Előző fejezet kódja
... negyzetek = [1, 8, 27, 65, 125]
>>> negyzetek = negyzetek[:3] + negyzetek[4:]
>>> negyzetek
[1, 8, 27, 125]
>>> # Új kód
... negyzetek = [1, 8, 27, 65, 125]
>>> del(negyzetek[3])
>>> negyzetek
[1, 8, 27, 125]

Másik elképesztő képessége a pythonnak, hogy akár egyszerre több változót is tudunk létrehozni különböző értékekkel.

>>> a, b = 2, 3 # a = 2, b = 3
>>> print(a, b)
2 3

Sőt akár meg is tudjuk őket cserélni egy sorban

>>> a, b = 2, 3 # a = 2, b = 3
>>> a, b = b, a # a = 3 és b = 2
>>> print(a, b)
3 2

Indentáció

Indentációban a kód blokkosítását értjük, azaz mikor az egyes logikai egységeket külön választjuk.
Például C-ben {} -el tudjuk ezt megtenni.

Pythonban ehhez tabulátort vagy szóközt használunk.

C++-ban:
Megjelölt sorok 1-1 új blokkot kezdenek meg

int j = 0;
for (int i= 0; i < 10; i++) {
std::cout<<i
if (j % 2 == 0) {
std::cout<<"2-vel oszthato iteraciohoz ertunk"
}
j++
}

Pythonban:

j = 0
for i in range(0, 10):
print(i)
if j % 2 == 0:
print("2-vel oszthato iteraciohoz ertunk")
j += 1

Ha netán elfelejtenénk indentálni, akkor szól a Python.

>>> if 1>0:
... print("hi")
File "<stdin>", line 2
print("hi")
^
IndentationError: expected an indented block

Ilyenkor felismerte a Python, hogy egy új blokkot kezdünk meg és beljebb fogunk kezdeni a következő sorban.

Tabulátorral: (ajánlott)

>>> if 1 > 0:
... print("hi")
...
hi

Szóközzel: (nehezen látható)

>>> if 1 > 0:
... print("hi") # Itt van egy szóköz
...
hi

Egy feltételt akár több sorban is tudunk írni, csak szimplán jelezzük az interpreternek egy escapeléssel.

>>> if 1 > 0 \
... and 3 > 2:
... print("Több soros feltétel")
...
Több soros feltétel

if

if-nek több része is van.

  • if: Feltétel
  • elif: else if, avagy egy különben ág feltétellel
  • else: Ha már egy feltétel sem teljesül
>>> x = int(input("Adj meg egy számot: "))
Adj meg egy számot: 42
>>> if x < 0:
... x = 0
... print('Negatív értéket 0-ra cseréltük')
... elif x == 0:
... print('Nulla')
... elif x == 1:
... print('Egy')
... else:
... print('Több')
...
Több

Az input függvény szöveget kér be, szóval át kellett alakítani.

Valaki felkapcsolta a lámpát?

switch és a hozzá kapcsolódó case nincs a pythonban. Helyette sok-sok elif-et tudunk írni.

Feltételünket tovább tudjuk spékelni köztük elhelyezett logikai operátorokkal.

  • and: x < 3 and x > 0
  • or: x >= 3 or x =< 0
  • not: not (x < 3 and x > 0)

Sőt bit operátorok is elérhetőek. (&, |, ^, ~, ...)

>>> a = 10 # 1010 (binárisan)
>>> b = 6 # 0110
>>> a & b # És operátor
2 # 0010

while ...

Talán a legegyszerűbben magyarázható eszközunk a pythonban. Addig fut újra és újra, amig a feltétele igaz.

>>> iteracio_szam = 0
>>> while True:
... iteracio_szam += 1
... print(iteracio_szam)
... print("Nyomj CTRL + C -t, hogy megállíts")
De lassú ez a terminálra kiíratás :/

Ha kiveszed a kiíratásokat és ctrl + c után kiírod a változódat azt fogod tapasztalni, hogy sokkal nagyobb lett az iteracio_szam, mint kiíratásokkal. Szerinted miért?

>>> paros = False
>>> while True:
... if not paros:
... print("work hard")
... else:
... print("play hard")
... paros = not paros # ?v=5dbEhBKGOtY

for ... in ...

A for cíklus Pythonban lehetővé teszi, hogy szekvenciákon menjünk végig.
Tehát nem a szokásos ciklus i=0 ...-t fogjuk eljátszani.

Ilyen szekvencia például egy lista.

>>> # Írjunk ki egymás alá a szavakat:
... szavak = ['macska', 'kutya', 'horcsog']
>>> for szo in szavak:
... print(szo)
...
macska
kutya
horcsog

Sőt a sztring is egy szekvencia.

>>> kszk = "KSZK"
>>> for betu in kszk:
... print(betu)
...
K
S
Z
K

Na és mi van akkor ha 0-tól 18-ig kiakarjuk írni a számokat?

Sima ügy.

>>> for i in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]:
... print(i)
...
0 # ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
1 # ░░░░░░░░░░░░░▄▄▄▄▄▄▄░░░░░░░░░
2 # ░░░░░░░░░▄▀▀▀░░░░░░░▀▄░░░░░░░
3 # ░░░░░░░▄▀░░░░░░░░░░░░▀▄░░░░░░
4 # ░░░░░░▄▀░░░░░░░░░░▄▀▀▄▀▄░░░░░
5 # ░░░░▄▀░░░░░░░░░░▄▀░░██▄▀▄░░░░
6 # ░░░▄▀░░▄▀▀▀▄░░░░█░░░▀▀░█▀▄░░░
7 # ░░░█░░█▄▄░░░█░░░▀▄░░░░░▐░█░░░
8 # ░░▐▌░░█▀▀░░▄▀░░░░░▀▄▄▄▄▀░░█░░
9 # ░░▐▌░░█░░░▄▀░░░░░░░░░░░░░░█░░
10 # ░░▐▌░░░▀▀▀░░░░░░░░░░░░░░░░▐▌░
11 # ░░▐▌░░░░░░░░░░░░░░░▄░░░░░░▐▌░
12 # ░░▐▌░░░░░░░░░▄░░░░░█░░░░░░▐▌░
13 # ░░░█░░░░░░░░░▀█▄░░▄█░░░░░░▐▌░
14 # ░░░▐▌░░░░░░░░░░▀▀▀▀░░░░░░░▐▌░
15 # ░░░░█░░░░░░░░░░░░░░░░░░░░░█░░
16 # ░░░░▐▌▀▄░░░░░░░░░░░░░░░░░▐▌░░
17 # ░░░░░█░░▀░░░░░░░░░░░░░░░░▀░░░
18 # ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

Vagy használd a range nevezetű funkciót ez alatt

range

Ez a funkció arra képes, hogy egy olyan iterálható objektumot készítsen nekünk, melyet a for cíklus képes elfogadni.
(Ne aggódj, nem generál egy 0-tól millióig tartó tömböt, ennél okosabb)

>>> for i in range(5): # 0,1,2,3,4
... print(i)
...
0
1
2
3
4

Ez a range függvény több paramétert is elfogad.

range(mettől, meddig, lépésszám)

range(5, 10)
5, 6, 7, 8, 9

range(0, 10, 3)
0, 3, 6, 9

range(-10, -100, -30)
-10, -40, -70

Ha egy szekvencián mégis index alapján szeretnénk végig menni, akkor tudjuk a len-t és a range-t kombinálni.

>>> abc = "abcdefghijklmnopqrstuvwxyz"
>>> for i in range(len(abc)):
... print(str(i) + ". betű: " + abc[i])

break, continue, else

Egy ciklus szokásos lefutásán tudunk módosítani is ha szeretnénk.

break: Kitör a legközelebi for vagy while ciklusból

>>> for i in range(5):
... print(i)
... if i == 3:
... break
...
0
1
2
3 # 4-es számot szkippeltük

continue: Kihagyja a jelenlegi iteráció többi részét

>>> for i in range(5):
... print("< " + str(i))
... if i == 3:
... continue
... print("> " + str(i))
...
< 0
> 0
< 1
> 1
< 2
> 2
< 3 # > 3 hiányzik utána
< 4
> 4

else: Akkor fut le, ha a ciklusban nem történik break vagy valami error

>>> for i in range(5):
... print(i)
... else:
... print("Nem volt break")
...
0
1
2
3
4
Nem volt break
>>> for i in range(5):
... print(i)
... break
... else:
... print("Nem volt break")
...
0

pass

¯\_(ツ)_/¯

Nem csinál semmit. Arra használható, ha szintaktikailag valahova írni kell valamit.

>>> class MyEmptyClass: # Spoiler: Így néz ki egy osztály
... pass
...

Például hasznos lehet, ha a programozó még nem szeretne implementálni egyes részeket.

>>> def how_to_make_a_lot_of_money(a):
... pass # TODO: Ne felejtsd el implementálni
...

funkciók

Hasonló, mint C-ben, viszont továbbra sincsenek típusaink

def funkció_neve(paraméterek):

Például így tudunk egy fibonacci kiíró funkciót készíteni:

>>> def fib(n):
... """Fibonacci sorozat kiíró n-ig."""
... a, b = 0, 1
... while a < n:
... print(a, end=' ')
... a, b = b, a+b
... print()
...
>>> fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
Dokumentáció

Funkcióink első soraiban eltudunk helyezni dokumentációt, majd azt később akár elérni.
Javasolt, hogy hasonlóképp dokumentáld a funkcióid.

>>> fib.__doc__
'Fibonacci sorozat kiíró n-ig.'

Argumentum

Akár alapértelmezett argumentum definícióink is lehetnek.

>>> def primek_bejelentkezes_utan(udvozlo_uzenet, # vessző miatt
... max_probalkozas=4, # tudja a python
... hiba_eseten='Próbáld újra!'): # hogy több soros
... """Helyes jelszó beírása esetén kiírja az első 30 prímszámot"""
... pass # Próbáld implementálni

Ilyenkor a függvény hívásakor nem kötelező átadni az alapértelmezett értékeket.

Akár kulcsszó szerint is hívhatjuk a függvényeink.

>>> primek_bejelentkezes_utan(udvozlo_uzenet="Helló",
... max_probalkozas=3)

Sőt, nem kell minden paramétert feltüntetni!

>>> def hmmm(required, *tuple_arg, **dictionary_arg):
... print(required)
... print(tuple_arg)
... print(dictionary_arg)

És utána így tudjuk meghívni:

>>> hmmm("Kotelezo mezo",
... "ez mar nem",
... "ez se",
... foszereplo="Kata",
... postas="Pista")

Ilyenkor az arguments úgynevezett Tuple-ként működik, a keywords pedig Dictionary-ként. Következő fejezetben lesz ezekről szó.

Egyenlőre látható, hogy Tuple-be csak az értékek kerültek be sorban, míg a Dictionary-be már kulcs-érték párosok.

Lambda

Akár le is tudjuk rövidíteni a függvény definícióink.

lambda a, b: a + b: Ilyenkor készítünk egy függvényt, melynek a két paramétere a és b és visszatér ezek összegével.

>>> f = lambda a, b: a+b
>>> f
<function <lambda> at 0x7fb0602f31f0>
>>> f(1, 2)
3