Upload failed. Maybe wrong permissions?

User Tools

Site Tools



10. Függvények 2.

10-0.jpg
  

27:22
1985. március 20.
MTV 2. csatorna, 19:30

Bevezető

10-1.jpgHerneczki Katalin Commodore 64
  0:57 Köszöntöm önöket. Először is nézzük meg múltkori adásunk házi feladatának megoldását. A feladat a következő volt: írjunk egy programot, amely egy tetszőleges szövegből kikeresi az e betűket, és eredményként kiírja az e betűk számát. Mi a következő megoldást javasoljuk.
  10-2.jpgA programunk három részből áll. Az előkészítő rész áll egy INPUT utasításból, egy gyűjtő-nullázásból – ez a LET GY=0 utasítás –; a program gerincét egy ciklus tartalmazza, ez egy FOR utasítás, ahol a ciklusváltozó I, 1-ről indul, és addig tart, amilyen hosszú az inputként megadott szövegünk. Ezt a LEN függvény segítségével biztosítjuk. A ciklus magjában egy MID$ függvény szerepel, amelynek három bemenete van: A$, tehát a szöveg, I, illetve 1, és eredménye pedig egy betű I-től (azaz a szöveg I-edik karakterétől – L. A. D.) kezdve. A ciklusmagban szerepel még egy IF utasítás, amely megvizsgálja ezt a betűt, és hogyha ez a betű e betű, akkor a gyűjtő értékét eggyel növeljük. Végül pedig a program befejező részében egy PRINT utasítás szerepel, ami kiírja az összegyűjtött e betűk számát.
  Most nézzük meg, jól működik-e a programunk. Tehát RUN.
  A program először a szöveget kéri. A szöveg legyen mondjuk az, hogy „keresem az E karaktereket”.
  Az eredmény hét, és ha jól megnézzük a szöveget, akkor ez az eredmény valóban helyes.
  Egyébként természetesen más karakterrel is lefuttathatjuk ugyanezt a programot minimális átalakítással. Készíthetünk egyébként kicsit bonyolultabb programot is, amely a szövegben előforduló összes magánhangzók előfordulását kiírja, tehát egy statisztikát készít.

DEF FN és RND

10-3.jpgKiss Donát Spectrum
  3:02 Mint említettük, a számítógépekben több tucat beépített függvény van. Úgy is mondhatnám, hogy előregyártott függvény. Nem jelenti azonban ez azt, hogy feltétlenül minden igényt kielégítenek ezek, nem biztos például, hogy az a lakatos kisiparos, aki adott méretek alapján ki tudná számítani, hogy egy kapu legyártásához milyen szögvasakat kell vennie, mennyit és hogy kell azokat leszabni. Ezért a BASIC nyelv lehetőséget nyújt arra, hogy mi magunk is gyártsunk függvényeket. 10-4.jpgÚgy hívják ezeket, hogy felhasználó által definiált függvények, és a DEF FN kulcsszóval lehet ezekre általában hivatkozni, illetve ezzel lehet ezeket definiálni. Természetesen a különböző gépeken különböző tájszólásbeli különbségek vannak, ezért azt javaslom, hogy mindenki ennek a kézikönyvben majd nézzen utána. A lényeg az, hogy megadhatunk, definiálhatunk úgy függvényt, hogy tetszőleges változókból, konstansokból álló kifejezést adunk meg függvényként. A későbbiekben erre pedig ugyanúgy hivatkozhatunk, mint az előregyártott függvényekre, tehát például a szinuszra, koszinuszra. Például – az előbbi példa nyomán – ha csinálunk egy szögvasfüggvényt, elnevezzük ezt szögvasnak, a továbbiakban erre hivatkozhatunk.
  A felhasználók által definiálható függvények leggyakoribb alkalmazásai a különböző átszámítások, mint például a fok–radián vagy a különböző pénznemek között elvégzett átszámítások. Vitatkozhatunk arról, hogy a következőkben ismertetendő függvény, a véletlenszámfüggvény az vajon valóban függvény-e vagy sem. Ez amolyan számítástechnikai vallási hitvitához vezetne. Ugyanis bizonyos felfogás szerint függvény, mivel kimenő eredményt ad és számítást végez. Bizonyos felfogás szerint nem függvény, hiszen nem adunk neki bemenő adatot. Tekintsünk most el ettől a vitától és ismerkedjünk meg magával a függvénnyel, amely a BASIC-ben általában az RND rövidítéssel hívható. Arról van szó, hogy az RND függvény minden olyan esetben, amikor szóhoz jut, egy véletlenszerű számot, egy véletlenszámot generál, képez, legtöbbször 0 és 1 között, de van olyan gép, ahol meg lehet adni rögtön az RND függvény argumentumában a felső határt. A Sinclair Spectrumon ez a szám mindig 0 és 1 közé esik. Ez azonban nem fog minket nagyon zavarni, mint majd a későbbiekben látni fogjuk. Hogy mennyire véletlenszerű ez a szám, ennek bizonyítására írjunk egy egészen icipici kis programot. Két sorból áll, mégpedig kiíratjuk a véletlengenerálásnak az eredményét, s a második sorban visszaugratjuk erre a sorra a programot, tehát egy végtelen hurkot képeztünk. Ha ezt elindítjuk, akkor a program kirajzol számunkra a képernyőn egymás után képzett véletlenszerű számokat.
  

