2013. február 15., péntek

Tojásrántotta algoritmusa

Az alapvető gondolkodásmód elsajátításához egy hétköznapi példa következik!
Mint korábban már többször írtam, jót tesz a megfelelő gondolkodásmód kialakításához az, ha hétköznapi tevékenységeket is "algoritmizálunk". Ennek érdekében, most tojásrántottát fogunk készíteni!

Tojásrántotta készítése

Kérdezzük meg hány tojásból készítsük a rántottát! Nézzük meg van-e annyi tojásunk, ha van akkor készítsük el, ha nincs akkor pedig jelezzük hogy nincs ennyi tojásunk.

Be: Hány tojásból készüljön?

HA van elegendő tojás AKKOR
   Törjük fel a tojásokat és tegyük tálba
   Verjük fel a tojásokat

   CSINÁLD
        Melegítsünk olajat
   AMÍG olaj eléggé forró

   Öntsd a tojást a forró olajba
   
   CSINÁLD
       Lassan kevergesd a tűzön
   AMÍG megfelelően megsül

   Tedd tányérba
   KI: A rántotta kész! Jó étvágyat

KÜLÖNBEN
   KI: Nincs ennyi tojás így sajnos nem tudom elkészíteni!


Csodálatos algoritmus! Egy nagy szelekció fogja keretbe az algoritmust (van-e elegendő tojás?) Majd a szekvenciák sorozata következik, közben két iterációval, ráadásul hátultesztelőkkel (olajmelegítés, sütés)

Erről jut eszembe egy vicc!
A programozót elküldi a barátnője boltba a következő utasítással:
- "Drágám! Menj el a boltba! Hozzál halat, ha van tojás akkor tízet!"
A programozó elmegy a boltba, majd miután bevásárolt hazajön és odaadja kedvesének a táskát, benne a bevásárolt dolgokkal. A barátnője megnézi, majd megkérdezi:
- "Miért hoztál tíz halat? És hol a tojás? Vagy az nem volt?"
- "De volt!" - mondja a programozó!

:)

Szóval a programozó mindig úgy végzi el a feladatot, ahogy az meg van fogalmazva. Abból baj nem lehet..... Legfeljebb át kell fogalmazni a feladatot, ha nem a megfelelő eredmény születik!
Gondolkozz el ezen! Hogyan kellett volna mondani a barátnőnek, hogy megértse szerencsétlen programozó, hogy mit is akar tőle a kedvese?

2013. február 12., kedd

Legnagyobb szám kiválasztása

A következő bejegyzésben egy egyszerű algoritmust készítek el. A cél, hogy megmutassak egyfajta gondolkodásmenetet.
Elvárt ismeretek: adatbekérés, kiírás, összehasonlítás, elágazás, iteráció

Feladat: A bekért pozitív számok közül írassuk ki a legnagyobbat!

Az adatbekérést nem ellenőrizzük, feltételezzük hogy egész számokat kapunk. Feltételezzük hogy nem kell megjegyezni az összes bekért adatot.

Olvassuk el és értelmezzük a feladatot.

Mit csinálunk? Bekérünk számokat.
Mi lesz ezekkel a számokkal? Kiíratjuk a legnagyobbat.

Ez eddig elég egyszerűnek hangzik, de gondoljunk bele egy picit mélyebben. 
Hogyan határozzuk meg a legnagyobbat? Nyilván összehasonlítással.
Sorra kell vennünk az adatokat és a nagyobbat megjegyezve ismételni az összehasonlítást addig, míg az összes adatot égig nem vettük. 
Éppen ezt a tevékenységet kellene programozni!
  1. az aktuális legnagyobb számnak jegyezzük meg a 0 értéket. Ennél csak nagyobbakkal kell foglalkozni.
  2. Kérjük be a soron következő számot.
  3. hasonlítsuk össze az aktuális legnagyobb számmal
  4. ha nagyobb mint az aktuális legnagyobb, akkor felejtsük el az eddigi legnagyobbat és helyette jegyezzük meg az éppen soron lévőt legnagyobbként.
  5. ha van még további bekért szám akkor vegyük a következőt és folytassuk a 2. pontnál
  6. írassuk ki a megjegyzett legnagyobb számot.
