Informatika2-2012/Kukaba12

A MathWikiből
(Változatok közti eltérés)
(Funkcionális programozás python-ban)
(Funkcionális programozás python-ban)
24. sor: 24. sor:
  
 
=== Függvényközpontú programozás ===
 
=== Függvényközpontú programozás ===
 +
 +
==== A függvényközpontú programoz klasszikus elemei a korai Pythonban ====
 +
 +
A <tt>lambda</tt> kifejezések névtelen függvények, alakjuk:
 +
<python>
 +
lambda paraméterek: kifejezés
 +
</python>
 +
ahol a <tt>paraméterek</tt> egy esetleg üres lista, a <tt>kifejezés</tt> pedig egy elágazást, ciklust, <tt>return</tt> vagy <tt>yield</tt> utasítást nem tartalmazó kifejezés lehet.
 +
<python>
 +
lambda x: x ** 2
 +
lambda x: "pozitív" if x > 0 else "nem pozitív"
 +
lambda x, y: x + y
 +
</python>
 +
 +
A ciklusok elkerülésére három egyszerű mód szolgál:
 +
* megfeleltetés -- egy függvény egy bejárható (iterable) objektum minden elemére hat: <tt>map()</tt>
 +
<python>
 +
list(map(lambda x: x ** 2, [1, 2, 3, 4]))  # [1, 4, 9, 16]
 +
</python>
 +
* szűrés -- egy bejárható objektumnak csak azokat az elemeit tartjuk meg, amelyre egy függvény <tt>True</tt> értéket ad:  <tt>filter()</tt>
 +
<python>
 +
list(filter(lambda x: x > 0, [-1, 2, -3, 4]))  # [2, 4]
 +
</python>
 +
* elhagyás: <tt>reduce()</tt> (3.0-tól a standard könyvtárból törölve: <tt>functools.reduce()</tt>)
 +
<python>
 +
reduce(lambda x, y: x + y, [1, 2, 3, 4]))  # 10
 +
</python>
 +
 +
==== Listaértelmezések (list comprehensions) ====
 +
 +
A fenti három függvény ''helyettesítésére'' szolgál a lista elemeinek a matematikában szokásos halmazmegadási módjára emlékeztető leírása, amelyben ciklus-szerű és feltétel-szerű nyelvi elem is szerepelhet. Alakjuk azonnal érthető:
 +
<python>
 +
[kifejezés for elem in bejárható_objektum]
 +
[kifejezés for elem in bejárható_objektum if feltétel]
 +
</python>
 +
Megadjuk a fenti első két példa e szintaktika szerinti változatát:
 +
<python>
 +
[x ** 2 for x in [1, 2, 3, 4]]  # [1, 4, 9, 16]
 +
[x for x in [-1, 2, -3, 4] if x > 0]
 +
</python>
 +
A harmadik esetre Guido van Rossum azt mondja, hogy tipikusan csak asszociatív függvényekre használjuk, mint + vagy *.
 +
<python>
 +
sum([1, 2, 3, 4])  # 10
 +
</python>
 +
A [http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Python_Language_Rules Google] is azt javasolja, hogy map, filter, reduce helyett használjunk listaértelmezéseket vagy for ciklust, jobban olvasható.
 +
 +
==== Egy példa: a nyolc királynő ====

A lap 2012. április 30., 17:03-kori változata

Tartalomjegyzék

Funkcionális programozás python-ban

Programozási paradigmák

Egy probléma megoldásához többféleképp közelíthetünk. Az, hogy a problémát hogyan bontjuk részekre, meghatározza a használható/andó programnyelvi elemeket. Ennek megfelelően a programnyelvi elemeknek négy fő típusát szokás megkülönböztetni:

  • Parancsközpontú (imperative), vagy vele majdnem azonos értelemben használt eljárásközpontú (procedurális, procedural)
    • algoritmikus gondolkodás, receptszerű programozás, ,,tedd ezt, majd ezt,..."
    • A Neumann-elvű számítógép ötletére épül
    • Számítási lépések időben egymás utáni elvégzése (parancsok végrehajtása)
    • Tipikus parancsok: értékadás, eljárás meghívása,
    • Az eljárások megváltoztatják a program kontrollstruktúráinak állapotát
  • Objektumközpontú (objektumorientált, object-oriented)
    • Az emberek közti interakciókat és a való világ jelenségeit modellezi
    • A fogalmakat osztályok, a jelenségeket objektumok valósítják meg
  • Függvényközpontú (funkcionális, functional)
    • A függvények matematikai elméletére épül,
    • A függvények értéket adnak vissza, de nincs mellékhatásuk, nincsenek változók
    • A program függvényhívásokból áll
    • A parancsközpontúnál egyszerűbb struktúra, könnyebben bizonyítható a program helyessége, könnyebben tesztelhető, debug-olható
  • Logikai, vagy a nála általánosabb értelemben használt deklaratív (logic, declarative)
    • A program végrehajtása az axiómáknak és a következtetési szabályoknak (deklarációknak) megfelelő lehetőség(ek) megkeresésből áll
    • Matematikai logikai alapú
    • Szűkebb alkalmazási lehetőségek

Függvényközpontú programozás

A függvényközpontú programoz klasszikus elemei a korai Pythonban

A lambda kifejezések névtelen függvények, alakjuk:

lambda paraméterek: kifejezés

ahol a paraméterek egy esetleg üres lista, a kifejezés pedig egy elágazást, ciklust, return vagy yield utasítást nem tartalmazó kifejezés lehet.

lambda x: x ** 2
lambda x: "pozitív" if x > 0 else "nem pozitív"
lambda x, y: x + y

A ciklusok elkerülésére három egyszerű mód szolgál:

  • megfeleltetés -- egy függvény egy bejárható (iterable) objektum minden elemére hat: map()
list(map(lambda x: x ** 2, [1, 2, 3, 4]))  # [1, 4, 9, 16]
  • szűrés -- egy bejárható objektumnak csak azokat az elemeit tartjuk meg, amelyre egy függvény True értéket ad: filter()
list(filter(lambda x: x > 0, [-1, 2, -3, 4]))  # [2, 4]
  • elhagyás: reduce() (3.0-tól a standard könyvtárból törölve: functools.reduce())
reduce(lambda x, y: x + y, [1, 2, 3, 4]))  # 10

Listaértelmezések (list comprehensions)

A fenti három függvény helyettesítésére szolgál a lista elemeinek a matematikában szokásos halmazmegadási módjára emlékeztető leírása, amelyben ciklus-szerű és feltétel-szerű nyelvi elem is szerepelhet. Alakjuk azonnal érthető:

[kifejezés for elem in bejárható_objektum]
[kifejezés for elem in bejárható_objektum if feltétel]

Megadjuk a fenti első két példa e szintaktika szerinti változatát:

[x ** 2 for x in [1, 2, 3, 4]]  # [1, 4, 9, 16]
[x for x in [-1, 2, -3, 4] if x > 0]

A harmadik esetre Guido van Rossum azt mondja, hogy tipikusan csak asszociatív függvényekre használjuk, mint + vagy *.

sum([1, 2, 3, 4])   # 10

A Google is azt javasolja, hogy map, filter, reduce helyett használjunk listaértelmezéseket vagy for ciklust, jobban olvasható.

Egy példa: a nyolc királynő

Személyes eszközök