10-5.jpg10-6.jpg

  Láthatjuk, hogy ebben semmilyen szabályszerű ismétlődés nincs, elfogadhatjuk, hogy ez valóban véletlen.
  Azok számára, akik mélyebben tanulmányozzák majd a véletlenszámok képzésének módszerét, azok valószínűleg rájönnek majd, hogy ez azért nem egészen véletlen, hanem úgynevezett álvéletlen vagy pszeudovéletlen szám, amelyet különböző rafinált trükkökkel képeznek a különböző számítógépek sorozatok alapján vagy függvények alapján.
  Leggyakrabban azonban nekünk nem arra van szükségünk, vagy nem feltétlenül csak arra van szükségünk, hogy 0 és 1 között képezzünk véletlenszámot. Hogyan lehet mondjuk elérni azt, hogy ez a véletlenszám most ne 0 és 1 közé, hanem mondjuk 0 és 100 közé essen? Nos, ennél mi sem egyszerűbb: ennek a programnak a legelső sorát módosítjuk, mégpedig úgy, hogy ezt az RND kifejezést megszorozzuk százzal. Hiszen evvel csakúgy, mint a függvényekkel, ugyanúgy bánhatunk, vagyis kifejezésekben felhasználhatjuk, szorozhatjuk, oszthatjuk, ha kell, és a többi.
  
10-8.jpg10-7.jpg

  Ha most megnézzük az eredményt, akkor látjuk, hogy a számok valóban 0 és 100 közé esnek. Továbbfuttatjuk a programot: újabb huszonkét véletlenszámot látunk a képernyőn.
  7:14 Hogy mire is jók ezek a véletlenszámok, erre még nagyon sok példát fogunk látni, vegyünk most egy jólismertet. Ez pedig a szerencsejátékok programozása. Minden szerencsejátékban szükség van a véletlenszámra, így például a lottóhúzásban vagy a kockadobásban is. Az utóbbi esetén ugye 1 és 6 közötti számokat kellene előállítanunk valamilyen véletlenszerű sorozat alapján. Próbáljuk meg most ezt a programot úgy módosítani, hogy 1 és 6 közötti számokat kapjunk. Ehhez ugye mindenekelőtt a százas szorzót kicseréljük hatosra. Nézzük meg, mi az eredmény.
  10-9.jpg
  Ez még nem egészen sikerült, mert nulla egész nyolcvanöt századot biztos nem tudunk dobni egy kockával, ezért itt még ezen módosítani kell. Szó volt már az egészrészfüggvényről, amely a BASIC-nek egy szabványfüggvénye. Ezt fogjuk most is használni: ennek a kifejezésnek vesszük az egész részét. S evvel tulajdonképpen megszabadulunk a tizedesektől. Nézzük, hogy mi az eredmény.
  10-10.jpg
  Már majdnem jó. Ugyanis csak azért majdnem, mert amint látjuk, itt az eredmények között van bizony még nulla, és egyetlenegy hatos sincs, akárhogy is nézzük. Márpedig ez azt jelenti, hogy a Ki nevet a végén?-ben elég sokára fogunk bejutni majd a házba. Ennek az oka teljesen logikus. Ugyanis gondoljuk végig, hogy mit csinál az egészrészfüggvény. Hát például az 5,98-ból ötöt csinál, mert az 5,98-nak az egész része öt. Valamint a 0,63-nak az egész része nulla. Vagyis ez még csak majdnem jó, ez a kifejezés; úgy lesz ebből valóban 1 és 6 közötti számokat előállító programsor, hogyha ehhez hozzáadunk egyet. Tegyük ezt meg és futtassuk most le, nézzük meg az eredményt.
  