Hát ennyi a teendő. Kész a program, jöhet a kódolás.
Először célszerű valamilyen szabványos általános jelölésrendszert alkalmazva a programot leírni. Később már erre nem lesz szükség egyszerűbb feladatnál, de most tegyük meg.
Picit pontosítani kell a feladatot. Honnan tudjuk, hogy van-e még további kiértékelendő szám? A feladat kiírásában az szerepel, hogy pozitív számokkal kell dolgozni. Ezért most hozunk egy olyan döntést, hogy ha 0-át kapunk kiértékelésre, az azt jelenti hogy nincs több kiértékelendő adat.
(Itt jegyzem meg, hogy az ilyen döntéseket mindig egyeztetni kell a megrendelővel és azt el kell fogadtatni vele, hiszen ő tudja hogy pontosan mit is szeretne megvalósítani!)
Ezzel a döntéssel már elkészíthető az alkalmazás.

Az adatmodell és a pszeudó nyelvű megoldás:




A REPEAT...UNTIL iteráció úgynevezett hátul tesztelő ciklus. Ez azt jelenti, hogy a ciklusmag lefutása után értékelődik ki a ciklus feltétele. Tehát a ciklusmag legalább egyszer lefut. Az UNTIL után megadott feltétel a kilépés feltétele.


Írjuk meg Pascalban ezt a feladatot:















Ennyi volt a legnagyobb számot kiírató programocska.
A feladat elején megfogalmazott ismeretek birtokában elkészíthetők az alábbi módosított feladatok is! A feladatok egyre összetettebbek, de mind megoldható szelekcióval és iterációval.
Próbálj ezek közül minél többet elkészíteni pszeudó nyelven és az éppen tanult programnyelven is (C/Pascal)
Ha elküldöd emailen a megoldást, szívesen véleményezem!

Írd át a programot, hogy kiírja a legnagyobb és a legkisebb számot is!
Írd át a programot, hogy kiírja azt is hogy hány szám lett összesen megadva!
Írd át úgy a programot, hogy pozitív számok mellett a 0 is szerepelhessen input adatként!
Írd át úgy a programot, hogy összesen 10 adatot kell bekérni és azok közül kiválasztani a legnagyobbat stb...
Írd át úgy a programot, hogy először megkérdezi, hogy hány adatot szeretnék megadni és fogadjon el negatív számokat is.



  


Programnyelvek, programozás őstörténete

Minap egy antikváriumba, megláttam egy FORTRAN programozással kapcsolatos könyvet, mely kiadásának dátuma 1970 volt. Eltöprengtem azon, hogy a könyv egy évvel idősebb nálam. Azt tudom, hogy a számítógép programozás nem éppen újkeletű dolog, de azt hogy magyar nyelvű szakirodalom már ilyen korán megjelent, nem gondoltam. (messze a PC-s korszak még, szűk réteg aki számítógéphez fér)
A könyv akkor 12 Ft volt most 275 Ft-ot kért érte az antikvárium. Gyorsan körülnéztem még és végül megvásároltam néhány régi, programozási nyelvekről szóló szakkönyvet.





