Programozásoktatás

Tartalomjegyzék

Alapvetően kétféle megközelítés létezik a programozás oktatására: alulról felfelé, vagy felülről lefelé.  Az előbbi a történelmet követve, szinte a villamosmérnökség kinövéseként tekintve a területet, alacsonyszintű nyelvvel (pl. C) kezd, és onnan halad egyre feljebb.  Ezt a megközelítést követik például a BME-n, és kétséget kizáróan működik.  A másik lehetőség az ellenkező irányból fogja meg a témát: előbb algoritmusok, és csak utána "nézünk be a padló alá", részletesen hogyan is működik mindez.

Itt az ITK-n elvileg az utóbbi megközelítést alkalmazzuk.  Gyakorlatilag az oktatásban használt nyelv a C++ (illetve később Java, egyes célokra pedig Matlab).  Az előbbi kettő erre a célra nem alkalmas: hiányzik belőlük számos tulajdonság (elsőosztályú függvények és típusok, hogy csak kettőt említsek) ami a megközelítéshez elengedhetetlen, sőt a C++ a kézi memóriakezelést is megtartja.  Például szolgálhatna a megközelítés legnevesebb alkalmazója, az MIT: ott a Scheme nyelvet használják.

Kapcsolat a valósággal

Sajnos sikerül egy ellentétes irányú hibát is elkövetni az oktatásban.  A fordítási folyamatról ugyanis nem esik szó sehol.  A gyakorlatokon a hallgatók mindig IDE-ben írják a kódot, annak a fordítás parancsát használják, és a futtatást is így végzik.  Így nem tanulják meg, hogy mi a forrásfájl, ezért a gyakorlatvezetők és tanárok rendszeresen a project konfigurációs fájlját kapják meg mint "beadandót".  Ez nem egyszerű tévedés: a saját gépükön a hallgatóknak a konfig fájlt kell megnyitni ahhoz hogy minden rendesen működjön; ha a forrást nyitják meg, a project beállításai hiányoznak, és általában fordítási vagy szerkesztési hiba az eredmény.

Továbbá a hallgatók nem tudják hogy a program hogyan indítható el parancssorból, vagy hogy egyáltalán hova kerül a futtatható állomány?  Ennek következtében a hallgatók a megírt programot nem fogják tudják használni, elindítani a fejlesztőkörnyezeten kívül.  Szerintem a megírt program fordítása és futtatása szerves részét képezi a programozásnak – ha valaki ezt nem tudja megtenni, az nem is tud igazán programozni.

Az előbbi sajnos nem mellékhatás, úgy tűnik: egy harmadéves tárgy részeként megtanuljuk a Python nyelv alapjait.  Ennek gyakorlatvezetőjétől megkérdeztem, miért nem tanuljuk meg a scripteket parancssorból végrehajtni?  Válaszának lényege az volt, hogy ehhez meg kéne tanítani a parancssorból paraméter átvételét, ami advanced topic [sic!].  Harmadévben!

Ráadásul a gyakorlati használhatóság legnagyobb hiánya nem is egy programozás tárgyban fordul elő: a díjat az adatbázisok kurzus viszi el.  Itt ugyanis egy teljes félévig tanuljuk az SQL nyelv használatát úgy, hogy kizárólag a fejlesztőkörnyezetben kézzel futtatjuk amit írtunk.  Holott a valós használhatósághoz az lenne a minimum, hogy legalább egy nyelvből megtanítják lekérdezések programmatikus végrehajtását.

A fordítási folyamat

Fentebb említettem hogy a fordítás itt az IDE beépített funkcióját jelenti.  Ennek a csúcsa az, hogy egy könyvtár használatához még csak azt sem tanítják meg, hogyan lehet hozzáadni a projekthez, hanem egy, a könyvtárat tartalmazó, helyesen konfigurált projektet adnak ki, hogy a hallgatók másolják le és abban dolgozzanak.

Egyáltalán az is megkérdőjelezendő, minek is használunk a kezdetben IDE-t.  Az első két félév legnagyobb munkái sem nagyobbak 2-300 sornál, és nem állnak két fordítási egységnél többől.  Ekkora méretben szinte bonyolultabb kezelni az új projekt varázslót, mint a feladat többi része, ráadásul nagyszerű alkalom lenne a segédeszközök (pl. make) bemutatására.  Sőt magának a fordítóprogramnak a lehetőségeit is meg lehetne így ismertetni.

Nyelvválasztás

A legelső néhány órát leszámítva az oktatás C++ és Java nyelven folyik.  A hivatalos indoklás az, hogy az egyetem elvégzése után a hallgatóktól ezeknek a nyelveknek az ismeretét várják majd el.  Ezzel az érvvel a kisebb hiba az, hogy nem feltétlenül igaz A hallgatók képzése tart legkevesebb három évig.  Az pedig közismert, hogy a programozásban a technológiák népszerűsége milyen gyorsan változik.  Ezért az általános érvényű igazság, hogy a tanulás nem fejeződik be az utolsó vizsga letételével, a programozókra különösen vonatkozik.  Könnyen megtörténhet tehát, hogy mire a hallgatók kilépnek az egyetemről, a konkrét nyelv vagy eszköz ismerete elavulttá válik.