10-11.jpg10-12.jpg

  Valóban, hat és egy közötti számokat látunk, tehát ezek tényleg megfelelnek a kockán látható számoknak.
  Kis fáradsággal és némi programozással ennél dekoratívabb kockát is lehet azért előállítani a számítógépen, erre fogunk majd most itt mindjárt példát látni. Írhatunk olyan programot, amely ki is rajzolja ezt a kockát, a kocka éleit. A program úgy működik egyébként, hogy helyesen szimulálja a kockát, ugyanis a kocka élein (oldalain – L. A. D.) a pöttyök bizonyos szabályszerűség szerint vannak elhelyezve, amint azt megfigyelhetjük.
  
10-13.jpg10-14.jpg

  
10-15.jpg10-16.jpg

  10-17.jpgNézzük meg most ebben a programban azt a részt, amely felelős a véletlenszámképzésért, ezt pedig az 55-ös sorban találjuk meg. Ami látszólag egy értékadó utasítás, a vsz változónak – nem véletlenül vsz, mert véletlenszám – adja a következő értéket: az egész részét képezzük a 6*RND-nek és hozzáadunk egyet, vagyis pontosan ugyanaz, amit az előbb megbeszéltünk.
  10:16 A véletlenszám-előállításnak azonban nemcsak a játékprogramoknál van szerepe, hanem minden olyan programnál, amely valamilyen folyamatot modellez. Valamint használjuk a véletlenszámot a tanulást segítő oktatóprogramokban is. Erre egyébként példa a BASIC-tankönyvben is található. Nézzük meg most, hogy az ott ismertetett szorzótábla-gyakorló programban hol történik a véletlenszám előállítása.
  
10-18.jpg10-19.jpg

  Mint minden program, ez is tökéletesíthető. Hiszen a számítógéppel való foglalatoskodás örömét egészen odáig lehet fokozni – különösen a gyerekeknél –, hogy észre sem veszik, hogy tanulnak. Erre jó példa az a szorzást oktató program majd, amely egy robotgyár példáján mutatja be a szorzótábla gyakorlását, és hát ennek segítségével próbálja a gyerekeket hosszú távon a képernyő előtt tartani, miközben megtanulnak szorozni. Nézzük, hogy hogy is néz ez ki.
  
10-20.jpg10-21.jpg

  
10-22.jpg10-23.jpg

  
10-24.jpg10-25.jpg

  10-26.jpg
  Arról van szó, hogy amennyiben ebbe a robotgyártó gépbe bekerülő alapanyag és az alapszám szorzata nem egyenlő a kijelzett értékkel, akkor válaszolni kell, hogy a kijelzett értéket elfogadjuk vagy sem. Jó válasz esetén egy hibátlan robot kerül ki a gépből – az a cél egyébként, hogy tíz ilyet legyártsunk a megfelelő helyes válaszokkal –, rossz válasz esetén pedig selejt robotot gyártunk, amely igen látványosan és elkeserítően mutatja a hibánkat.
  10-27.jpgVégezetül pedig a véletlenszám témaköréből még egy megjegyzést mindenképpen meg kell hogy ejtsünk, ez pedig az egyes gépeken található RANDOMIZE lehetőség. Mit is jelent ez a RANDOMIZE? Arról van szó, hogy – mivel megbeszéltük, hogy a véletlenszámok tulajdonképpen csak álvéletlenszámok vagy pszeudovéletlenszámok – tulajdonképpen a számítógépben egy sorozat indul minden véletlenszám-generáláskor. Na most ez a sorozat indítható mindig ugyanarról a számról, így elérhe…

