{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Függvények bevezetés\n",
"\n",
"Python-ban a kódban bárhol definiálható függvény, a def
kulcsszóval."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def fv_neve(n):\n",
" \"... kód ...\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Példa függvényre és meghívására\n",
"\n",
"Ez egy függvény definíció, itt csak azt írjuk le, hogy mit csináljon a negyzetel
függvény, ha meghívjuk:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def negyzetel(L):\n",
" uj_L = []\n",
" for i in L:\n",
" uj_L.append(i*i)\n",
" return uj_L"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A def
kulcsszó után a függvény nevét írjuk, utána zárójelekben felsoroljuk a bemeneti paramétereket. A kettőspont után új blokk kezdődik, mint például egy for
ciklusban, ez a blokk fut le amikor meghívjuk a függényt.\n",
"\n",
"A blokkon belül új kulcsszó a return
mely hatására a függvény futása leáll és az eredménye a return
után írt kifejezéssel."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Egy függvényt a nevével tudunk meghívni, mely után zárójelekben a bemeneti argumentumokat kell felsorolni (itt csak egy lista a bemeneti argumentum):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"negyzetel([4, 3, 5])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Természtesen egy változón is meg lehet hívni a függvényt:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"szamok = [5, 1, 8]\n",
"negyzetelt_szamok = negyzetel(szamok)\n",
"print szamok, negyzetelt_szamok"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Mivel \"jól\" volt megírva a függvényünk így semmi nem kívánt dolog nem történt, de nézzük meg mi lesz, ha ezt a megvalósítást használjuk:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def negyzetel2(L):\n",
" i = 0\n",
" while i < len(L):\n",
" L[i] = L[i] ** 2\n",
" i += 1\n",
" return L\n",
"\n",
"szamok = [5, 1, 8]\n",
"negyzetelt_szamok = negyzetel2(szamok)\n",
"print szamok, negyzetelt_szamok"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tehát amilyen műveletet a függvényen belül végrehajtottunk a listán az a beadott argumentumon végrehajtódott, megváltozott a szamok
lista. Erről egy későbbi előadáson még részletesen beszélünk, addig is tudjunk róla, hogy ilyen is lehetséges."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Példa többváltozós függvényre\n",
"\n",
"A paramétereket vesszővel választjuk el:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def skalaris_szorzat(v1, v2):\n",
" osszeg = 0\n",
" for i in range(len(v1)):\n",
" osszeg += v1[i] * v2[i]\n",
" return osszeg"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"skalaris_szorzat([2, 3, 5], [1, 5, 2])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A paraméterek bármilyen típusúak lehetnek. Akárhány paramétere lehet egy függvénynek, akár nulla is, a zárójelek ebben az esetben is kellenek:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def ures_lista():\n",
" return []"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L = ures_lista()\n",
"L.append(5)\n",
"print L"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Különbség függvény és metódus között\n",
"\n",
"Első (felszínes) megközelítésben **függvényről** beszélünk, ha meghívásának módja: függvénynév, majd zárójelpárban az argumentumok felsorolása, **metódusról**, ha meghívásának módja: az objektum után pont, majd a metódus neve, majd zárójelben az argumentumok. Pl.:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L = [5, 2, 4]\n",
"L.sort()\n",
"print L"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A sort
a pythonban egy beépített metódusa a listáknak, mely rendezi az adott listát. Jó példa, mert létezik függvény formában is:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L = [5, 2, 4]\n",
"ujL = sorted(L)\n",
"print L, ujL"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A sorted
függvény nem rendezi az argumentumként adott listát, hanem visszaad egy rendezett listát.\n",
"\n",
"Ez a legtöbbször igaz a beépített metódusokra és függvényekre, tehát a függvények nem módosítják a kapott változókat, míg a metódusok módosítják az objektumot (változót) amin meg vannak hívva (ami a pont bal oldalán áll). Ezt a konvenciót hasznos követni és csak olyan függvényeket írni, melyek nem módosítják a kapott változókat.\n",
"\n",
"Metódus írásról később tanulunk."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A return
használata \n",
"\n",
"A return
utasítás függvényből kilépését ki lehet használni, például:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def prim_e(n):\n",
" for oszto in range(2, n/2):\n",
" if n % oszto == 0:\n",
" return False\n",
" return True"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print prim_e(15)\n",
"print prim_e(23)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Itt azt használtuk ki, hogy amint egy return
parancshoz ér a függvény azonnal kilép és visszaadja ezt az eredményt. Tehát amint találunk egy osztót azonnal visszatérünk a hamis eredménnyel. Igazzal pedig csak akkor térünk vissza, ha végigért a ciklus, azaz nem találtunk megfelelő osztót.\n",
"\n",
"_Megjegyzés_: a __break__ egy ciklusból lép ki (csak ciklusból és csak egyből), míg a __return__ függvényből (csak egy függvényből, de annak bárhány ciklusából). "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### None ###\n",
"`return` után állhat `None`, jelezvén, hogy _\"semmit\"_ adott vissza a függvény.\n",
"\n",
"Ha egy függvény nem találkozik futása során `return` paranccsal, akkor `None`-t ad ki eredményül.\n",
"Például ha elfelejtünk `return`-t írni vagy rossz helyre tesszük.\n",
"\n",
"_Megjegyzés_: a `.sort()` metódus eredénye `None`, de mellékhatása, hogy közben rendezi a paraméterként kapott listát."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L = [3, 2, 1, 4]\n",
"l = L.sort()\n",
"print l, L"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Függvények használata függvényekben\n",
"\n",
"Általunk írt függvényeket természetesen használhatunk más általunk írt függvényekben. Ez erősen ajánlott is.\n",
"\n",
"Érdemes 4-5 sornál hosszabb függvényeket mellőzni, pontosabban azokat kisebb függvényekből összerakni.\n",
"Így a függvényeink rövidek és egyértelműek lesznek. A működésük derüljön ki a változók és magának a függvénynek a nevéből."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nézzünk egy példát:\n",
"\n",
"**Írjunk egy függvényt, melynek bemenete egy lista, a függvény keresse meg a lista legkisebb és legnagyobb elemét és nullázza ki az összes valamelyikükkel azonos értéket a listában!**\n",
"\n",
"Hogyan futunk neki egy ilyen feladatnak?\n",
"1. Részfeladatokra bontjuk\n",
"1. A részfeladatokat megvalósítjuk\n",
"1. Összekötjük a teljes programot\n",
"\n",
"Itt a következő részfeladatokra bontható:\n",
"- Listában minimum keresés\n",
"- Listában maximum keresés\n",
"- Adott elemmel egyenlő elemek kinullázása egy listában\n",
"\n",
"Oldjuk is meg ezeket:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def minimum(L):\n",
" min_elem = float(\"inf\")\n",
" for e in L:\n",
" if e < min_elem:\n",
" min_elem = e\n",
" return min_elem\n",
"\n",
"def maximum(L):\n",
" max_elem = -float(\"inf\")\n",
" for e in L:\n",
" if e > max_elem:\n",
" max_elem = e\n",
" return max_elem\n",
"\n",
"def kinullaz(L, elem):\n",
" ujL = L[:] # Másolatot készítek a listáról (elejétől végéig részlista)\n",
" for i in range(len(ujL)):\n",
" if ujL[i] == elem:\n",
" ujL[i] = 0\n",
" return ujL"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most, hogy a részfeladatokat már megoldottuk nem maradt hátra más, mint hogy összerakjuk egybe a fő függvényt:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def min_max_nullaz(L):\n",
" minelem = minimum(L)\n",
" maxelem = maximum(L)\n",
" ujL = kinullaz(L, minelem)\n",
" ujL = kinullaz(ujL, maxelem)\n",
" return ujL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_max_nullaz([2, 3, 1, 4, 6, 2, 9, 3, 1, 3, 1, 9, 3, 9])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_max_nullaz([])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_max_nullaz([1, 1, 1, 2])"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"Az utolsó három sor helyett írhattuk volna akár ezt is:\n",
"\n",
" return kinullaz(kinullaz(L, minelem), maxelem)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Természetesen meg lehetett volna oldani ezt a feladatot egy függvénnyel is, itt az eredmény:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def min_max_nullaz2(L):\n",
" min_elem = float(\"inf\")\n",
" for e in L:\n",
" if e < min_elem:\n",
" min_elem = e\n",
" \n",
" max_elem = -float(\"inf\")\n",
" for e in L:\n",
" if e > max_elem:\n",
" max_elem = e\n",
" \n",
" ujL = L[:] # Másolatot készítek a listáról (elejétől végéig részlista)\n",
" for i in range(len(ujL)):\n",
" if ujL[i] == min_elem:\n",
" ujL[i] = 0\n",
" \n",
" for i in range(len(ujL)):\n",
" if ujL[i] == max_elem:\n",
" ujL[i] = 0\n",
" \n",
" return ujL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_max_nullaz2([2, 3, 1, 4, 6, 2, 9, 3, 1, 3, 1, 9, 3, 9])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Az első megoldás:\n",
"* olvashatóbb,\n",
"* könnyebb módosítani rajta valamit,\n",
"* hibákat könnyebb benne megtalálni.\n",
"* És még az is jó benne, hogy utólag fel lehet használni másra a már megírt függvényeket.\n",
"\n",
"Bár a második megoldás is működik."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ciklusok ciklusokban, bonyolultabb algoritmusok\n",
"\n",
"## Rendezés\n",
"\n",
"**Írjunk függvényt, mely rendez egy adott listát, de nem használja se a sort
metódust, se a sorted
függvényt!**\n",
"\n",
"Első ötlet a buborékrendezés [zenés](https://www.youtube.com/watch?v=Cq7SMsQBEUw), [táncos](https://www.youtube.com/watch?v=lyZQPjUT5B4) szemléltetéssel:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def buborek(L):\n",
" ujL = L[:]\n",
" for i in range(len(ujL) - 1):\n",
" for j in range(len(ujL) - i - 1):\n",
" if ujL[j] > ujL[j + 1]:\n",
" temp = ujL[j]\n",
" ujL[j] = ujL[j + 1]\n",
" ujL[j + 1] = temp\n",
" return ujL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"buborek([2, 3, 1, 4, 6, 2, 9, 3, 1, 3, 1, 9, 3, 9])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"buborek(range(10, 0, -1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Írjuk ki minden lépés után a rendezés aktuális állapotát:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def buborek_kiir(L):\n",
" ujL = L[:]\n",
" for i in range(len(ujL) - 1):\n",
" for j in range(len(ujL) - i - 1):\n",
" print ujL # Kiírás \n",
" if ujL[j] > ujL[j + 1]:\n",
" temp = ujL[j]\n",
" ujL[j] = ujL[j + 1]\n",
" ujL[j + 1] = temp\n",
" return ujL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"buborek_kiir(range(10, 0, -1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ennél hatékonyabb algoritmusok léteznek a keresésre, ezekről részletesebben az Algoritmuselmélet című tárgyban lesz szó.\n",
"\n",
"Valósítsuk meg még azt az ötletet, hogy egyesével megkessük a legkisebb, a második legkisebb, stb. elemet és ezeket a megfelelő helyre tesszük."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def minimum_index(L):\n",
" min_index = 0\n",
" for i in range(len(L)):\n",
" if L[i] < L[min_index]:\n",
" min_index = i\n",
" return min_index\n",
"\n",
"def min_rendez(L):\n",
" ujL = L[:]\n",
" for i in range(len(ujL) - 1):\n",
" minindex = i + minimum_index(ujL[i:])\n",
" ujL[i], ujL[minindex] = ujL[minindex], ujL[i]\n",
" return ujL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_rendez([2, 3, 1, 4, 6, 2, 9, 3, 1, 3, 1, 9, 3, 9])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_rendez(range(10, 0, -1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def min_rendez_kiir(L):\n",
" ujL = L[:]\n",
" for i in range(len(ujL) - 1):\n",
" print ujL\n",
" minindex = i + minimum_index(ujL[i:])\n",
" ujL[i], ujL[minindex] = ujL[minindex], ujL[i]\n",
" return ujL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_rendez_kiir(range(10, 0, -1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_rendez_kiir([4, 5, 2, 3, 6, 7, 1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A kiírástól csalóka lehet, mert kevesebb kimenetet kaptunk, ez azért van, mert itt csak a külső for
ciklusban van a kiírás, nem a belsőben. Itt a belső ciklus el van rejtve a minimum_index
függvényben."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.15"
}
},
"nbformat": 4,
"nbformat_minor": 1
}