Az érvvel a nagyobb hiba az, hogy tévesen feltételezi, minden nyelv egyformán alkalmas a kezdők oktatására.  A C++, különösen a C++11 és még modernebb szabványok, nem alkalmasak erre.  Túl bonyolultak, túl sok különböző nyelvi elem van bennük egyszerre.  A Java szintén alkalmatlan erre a célra: egy bizonyos programozási módszertant erőltet a használójára.  Ha a munkavégzést ez nem is akadályozza, az oktatást igen; ebben a nyelvben nem igazán lehet bemutatni hogy a problémák többféleképpen is megközelíthetők.

Csak a lényeg marad ki

Nyelv vagy programozás?

A karon jelentős mértékben a konkrét nyelvet tanuljuk, nem pedig a nyelven tanulunk programozni.  Nem esik szó arról, hogy más nyelvben is ugyanúgy lehet a problémákat megoldani, mint a tanultban.  Ha lehet, még ennél is kevesebb szó esik arról hogy ha valaki megtanult programozni, akkor egy új nyelvet pár nap alatt elsajátíthat. 

Ez azért is különösen szomorú, mert – mint említettem – az első néhány előadáson egy másik nyelvet használunk.  A hivatalos indoklás szerint erre azért van szükség, hogy a hallgatók rájöjjenek az előbbi tényekre.  Ugyanakkor az oktatók ezt nem mondják el, így az erőfeszítés – sajnos – nem jár sikerrel. 

Programozási paradigmák

Szintén nem része a tananyagnak az, hogy többféle megközelítése is létezik a programozásnak.  Ezek közül a hallgatók számottevően csak az objektum-orientált szemlélettel találkoznak.  Így olyan hallgatók kap(hat)nak diplomát, akik nincseken tisztában azzal, milyen is a procedurális, vagy a funkcionális paradigma. 

Az objektumok középpontba állítása azért is káros, mert így a hallgatók nem fognak tudni mozogni pl. a rekurzió területén

A programozásról, programozás nélkül

A kari képzésre beszivárgott az ELTE programozó matematikus képzése.  Ezzel az a baj, hogy a nevükkel ellentétben nem programoznak.  Inkább ilyen állításokat fogalmaznak meg:

előfeltétel:
v=v' ∧ v' ≠ ∅
utófeltétel:
((v=v' \{(ej, tj)}) ∧ (e = ej) ∧ ((ej, tj) ∈ v' ) ∧ (∀ i ((ei, ti) ∈ v' ∧ i ≠ j) : tj > ti))

Ezt mind a "veremből kiveszünk egy elemet" leírására.  Ez a leírás legalább olyan bonyolult mint a műveletet megvalósító kód, így teljesen haszontalan.  A kód helyességét ugyanis egyszerűbb igazolni magának a kódnak a vizsgálatával, mint a fentihez hasonló formulákat felírni, levezetni, majd vizsgálni hogy a kód ezeknek megfelelően viselkedik.

Ez az "absztrakt programozás" megközelítés lehetővé tette például, hogy hallgatók elvégezzenek egy programozás kurzust úgy, hogy megtanultak gépiesen fordítani struktogramokról programkódra, anélkül hogy tudak volna ténylegesen programozni.  A struktogramok a kiadott jegyzetben szerepeltek.

Hogyan lehetne jobban?

Szerintem a következőkkel lehetne jól működővé tenni a képzést:

Megközelítés

Egyértelműen eldönteni, hogy alulról fölfelé, vagy felülről lefelé tanmenet legyen.  Személy szerint az előbbi híve vagyok. 

Nyelvválasztás

A kiválasztott megközelítésnek megfelelő nyelven tanítani a hallgatókat.  Az első esetben ez célszerűen a C nyelvet jelentené, utóbbi esetben a scriptnyelvek valamelyikét (Python) vagy Scheme, esetleg Haskell.  Az olyan nyelvek, amit "majd elvárnak tőlük amikor elhelyezkednek" bőven elég, ha másod- vagy harmadévben kerülnek elő, amikor már van egy szilárd alap amire lehet építeni.

Eszköztár

Az első órákon, vagy akár az első kurzus egésze alatt, valamilyen szövegszerkesztő (gedit, Notepad++) és a parancssor használata.  Így egyrészt a hallgatók tudása ténylegesen hasznos lehetne, megírt programjaikat a fejlesztőkörnyezeten kívül is tudnák használni.  Másrészt egyértelműen helyükre kerülnének az alapfogalmak, nem lenne olyan probléma hogy a hallgatók összekeverik a forráskódot és a konfigurációs fájlokat. 

Nyelvfüggetlen tudás

Megmutatni a hallgatóknak, hogy a programozás lényege nem az adott nyelv ismerete, hanem az algoritmizálási készség.  Például C-ben, Pascalban és még számtalan további nyelvben feltűnően hasonló, szinte sorról sorra lefordítható egy azonos algoritmusú program – talán van mögöttük valami közös? 

Ugyanezen a húron maradva, azonos nyelven megírva is teljesen felismerhetetlen ugyanaz a kód ha más megközelítés alapján készült.  Így a hallgatók azzal a magabiztos tudással rendelkeznének, hogy a tudásuk általánosan hasznosítható, és egy korábban ismeretlen nyelvet is tudnak használni pár nap után.

Vissza az oldal elejére