(A bedigitalizált videófelvételen 12:3913:00 között szakadás van – L. A. D.)

POKE, PEEK

10-28.jpgHerneczki Katalin Commodore 64
  13:00 …szükség van arra, hogy néhány alapvető számítástechnikai ismeretet felfrissítsünk, és egy új utasítást is meg kell tanulnunk. Amikor a változókról beszéltünk, akkor a számítógép memóriáját egy fiókos szekrényhez hasonlítottuk. A fiók felirata volt a változó neve, a fiók tartalma pedig maga az adat. Most tovább folytathatjuk ezt a hasonlatot, mégpedig úgy, hogy a fiókokat rekeszekre osztjuk. Egy-egy ilyen rekeszbe egy karakter kerülhet, szám, betű vagy írásjel. Ezeket a rekeszeket egyébként a számítástechnikában byte-oknak nevezzük. A számítógép ezeket a byte-okat sorszámmal látja el, ez Commodore gép esetében 0-tól 65 536-ig (helyesen 65 535-ig – L. A. D.) terjed. Tehát hogyha egy változót akarunk a programunkban kijelölni, akkor a gép a változó méretétől, típusától függően megfelelő számú byte-ot jelöl ki, és ezeknek a címeit tárolja, és természetesen a változó nevét is megjegyzi. 10-29.jpgPersze a számítógép elektronikus eszköz, úgyhogy nem számíthatunk arra, hogy a byte-okban ténylegesen a betűk, karakterek kerülnek tárolásra, hanem valamiféle kódrendszer formájában kell ezeket tárolni. Egy byte nyolc kisebb egységből, úgynevezett bitekből áll, tehát egy byte nyolc bitből áll, és ezek a bitek hordozzák az információt. Ezek a bitek kétállapotú áramköri elemnek felelnek meg, ahol a két állapot a nulla és az egyes lehet. Korábbi adásunkban egyébként erről már beszéltünk. Szemléletesen ezt úgy lehet elképzelni, hogy egy rekeszben nyolc lyukacska van egymás mellett, és ezekbe a lyukakba mondjuk gyufaszálat tehetünk. Amelyik lyukban gyufaszál van, ott a bit értéke egyes, amelyikben pedig nincs, ott nulla. Így összesen 256 variációnk lehet, tehát 2⁸ nyilván, merthogy egy byte nyolc bitből áll.
  10-30.jpgEgy byte tartalmát tehát a bitek állapota határozza meg. Közvetlenül a bitekhez nem tudunk hozzáférni, csak egy byte-hoz. De vajon hogyan? Erre van egy utasításunk, és ez az utasítás a POKE utasítás. A kulcsszó tehát a POKE, ezután meg kell adni a címet, tehát annak a byte-nak a címét, ahova írni szeretnénk, legyen ez a 3456, és ezután pedig meg kell adnunk azt, hogy mit szeretnénk ebbe beírni, legyen ez mondjuk a 85. Természetesen ez a tartalom, ami jelen esetben a 85, egy tízes számrendszerbeli szám, a gép nyilvánvalóan ezt bináris formában, tehát kettes számrendszerben tárolja majd az egyes bitekben. Tehát ez úgy néz ki 85 esetében, hogy a legkisebb helyiértéken egyes van, aztán nulla, egyes, nulla, egyes, nulla, és így tovább, ennek utána lehet gondolni.
  10-31.jpgPersze nemcsak írni szeretnénk egy byte-ba, hanem egy byte-ból olvasni is szeretnénk. Ezzel tulajdonképpen megtudjuk a bitek állapotát. Olvasni a PEEK függvénnyel lehet. Legyen egy A változónk, és ez az A változó, amibe ki szeretnénk nyerni a byte értékét. Jön a kulcsszó, a PEEK, a függvény neve, ezután zárójelet kell tennünk, majd meg kell adni a címet, 3456-os byte legyen, hiszen ebben tároltunk az előbb adatot. És ezután megnézzük, hogy valóban jól működik-e ez a függvény, tehát PRINT A. Az eredmény valóban 85, tehát megkaptuk azt az értéket, amit ebben a byte-ban tároltunk.