Mindig is érdekeltek a különféle programozási nyelvek. Nem maga a hatékonyság, vagy a használhatóság az ami felkeltette az érdeklődésemet, hanem magának a nyelvnek a logikája, működése, szintaktikája. A régi nyelvek meg azért érdekesek, mert látni lehet a fejlődést, ahogy egyik a másikból építkezve egy újat - talán jobbat - hoz létre. Nem ismerem a régi nyelveket. BASIC majd PASCAL voltak a tanulónyelveim. Mellette kis gépikód és Assembly is adódott. Utána megismerkedtem a dBase/Clipper nyelvekkel, amik az adatbáziskezelési feladatokhoz voltak nagyszerű eszközök, majd jött a C és végül az obejktumorientált progrmaozás a JAVA, a C++ és a C# nyelveken keresztül.
Most elhatároztam hogy meg fogok ismerkedni néhány régi programozási nyelvvel. Nem feltétlenül azért, hogy használjam, hanem hogy megismerjem a programozás történelmét.

Szeretem a régi szakkönyvek előszavait, bevezető fejezeteit olvasni, mert sok érdekesség van benne. A FORTRAN könyvben is találtam egy érdekes gondolatot a programozással kapcsolatban:
"...nem a programozási nyelv oktatásáról van szó, hanem a programozási nyelvnek mint eszköznek a felhasználásával a megfelelő szaktudomány oktatásáról."
Itt arra utal a szerző, hogy egy programozási nyelv oktatása, megismerése nem azonos a programozás szaktudományának oktatásával, megismerésével.
Később ezt írja:
"A lényeges különbség a hagyományos oktatási módszerrel szemben itt az, hogy az egyes eljárásokat nem csak formulák hanem egyúttal programok formájában is megfogalmazzák. Ehhez természetesen elkerülhetetlen valamelyik konkrét algoritmikus nyelv ismerete, azonban a hangsúly nem ezen van. Ennek az  oktatási módszernek előnye, hogy a numerikus ismereteken túlmenően kifejleszti a hallgatóban az "algoritmus teremtés" készségét, amelyre egy holt képletnek élő programmá való "átvarázsolásához" van szükség. Tulajdonképpen ez az amit programozásnak nevezünk." (Lőcs-Vigassy FORTRAN programozási nyelv 6. oldal)

A gondolat nagyon sokatmondó! A Programozz! blog bevezetőjében említettem hogy ki kell alakulnia az algoritmikus gondolkodásnak ahhoz, hogy valaki tudjon programozni. Írtam ugyan itt, hogy sokan azt mondják: "Pascalban ezt simán megírom, de C-ben nem megy!"
Nos aki ezt mondja azzal az a helyzet, hogy sajnos nem tud programozni. Tud "pascalul", de nem tud programozni. Ismeri a nyelvet és az használja is, de nem tud algoritmust alkotni. Ez nagy baj! Egy programozónak a nyelv "csak" egy eszköz. A holt képletek élő programmá történő átvarázsolásához ennél több kell és ezt hívják programozásnak.

Még egy érdekes dolog, amit a könyv elszavát olvasgatva érzek. A programozás mérnöki feladat, a kódolás szakmunka. Például annak idején a programozói tevékenység nem terminál előtt zajlott, hanem programkártyákon kézzel, ceruzával írta meg a programozó a programot, majd ezt átadták a kódolónak, aki a megfelelő módon bevitte a gépbe és elkészítette a lyukkártyát, amin a betölthető programok voltak.

A példa nem teljesen "ül", hiszen itt gyakorlatilag a kódoló gépi kódra fordította (compiler) át a FORTRAN programot. Manapság a kódoláson azt értjük, hogy adott programnyelven leírunk egy algoritmust.
Ha belegondolunk mégiscsak helyes a hasonlat. Aki kódol, az egy működő modellt valósít meg. Aki programozik az magát a modellt készíti el. A kettő a programozás mai értelmében összeolvad és egyben jelenti az algoritmizálási képesség és egy programnyelv ismeretét, de a kettőt külön kell tudni választani ahhoz, hogy programozni tudjunk! Először algoritmust tervezünk, majd lekódoljuk valamely programnyelven.

Ez az átvarázsolás lesz az amit a programozónak tudnia kell, különben csak egy ócska bűvésztrükk betanulására és többé kevésbé sikeres bemutatására lesz képes...