INKEY$

10-32.jpgPinkert László Primo
  17:20 Amiről most lesz szó, az nem tartozik szorosan a függvényekhez. Inkább az adatbevitelhez. Az INKEY$ kulcsszóról van szó. Programban a következő alakban használjuk.
  10-33.jpg
  A$, vagyis szöveges változó egyenlő INKEY$. Vannak azonban olyan gépek, amelyek nem ismerik ezt a kulcsszót, azokon helyette a GET utasítást használhatjuk.
  10-34.jpg
  A két utasítás hatásában teljesen egyenértékű, mi a továbbiakban az INKEY$-ről fogunk beszélni. Az INKEY$ utasítás működését egy programpéldán keresztül érthetjük meg.
  10-35.jpg
  A program egyszerű, csak három sorból áll. Első sora a már ismert A$=INKEY$. Az utasítás hatása a következő. Amikor a gép a 100-as utasításhoz ér, akkor az INKEY$ olvassa a billentyűzetet. Vagyis megfigyeli azt, hogy melyik billentyűt nyomtuk meg. Ennek a billentyűnek megfelelő karakter kerül az A$ szöveges változóba. Azonban az INKEY$ nem vár, vagyis ha éppen egyetlen billentyűt se nyomtunk le, akkor a szöveges változóba egy nulla hosszúságú szöveg kerül. Azt hiszem, itt meg kell állnunk egy pillanatra, mi az, hogy nulla hosszúságú szöveg? Nos, a BASIC nyelvben eddig olyan szövegkonstansokat használtunk, hogy idézőjel, utána karaktersorozat, majd másik idézőjel. Amennyiben a két idézőjel között nincsen semmi, akkor már elő is állítottunk egy nulla hosszúságú, vagy ahogy egyszerűbben nevezzük, üres szöveget. Tehát ha a százas utasítás végrehajtásakor egyetlen billentyűt se nyomunk le, akkor az A$ szöveges változóba ilyen üres szöveg kerül.
  Ügyeljünk azonban arra, hogy a nulla hosszúságú szöveg nem egyenértékű azzal, amely egy vagy több szóközt tartalmaz.
  10-36.jpg
  És most nézzük ismét a programlistát. Tehát a 100-as utasítás az A$ szöveges változóba helyez egyetlen karaktert vagy egy üres szöveget. A 110-es utasítás ezt kinyomtatja. A 120-as utasítás végtelen ciklust valósít meg: visszaugrat a 100-as utasításra. Gondoljunk arra, hogy a 110-es utasítás egyrészt minden alkalommal új sorba ír, másrészt hogyha az A$ szöveges változó üres szöveget tartalmaz, akkor gyakorlatilag ez az utasítás egy soremeléssel egyenértékű.
  A magyarázat talán kissé hosszú és bonyolult volt, nézzük meg most a program futását.
  10-37.jpgA programlista fölül kifutott a képből. Ha most megnyomok egy-egy billentyűt, akkor a megfelelő karakter megjelenik a képernyőn, majd szintén kifut a képből fölfelé.
  Hogy miért fut ki, az nyilvánvaló. Hiszen ha nem nyomok le egyetlen billentyűt sem, akkor a PRINT utasítás csupa üres sort fog a képernyőre írni. Ez a programrészlet tehát ilyen formában nem használható semmire, kis módosításra van szükség, hogy csak akkor írjon a PRINT utasítás, ha az A$ szöveges változó nem üres. Ezt valósítja meg a következő programrészlet.
  10-38.jpgAz előző programot kibővítettük egy IF utasítással, amely visszaugrat a 200-as, vagyis az INKEY$ utasításra, abban az esetben, hogyha az A$ szöveges változó üres. Magyarázat nélkül megnézhetjük most már ezt a programot futás közben. Először is a programlista nem futott ki a képből, és ha megnyomom a billentyűket, akkor minden sorba egy-egy betűt ír.
  10-39.jpg
  Természetesen kis átalakítással elérhető, hogy ezek a betűk egymás mellé kerüljenek, és akkor már gyakorlatilag meg is valósítottuk a célunkat, vagyis adatbevitelre használhatjuk az INKEY$ utasítást. Adatbevitelre az eddigiekben az INPUT utasítást használtuk, aminek több hátránya is van. Az egyik, hogy adatbevitelnél mindig megjelenik a képernyőn a kérdőjel, és ez nem mindig esztétikus; némely alkalmazások esetén kifejezetten zavaró.
  

10-40.jpg10-41.jpg

  10-42.jpg
  10-43.jpgA másik, hogy ha az adatbevitelt elrontjuk, tehát például szám helyett szöveget viszünk be, akkor a gép hibajelzést ad, és ezt csak a képernyő teljes újraírásával tudjuk eltüntetni. A harmadik hátrány, hogy nem vihető be kettőspont és vessző, akkor sem, hogyha az INPUT utasítás szöveg bevitelét várja. Negyedik és talán a legfontosabb, hogy az INPUT utasításnál az adatbevitelt mindig a sorzáró billentyű lenyomásával kell befejezni. Amint az előbbi, rövid programpélda használatánál is láttuk, az INKEY$ utasítás használata esetén ez nincs így.
  Talán feltűnt, hogy műsorunk előadói egész programsorokat, sőt képernyőt betöltő ábrákat varázsolnak a képernyőre egyetlen gombnyomással. Ezek a programok is az INKEY$ utasításnak ezt a fontos tulajdonságát használják ki. Nézzünk meg most egy olyan programot, amely raktárkészlet-nyilvántartás, azonban használatát megkönnyíti az INKEY$, helyesebben ebben az esetben a GET utasítás használata.
  23:3910-44.jpgA program menüjét látjuk. Az egyes funkciók közül úgy kell választani, hogy lenyomjuk azt a billentyűt, amely betű a funkció előtt bekeretezve áll. Például ha listát kérünk, akkor az L betűt nyomjuk le. Mivel a program INKEY$-vel, pontosabban GET-tel működik, ezért sorzáró billentyűre nem volt szükség.
  
10-45.jpg10-46.jpg

  Nézzük meg most ismét a választási lehetőségeinket: sorszám vagy anyagnév szerinti lista; ismét egyetlen betű lenyomásával léphetünk tovább, majd a képernyő vagy a nyomtató közül kell választani, ismét egyetlen betűvel.
  
10-47.jpg10-48.jpg

  És ezek után egy INPUT utasítással megvalósított adatbevitel következik, amikor a listázni kívánt sorokat kell megjelölni. Láthatjuk, hogy megjelent a képernyőn a kérdőjel és villog a kurzor, várja az adatbevitelt.
  24:36 Az INPUT és a GET, illetve INKEY$ utasítással megvalósított adatbevitel között alapvető különbség van. Ha az INPUT utasítást használjuk, a bebillentyűzött karakterek azonnal megjelennek a képernyőn. A GET utasítás nem ír a képernyőre. Ha kíváncsiak vagyunk arra, hogy milyen billentyűt nyomtunk meg, a PRINT utasítással kell azt képernyőre írnunk.
  Az eddig tanultak alapján most próbáljuk megoldani a következő házi feladatot. Írjunk programot, amelynek segítségével egy jelet, mondjuk egy pontot mozgatni lehet a képernyőn négy irányban.
  
10-49.jpg10-50.jpg

  Ha ez nagyon egyszerű feladatnak látszik, akkor próbáljuk megvalósítani azt is, hogy másik négy billentyű segítségével a program vonalat is tudjon húzni.
  
10-51.jpg10-52.jpg

  Természetesen nem csak négy, hanem nyolc irányban is lehet vonalat húzni.
  10-53.jpg
  És ha mindezzel elkészültünk, akkor oldjuk meg a feladatnak a legutolsó részét is, vagyis hogy az ábrához – amit rajznak is nevezhetünk ezek után – feliratot lehessen készíteni.
  10-54.jpg
  26:24