programozzunk pythonban – 1. rész

43
full circle magazin Python 1. kötet 1 full circle Programozói sorozat - Különkiadás PROGRAMOZZUNK PYTHONBAN 1. Kötet Programozói sorozat Különkiadás

Upload: duongkhanh

Post on 30-Jan-2017

248 views

Category:

Documents


13 download

TRANSCRIPT

Page 1: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 1 tartalom ^

full circleAZ UBUNTU LINUX KÖZÖSSÉG FÜGGETLEN MAGAZINJA

Programozói sorozat - Különkiadás

A Full Circle Magazin nem azonosítandó a Canonical Ltd-vel!

PROGRAMOZZUNKPYTHONBAN1. Kötet

Programozói sorozat

Különkiadás

Page 2: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 2 tartalom ^

Programozzunk Pythonban1. rész 3. oldal

Minden szöveg- és képanyag, amelyet a magazin tartalmaz, a Creative Commons Nevezd meg! ‒ Így add tovább! 2.5 Magyarország Licenc alattkerül kiadásra. Ez annyit jelent, hogy átdolgozhatod, másolhatod, terjesztheted és továbbadhatod a benne található cikkeket a következő feltéte-lekkel: jelezned kell eme szándékodat a szerzőnek (legalább egy név, e-mail cím vagy url eléréssel) valamint fel kell tüntetni a magazin nevét

(full circle magazin) és az url-t, ami a www.fullcirclemagazine.org (úgy terjeszd a cikkeket, hogy ne sugalmazzák azt, hogy te készítetted őket vagy a te munkád vanbenne). Ha módosítasz, vagy valamit átdolgozol benne, akkor a munkád eredményét ugyanilyen, hasonló vagy ezzel kompatibilis licenc alatt leszel köteles terjeszteni.A Full Circle magazin teljesen független a Canonical-tól, az Ubuntu projektek támogatójától. A magazinban megjelenő vélemények ésállásfoglalások a Canonical jóváhagyása nélkül jelennek meg.

Programozzunk Pythonban2. rész 7. oldal

Full CircleAZ UBUNTU LINUX KÖZÖSSÉG FÜGGETLEN MAGAZINJA

Programozzunk Pythonban3. rész 12. oldal

Programozzunk Pythonban4. rész 17. oldal

Programozzunk Pythonban5. rész 20. oldal

Programozzunk Pythonban6. rész 24. oldal

Programozzunk Pythonban7. rész 29. oldal

Programozzunk Pythonban8. rész 34. oldal

A Full Circle magazin különkiadása

Üdvözöllek egy újabb, „egyetlen témárólszóló különkiadásban”

Válaszul az olvasók igényeire, néhány sorozatként megírt cikktartalmát összegyűjtjük dedikált kiadásokba.

Most ez a „Programozzunk Pythonban” első nyolcrészének az újabb kiadása (a magazin 27.-34. számaiból),semmi extra, csak a tények.

Kérlek, ne feledkezz meg az eredeti kiadási dátumról. Ahardver és szoftver jelenlegi verziói eltérhetnek az akkorközöltektől, így ellenőrizd a hardvered és szoftvered verzióit,mielőtt megpróbálod emulálni/utánozni a különkiadásokbanlévő ismertetőket. Előfordulhat, hogy a szoftver későbbiverziói vannak meg neked, vagy érhetők el a kiadásodtárolóiban.

Jó szórakozást!

Page 3: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 3 tartalom ^

HOGYANOKÍrta: Greg Walters

Programozzunk Pythonban – 1. rész

A legtöbb használatban lé-vő programozási nyelv kö-zül talán a Python az, a-melyik a legkönnyebben

elsajátítható. A nyelvet az 1980-asévek végén készítették, és azótaigen sokat fejlődött. A legtöbb Linuxrendszeren már előtelepítve meg-található, ennek ellenére a leg-többször figyelmen kívül hagyjuk,amikor egy új nyelv megtanulásamellett döntünk. A cikkben most aparancssoros programozással fog-lalkozunk, a jövőben pedig eljátsza-dozgatunk a GUI (Graphical User

Interface, azaz grafikus kezelőfelü-let) programozásával. Csobbanjunkis rögtön a dolgok közepébe egyegyszerű alkalmazás készítésével!Első programunk

Néhány sornyi kódot fogunk írniegy gedit-féle szövegszerkesztővel,majd pedig megtárgyaljuk, hogymelyik sor mit végez.

Gépeljük be a következő négysort:#!/usr/bin/env python

print 'Hello. I am a python

program.'

name = raw_input("What is your

name? ")

print "Hello there, " + name +

"!"

Ennyi az egész. Mentsük el hel-lo.py néven valahova. Én talán egyhome mappabeli python_peldaknevű mappába tenném. Ez az egy-szerű példa már mutatja, hogymennyire könnyű a kódolás Py-thonban. Mielőtt használnánk aprogramot, előbb futtathatóvá kell

tennünk. Ezt achmod +x hello.py

parancs begépelésével érhetjük elabban a mappában, ahol a pythonfájlunk van. Most már elindíthatjuka programot.greg@earth:~/python_examples$

./hello.py

Hello. I am a python program.

What is your name? Ferd Burphel

Hello there, Ferd Burphel!

greg@earth:~/python_examples$

Eddig mindez nem is volt túl bo-nyolult. Eljött az idő, hogy megnéz-zük a sorok jelentését.#!/usr/bin/env python

Ez a rész mondja meg a rend-szernek, hogy egy python prog-rammal van dolga, és annak alap-értelmezett python fordítóját kellhasználnia a kód futtatásához.print 'Hello. I am a python

program.'

Egyszerűen megfogalmazva,ez a sor íratja ki a „Hello, I am apython program.” szöveget aterminálra.name = raw_input("What is your

name? ")

Itt már egy kissé bonyolódnak adolgok. Ennek a sornak két része isvan. Az első a name =, a másodika raw_input("What is your name?"). Először a utóbbit nézzünk meg.A raw_input parancs kiíratja apromptot a terminálra ("What isyour name? ", ami magyarul:„Hogy hívnak? ”), majd vár a fel-használóra (rád), hogy begépeljenvalamit (egy <Enter>-rel lezárva).Most nézzük az elsőt: name =. Aparancs ezen részében a „name”nevű változóhoz rendelünk vala-mit. Mi egy változó? Képzeljük úgyel, mint egy cipősdobozt. Egy cí-pősdobozt tárgyak tárolására lehethasználni -- cipők, számítógép al-katrészek, papírok, stb. A cipősdo-boz számára nem lényeges, hogymi is van benne ‒ csak dolgok tá-rolására használjuk. Ebben az eset-ben azt tartalmazza, amit begé-pelünk. Esetemben, a Fred Burphelnevet adtam neki. A Python itt

ELŐZŐ SZÁMOK:N/A

ITT HASZNÁLHATÓ:

KATEGÓRIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/média Rendszer

MerevlemezCD/DVD USB eszköz Laptop Vezetéknélküli

Page 4: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 4 tartalom ^

PROGRAMOZZUNK PYTHONBAN – 1. RÉSZcsak fogja ezt, majd eltárolja a„name” nevű cipősdobozba, későb-bi felhasználásra.print "Hello there, " + name +

"!"

Még egyszer használjuk a printparancsot valami megjelenítésérea képernyőn ‒ ebben az esetben eza „Hello there, ” („Hali, ”), pluszmég a „name” változó tartalma(akármi is legyen benne), illetvemég egy felkiáltójel van a végén.Ebben a sorban három információ-darab összerakására koncentrál-tunk: a „Hello there”, a „name”tartalma és a felkiáltójel.

Most pedig szakítsunk egy kisidőt néhány dolog alaposabb meg-értésére, mielőtt továbblépnénk akövetkező példára. Nyissunk megegy terminált és gépeljük be:python

Valami ilyesmit kellene kap-nunk:greg@earth:~/python_examples$

python

Python 2.5.2 (r252:60911, Oct 5

2008, 19:24:49)

[GCC 4.3.2] on linux2

Type "help", "copyright", "cre­

dits" or "license" for more in­

formation.

>>>

Most a python felületén va-gyunk. Ettől kezdve sok dolgot tu-dunk majd véghezvinni, de előbbnézzük meg, hogy valójában mik isvannak itt. Az első dolog, amit ész-re fogunk venni az a python verzió-száma -- az enyém 2.5.2. A követ-kező az az, hogy a súgóért a„help”-et kell begépelni. Ezt majdkipróbálhatjuk később. Most azon-ban gépeljük be:print 2+2

és üssünk Enter-t. A következőtkapjuk vissza:>>> print 2+2

4

>>>

Remélem feltűnt, hogy a „print”szót kisbetűsen írtuk. Mi történne,ha „Print 2+2”-őt írnánk? A fordítóaz alábbi módon válaszolna:>>> Print 2+2

File "<stdin>", line 1

Print 2+2

^

SyntaxError: invalid syntax

>>>

Ez azért van, mert amíg a„print” szó egy létező parancs, ad-dig a „Print” nem ismert. A kis- ésnagybetűs különbségek igen fonto-sak a Pythonban.

Most pedig játszadozzunk el egykicsit a változókkal. Írjuk be:var = 2+2

Nem fogunk semmilyen válto-zást észlelni azon kívül, hogy a Py-thon prompt (a '>>>') visszatér.Nincs is semmi gond, mert aztmondtuk a Pythonnak, hogy hoz-zon létre egy változót („cipősdo-bozt”), amit var-nak neveztünk el,és pakolja bele a „2+2” eredmé-nyét. Ahhoz, hogy megnézhessük avar tartalmát aprint var

parancsot kell begépelni Enter-rellezárva.>>> print var

4

>>>

Mostantól újra meg újra fel tud-juk használni a var-t a 4-es számhelyett úgy, ahogy itt is:>>> print var * 2

8

>>>

Ha ismét begépeljük a „printvar”-t, akkor az alábbit kapjuk:>>> print var

4

>>>

A var értéke nem változott. Mégmindig a 2+2 eredményét, azaz a4-et tárolja.

Mindez természetesen csak egyegyszerűbb programozási gyakor-lat kezdők számára. A bonyolultságaz elkövetkező cikkek folyamán nő-ni fog. Nézzünk most még néhánypéldát változókra.

Írjuk be az értelmezőbe:>>> strng = 'The time has come

for all good men to come to the

aid of the party!'

>>> print strng

The time has come for all good

men to come to the aid of the

party!

>>>

Létrehoztunk egy „strng” (astring rövidítéseként) nevű változótmelyben a „The time has come forall good men to come to the aid ofthe party!” értéket (magyarul: „El-jött az idő minden jó ember számá-

Page 5: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 5 tartalom ^

ra, hogy bulizni induljon!”) tároljuk.Mostantól (amíg a fordítónak eb-ben a futtatásában vagyunk), astrng változónk tartalma ugyanazlesz, hacsak meg nem változtatjuk.Mi fog történni, ha ezt a változót 4-gyel megszorozzuk?>>> print strng * 4

The time has come for all good

men to come to the aid of the

party!The time has come for all

good men to come to the aid of

the party!The time has come for

all good men to come to the aid

of the party!The time has come

for all good men to come to the

aid of the party!

>>>

Nos, nem éppen az, amit vár-tunk, ugye? Kiíratta az strng érté-két négyszer. Hogy miért? Hát, afordító tudta, hogy az strng egy ka-rakterlánc és nem egy megszám-lálható érték. Matematikai művele-teket nem lehet sztringeken végre-hajtani.

Mi történne akkor, ha lenne egys nevű változónk, ami a „4”-et tar-talmazza, ahogy itt is:>>> s = '4'

>>> print s

4

Úgy tűnik, mintha az s az inte-ger (azaz egész) 4-et tárolná, devalójában annak a karakteres rep-rezentációjáról van szó. Tehát, habegépeljük a „print s * 4”-et, akkoraz alábbi kimenetet fogjuk kapni:>>> print s*4

4444

>>>

Ismét csak tudta a fordító, hogyaz s egy sztring, nem pedig egyszám. Tudja, mert szimpla idézője-lek (') közét tettük a 4-et, ezzelhozva létre egy karaktert.

Ezt be is tudjuk bizonyítani aprint type(s) begépelésével. Ekkorláthatjuk, hogy mit is gondol arendszer egy változó típusáról.>>> print type(s)

<type 'str'>

>>>

Pont úgy van, ahogy mondtam.Ez egy sztring típus. Ha számérték-ként akarjuk használni, akkor a kö-vetkezőképpen járhatunk el:>>> print int(s) * 4

16

>>>

Az (s) sztringet, ami a „4”, mostmár átváltotta egy integerré, és

meg lehet szorozni 4-el, hogy 16-otkapjunk.

Most már ismerjük a print és araw_input parancsokat, illetve vál-tozókhoz tudunk értéket rendelni,továbbá tudjuk azt is, hogy mi akülönbség a sztringek és az intege-rek között.

Lépjünk még egy kicsit tovább.A Python fordítójába gépeljük be aquit()-et a parancssorba valóvisszatéréshez.Egyszerű For ciklus

Eljött az idő arra, hogy megis-merkedjünk egy egyszerű progra-mozási ciklussal. Térjünk vissza aszövegszerkesztőnkbe és írjuk megaz alábbi programot:#! /usr/bin/env python

for cntr in range(0,10):

print cntr

Fontos, hogy tabulátort használ-juk a „print cntr” sorban, mivel aPython sem zárójeleket „(”, semkapcsos zárójeleket „{” nem hasz-nál a blokkok elválasztásához, mintahogy azt más hasonló nyelvek te-szik. Ehelyett itt indentálást (behú-

zást) kell használunk.Mentsük el a programot „for_lo-

op.py” néven. Mielőtt kipróbál-nánk, meg kell beszélnünk, hogymi is valójában egy ciklus.

A ciklus egy olyan kód, ami egymegadott utasítást, vagy utasítá-sok egy halmazát többször végre-hajtja. Programunk ebben az eset-ben 10-szer fogja megismételni acntr (mint counter, azaz számláló)kiíratását. Magyarul, azt mondtuk arendszernek, hogy „add a cntr vál-tozónak a 0 értéket, majd ismé-teld meg 10-szer a cntr változó tar-talmának kiíratását úgy, hogy min-dig egyet adj hozzá, és ismételdezt újra”. Elég egyszerűnek tűnik.A kód „range(0,10)” része azt je-lenti, hogy kezdjen 0-val és hajtsavégre újra addig, amíg a cntr érté-ke 10 nem lesz, majd lépjen ki.

Most is, mint az előbb, használ-juk achmod +x for_loop.py

parancsot, majd futtassuk a./for_loop.py

fájlt a terminálban.

PROGRAMOZZUNK PYTHONBAN – 1. RÉSZ

Page 6: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 6 tartalom ^

PROGRAMOZZUNK PYTHONBAN – 1. RÉSZgreg@earth:~/python_examples$

./for_loop.py

0

1

2

3

4

5

6

7

8

9

greg@earth:~/python_examples$

Úgy tűnik, ez működik is, de mi-ért csak 9-ig számol és nem 10-ig?Nézzük meg a kimenetet megint.Tíz szám sorozatát íratjuk ki, amelynullával kezdődik és a kilencesselér véget. Éppen ezt akartuk ‒ íras-sa ki a cntr értékét 10-szer úgy,hogy mindig egyet ad a változó-hoz, majd lépjen ki, ahogy az érté-ke 10 lesz.

Most, hogy mindezt már értjük,láthatjuk, hogy a programozás le-het egyszerű, de ugyanakkor bo-nyolult is. Ezért is tudnunk kellmindig, hogy mit kérünk éppen agéptől. Ha megváltoztatnánk arange parancsot mondjuk„range(1,10)”-re, akkor 1-től kez-dene el számolni, de 9-nél ismétcsak megállna, mivel amint a cntrértéke 10 lesz, kilép. Ahhoz, hogyaz „1,2,3,4,5,6,7,8,9,10” számsortírja ki, a range(1,11) parancsot kell

használnunk ‒ mivel a for-ciklusakkor lép ki, amikor a felső határtelérte. Vegyük továbbá észre az ál-lítás szintakszisát: „for változó inrange(kezdőérték,végérték):”. A„:” azt jelenti, hogy egy olyan kód-blokkot kezdünk, amit indentálnikell. Nagyon fontos, hogy emlékez-zünk a kettőspontra, mindig addigkell indentálni a kódot, amíg ablokknak vége nem lesz.

Ha az alábbi módon módosítjukprogramunkat:#! /usr/bin/env python

for cntr in range(1,11):

print cntr

print 'All Done'

akkor egy ilyen kimenetet ka-punk:greg@earth:~/python_examples$

./for_loop.py

1

2

3

4

5

6

7

8

9

10

All Done

greg@earth:~/python_examples$

Ne felejtsünk el helyesen in-dentálni, mivel ily módon tudatjuka géppel, hogy egy új blokkról vanszó. A következő alkalommal job-ban bele fogunk mélyedni a blok-kok indentációjába.

Ez minden, amit az első alka-lomra tartogattam. Legközelebbegy kis ismétlés után továbblépünknéhány újabb python programozásiútmutatóval. Addig is jó lenne, hafeltelepítenénk egy python specifi-kus szerkesztőt, mint pl a Dr. Py-thon, vagy az SPE (Stani's PythonEditor), melyek a Synapticból is el-érhetők.

Greg Walters a RainyDay Solu-tions tulajdonosa, amely korlátoltfelelősségű tanácsadó cég a Co-lorado-i Aurorában. Programo-zással 1972 óta foglalkozik.Szeret főzni, hegyeket mászni,zenét hallgatni és szabadidejétcsaládja körében tölteni.

Page 7: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 7 tartalom ^

HOGYANOKÍrta: Greg Walters

Programozzunk Pythonban – 2. részElőző számunkban egyolyan egyszerű progra-mot néztünk meg, ami a„raw_input”-ot használta

a felhasználói visszajelzés be-olvasásához, illetve néhány egy-szerű változótípust, meg egyegyszerű „for” ciklust is tartal-mazott. Ez alkalommal mélyebb-re fogunk ásni a változók világá-ban, plusz írunk még néhányprogramot is.

LISTÁK

Először is kezdjük a listáknaknevezett változótípusokkal. Másnyelvekben egy listát tömbnektekintenénk. Ha visszatérünk acipősdoboz analógiájához, akkoregy tömb (vagy lista) sok, tár-gyakat tartalmazó doboz egymásoldalához ragasztásának felelnemeg. Például: a villákat az egyikdobozban tárolnánk, a késeket amásikban és a kanalakat a har-madikban. Lássunk is egy egy-szerű listát. A könnyű értelmezésvégett ez most a hónapok neveitfogja tárolni. Ennek a kódja ígynéz ki:

months =

['Jan','Feb','Mar','Apr','May'

,'Jun','Jul','Aug','Sep','Oct'

,'Nov','Dec']

A lista létrehozásához annakösszes értékét szögletes nyitó- észárójelek („[” és „]”) közé helyez-zük. A listánkat „months” (hóna-pok) néven hoztuk létre. Ahhoz,hogy használjuk, mondjuk amonths[0] vagy months[1] pa-rancsot írnánk be (ami a „Jan”vagy a „Feb” szavakat adnáeredményül). Fontos megjegyez-ni, hogy mindig nullától számo-lunk. A lista hosszának megálla-pításához az alábbi parancsotkell használnunk:print len(months)

ami 12-vel tér vissza.A listákra egy másik példa a

receptkönyvek kategóriái lenné-nek. Mondjuk így:categories = ['Main

dish','Meat','Fish','So­

up','Cookies']

Ekkor a categories[0] a „Maindish” (főétel), a categories[4] pe-

dig „Cookies” (sütik) lennének.Ezek megint csak elég nyilván-valóak. Biztos vagyok benne,hogy sok olyan dolgot ki tudtoktalálni, amire egy listát lehethasználni.

Mindeddig olyan listákat ké-szítettünk, amik karakterláncokattároltak. Olyan listát is létre tu-dunk hozni, ami egész számokattárol. Ha visszagondolunk a hó-napos listára, olyat is tudnánkcsinálni, ami a hónapok napjai-nak a számát tárolná:DaysInMonth =

[31,28,31,30,31,30,31,31,30,31

,30,31]

Ha kiíratnánk a DaysIn-Month[1] (Február) elemet, akkora 28-at kapnánk vissza. Észreve-hetjük, hogy a listanév a DaysIn-Month (hónap napjai). Ugyan-ilyen egyszerűen használhattamvolna „daysinmonth”-ot is, vagycsak egyszerűen „X”-et… De ak-kor nem lenne olyan jól olvashatóa kód. A helyes programozásiszokások azt diktálják (ami értel-mezés kérdése is), hogy a válto-zónevek könnyen olvashatóak

Helyesbítés az első részhezDavid Turnertől kaptam egy e-mailt,amiben azt javasolta, hogy a Tab billen-tyű indentálásra (behúzásra) való hasz-nálata félrevezető lehet, mivel néhányszerkesztő négynél több, vagy keve-sebb szóközt is használhat behúzáson-ként. Ez természetesen igaz. SokPython programozó (köztük én is) a Tabbillentyű négy szóközre való beállításá-val spórol az idején. A gond azonban az,hogy mások szerkesztője nem feltétle-nül fogja ugyanezt a beállítást használ-ni, ami pedig ronda kódhoz és máshasonló hibákhoz vezethet. Magyarul,inkább a szóközök használatára szokjrá, mint a Tab-okéra.

ELŐZŐ SZÁMOK:FCM 27. számPython ‒ 1. részITT HASZNÁLHATÓ:

KATEGÓRIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/média Rendszer

MerevlemezCD/DVD USB eszköz Laptop Vezetéknélküli

Page 8: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 8 tartalom ^

PROGRAMOZZUNK PYTHONBAN ‒ 2. RÉSZlegyenek. Arról, hogy miért isolyan fontos ez, majd a későb-biekben lesz szó. A listákkalmég eljátszogatunk egy kicsitkésőbb.

Mielőtt azonban rátérnénk akövetkező példaprogramra, néz-zünk még néhány pythonos dol-got.

A sztringek rejtelmei

Még az első részben rövidenbemutattam a karakterláncokat.Most nézzük meg őket közelebb-ről. Egy sztring karakterek soro-zata. Nem sokkal több ennél. Amiazt illeti, tekintsünk úgy egy ka-rakterláncra, mint karakterektömbjére. Például, ha a „The timehas come” (eljött az idő) szringetegy strng nevű változóhoz ren-deljük hozzá, és meg szeretnénktudni, hogy mi a második karak-tere, akkor astrng = 'The time has come'

print strng[1]

utasításokat írnánk be. Az ered-mény egy „h” lenne. Emlékez-zünk, hogy mindig nullától szá-molunk, tehát az első karaktera [0], a második az [1], a har-madik a [2], és így tovább. Hameg szeretnénk keresni a ne-

gyedik pozíciótól nyolcadikigtartó karaktereket, akkor aprint strng[4:8]

parancsot írnánk be, ami a „ti-me” szóval térne vissza. Mintaz első cikkben bemutatott„for” ciklusban, a számlálásnyolcnál megáll, de a nyolcadikkarakter már nem adódik visz-sza, ami itt a szóköz lenne a „ti-me” szó után.

Sztringünk hosszúságának le-kérdezéséhez használhatjuk alen() függvényt:print len(strng)

ami 17-el tér vissza. Ha viszontazt akarnánk megtudni, hogy akarakterláncunkban a „time” szóhol található, akkor apos = strng.find('time')

parancsot alkalmazhatjuk. Itt apos (mint position, azaz pozíció)változó a 4-et tartalmazza, amiazt jelenti, hogy a „time” szó anegyedik pozíción keződik. Haolyan szóra vagy szavakra ke-resnénk rá, amik nincsenek asztringben, mint ahogy itt is:pos = strng.find('apples')

a posba bekerülő érték -1 lenne.Azt is meg tudjuk csinálni, hogya „split” paranccsal mindenegyes szót külön kiíratunk. Ez-zel több részre szedjük (vagybontjuk) a karakterláncot min-den egyes szóköznél:print strng.split(' ')

A parancs a ['The','time','has','come'] listával tér vissza. A splitegy igen jól használható dolog.Még sok ilyen beépített sztring-kezelő függvény áll rendelkezé-sünkre, amiket a későbbiekben ishasználni fogunk.

Változó helyettesítés

Van még egy dolog, amit bekell mutatnunk, mielőtt rátér-nénk a következő programozásipéldára. Amikor egy olyan dol-got szeretnénk kiíratni, amikonstans és változó szöveget istartalmaz, akkor a változóhe-lyettesítés nevű eszközt hasz-nálhatjuk. Alkalmazása igenegyszerű. Ha helyettesíteniakarunk egy sztringet, akkor a'%s'-et használjuk, majd a Py-thonnak megadjuk, hogy mirekell lecserélnie. Például ahhoz,hogy egy hónapot kiírassunk afenti listából, a

print 'Month = %s' % month[0]

parancsot használhatjuk, amikiírja a „Month = Jan” szöveget.Ha egy integert szeretnénk he-lyettesíteni, akkor a '%d'-thasználjuk. Nézzük meg azalábbi esetet:Months =

['Jan','Feb','Mar','Apr','May'

,'Jun','Jul','Aug','Sep','Oct'

,'Nov','Dec']

DaysInMonth =

[31,28,31,30,31,30,31,31,30,31

,30,31]

for cntr in range(0,12):

print '%s has %d days.'

% (Months[cntr],DaysIn­

Month[cntr])

Ennek a kódnak az eredmé-nye:Jan has 31 days.

Feb has 28 days.

Mar has 31 days.

Apr has 30 days.

May has 31 days.

Jun has 30 days.

Jul has 31 days.

Aug has 31 days.

Sep has 30 days.

Oct has 31 days.

Nov has 30 days.

Dec has 31 days.

Nagyon fontos, hogy megért-sük az egyszeres és kétszeresidézőjelek használatát. Ha egy

Page 9: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 9 tartalom ^

PROGRAMOZZUNK PYTHONBAN ‒ 2. RÉSZváltozóhoz az alábbi karakter-

láncokat rendeljük:st = 'The time has come'

vagyst = “The time has come”

akkor az eredmény ugyanaz.Azonban, ha aposztrófokat kellhasználni a szövegen belül, mintitt is:

st = 'He said he's on his way'

akkor szintaktikai hibát kapunk.Helyesen ezt így kell csinálni:st = “He said he's on his way”

Gondoljunk erre úgy, hogyegy sztring meghatározásánál aszöveget mindig valamilyen idé-zőjelek közé kell tenni ‒ egyet azelejére, egyet a végére ‒, mind-ezt úgy, hogy azok megegyezőeklegyenek. Ha keverni kell az idé-zőjeleket, akkor mindig azt hasz-náljuk a külső helyeken, amely-ből nincs a szövegben. Viszontfelmerülhet olyan is, amikor asztring valami ilyesmi: “She said“Don't Worry”” (Azt mondta,

hogy ne aggódjak). Ebben azesetben ezt így is meg lehet ad-ni:st = 'She said “Don\'t Worry”'

Vegyük észre, hogy egy back-slash van a „Don't” szóban lévőegyes aposztróf előtt. Ez egyúgynevezett escape karakter. Ezmondja meg a Pythonnak, hogyírasson ki (ebben az esetben)egy egyszeres idézőjelet ‒ anél-kül, hogy figyelembe venné asztring határolójeleit. Néhánymásik escape szekvencia még (ateljesség igénye nélkül) a „\n”,ami az új sor megfelelője, vagy a„\t”, ami pedig a tabulátoré. Egykésőbbi példakódban ezek mégelő fognak kerülni.

Hozzárendelés kontraegyenlőség

Még mindig van néhány do-log, amit meg kell beszélnünk,hogy a következő példát értel-mezni tudjuk. Az első ilyen dologa hozzárendelés és az egyenlő-ség közötti különbség. A hozzá-rendelést már sokszor használtuka példákban. Amikor egy változó-hoz értéket akarunk rendelni, ak-kor a hozzárendelés operátort

használjuk, vagyis az „=” szim-bólumot (egyenlőségjelet):variable = value

Viszont abban az esetben, a-mikor meg akarjuk állapítani egyváltozó egyenlőségét valamivel,akkor az összehasonlítás operá-tort kell alkalmaznunk. Mondjukle szeretnénk ellenőrizni, hogyegy változó egyenlő-e egy érték-kel. Ekkor a „==” jeleket (kétegyenlőségjel) használnánk:variable == value

Tegyük fel, hogy van egy loop(ciklus) nevezetű változónk ésmeg akarjuk tudni róla, hogyegyenlő-e például 12-vel:if loop == 12:

Nem szükséges értenünk mégaz if és a kettőspont jelentését.Csak arra kell emlékeznünk, hogyaz egyenlőség megállapításáhozkét egyenlőségjelet használunk.

Kommentek

A következő témánk a meg-jegyzéseké. A kommentek sokminden miatt fontosak. Segítsé-gükkel nem csak értelmezni tud-

juk, hogy valaki mit is akar vég-rehajtani a kódban, hanem arrais, ha mondjuk hat hónap utánelőveszed egy programodat, em-lékeztetnek majd arra, hogy mitis akartál csinálni. Amikor elkez-desz rengeteg programot készí-teni, ez nagyon fontos lesz. Amegjegyzések arra is jók, hogyhasználatukkal a Python figyel-men kívül hagyhat bizonyos so-rokat. Egy sor kikommentelésé-hez a „#” jelet használjuk:# Ez egy komment

Bárhova rakhatunk kommen-teket egy sorban, de ha ezt tesz-szük, akkor a Python minden „#”mögötti dolgot figyelmen kívülfog hagyni.

If utasítások

Most visszatérünk ahhoz az„if” utasításhoz, amiről már azelőbb volt szó. Ha valamit egydolog értékének függvényébenakarunk eldönteni, akkor az „if”kulcsszót kell használnunk:if loop == 12:

Ezzel leellenőrizzük a „loop”változó értékét, ha annak tartal-ma 12, akkor végrehajtjuk az

Page 10: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 10 tartalom ^

PROGRAMOZZUNK PYTHONBAN ‒ 2. RÉSZalatta lévő indentált blokk tar-talmát. A legtöbb esetben ezépp elég is, de mi van akkor, haazt akarjuk mondani, hogy „haez a változó valami, akkor csi-náld ezt, különben pedig azt”.Pszeudokódban ezt így írhat-nánk:if x == y then

csinálj valamit

else

csinálj valami mást

Pythonba ugyanez:if x == y:

csinálj valamit

else:

csinálj valami mást

meg még pár dolgot

A fontosabb dolgok:1. Az 'if' vagy az 'else' utasítástkettősponttal kell lezárni.2. INDENTÁLD a kódsorokat.

Ha egymás után több dolgot isle kell ellenőriznünk, akkor hasz-nálhatjuk az if/elif/else formátu-mot. Például:x = 5

if x == 1:

print 'X is 1'

elif x < 6:

print 'X is less

than 6'

elif x < 10:

print 'X is less

than 10'

else:

print 'X is 10 or

greater'

Figyeljük meg, hogy a„<” operátort használtuk ahhoz,hogy megállapítsuk, vajon az xkisebb-e egy megadott értéknél‒ ebben az esetben 6-nál vagy10-nél. Más gyakori összehasonlí-tási műveletek a nagyobb mint(„>”), a kisebb vagy egyenlőmint („<=”), a nagyobb vagyegyenlő mint („>=”) és a nemegyenlő („!=”) operátorok.

While utasítások

Végezetül megnézünk egyegyszerű példát a „while” ciklu-sokra. A „while” utasítás segítsé-gével egy olyan ciklust tudunklétrehozni, ami addig ismétlődik,amíg egy megadott küszöbérté-ket el nem ér. Egy könnyen ért-hető példa az lenne, ha a „loop”változóhoz 1-et rendelnénk úgy,hogy a „while” ciklus addig íratnáki a loop változó értékét, amíg azkisebb vagy egyenlő, mint tíz, ésminden iterációban eggyel növelia loop értékét. Ha a loop tíznél

nagyobb, akkor kilép:loop = 1

while loop <= 10:

print loop

loop = loop + 1

A futtatás eredménye terminálban:1

2

3

4

5

6

7

8

9

10

Éppen az, amit vártunk. Az el-ső ábrán (jobbra fent) egy hason-ló, de valamivel bonyolultabbpélda látható, ami azért mégmindig elég egyszerű.

Ebben a példában, az „if” uta-sítást a „while” ciklussal, a„raw_input” utasítással, újsor es-cape szekvenciával, hozzárende-

lés és összehasonlítás operáto-rokkal kevertük ‒ összesen nyolcsornyi programban.

A példa végrehajtása az alábbikimenetet hozná létre:Enter something or 'quit' to

end

=> FROG

You typed FROG

Enter something or 'quit' to

end

=> bird

You typed bird

Enter something or 'quit' to

end

=> 42

You typed 42

Enter something or 'quit' to

end

=> QUIT

You typed QUIT

Enter something or 'quit' to

end

=> quit

quitting

Figyeljük meg, hogy amikor a„QUIT”-et írtuk be, a programnem állt meg. Ez azért van, merta response (válasz) változót a

loop = 1

while loop == 1:

response = raw_input("Enter something or 'quit' to end => ")

if response == 'quit':

print 'quitting'

loop = 0

else:

print 'You typed %s' % response1. ábra

Page 11: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 11 tartalom ^

Greg Walters a RainyDay Soluti-ons tulajdonosa, ami egy korlátoltfelelősségű tanácsadó cég a colo-radói Aurorában. Programozással1972 óta foglalkozik. Szeret főzni,túrázni, zenét hallgatni és szabad-idejét családja körében eltölteni.

PROGRAMOZZUNK PYTHONBAN ‒ 2. RÉSZ„quit”-el hasonlítottuk össze(response == 'quit'). A „QUIT”pedig NEM egyenlő a „quit”-tel.

Még egy gyors példa, mielőttlezárnánk e havi adagunkat. Te-gyük fel, hogy meg akarjuk néz-ni, vajon egy felhasználó jogo-sult-e programunk használatára.Ez a példa pont jó arra, hogymegmutassa, mit is tanultunkeddig, habár éppenséggel nem alegmegfelelőbb módja a problé-ma megoldásának. Egyszerűenel fogjuk kérni a felhasználótól anevét és jelszavát, majd össze-hasonlítjuk azzal, ami a kódunk-ban van, és döntünk az ered-mény függvényében. Két listátfogunk használni ‒ az egyikben ajogosult felhasználók, a másik-ban azok jelszavai lesznek. Eztkövetően a raw_inputtal bekérjüka felhasználó adatait, végezetülpedig az if/elif/else utasítások-kal leellenőrizzük a felhasználót.Tartsuk azonban szem előtt,hogy a gyakorlatban nem ígyszoktunk eljárni. A soron követ-kező cikkekben rátérünk másmódszerekre is. A kód a jobbralevő szövegdobozban látható.

Mentsük is „python_test.py”néven, majd futtassuk különböző

bemenetekre.Az egyedüli dolog, amiről még

nem beszéltünk, az a leellenőrzőrutin, ami az 'if usrname inusers:' utasítással kezdődik. Amititt csinálunk, az az, hogy meg-nézzük, vajon a begépeltfelhasználónév benne van-e alistánkban. Majd használjuk ausers.index(usrname) függvényta listában elfoglalt helyénekmeghatározásához, hogy ezzel kitudjuk olvasni a jelszavát is, amiugyanezen a pozíción van a má-

sik listában. Például: John azelső pozíción van a felhaszná-lónév listában. Jelszava a„dog”, ami szintén az első po-zíción található a jelszavak lis-tájában. Ezzel a módszerrelmeg tudjuk találni az egyespárokat. Innentől már a többiegyértelmű.Ennyi elég is volt erre a hó-napra. A következő alkalommala függvényekről és modulokrólfogunk tanulni. Addig is ját-szadozzatok el a tanultakkal,és érezzétek jól magatokat.

#­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

#password_test.py

# example of if/else, lists, assignments,raw_input,

# comments and evaluations

#­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

# Assign the users and passwords

users = ['Fred','John','Steve','Ann','Mary']

passwords = ['access','dog','12345','kids','qwerty']

#­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

# Get username and password

usrname = raw_input('Enter your username => ')

pwd = raw_input('Enter your password => ')

#­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

# Check to see if user is in the list

if usrname in users:

position = users.index(usrname) #Get the position in the list of the users

if pwd == passwords[position]: #Find the password at position

print 'Hi there, %s. Access granted.' % usrname

else:

print 'Password incorrect. Access denied.'

else:

print "Sorry...I don't recognize you. Access denied."2. ábra

Page 12: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 12 tartalom ^

HOGYANOKÍrta: Greg Walters

Programozzunk Pythonban – 3. rész

Az előző cikkben megta-nulhattunk változókatbehelyettesíteni, meg-jegyzéseket elhelyezni,

és azt is tudjuk, hogy mi a hozzá-rendelés és az egyenlőség közöttikülönbség, valamint ismerjük azif, illetve a while utasításokat is.Továbbá megígértem, hogy ebbena részben a modulokról és afüggvényekről egyaránt szót fo-gunk ejteni.Modulok

Modulok használatával a Py-

thon nyelvet bővíthetjük, akárújakat létrehozva, vagy felhasz-nálva a Pythonnal együtt telepí-tetteket, illetve más felhasználókáltal létrehozottakat. A Pythonmaga, sok száz különböző mo-dullal rendelkezik, amik a progra-mozási folyamatot nagyban meg-könnyítik. A Python általános mo-duljainak listáját ahttp://docs.python.org/modin-dex.html címen találhatjátokmeg. Néhány modul operációsrendszertől függő, de a leg-több teljesen platformfüggetlen(ugyanúgy lehet Linux, Mac ésWindows alatt használni). Ah-hoz, hogy egy külső modulthasználjunk, először be kell im-portálni azt a programunkba. APythonban lévő modulok egyikeaz úgynevezett „random”. Se-gítségével pszeudovéletlen szá-mokat tudunk generálni. Ajobbra fenn látható modult fog-juk az első példában használni.

Vizsgáljunk meg mindenegyes kódsort. Az első négy sormegjegyzés. Ezekről már szó voltaz előző cikkben. Az ötödik sormegmondja a Pythonnak, hogy

használja a ran-dom modult. Eztmindig különmeg kell mon-dani a Python-nak.

A hetedik sorbeállít egy „for”ciklust 14 véletlengenerált számkiírásához. A nyolcadik sor hasz-nálja a randint() függvényt, hogy0 és 10 között egy véletlen szá-mot megjelenítsen. Figyeljükmeg, hogy jelezni kell a függvénymoduljának nevét a Pythonban.Ezt úgy tesszük (ebben az eset-ben), hogy random.randint. Fel-merülhet azonban a kérdés, hogyegyáltalán miért jó modulokatkészíteni? Nos, ha minden egyesfüggvényt belevennénk a Py-thonba, irgalmatlanul nagy éslassú lenne, a debuggolás egyrémálommá válna. A modulokhasználatával részekre tudjukbontani kódunkat úgy, hogy min-den egyes darab egy bizonyosfeladathoz van rendelve. Ha pél-dául nincs szükséged adatbázis-kezelő funkciókra, nem kell tud-nod róla, hogy van egy SQLite

nevű modul. De ha kell, akkormár ott is van. (Ami azt illeti, fo-gunk is használni adatbázis mo-dulokat a jövőben.)

Amint igazán belelendülsz aPython programozásába, valószí-nűleg saját modulokat fogsz lét-rehozni, így téve lehetővé kódodkésőbbi felhasználását anélkül,hogy újra be kellene azt gépel-ned. Ha esetleg valamit változ-tatnod kellene a kódban, anélkülteheted meg, hogy túl nagy koc-kázatot vállalnál a fő program-rész elrontására. Vannak azon-ban bizonyos korlátok is, de eb-ben majd később mélyedünk el.Amikor korábban az „import ran-dom” utasítást használtuk, aztmondtuk meg a Pythonnak, hogyhasználjon minden függvényt arandom modulon belül. Ha azon-

#=======================================

# random_example.py

# Module example using the random module

#=======================================

import random

# print 14 random integers

for cntr in range(1,15):

print random.randint(1,10)

ELŐZŐ SZÁMOK:FCM 27–28. számPython ‒ 1–2. részITT HASZNÁLHATÓ:

KATEGÓRIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/média Rendszer

MerevlemezCD/DVD USB eszköz Laptop Vezetéknélküli

Page 13: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 13 tartalom ^

PROGRAMOZZUNK PYTHONBAN – 3. RÉSZban csak a randint()-re vanszükségünk, átírhatjuk az im-port utasítást így:from random import randint

Ha most hívjuk meg a függ-vényt, akkor már nem kell hasz-nálnunk a „random” azonosítót.A kódunk tehát így fog kinézni:from random import randint

# print 14 random integers

for cntr in range(1,15):

print randint(1,10)

Függvények

Amikor a „random” modultimportáltuk, a „randint()” függ-vényt használtuk. A függvényegy olyan kódblokk, amit ‒ álta-lában ‒ többszöri meghívásraterveztek, ezáltal könnyebb a ke-zelése: megóv minket ugyanan-nak a kódnak az újbóli begépelé-sétől. Nagyon erős általánosítás-sal élve, amikor ugyanazt a kódotmeg kell írnunk egynél többször,akkor az egy jó alkalom a függ-vényírásra. Bár a következő kétpélda nagyon egyszerű, mégis jólbemutatja a függvények haszná-latát. Tegyük fel, hogy szeretnénkkét számot összeadni, megszo-rozni őket és kivonni egymásból,

végül megjeleníteni amegadott számokat ésaz eredményeket min-den alkalommal. Nemminden habostorta:mindezt háromszor kellmegismételnünk, há-rom eltérő számhal-mazzal. Leegyszerűsí-tett példánk végül úgynéz ki, amint az a jobboldali szövegben látha-tó.

A függvények alkalmazásanélküli nagy, ömlesztett kódhal-maz nemcsak a több gépelés mi-att vezethet sok hibához, de akésőbbi változtatások miatt is, hi-szen ugyanazt a változtatástegyszerre több helyen is ugyan-úgy el kell végezni a programkódjában. Ehelyett készíteni fo-gunk egy „DoTwo” nevű függ-vényt, amely a megadott kétszám-mal el-végzi aszük-ségesmate-matikaiműve-leteketés az

eredményt kiírja. A függvényt a„def” kulcsszó beírásával kezdjük(ami megmondja a programnak,hogy definiálni fogunk egy függ-vényt). A „def” után hozzáadjuka függvény nevét és a paraméte-rek listáját (ha vannak) zárójelekközött. A sort egy kettősponttal(:) zárjuk. A következő sortól afüggvény törzsét képező kódotbe kell húzni (beljebb kell írni, in-dentálni). Továbbfejlesztett, má-

sodik kis példánk az alábbiakbantekinthető meg.

Mint látható, sokkal kevesebbgépelésre volt szükség: egészpontosan 12 sor helyett csaknyolcra. Ha később valamilyenváltoztatásra van szükség függ-vényünkben, könnyebben meg-tehetjük, anélkül, hogy a prog-ram fő részében bármit megvál-toztatnánk. Függvényünk hasz-

#silly example

print 'Adding the two numbers %d and %d = %d ' % (1,2,1+2)

print 'Multiplying the two numbers %d and %d = %d ' % (1,2,1*2)

print 'Subtracting the two numbers %d and %d = %d ' % (1,2,1­2)

print '\n'

print 'Adding the two numbers %d and %d = %d ' % (1,4,1+4)

print 'Multiplying the two numbers %d and %d = %d ' % (1,4,1*4)

print 'Subtracting the two numbers %d and %d = %d ' % (1,4,1­4)

print '\n'

print 'Adding the two numbers %d and %d = %d ' % (10,5,10+5)

print 'Multiplying the two numbers %d and %d = %d ' % (10,5,10*5)

print 'Subtracting the two numbers %d and %d = %d ' % (10,5,10­5)

print '\n'

#silly example 2...still silly, but better

def DoTwo(num1,num2):

print 'Adding the two numbers %d and %d = %d ' % (num1,num2,num1+num2)

print 'Multiplying the two numbers %d and %d = %d ' % (num1,num2,num1*num2)

print 'Subtracting the two numbers %d and %d = %d ' % (num1,num2,num1­num2)

print '\n'

DoTwo(1,2)

DoTwo(1,4)

DoTwo(10,5)

Page 14: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 14 tartalom ^

PROGRAMOZZUNK PYTHONBAN – 3. RÉSZnálatakor a meghívás a függ-vény nevével és az utána írt ar-gumentumokkal történik.

A függvény további alkalma-zására tekintsük a következőket.

Szeretnénk egy olyan progra-mot írni, mely ki fogja írni a meg-vásárolt termékek listáját szép,formázott módon, az alábbi szö-vegkiíráshoz hasonlóan.

Az árucikkek egyenkénti ésösszegzett ára dollárban és cent-ben lesz formázva. A megjelení-tés szélessége változtatható kellhogy legyen. A bal- és jobboldaliértékek szintén változóból kellhogy jöjjenek. Három függvénytfogunk elkészíteni a feladat meg-oldására. Az első kiírja a legfelsőés a legalsó sort, a második kiírjaaz egyes cikkek részleteit az ösz-szegző sorral együtt, a harmadikpedig az elválasztó vonalat jele-níti meg. Szerencsére a Pythonsok olyan beépített jellemzővel

bír, amely könnyebbé teszi a fel-adatunkat. Ha visszaemlékezünk,programunkban kiírattuk a szö-veget négyszer, és az ugyanan-nak a sztringnek a négy másola-tával tért vissza.

Ezt mi kihasználhatjuk a sajátjavunkra. A legfelső, vagy a leg-alsó sor kiíratásához vegyük a kí-vánt szélességet, vonjunk ki be-lőle kettőt a két '+' jel miatt éshasználjuk a „ '=' * (width-2)”formulát. A dolgok még könnyeb-bé tételéhez a változóbehelyette-sítést fogjuk használni, hogy azösszes elemet egy sorba tegyük.Tehát kiírandó sztringünket a('+',('=' * width-2)),'+') karakter-sorral lehet lekódolni. Függvé-nyünk közvetlenül is írhatna aképernyőre, azonban ehelyett areturn kulcsszóval visszaadjuk alétrehozott sztringet a hívó fél-nek. Függvényünket nevezzük el„TopOrBottom”-nak, és a kódjátírjuk a következők szerint:

def TopOrBot­

tom(width):

# width is total

width of returned

line

return '%s%s%s' %

('+',('=' * (width­

2)),'+')

A megjegyzést kihagyhatnánk,de mégis jó, ha megtudhatjukbelőle egy pillanat alatt a „width”paraméter rendeltetését. A függ-vény meghívása a „print TopOr-Bottom(40)” módon történik,amelyben szélességnek termé-szetesen más értéket is beállít-hatunk. Most tehát már van egyfüggvényünk, mely a két említettsorral foglalkozik. Létrehozhatunkegy új függvényt, hogy az elvá-lasztó vonallal foglalkozzonugyanannak a kódnak a felhasz-nálásával… VAGY módosíthat-nánk a már meglevő függvé-nyünket is, hogy egy további pa-raméterrel az alkalmazandó ka-raktert meghatározhassuk. Te-gyük inkább ezt, neve pedig mégmindig maradhat „TopOrBottom”.def TopOrBottom(charac­

ter,width):

# width is total width of

returned line

# character is the cha­

racter to be placed between

the '+' characters

return '%s%s%s' %

('+',(character * (width­

2)),'+')

Most látható, hogy a megjegy-zések milyen hasznosak. Ne fe-ledjük, hogy a generált sztringgelvisszatérünk, tehát nekünk kell

valamit tennünk vele, hogy visz-szakapjuk, amikor meghívjuk.Ahelyett, hogy hozzárendelnénkegy másik sztringhez, egyszerű-en csak kiírjuk a képernyőre.Használata így néz ki:print TopOrBottom('=',40)

Tehát most nem csak háromsorról gondoskodtunk, hanem aszükséges rutinok számát iscsökkentettük háromról kettőre.Tehát innentől már csak a közép-ső rész kiírásával kell törődnünk.

Az ehhez szükséges új függ-vényt nevezzük „Fmt”-nek. Négyparamétert fogunk neki átadni:val1 – a bal oldali kiírandó érték,leftbit – ennek az „oszlop”-nak aszélessége,val2 – a jobb oldali kiírandó érték(lebegőpontos),rightbit – ennek az „oszlop”-naka szélessége.

Az első feladat az, hogy az in-formációkat a jobb oldalon meg-formázzuk. Mivel dollár és centértéket akarunk megformázni,használhatunk egy speciális vál-tozóbehelyettesítési függvényt,amely azt az utasítást adja ki,hogy az érték lebegőpontosszámként íródjon ki, az n. számú

'+===============================+'

'| Item 1 X.XX |'

'| Item 2 X.XX |'

'|­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­|'

'| Total X.XX |'

'+===============================+'

Page 15: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 15 tartalom ^

PROGRAMOZZUNK PYTHONBAN – 3. RÉSZhelyen, a tizedes ponttól jobb-ra. A parancs pedig a „%2.f”.Ezt a „part2” változóhoz fogjukhozzárendelni. Ehhez kódunk a„part2 = '%.2 f' % val2” lesz.Használhatunk olyan függvé-nyeket is még, amik a Pythonsztringekbe alapértelmezettenbe vannak építve „ljust” és„rjust” néven. Az „ljust” balraigazítja a sztringet, kitöltve azta jobb oldalon, bármilyen kí-vánt karakterrel. Az „rjust”ugyanazt teszi, csak a kitöltés abal oldalon van. Ez már ígyszép darab. A helyettesítéseksegítségével összedobtunk egynagy sztringet és visszaadtukazt a hívó kódnak. Következősorunk így néz ki:return 'ss' % ('|

',val1.ljust(leftbit­2,'

'),part2.rjust(rightbit­2,'

'),' |')

Miközben ez inkább ijesztőnektűnik elsőre, elemezzük ki egy ki-csit, és nézzük meg, valójábanmilyen egyszerű is:return ‒ az elkészült sztring,melyet visszaküldünk a hívó kód-nak.'ss' ‒ 4 értéket fogunk tárolniegy sztringben. Mindegyik „%s”egy helyőrző.

% ( ‒ Elindítja a változó listát.' | ' , ‒ Kiírja ezeket literálisan.val1. ljust(leftbit-2, ' ' ) ‒ Veszi a'val1' változót, melyet átadtunk,balra igazítja szóköz karakterek-kel (leftbit-2). Ki kell vonni 2-t ah-hoz, hogy a "|" a bal oldalonmegfelelően legyen.part2.rjust(rightbit-2, ' ' ) ‒Jobbra igazítja az ár formázottsztringjét rightbit-2 mennyiségűszóközzel. A ' |' fejezi be a sztrin-get.

Ez minden, amit tennünk kel-lett. Még valójában egyes hibákellenőrzését kellene elvégez-

nünk, vehetjük aztsaját játékunknakis. Tehát az Fmtfüggvényünk való-jában csak két sor-nyi kód a definíciósorán és a megjegyzéseken kívül.A meghívás az alábbiak szerinttörténik:print Fmt('Item

1',30,item1,10)

A visszatérési értéket ismétegy másik szöveghez rendelhet-nénk, de mi csak ki fogjuk íratni.

Figyeljük meg, hogy adunk át 30-at a bal oldali rész, és 10-et ajobb oldal szélességének. Ezmegegyezik a 40-nel, melyet aTopOrBottom rutinunknak koráb-ban megadtunk. Majd indítsuk elszerkesztőprogramunkat és írjukbe az alábbi kódot.

Mentsük el a kódot„pprint1.py” néven és futtassuk

#pprint1.py

#Example of semi­useful functions

def TopOrBottom(character,width):

# width is total width of returned line

return '%s%s%s' % ('+',(character * (width­2)),'+')

def Fmt(val1,leftbit,val2,rightbit):

# prints two values padded with spaces

# val1 is thing to print on left, val2 is thing to print on right

# leftbit is width of left portion, rightbit is width of right portion

part2 = '%.2f' % val2

return '%s%s%s%s' % ('| ',val1.ljust(leftbit­2,' '),part2.rjust(rightbit­2,' '),' |')

# Define the prices of each item

item1 = 3.00

item2 = 15.00

# Now print everything out...

print TopOrBottom('=',40)

print Fmt('Item 1',30,item1,10)

print Fmt('Item 2',30,item2,10)

print TopOrBottom('­',40)

print Fmt('Total',30,item1+item2,10)

print TopOrBottom('=',40)

+======================================+

| Item 1 3.00 |

| Item 2 15.00 |

+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+

| Total 18.00 |

+======================================+

Page 16: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 16 tartalom ^

Greg Walters a RainyDay Solu-tions tulajdonosa, ami egy korlá-tolt felelősségű tanácsadó cég acoloradói Aurorában. Programo-zással 1972 óta foglalkozik. Sze-ret főzni, túrázni, zenét hallgatniés szabadidejét családja körébeneltölteni.

PROGRAMOZZUNK PYTHONBAN – 3. RÉSZle. A kimenet valahogy úgy nézki, ahogy az előző oldalon lát-ható jobbra fent.

Noha ez egy nagyon egyszerűpélda, mégis tippeket ad, hogymiért és hogyan kell használni afüggvényeket. Most pedig fejlesz-szük tovább egy kicsit, és tud-junk meg többet a listákról. Em-lékszünk a második részre, ami-kor először tárgyaltuk a listákat?Egy dolog, amit még nem mond-tam, hogy egy lista tartalmazhatszinte bármit, beleértve a listákatis. Definiáljunk programunkbanegy új „itms” nevű listát és tölt-sük fel így:itms = [['Soda',1.45],['Can­

dy',.75],['Bre­

ad',1.95],['Milk',2.59]]

Ha ezt a szokásos listakéntkezelnénk, akkor a „printitms[0]” módon érnénk el az ele-meit. Azonban erre a ['Soda',1,45] térne vissza, ami nem iga-zán az, amit normális körülmé-nyek között kerestünk. El szeret-nénk érni minden egyes elemetaz első listában. Tehát a „printitms[0][0]” formát kellene hasz-nálnunk, hogy megszerezzük a„Soda”-t és [0][1]-et, hogy meg-kapjuk a költségeket, vagyis az

1,45-öt. Szóval, mostmár négy elemünk van,amit már megvásárol-tunk, és ezt az informá-ciót szeretnénk hasz-nálni szép kiíró ruti-nunkban. Az egyetlendolog, amit meg kellváltoztatni, a programalja. Mentsük el a leg-utóbbi programot „pp-rint2.py”-ként, majdtegyük megjegyzésbe a két itemxdefiníciót, és tegyük bele a fentilistát. Mindennek valahogy ígykell kinéznie :#item1 = 3.00

#item2 = 15.00

itms = [['Soda',1.45],['Can­

dy',.75],['Bre­

ad',1.95],['Milk',2.59]]

Ezután távolítsuk el az összessort, mely az Fmt()-t hívja meg.Utána adjuk hozzá az alábbi soro-kat (#NEW LINE segítségével avégére), hogy a kód úgy nézzenki, mint a képen jobbra látható.

Vegyünk felmég egy szám-láló változót,amely végig-megy a listaminden elemén aciklus végéig. Fi-

gyeljük meg a „total” nevű válto-zó alkalmazását is. A „total”-t0-ra állítjuk, mielőtt a ciklus el-kezdődne. Aztán ahogy az el-adott tételeket kiírjuk, hozzáad-juk a költséget a „total”-hoz. Vé-gül kiíratjuk a „total”-t közvetle-nül az elválasztó vonal után.Mentsük el a programot és fut-tassuk le azt. Ilyesmit kell lát-nunk, mint ami az alábbi képenlátható.

Ha nagyon elvetemültek aka-runk lenni, akkor hozzáadhatunkegy sort az adó számára is. Közelazonos módon kezeljük, mint azt

tettük a „total” sorában, dehasználjuk a (total * .086)-otköltségként.print Fmt('Tax:',30,

total*.086,10)

Több elemet is felvehetünk alistára, és megnézhetjük, hogyanműködik.

Ennyi volt mára. A következőalkalommal az osztályokkal fo-gunk foglalkozni.

Jó szórakozást!

itms = [['Soda',1.45],['Candy',.75],['Bread',1.95],['Milk',2.59]]

print TopOrBottom('=',40)

total = 0 #NEW LINE

for cntr in range(0,4): #NEW LINE

print Fmt(itms[cntr][0],30,itms[cntr][1],10) #NEW LINE

total += itms[cntr][1] #NEW LINE

print TopOrBottom('­',40)

print Fmt('Total',30,total,10) #CHANGED LINE

print TopOrBottom('=',40)

+======================================+

| Soda 1.45 |

| Candy 0.75 |

| Bread 1.95 |

| Milk 2.59 |

+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+

| Total 6.74 |

+======================================+

Page 17: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 17 tartalom ^

HOGYANOKÍrta: Greg Walters

Programozzunk Pythonban – 4. rész

Előző alkalommal meg-ígértem, hogy az osztá-lyokról fogunk beszélni,tehát erre fogunk most

koncentrálni. De mik is az osztá-lyok és mire valók?

Az osztály az egyik módja an-nak, hogy objektumokat hozzunklétre. Egy objektum pedig egymódszer arra, hogy állapotokat ésviselkedéseket egy csoportkéntkezelhessünk. Tudom, hogy egykissé kuszának tűnik, de el fogommagyarázni. Gondoljunk erre csak

úgy, mintha az objektumok a va-lós élet modelljei lennének. Azosztályok pedig a módszerek,amivel mindezeket implementál-juk. Például, legyen otthon háromkutyánk. Egy beagle, egy labra-dor és egy német/ausztrál juhászkeverék. Mindhárom kutya, demindegyik különbözik. Vannakközös tulajdonságaik, de mind-egyiknek van még ezenkívül csakrá jellemző tulajdonságai is. Pél-dául, a kopó egy kicsi, pufók,barna és morcos kutya. A labra-dor közepes méretű, fekete ésnagyon nyugodt természetű. Anémet/ausztrál juhász keverékpedig magas, sovány, fekete és akelleténél egy kicsit bolondabb.Első ránézésre vannak nyilvánva-ló tulajdonságaik. A kicsi/köze-pes/magas méret például a

magasságukra vonatkozik. Amorcos, kényelmes és bolondmeg a természetüket jellemzi. Haa cselekedeteik felől nézzük adolgokat, akkor figyelembe ve-hetjük az evést, az alvást, a ját-ékot és hasonló dolgokat.

Mindhárom a „Dog” (Kutya)osztályba tartozik. Visszatérve azelőbb használt tulajdonságokhoz,vannak Dog.Name (Kutya.Név),Dog.Height (Kutya.Magasság),Dog.Build (Kutya.Testalkat, so-vány, pufók stb.) és Dog.Color(Kutya.Szín) jellemzőik. Vannakviselkedéseink is, mint aDog.Bark (Kutya.Ugat), Dog.Eat(Kutya.Eszik), Dog.Sleep (Ku-tya.Alszik) és így tovább.

Mint ahogy előzőleg is mond-

tam, mindegyik kutya különbözikis a fajtára vonatkozó tulajdon-ságokban. Mindegyik külön al-osztálya lenne a Dog (Kutya)osztálynak. Egy diagramon eztígy ábrázolhatnánk:

/­­Beagle

Dog ­­­|­­ Lab

\­­Shepherd/Heeler

Mindegyik alosztály örökli aDog osztály tulajdonságait. Ezért,ha létrehoznánk egy példányt aBeagle osztályból, megkapná aszülő osztály összes tulajdonsá-gát is, amik ebben az esetbenugye a Dog-ra vonatkozók lenné-nek.

class Dog():

def __init__(self,dogname,dogcolor,dogheight,dogbuild,dogmood,dogage):

#here we setup the attributes of our dog

self.name = dogname

self.color = dogcolor

self.height = dogheight

self.build = dogbuild

self.mood = dogmood

self.age = dogage

self.Hungry = False

self.Tired = False

ELŐZŐ SZÁMOK:FCM 27–29. számPython ‒ 1–3. részITT HASZNÁLHATÓ:

KATEGÓRIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/média Rendszer

MerevlemezCD/DVD USB eszköz Laptop Vezetéknélküli

Page 18: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 18 tartalom ^

PROGRAMOZZUNK PYTHONBAN – 4. RÉSZBeagle = Dog()

Beagle.Name = 'Archie'

Beagle.Height = 'Short'

Beagle.Build = 'Chubby'

Beagle.Color = 'Brown'

Kezdenek értelmet nyerni adolgok? Készítsük akkor el a dur-ván felvázolt Dog osztályunkat(fenn). A „class” kulcsszóval ésaz osztály nevével kezdünk.

Mielőtt még továbblépnénkkódunkban, vegyük észre, hogy afüggvény, amit itt definiáltunk,az __init__ metódus (két aláhúzás+ 'init' + két aláhúzás) egy inici-alizációs függvény, mely bárme-lyik osztálynál működik. Amintkódunkban meghívjuk az osztá-lyunkat, ez a függvény le fog fut-ni. Jelen esetben beállítunknéhány alap paramétert: van egynév, szín, testalkat, hangulat,kor, és még néhány változó, mintHungry (Éhes) és Tired (Fáradt).Még vissza fogunk térni ezekre.Írjunk még néhány sornyi kódot.Beagle = Dog('Ar­

chie','Brown','Short','Chub­

by','Grumpy',12)

print Beagle.name

print Beagle.color

print Beagle.mood

print Beagle.Hungry

Ez egy INDENTÁLATLAN kód,

ami az osztályon kívül helyezke-dik el. Ez az a kód, ami használjaaz osztályunkat. Az első sor létre-hoz egy példányt a kutya osztály-ból, amit Beagle-nek neveztünkel. Ezt nevezzük példányosítás-nak. Amikor ezt tettük, továbbí-tottunk még bizonyos informá-ciókat az osztály példánya felé,mint a Beagle neve, színe, stb. Akövetkező négy sor csak egysze-rű lekérdezésekből áll, melyek aBeagle objektumról adnak infor-mációt. Itt az idő még egy kiskódra. Adjuk még hozzá a jobbfelső dobozban látható kódot az__init__ függvény után.

Most pedig hívjuk meg a Be-agle.Eat()-tel vagy Beagle.Sle-ep()-pel. Adjunk hozzá egy újabbmetódust. Hívjuk ezt Bark-nak(Ugatás). A kódja jobbra látható.

Ezt egy kissé rugalmasabbátettem. A kutya hangulatától füg-gően az ugatás meg fog változni.A következő oldalon látható azeddigi teljes kód.

Nos, ha ezt futtatjuk, akkor akövetkezőt kellene kapnunk:My name is Archie

My color is Brown

My mood is Grumpy

I am hungry = False

Sniff Sniff...Not Hungry

Yum Yum...Num Num

GRRRRR...Woof Woof

Ezzel le is tudtuk a morcos kiskopónkat. De előbb azt mond-tam, hogy három kutyánk van.Mivel az osztályunkat előretekin-tően kódoltuk, annyi lesz csak adolgunk, hogy még kétszer pél-dányosítjuk a kutya osztályt.Lab = Dog('Nina','Black','Me­

dium','Heavy','Laid Back',7)

Heeler =

Dog('Bear','Black','Tall','Ski

nny','Crazy',9)

print 'My Name is %s' %

Lab.name

print 'My color is %s' %

Lab.color

print 'My Mood is %s' %

Lab.mood

print 'I am hungry = %s' %

Lab.Hungry

Lab.Bark()

Heeler.Bark()

Figyeljük meg, hogy mindkétkutya példányát a kiíratások előtthoztuk létre. Ez nem gond, mivela példányokat a metódusok hí-vását megelőzően definiáltam. Itta teljes kimenete a kutya osztá-lyos programunknak.

def Eat(self):

if self.Hungry:

print 'Yum Yum...Num Num'

self.Hungry = False

else:

print 'Sniff Sniff...Not Hungry'

def Sleep(self):

print 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'

self.Tired = False

def Bark(self):

if self.mood == 'Grumpy':

print 'GRRRRR...Woof Woof'

elif self.mood == 'Laid Back':

print 'Yawn...ok...Woof'

elif self.mood == 'Crazy':

print 'Bark Bark Bark Bark Bark Bark Bark'

else:

print 'Woof Woof'

Page 19: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 19 tartalom ^

PROGRAMOZZUNK PYTHONBAN – 4. RÉSZ

Greg Walters a RainyDay Solu-tions, LLC, az Aurora Colorado-itanácsadó cég tulajdonosa, ésmár 1972 óta foglalkozik progra-mozással. Szeret főzni, túrázni,szereti a zenét és családjával töl-teni szabadidejét.

My name is Archie

My color is Brown

My mood is Grumpy

I am hungry = False

Sniff Sniff...Not Hungry

Yum Yum...Num Num

GRRRRR...Woof Woof

My Name is Nina

My color is Black

My Mood is Laid Back

I am hungry = False

Yawn...ok...Woof

Bark Bark Bark Bark Bark Bark

Bark

Mivel már ismerjük az alapo-kat, a házi feladat az lenne, hogybővítsük a kutya osztályt többmetódussal, mint a Play (Játszik)vagy EncounterStrangeDog(TalálkozásIdegenKutyával) vagyvalami hasonlóval.

A következő alkalommal bele-kezdünk a GUI, avagy a grafikuskezelőfelület programozásába.Ehhez a Boa Constructor-t fog-juk használni.

class Dog():

def __init__(self,dogname,dogcolor,dogheight,dogbuild,dogmood,dogage):

#here we setup the attributes of our dog

self.name = dogname

self.color = dogcolor

self.height = dogheight

self.build = dogbuild

self.mood = dogmood

self.age = dogage

self.Hungry = False

self.Tired = False

def Eat(self):

if self.Hungry:

print 'Yum Yum...Num Num'

self.Hungry = False

else:

print 'Sniff Sniff...Not Hungry'

def Sleep(self):

print 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'

self.Tired = False

def Bark(self):

if self.mood == 'Grumpy':

print 'GRRRRR...Woof Woof'

elif self.mood == 'Laid Back':

print 'Yawn...ok...Woof'

elif self.mood == 'Crazy':

print 'Bark Bark Bark Bark Bark Bark Bark'

else:

print 'Woof Woof'

Beagle = Dog('Archie','Brown','Short','Chubby','Grumpy',12)

print 'My name is %s' % Beagle.name

print 'My color is %s' % Beagle.color

print 'My mood is %s' % Beagle.mood

print 'I am hungry = %s' % Beagle.Hungry

Beagle.Eat()

Beagle.Hungry = True

Beagle.Eat()

Beagle.Bark()

Page 20: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 20 tartalom ^

HogyanokÍrta: Greg Walters

Programozzunk Pythonban - 5. részELŐZŐ SZÁMOK:FCM 27-30. számPython - 1-4. részITT HASZNÁLHATÓ:

KATEGÓRIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/média Rendszer

MerevlemezCD/DVD USB Eszköz Laptop VezetéknélküliHa olyan vagy mint én,

akkor UTÁLNI fogodennek a cikknek az elsőfelét. Mert én KI NEM

ÁLLHATOM, amikor a szerző aztírja, hogy minden szót kétszer isvégig kell olvasnom a könyvé-ben/fejezetében/cikkében, mivelmár ekkor tudom, hogy dögu-nalmas lesz - még úgy is, hogyvalószínűleg igaza van, és az énérdekemet szolgálná, meg a vé-gén mégiscsak végig fogokmenni rajta újra.

Én figyelmeztettelek! Mostarra KÉRLEK, hogy figyelmesen

olvasd el a következő unalmasdolgokat. Hamarosan rátérünkaz izgalmasabb részekre, demielőtt akárcsak beszélhetnénkis programozásról, egy kis ala-pozásra lesz szükségünk.

ELŐSZÖR is fel kellene tele-píteni a Boa Constructor és wx-Python programokat. Használda Synaptic-ot és válaszd kimind a wxPythont, mind a BoaConstructort. Amikor ezeket fel-telepítetted, a Boát az Applica-tions/Programming/Boa Con-structor menüben találhatjukmeg. Indítsuk is el rögtön. Ígysokkal tisztábbak lesznek a dol-gok. Amint az alkalmazás elin-dult, három különböző ablakot(vagy frame-et) figyelhetünkmeg: egyet felül és kettőt alul.Valószínűleg át kell majd moz-gatni és méretezni őket, de jus-

sunk el arra a pontra, hogy aképen láthatóan nézzen ki.

A felső ablakot tool frame-nek (eszköz panel) nevezzük. Abal alsó az inspector frame (fel-ügyelő panel) és a jobb alsó azeditor frame (szerkesztő panel).Az editor frame-en több fajta fülvan (New, Containers/Layout, stb.),melyek segítségével új projek-teket tudunk létrehozni, továbbiframe-eket tudunk egy már lé-tező projekthez hozzáadni, illet-ve különböző vezérlőelemeketaz alkalmazásunk frame-jeibenelhelyezni. Az inspector frameigen fontos lesz, amint vezérlő-emeket kezdünk az alkalmazá-sunkhoz adni. Az editor frame-en tudjuk a kódunkat szerkesz-teni, elmenteni a projektünket,stb. Visszatérve a tool frame-re,nézzük meg mindegyik fület - a„New” füllel kezdve. Annak el-lenére, hogy sok-sok választásilehetőség áll itt rendelkezé-sünkre, csak kettővel fogunkfoglalkozni. Ezek balról az ötö-dik és hatodik gombok: a wx.Appés a wx.Frame. A wx.App segítsé-gével egy teljes alkalmazást tu-dunk létrehozni két automati-

kusan legenerált fájllal. Azegyik egy frame fájl, a másikpedig az alkalmazás állománya.Én ezt a módszert szeretemhasználni. A wx.Frame továbbiframe-ek alkalmazásunkhozvaló hozzáadására szolgálés/vagy egy különálló alkalma-zás egyetlen forráskódból valólétrehozására. Erről még ké-sőbb ejtünk szót.

Most nézzük meg a Contai-ners/Layout fület. Sok finomsá-got találhatunk itt. A legtöbb-ször használt a wx.Panel (balrólaz első) és a sizerek (mérete-zők - 2,3,4,5 és 6 jobbról). ABasic Controls alatt taláhatjuk astatikus szöveget (label), szö-vegdobozokat, jelölődobozokat,rádiógombokat, stb. A Buttonsalatt pedig a különféle gombokvannak. A List Controls-banvannak a táblázatok és a lenyí-ló listák. Most ugorjunk a Utili-ties-re, ahol sok időzítőt és me-nüelemet láthatunk.

Van néhány dolog, amit nemárt, ha észben tartunk, mielőttelső alkalmazásunkhoz hozzá-látnánk. Van néhány bug a Li-

Page 21: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 21 tartalom ^

Programozzunk Pythonban - 5. résznuxos verzióban. Az egyik az,hogy NÉHÁNY vezérlőelemetnem tudunk a designer nézet-ben mozgatni. Használd a<Ctrl>+Nyíl gombokat pozíció-juk megváltoztatásához és fi-nomhangolásához. Egy másikhibával akkor találkozhatunk,amikor a Boa Constructor beé-pített tutorialjait akarjuk kipró-bálni - amikor egy panelt pró-bálunk elhelyezni, nem nagyonlehet azt látni. Ilyenkor a kisdobozkákat kell keresni (hama-rosan lesz szó róla). Használ-hatnánk az Inspector frameObjs fülét is a kiválasztásához.

Akkor hát, indul a móka. Azeditor frame-en a „New” fül a-latt válasszuk ki a wx.Appot (5.balról). Ezzel létrehoztunk kétúj fület a szerkesztő panelen:az egyik „*(App1)*” nevű, amásik pedig „*(Frame1)*”. Hahiszed, ha nem, a LEGELSŐ do-log, amit tenni fogunk, hogy el-mentjük a két új fájlunkat a Fra-me1-el kezdve. A Mentés gombaz editor frame-en az ötödikbalról. A felugró „Save As” ab-lak azt kéri, hogy adjuk meg afájl mentési helyét, illetve ne-vét. Készítsünk egy GuiTestsnevű mappát a home map-pánkban és mentsük el bele a

fájlt „Frame1.py” néven. Figyel-jük meg, hogy a „*(Frame1)*”fül mostmár „Frame1” lett. (A„*(” jelzi, hogy a fájl még nincselmentve.) Csináljuk megugyanezt az App1 fülre is.

Most vizsgáljunk meg né-hány gombot az Editor eszköz-táron. A fontosabbak a Save (5.balról) és a Run (Sárga nyíl, 7.balról). Ha egy frame fülönvagy (Frame1 például), akkorlesz még pár gomb, amiről illiktudnunk. Egyelőre beszéljünkcsak a Designer gombról:

Ez egy fontos gomb. Segítsé-gével tudjuk a GUI-nkat meg-tervezni - épp az, amit csinálniszeretnénk. Amikor rákattin-tunk, egy üres frame-et fogunkkapni:

Ez egy olyan üres háttérfelü-let (canvas), amire bármilyenvezérlőelemet rá lehet pakolni(természetesen az észszerűséghatárain belül). Az első dolog,amit meg kell tennünk, hogyhelyezzünk el egy wx.panel ele-

met. Majdnem minden cikk,amit olvastam, azt javasolja,hogy vezérlőelemeket ne he-lyezzünk el (a wx.panel kivéte-lével) közvetlenül a frame-en.Kattintsunk hát a Tool Frame-ena Containers/Layout fülre, majdpedig a wx.Panel gombra. Utá-na menjünk vissza az új frame-re, amin épp dolgozunk és kat-tintsunk bele valahova. Akkorfogjuk tudni, hogy működött, havalami ilyesmit kapunk:

Emlékszünk még a figyel-meztetésemre a bugokkal kap-csolatban? Nos, ez pont egyilyen eset. De ne aggódjunk!Látjuk a nyolc kis fekete négy-zetet? Ezek jelzik a panel hatá-rait. Ha akarnánk, akkor rájukkattintva át tudnánk méreteznia panelt, azonban most mi aztakarjuk, hogy az egész frame-et befedje a panel. Ehhez egy-szerűen méretezzük át aFRAME-et. Most már van egy pa-nelünk, amire a többi vezérlő-eszközöket pakolhatjuk. Moz-

gassuk a frame-et amin dolgo-zunk úgy, hogy láthassuk azEditor frame eszközsorát. Két újgomb is megjelent: egy pipa ésegy „X”. Az X megnyomásávaleldobhatjuk a változtatásain-kat.

A pipa gomb:amit „Post”-nak hívnak. Meg-nyomásával a változtatásokbeleíródnak a frame fájljába.Még mindig el kell majd mente-nünk azt, de ezzel helyezzük elmagukat az új dolgokat a fájl-ban. Akkor nyomjuk is meg aPost gombot. Van egy másikpost gomb az Inspector frame-en is, de ezzel később fogunkfoglalkozni. Most mentsük el afájt.

Ugorjunk vissza Designmódba. Klikkeljünk a „Buttons”fülre a Tool frame-en, majd azelső gombra balról, ami awx.Button nevet viseli. Helyez-zük el valahol a frame-ünk kö-zepén, hogy valami ilyesmitkapjunk:

Page 22: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 22 tartalom ^

Programozzunk Pythonban - 5. részFigyeljük meg, hogy akár-

csak a panelnél, nyolc kis négy-zet van körülötte. Ezek mérete-ző fogantyúk. Továbbá azt ismegmutatják, hogy melyik ve-zérlőelem van kijelölve éppen.Ahhoz, hogy közelebb vigyük aframe közepéhez, nyomjuk le aControl gombot (Ctrl), és amígaz le van nyomva, használjuk anyíl billentyűket a mozgatásá-hoz. Most nézzük meg az Ins-pector frame-et. Négy fülünkvan. Kattintsunk a „Constr” fül-re. Itt tudjuk megváltoztatni agomb címkéjét, nevét, pozíció-ját, méretét és stílusát. Egyelő-re csak változtassuk meg agomb nevét „btnShowDialog”-ra és a Label property-t (címketulajdonság) „Click Me”-re (Kat-tints Rám).

Most ugorjunk át a fül mara-dékán és menjünk az Objs fülre.Ez a fül mutatja az összes álta-lunk használt vezérlőelemet, il-letve a köztük lévő szülő/gyerek

kapcsolatokat. Mint ahogy lát-hatjuk, a gomb a panel1 leszár-mazottja, ami pedig a Frame1gyereke.

Postoljunk (pipa gomb) ésmentsük el a változtatásokat.Ismét menjünk vissza designernézetbe és figyeljük meg, hogy(feltételezem, hogy még mindigaz „Objs” fül van kiválasztva azinspector frame-en) a Frame1van most kijelölve. Ez jó, mertépp rá lesz szükségünk. Men-jünk vissza a „Constr” fülre ésváltoztassuk meg a „Frame1”címet „Our First GUI”-ra (ElsőGUI-nk). Postoljuk és mentsünkmég egyszer. Futtassuk az al-kalmazást. Nyomjuk meg a sár-ga Run gombot az Editorframe-en.

Ám kattintgathatunk annyi-szor a gombra, amennyiszer jólesik, semmi sem fog történni.Hogy miért? Hát, nem mondtukmeg a gombnak, hogy mit iskellene csinálnia. Ezért kell egyeseményt beregisztrálni, amiakkor aktiválódik, amikor a fel-használó a gombra kattint. Klik-keljünk a frame jobb-felső sar-kában lévő X-re, hogy befejez-zük a frame futtatását. Ezutántérjünk vissza designer nézet-be, válasszuk ki a gombot ésmenjünk az „Evts” fülre az ins-pector frame-n. Kattintsunk aButtonEventre, majd kétszer afelbukkanó wx.EVT_BUTTONszövegre. Vegyük észre, hogyaz alsó ablakban lesz egy „OnB-tnShowDialogButton” nevűgomb eseményünk. Postoljunkés mentsünk.

Mielőtt továbblépnénk, lás-suk, hogy mit is csináltunk kód

szinten (23. oldal).Az első sor egy olyan kom-

ment, ami megmondja a BoaConstructornak, hogy ez egyboa fájl. A Python fordító ezt fi-gyelmen kívül fogja hagyni, dea Boa nem. A következő sor be-importájla a wxPythont. Mostugorjunk le az osztálydefiníció-hoz.

Legfelül van az __init_ctrlmetódus. Láthatjuk, hogy vanegy komment közvetlenül a le-írás sora alatt. Ne szerkesszükaz ebben a részben lévő kódot.Ha ezt tennénk, akkor későbbmegbánnánk. De bárhol ALATTAmár biztonságos. Ebben aszubrutinban található a frame-ünk összes vezérlőeleménekleírása.

Most nézzük meg az __init__metódust. Ide tetszőleges inici-alizációs kódot helyezhetünk el.Végezetül az OnBtnShowDia-logButton függvényt vizsgáljukmeg. Ide fogjuk beírni azt a kó-dot, ami akkor hajtódik végre,amikor a felhasználó a gombrakattint. Láthatjuk, hogy egyelő-re ez egy event.Skip() sort tar-talmaz. Egyszerűen megfogal-mazva, ezzel a paranccsal lé-pünk ki, amikor az eseményaktiválódik.

Page 23: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 23 tartalom ^

Greg Walters a RainyDaySolutions LLC tulajdonosa, amelyegy tanácsadó cég Aurorában,Coloradóban, Greg pedig 1972óta foglalkozik programozással.Szeret főzni, túrázni, zenéthallgatni, valamint a családjávaltölteni a szabadidejét.

Most pedig létre fogunk hoz-ni egy felugró ablakot valami-lyen szöveggel. Ez egy eléggyakori módja annak, hogy aprogramozó valamilyen infor-mációt közöljön a felhasználó-val - akár egy hibaüzenetet,vagy a folyamat befejeződésé-nek tényét. Mi a wx.Message-Box beépített függvényt fogjukmeghívni. Ennek a függvény-nek két paramétere van. Az el-ső az ablak által közlendő üze-net, a második az ablak címe.Kommenteljük ki az event.Skip()-et és helyezzük el a következősort:wx.MessageBox('You Clicked

the button', 'Info')

Mentsünk és kattintsunk afuttatás gombra (sárga nyíl).Valami ilyesmit kellene látnunk:

A kattintás után pedig:

Jó ha tudjuk, hogy eza legpuritánabb módjaegy felbukkanó ablaklétrehozásának. Mégnéhány egyéb paramé-tert is megadhatnánkneki.

Itt van egy rövidkeösszefoglaló arról, hogyhogyan lehet megvál-toztatni az ablak ikonjá-nak kinézetét (többrőlmajd a következő alka-lommal lesz szó).wx.ICON_QUESTION -egy kérdőjel ikon muta-tásawx.ICON_EXCLAMATI-ON - figyelmeztetésikon kirakásawx.ICON_ERROR - hiba ikonmutatásawx.ICON_INFORMATION - infoikon kirajzolása

Ekkor a függvényhívást ígyfogalmazhatnánk meg:wx.MessageBox('You Clicked

the button', 'Info',

wx.ICON_INFORMATION)

vagy valami hasonló módon,attól függően, hogy milyenikont akarnánk megjeleníteni.Vannak még továbbá különfélegombelrendezések, amirőlmajd a következő alkalommallesz szó.

Addig is játszadozzatokel a különböző vezérlőele-mekkel és azok elhelyezé-sével. Jó szórakozást!

#Boa:Frame:Frame1

import wx

def create(parent):

return Frame1(parent)

[wxID_FRAME1, wxID_FRAME1BTNSHOWDIALOG, wxID_FRAME1PANEL1,

] = [wx.NewId() for _init_ctrls in range(3)]

class Frame1(wx.Frame):

def _init_ctrls(self, prnt):

# generated method, don't edit

wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,

pos=wx.Point(543, 330), size=wx.Size(458, 253),

style=wx.DEFAULT_FRAME_STYLE, title=u'Our First GUI')

self.SetClientSize(wx.Size(458, 253))

self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,

pos=wx.Point(0, 0), size=wx.Size(458, 253),

style=wx.TAB_TRAVERSAL)

self.btnShowDialog = wx.Button(id=wxID_FRAME1BTNSHOWDIALOG,

label=u'Click Me', name=u'btnShowDialog', parent=self.panel1,

pos=wx.Point(185, 99), size=wx.Size(85, 32), style=0)

self.btnShowDialog.Bind(wx.EVT_BUTTON, self.OnBtnShowDialogButton,

id=wxID_FRAME1BTNSHOWDIALOG)

def __init__(self, parent):

self._init_ctrls(parent)

def OnBtnShowDialogButton(self, event):

event.Skip()

Programozzunk Pythonban - 5. rész

Page 24: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 24 tartalom ^

HogyanokÍrta: Greg Walters

Programozzunk Pythonban - 6. rész

ELŐZŐ SZÁMOK:FCM 27-31. számPython 1-5. részITT HASZNÁLHATÓ:

KATEGÓRIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/média Rendszer

MerevlemezCD/DVD USBEszköz Laptop VezetéknélküliRemélem, hogy leg-

utóbbi találkozásunkóta eljátszadoztatok aBoa Constructorral.

Először egy igen egyszerű prog-rammal fogunk foglalkozni, amiegy frame-et rajzol ki, melyenegy gomb megnyomásával meglehet jeleníteni egy másikat.Előző alkalommal ezt egy üze-nőablakkal csináltuk. Most teje-sen különálló frame-et készí-tünk. Ez akkor hasznos, amikorolyan alkalmazást készítünk,ami több frame-mel és ablakkaldolgozik. Csapjunk is a lovak

közé!Indítsuk el a Boa Construc-

tort és az Editor ablakban aShell és az Explorer kivételévelzárjunk be minden fület a (Ctrl-W) billenytűkombinációt hasz-nálva. Ezzel biztosítjuk, hogytiszta lappal kezdjünk. Mosthozzunk létre egy új projektet awx.App gombra való kattintás-sal (lásd az előző cikket, haszükséges).

Mielőtt bármi mást csinál-nánk, mentsük el a Frame1-et„FrameMain.py”-ként , illetve azApp1-et „Gui2.py”-ként. Ez na-gyon fontos. Mialatt a GUI2 fülvan kijelölve az Editorban,menjünk vissza a Toolbar ablakNew fülére, és adjunk még egyframe-et a projectünkhöz awx.Frame-re való kattintással(közvetlenül a wx.App gombmellett). Bizonyosodjunk megarról, hogy az Application fülModule oszlopában mindkétframe látszik. Most ugorjunkvissza az új frame-re és ment-sük el „FrameSecond.py”-ként.

Ezután nyissuk meg a Fra-meMaint a tervezőben. Adjunkegy wx.Panelt a frame-hez. Mé-

retezzük úgy, hogy lefedje aframe-et. Ezután megváltozta-tunk néhány beállítást – ezzelnem foglalkoztunk múltkor. Azinspector ablakban ellenőrizzük,hogy a Constr fül van kiválaszt-va és állítsuk a címet (title) „MainFrame”-re, majd a nevet (name)„FrameMain”-re. Hamarosan azelnevezési konvenciókra is kifogunk térni. A Size jelölődo-bozra való kattintással állítsuka méretet (size) 400x340-re. Ezle fog nyílni, hogy megmutassaa magasság és szélesség érté-keket. A magasságnak 400-nak,a szélességnek 340-nek kelllennie:

Most kattintsunk a Props fül-re. Klikkeljünk a Centered (kö-zépre igazított) tulajdonságra,és állítsuk azt wx.BOTH-ra.Nyomjuk meg a post pipa-jelét,majd mentsük munkánkat.Most futtassuk az alkalmazá-sunkat a sárga nyílra való katti-tással. A képernyőnk közepénmegjelenik a „Main Frame” ne-vű programunk. Most zárjuk beaz alkalmazást a jobb-felső sar-kában lévő „X” gombra valókattintással.

Hozzuk vissza a tervező né-zetbe a FrameMaint-t. Helyez-zünk el két wx.Buttont, egyiketa másik fölé rakva valahol aframe közepén. Válasszuk ki afelső gombot, nevezzük ezt„btnShowNew”-nak és állítsuk acímkéjét (label) az Inspectorablak Constr fülén „Show theother frame”-re. Méretezzük áta gombot a Shift+Nyilak billen-tyűkombinációval úgy, hogy azegész szöveg látszódjon, majdhasználjuk a Ctrl+Nyilak kom-binációt ahhoz, hogy visszavi-gyük a frame közepére. Válasz-szuk ki az alsó gombot és ne-

Page 25: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 25 tartalom ^

Programozzunk Pythonban - 6. részvezzük el „btnExit”-nek, a cím-kéje pedig legyen „Exit”. Pos-toljuk, mentsünk és futtasuk aprogramot a változtatások ki-próbálásához. Lépjünk ki ésmenjünk vissza a tervező né-zetbe. Most a gombnyomáskoraktiválódó eseményeket fogjukbeállítani. Válasszuk ki a felsőgombot, illetve az inspector ab-lakban az Evts fület. Kattint-sunk a ButtonEventre, majdkétszer a wx.Evt_BUTTON-ra.Vegyük észre, hogy az „OnB-tnShowNewButton” lent feltű-nik. Utána válasszuk ki abtnExit gombot. Csináljukugyanazt, mint előbb és bizo-nyosodjunk meg róla, hogy az„OnBtnExitButton”-t mutat.Postoljuk és mentsünk. Mostmenjünk az Editor ablakba ésgörgessunk le az aljáig.

Ellenőrizzük, hogy mindkétlétrehozott eseménymetódusmegvan-e. Eddig valahogy ígykellene kinéznie az ablaknak:

Itt az idő, hogy foglalkozzunka másik frame-ünkkel is. Nyis-suk meg a „FrameSecond”-öttervező nézetben. Állítsuk a ne-vét „FrameSecond”-re, a címétmeg „Second Frame”-re. Mind-kettőnél állítsuk a centeringetwx.BOTH-ra. Helyezzünk el egywx.Buttont valahova a frame alsófelébe. A neve legyen „btnFSE-xit” és a címe „Exit”. Állítsuk bea gomb eseményét is. Követke-zőnek tegyünk még egy wx.Sta-ticTextet a frame felső-középrészére. Nevezzük ezt „stHiThe-re”-re, a címet meg „Hi there...I'm the second form!”-ra, a be-tűtípust tegyük 14 pont magaswx.BOLD Sans-ra. Most állítsukvissza a pozícióját úgy, hogyjobbról és balról középre legyenigazítva. Ezt a Position (pozíció)tulajdonság kikapcsolásávaltudjuk megtenni, használjuk azX pozíciót a jobb és bal, az Y-t afent és lent értékek megadásá-hoz, amíg kielégítő eredménytnem érünk el. Postoljunk ésmentsünk.

Mivel az ablakaink készenvannak, már csak össze kellenevalahogy „ragasztani” őket.

Az Editor ablaban kattint-sunk a GUI2 fülre, majd ez alatta Source fülre. Az „import Fra-meMain” sor alá helyezzük el az„import FrameSecond” paran-csot. Mentsük el a változásokat.Ezután válasszuk ki a „Frame-Main” fület. Az „import wx” sorután helyezzük el megint az „im-port FrameSecond” utasítást.Most görgessünk le egészenaddig, amíg meg nem látjuk a„def __init__(self,parent):” tartal-mú sort. Helyezzünk el a„self.__init__ctrls(parent)” soralá a „self.Fs = FrameSecond.FrameSecond(self)” sort. A „defOnBtnShowNewButton(self,event):” eseménynél kommen-teljük ki az „event.Skip()” hí-vást, és írjuk be az alábbi kétsort:self.Fs.Show()

self.Hide()

Végezetül, az „OnBtnExitBut-ton” metódusnál is kommentel-jük ki az „event.Skip()”-et, éshelyezzük el a „self.Close()”-t.

De mire volt jó mindez?

Rendben. Amit először csinál-tunk, az az volt, hogy megis-mertettük az alkalmazásunkkalaz általunk használni kívánt ab-lakokat. Ezért importáltuk bemind a FrameMaint és a Frame-Secondöt a GUI2 fájlba. Ezutána FrameSecond referenciáját aFrameMainbe is beimportáltuk,mivel majd később itt akarunkhivatkozni rá. Inicializáltuk az„_init_” metódust. Az „OnBtnShowNewButton” eseménynekmegadtuk, hogy amikor a gom-bot megnyomjuk, először megszeretnénk jeleníteni a másodikablakot, majd eltüntetni az el-sőt. Legutoljára az alkalmazástbezáró parancsot helyeztük elaz Exit gomb megnyomásához.

Most váltsunk át a FrameSe-cond kódjára. A változtatásokitt viszonylag kicsik voltak. Az„_init_” metódusba beírt „self.parent = parent” sor egy self.parent változót hozott létre.Végezetül, az FSExitButton ese-ménynél is kommenteljük ki az„event.Skip()” sort, és helyez-zük el az alábbi két sort:self.parent.Show()

self.Hide()

Emlékezzünk arra, hogy mi-

Page 26: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 26 tartalom ^

Programozzunk Pythonban - 6. részvel elrejtettük az első ablakot,amikor megjelenítettük a má-sodikat, ezért azt újra meg kelljeleníteni. Végül a másodikat isel kell rejtenünk. Mentsük el aváltozásokat.

Itt van ellenőrzésképpen ateljes kód (ez az oldal és azutána lévő):

Most már futtathatjuk az al-kalmazásunkat. Ha mindenrendben ment, akkor rá tudunkkattintani a btnShowNew-ra ésláthatjuk, ahogy az első ablakeltűnik és a második megjele-nik. Az Exit gombra való kattin-tás eltünteti az ablakot és újramegjeleníti az elsőt. Ha a főablakban kattintunk az Exit

GUI2 code:

#!/usr/bin/env python

#Boa:App:BoaApp

import wx

import FrameMain

import FrameSecond

modules ={u'FrameMain': [1, 'Main frame of Application',

u'FrameMain.py'],

u'FrameSecond': [0, '', u'FrameSecond.py']}

class BoaApp(wx.App):

def OnInit(self):

self.main = FrameMain.create(None)

self.main.Show()

self.SetTopWindow(self.main)

return True

def main():

application = BoaApp(0)

application.MainLoop()

if __name__ == '__main__':

main()

FrameMain code:

#Boa:Frame:FrameMain

import wx

import FrameSecond

def create(parent):

return FrameMain(parent)

[wxID_FRAMEMAIN, wxID_FRAMEMAINBTNEXIT,

wxID_FRAMEMAINBTNSHOWNEW,

wxID_FRAMEMAINPANEL1,

] = [wx.NewId() for _init_ctrls in range(4)]

class FrameMain(wx.Frame):

def _init_ctrls(self, prnt):

# generated method, don't edit

wx.Frame.__init__(self, id=wxID_FRAMEMAIN,

name=u'FrameMain',

parent=prnt, pos=wx.Point(846, 177),

size=wx.Size(400, 340),

style=wx.DEFAULT_FRAME_STYLE, title=u'Main

Frame')

self.SetClientSize(wx.Size(400, 340))

self.Center(wx.BOTH)

self.panel1 = wx.Panel(id=wxID_FRAMEMAINPANEL1,

name='panel1',

parent=self, pos=wx.Point(0, 0),

size=wx.Size(400, 340),

style=wx.TAB_TRAVERSAL)

self.btnShowNew =

wx.Button(id=wxID_FRAMEMAINBTNSHOWNEW,

label=u'Show the other frame',

name=u'btnShowNew',

parent=self.panel1, pos=wx.Point(120, 103),

size=wx.Size(168, 29),

style=0)

self.btnShowNew.SetBackgroundColour(wx.Colour(25,

175, 23))

self.btnShowNew.Bind(wx.EVT_BUTTON,

self.OnBtnShowNewButton,

id=wxID_FRAMEMAINBTNSHOWNEW)

Page 27: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 27 tartalom ^

Programozzunk Pythonban - 6. rész

FrameMain Code (cont.):self.btnExit =

wx.Button(id=wxID_FRAMEMAINBTNEXIT, label=u'Exit',

name=u'btnExit', parent=self.panel1,

pos=wx.Point(162, 191),

size=wx.Size(85, 29), style=0)

self.btnExit.SetBackgroundColour(wx.Colour(225,

218, 91))

self.btnExit.Bind(wx.EVT_BUTTON,

self.OnBtnExitButton,

id=wxID_FRAMEMAINBTNEXIT)

def __init__(self, parent):

self._init_ctrls(parent)

self.Fs = FrameSecond.FrameSecond(self)

def OnBtnShowNewButton(self, event):

#event.Skip()

self.Fs.Show()

self.Hide()

def OnBtnExitButton(self, event):

#event.Skip()

self.Close()

FrameSecond code:#Boa:Frame:FrameSecond

import wx

def create(parent):

return FrameSecond(parent)

[wxID_FRAMESECOND, wxID_FRAMESECONDBTNFSEXIT,

wxID_FRAMESECONDPANEL1,

wxID_FRAMESECONDSTATICTEXT1,

] = [wx.NewId() for _init_ctrls in range(4)]

class FrameSecond(wx.Frame):

def _init_ctrls(self, prnt):

# generated method, don't edit

wx.Frame.__init__(self, id=wxID_FRAMESECOND,

name=u'FrameSecond',

parent=prnt, pos=wx.Point(849, 457),

size=wx.Size(419, 236),

style=wx.DEFAULT_FRAME_STYLE, title=u'Second

Frame')

self.SetClientSize(wx.Size(419, 236))

self.Center(wx.BOTH)

self.SetBackgroundStyle(wx.BG_STYLE_COLOUR)

self.panel1 = wx.Panel(id=wxID_FRAMESECONDPANEL1,

name='panel1',

parent=self, pos=wx.Point(0, 0),

size=wx.Size(419, 236),

style=wx.TAB_TRAVERSAL)

self.btnFSExit =

wx.Button(id=wxID_FRAMESECONDBTNFSEXIT, label=u'Exit',

name=u'btnFSExit', parent=self.panel1,

pos=wx.Point(174, 180),

size=wx.Size(85, 29), style=0)

self.btnFSExit.Bind(wx.EVT_BUTTON,

self.OnBtnFSExitButton,

id=wxID_FRAMESECONDBTNFSEXIT)

self.staticText1 =

wx.StaticText(id=wxID_FRAMESECONDSTATICTEXT1,

label=u"Hi there...I'm the second form!",

name='staticText1',

parent=self.panel1, pos=wx.Point(45, 49),

size=wx.Size(336, 23),

style=0)

self.staticText1.SetFont(wx.Font(14, wx.SWISS,

wx.NORMAL, wx.BOLD,

False, u'Sans'))

def __init__(self, parent):

self._init_ctrls(parent)

self.parent = parent

def OnBtnFSExitButton(self, event):

#event.Skip()

self.parent.Show()

self.Hide()

Page 28: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 28 tartalom ^

Greg Walters a RainyDaySolutions tulajdonosa, ez egykorlátolt felelősségű tanácsadócég a coloradoi Aurorában.Programozással 1972 ótafoglalkozik. Szeret főzni, túrázni,zenét hallgatni és szabadidejétcsaládja körében eltölteni.

Programozzunk Pythonban - 6. részgombra, akkor bezárjuk az al-kalmazást.

Megígértem, hogy megtár-gyaljuk az elnevezési konvenci-ókat. Emlékszünk még, hogyvalamikor régen beszéltem akód kommentelésről? Nos, jólmegfogalmazott GUI vezérlő-elemnevek használatával a kó-dunk éppen eléggé öndoku-mentáló lesz.

Ha staticText1, button1 vagyhasonló neveket használtunkvolna, akkor egy összetettebbablak létrehozásakor - melyrengeteg vezérlőelemet tartal-maz, kiváltképpen sok szöveg-dobozt és gombot - sok prob-lémánk adódhatott volna. Ilyenesetben a megfelelő jelentésűelnevezés igen fontos. Talánnem annyira lényeges, ha tevagy az egyetlen, aki valaha islátni fogja a kódot, de ha eset-leg valaki majd átveszi, akkor ajó elnevezés sokat fogja segíte-ni a munkáját. Éppen ezért,használjunk valami ilyesmit:Control type ­ névprefix

Statikus szöveg ­ st_

Gomb ­ btn_

Szövegdoboz ­ txt_

Jelölo”doboz ­ chk_

Rádió gomb ­ rb_

Frame ­ Frm_ vagy Frame_

Ahogy fejlődünk a progra-mozás terén, kitalálhatjuk a sa-ját elnevezési szabályainkat is,és néhány esetben a munkahe-lyeden meg is szabják azokathelyetted.

Következő alkalommal félre-tesszük a GUI programozástegy kicsit, és az adatbázisokrafogunk koncentrálni. Addig is,tegyétek fel a python-apsw-t ésa python-mysqldb-t a rendsze-retekre. Továbbá szükségünklesz az SQLite-unkhoz az sqlite-ra és az sqlitebrowser-re. Haszeretnétek a MySql-lel is kí-sérletezni, akkor az is elérhetőa Synaptic-ból.

Rédei RichárdRédei Richárd

Page 29: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 29 tartalom ^

HogyanokÍrta: Greg Walters

Programozzunk Pythonban - 7. rész

ELŐZŐ SZÁMOK:FCM 27-32. számPython - 1-6. részITT HASZNÁLHATÓ:

KATEGÓORIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/media Rendszer

MerevlemezCD/DVD USB Eszköz Laptop Vezetéknélküli

Jó reggelt fiúk-lányok! Meseidő van. Mindenki helyezzekényelembe magát. Készenálltok? Rendben!

Egyszer régen a világot a pa-pír uralta. Mindenhol papír éspapír. Még saját otthonokat iskészíteni kellett a papíroknak.Ezeket hívtuk kartotékszekré-nyeknek, melyek nagy, terme-ket, termeket és termeket felö-lelő fém dolgok voltak az üzletiéletben a papírok eltárolásához.Minden kartotékszekrényben

volt egy mappa, amivel a fon-tos papírokat próbálták össze-fogni. Egy idő után túltöltődtekés szétestek, mivel már nagyonrégiek voltak, vagy sokszor nyi-tották ki őket.

Ezeknek a kartotékszekré-nyeknek a használatához főis-kolai végzettség kellett. Napokkellettek ahhoz, hogy megtalál-junk minden papírt a különbözőszekrényekben. Az üzlet iszo-nyúan meg is szenvedte. Ezegy nagyon sötét időszaka voltaz emberiségnek.

Ekkor egy nap, valahonnan ahegy tetejéről (személyszerintúgy gondolom, hogy Colorádó-ból, de ebben nem vagyok biz-tos) előjött egy bájos tündér. Eza tündér kék és ezüst színű volt- 35 centiméter magas, csoda-szép szárnyakkal és fehér haj-jal. A neve, hiszed vagy sem,Szíkvill volt. Hát nem egy vic-ces kis név? Mindenesetre,Szíkvill azt ígérte, hogy megoldminden problémát, amit azösszes papír, kartoték és elpo-csékolt idő okozott, azzal az

egy feltétellel, ha az emberekbíznak majd a számítógépek-ben és benne. Ezt a hatalmat Ő„Adatbázisoknak” nevezte. Aztmondta, hogy az „Adatbázis”az egész kartotékrendszert letudja váltani. Néhányan hittekbenne és hamarosan boldogéletük lett. Azonban voltakolyanok akik nem és számukraminden nap ugyanolyan papír-hegyekben kutakodós maradt.

Azonban minden tündérígé-ret valamilyen feltétellel jár. Eza feltétel az volt, hogy minden-ki, aki Szíkvill bűbáját akartahasználni, meg kellett tanulnjonegy kicsit egy másik nyelvből.Nem lenne túl nehezen tanul-ható nyelv. Ami azt illeti, na-gyon hasonló volt ahhoz, amitaz emberek eddig is használtak.Egyszerűen csak máshogy lehetrajta kifejezni magunkat, ésigencsak el kellett gondolkodnia dolgokon, MIELŐTT kimond-tad őket ahhoz, hogy Szíkvill va-rázsa hasson.

Egy nap egy fiatal fiú, akitérdekes módon Felhasználónak

hívtak, eljött, hogy csodájárajárjon Szíkvillnek. Teljesen el-bűvölte szépsége és azt mond-ta: „Szíkvill, kérlek taníts megaz erőd használatára”. MireSzíkvill megígérte, hogy meg-teszi. Szíkvill ezután így szólt:„Először ismerned kell az infor-mációid szerkezetét. Mutasdmeg a papírjaidat.”

Mivel Felhasználó még igenfiatal volt, ezért csak néhánydarab papírt birtokolt. Szíkvillerre azt mondta: „Felhasználó,jelenleg még el tudsz éldegélnipapírokkal és kartotékokkal, delátom, hogy a jövőben olyansok papírod lesz, hogy ha egy-más tetejére raknánk őket, ak-kor 15-ször magasabb lenne,mint te vagy. Használjuk hát avarázserőmet.”

Így történt hát, hogy Fel-használó és Szíkvill megalkottaaz „adatbázis bigyót” (ami egytündér szakkifejezés), és Fel-használó boldogan élt, amígmeg nem halt.

Itt a vége, fuss el véle.

Page 30: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 30 tartalom ^

Programozzunk Pythonban - 7. részTermészetesen a történet

teljes egészében nem igaz.Mindazonáltal az adatbázisokés az SQL használata könnyeb-bé teheti az életünket. Ez alka-lommal egy kis SQL lekérdezés-ről tanulunk, illetve arról, hogyhogyan használjuk őket a prog-ramokban. Néhány ember úgygondolhatná, hogy ez nem tel-jesen a „legkorrektebb” vagy„legjobb” módszer, de ennekellenére nagyon is elfogatható.Kezdjük hát el.

Az adatbázisok olyasmik,mint a kartotékszekrényeink afenti történetben. Az adattáblákolyanok, mint a mappák. Azgyes bejegyzések (avagy rekor-dok) pedig hasonlóak a papírla-pokhoz. Minden egyes informáci-ódarabot mezőnek nevezünk.Igen egybevágóak, igaz? AzSQL (amit Szíkvillnek ejtünk)utasításokat használjuk az ada-tok manipulálására. Az SQL ma-ga a Structured Query Language(struktúrált lekérdező nyelv) rö-vidítése és alapjaiban véve azadatbázisok egyszerű használa-tára találták ki. A gyakolatbanazonban igen bonyolulttá vál-hat. Ebben a részben csak egy-szerű dolgokkal fogunk foglal-kozni.

Először is szügségünk vanegy tervre, ugyanúgy, mint egyépítkezés kezdetén. Gondoljunkmost receptkártyákra, melyenazért jó elmélkedni, mivel egyreceptadatbázis-programot fo-gunk készíteni. Az én házam tá-ján a receptek különböző for-mában vannak jelen: 3x5-öskártya, 8x10-es papírdarab,szalvétán lévő irka-firka, maga-zinból való lapok, és még ennélis különösebb dolgok. Mindezekkönyvekben, dobozokban, köte-gekben és hasonló helyeken ta-lálhatóak meg. Ennek ellenérelegtöbbször van egy közös tu-lajdonságuk: a formátumuk. Alegtöbb esetben a felső részenvan a recept neve és talán az,hogy hány személyre való, illet-ve, hogy honnan származik. Aközépső rész tartalmazza a hoz-závalók listáját, a legalsó pedigaz elkészítéséhez tartozó utasí-tásokat - az egyes műveleteksorrendje, az elkészítés ideje ésígy tovább. Ezt az általános for-mátumot fogjuk sablonkénthasználni az adatbázis projek-tünkben. Először is, két részrefogjuk osztani a dolgokat. Azadatbázist most fogjuk elkészí-teni, az alkalmazást, ami olvas-ni és frissíteni fogja, a követke-ző alkalommal.

Itt egy példa. Tegyük fel,hogy a jobbra lévő recep-tünk van.

Vegyük észre a sorren-det, amiről az előbb be-széltünk. Most mikor azadatbázisunkat tervezzük,nagyon nagyot is készít-hetnénk és lehetne egy kü-lön rekordja minden recept-nek. Ez azonban kimondot-tan esetlen és nehezen ke-zelhető lenne. Éppen ezért,a receptkártyákat fogjuksablonként használni. Egytábla a kártya felső részétfogja kezelni, azaz az álta-lános információkat a re-ceptről, egy másik tábla akártya közepét fogja tárol-ni, avagy a hozzávalókat,és egy megint másik az al-só rész, ami az instrukciók-nak felel meg.

Bizonyosodjunk meg ró-la, hogy az SQLite és azAPSW fel vannak telepítvegépünkre. Az SQLite egyapró adatbáziskezelő mo-tor, mely nem követelimeg, hogy egy külön adat-bázisszerverünk legyen,éppen ez teszi ideálissá az al-kalmazásunk számára.

Spanyol rizs

Adagok: 4Forrás: Greg WaltersHozzávalók:1 bögre opál rizs1 font hamburgerhús2 bögre víz1 8 unciás sűrített paradicsom1 kicsi darabolt hagyma1 gerezd darabolt fokhagyma1 kanál őrölt kömény1 kiskanál őrölt oreganosó és paprika ízlés szerintSalsa ízlés szerintIInnssttrruukkcciióókk::Süssük barnára a hamburgerhúst.Addjuk hozzá az összes alap-anyagot.Forraljuk fel.Keverjük, kis lángon főzzük ésfedjük le.Húsz percig főzzük.Ne nézegessük és ne nyúljunkhozzá.Kavarjuk meg és szolgáljuk fel.

Page 31: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 31 tartalom ^

Programozzunk Pythonban - 7. részMinden, amit itt tanulsz, fel-

használható nagyobb adatbá-zisrendszereknél is, mint ami-lyen a MySQL és a többiek. Amásik jó dolog az SQLite-ban,hogy előre meghatározott adat-típusokat használ. Ezek a Text(szöveg), Numeric (szám), Blobés Integer Primary Key (egészértékű elsődleges kulcs). Mintahogy azt már korábban meg-tanultuk, szöveg gyakorlatilagbármi lehet. A hozzávalóink, azinstrukcióink és a receptünk cí-me mind szöveg típusú - mégannak ellenére is, hogy számo-kat tartalmazhatnak. A numeri-kus adattípusok számokat tárol-nak. Ezek lehetnek egészek, le-begőpontosak vagy valós érté-kűek. A Blob-ok bináris adatok,melyekben képeket és hasonlódolgokat lehet eltárolni. Az e-gészértékű elsődleges kulcs kü-lönleges. Az SQLite adatbázis-motor mindig automatikusanegy egyedi egész értéket gene-rál számunkra. Ez a későbbiekfolyamán fontos lesz. Az APSWaz Another Python SQLiteWrapper-ből (Másik Python SQ-Lite Csomag) ered, egy gyorsmódszere az SQLite-tal valókommunikációnak. Most fussukát az SQL utasítások létrehozá-sának néhány lehetőségét.

Ahhoz, hogy rekordokat tud-junk kiolvasni az adatbázisból,a SELECT utasítást kell használ-nunk. A szerkezete így néz ki:SELECT [mit] FROM [melyik

táblá(k)ból] WHERE [megszorítá­

sok]

Tehát, ha minden mezőt kiszeretnénk olvasni a Recipes(receptek) táblából, akkor a kö-vetkezőt írnánk:SELECT * FROM Recipes

Ha csak az elsődleges kulcsalapján akarunk egy rekordotkiolvasni, akkor tudnunk kell miaz értéke (ebben az esetben apkID értékéről van szó) és aWHERE parancsot is bele kellrakni az utasításba. Használjukezt:SELECT * FROM REcipes WHERE

pkID = 2

Egyszerű... igaz? Igen vilá-gos egy nyelv. Tegyük fel, hogymost csak a recept nevére (na-me), illetve az adagok számára(serving) van szügségünk, min-den receptből. Könnyű. Mind-össze csak annyit kell csinál-nunk, hogy megadjuk azokat amezőket, amiket a SELECT uta-

sítással le akarunk kérdezni:SELECT name, servings FROM

Recipes

Ahhoz, hogy rekordokat szúr-junk be, az INSERT INTO utasí-tást használjuk. Szintaxisa:INSERT INTO [tábla neve] (me­

zolista) VALUES (beszúrandó

értékek)

Tehát ahhoz, hogy egy re-ceptet adjunk hozzá a recepttáblához, az alábbi parancsothasználhatnánk:INSERT INTO Recipes

(name,servings,source) VALUES

("Tacos",4,"Greg")

Rekordok törléséhez ezthasználhatjuk:DELETE FROM Recipes WHERE

pkID = 10

Van még egy UPDATE utasí-tás is, de ezt egy másik alka-lomra hagyom.Még több a SELECT-rol

Adatbázisunknak három táb-lája lesz, mindegyik a recipeIDhasználatával kapcsolódik egy-

máshoz, mely a recipe táblapkID-jére mutat. Tegyük fel,hogy meg szeretnénk szerezniegy adott recept összes inst-rukcióját. Ezt így tehetjük meg:SELECT Recipes.name, Reci­

pes.servings, Recipes.source,

Instructions.Instructions

FROM Recipes LEFT JOIN inst­

ructions ON (Recipes.pkid =

Instructions.recipeid) WHERE

Recipes.pkid = 1

De ez nagyon sok gépelésselés redundanciával jár. Ehelyetthasználhatjuk a helyettesítés-nek nevezett technikát. Ezt ígycsinálhatjuk:SELECT r.name, r.servings,

r.source, i.Instructions FROM

Recipes r LEFT JOIN instruc­

tions i ON (r.pkid = i.reci­

peid) WHERE r.pkid = 1

Így rövidebb és olvashatóbblett a lekérdezés. Most egyolyan aprócska programot fo-gunk készíteni, ami létrehozzaaz adatbázisunkat, megcsináljaa tábláinkat, és néhány egy-szerű adattal feltölti azokat,hogy legyen mivel dolgoznunk.Beleírhatnánk a teljes progra-munkba, de - a példa kedvéért -egy különálló alkalmazást fogunkkészíteni. Ez egy egyetlen futásra

Page 32: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 32 tartalom ^

Programozzunk Pythonban - 7. résztervezett program - ha másod-jára is elindítanánk, akkor atáblalétrehozó utasításnál hibá-ba ütközne. Befoglalhatnánkegy try...catch blokkba is, deezt majd a következő alkalom-mal tesszük.

Először beimportáljuk azAPSW-t.import apsw

Majd létre kell hoznunk egykapcsolatot az adatbázisunkkal.Ugyanabban a könyvtárbanlesz elérhető, amiben a progra-munk is van. Amikor létrehoz-zuk a kapcsolatot, az SQLiteautomatikusan meg fogja néz-ni, hogy létezik-e az adatbázis.Ha létezik, megnyitja. Ha nem,akkor pedig létrehozza azt.Amikor van már egy kapcsola-tunk, szükségünk lesz egy cur-sornak (mutató) nevezett do-logra. Ez egy olyan konstrukció,amit az adatbázissal való mun-kához használhatunk. Amit megkell jegyezni, az az, hogy egykapcsolatra és egy cursorra vanszügségünk. Ezeket így hozzuklétre:# Opening/creating database

connection=apsw.Connecti­

on("cookbook1.db3")

cursor=connection.cursor()

Rendben - megvan a kapcso-latunk és a cursorunk. Most egytáblát kellene létrehozni. Össze-sen három tábla lesz az alkal-mazásban. Egy az általános re-ceptinformációknak, egy az in-strukcióknak és egy a hozzáva-lók listájának. Azonban miértnem használunk mindenhezegyetlen táblát? Hát, lehetne,de ahogy látni fogjuk, így túlnagy lenne és sok azonos infor-mációt tartalmazna.

A tábla szerkezetét így is eltudnánk képzelni. Minden osz-lop egy külön tábla, mint ahogyazt a fent látható ábra is mutat-ja.

Minden táblának van egypkID nevű mezője. Ez lesz az el-sődleges kulcs, ami mindentáblában egyedi. Ez fontos, mi-

vel így az adattáblákban sohanem lesznek teljesen ugyano-lyan rekordok. Ez egy egész ér-tékű adattípus és automatiku-san kiosztja az adatbázisrend-szer. De kell ez nekünk? Igenkell, mert megvan annak azesélye, hogy ugyanazt a re-kordazonosítót kétszer hozzuklétre. Az Recipes tábla esetébenezt a számot arra fogjuk hasz-nálni, hogy beazonosítsuk azegyes receptek instrukcióit éshozzávalóit.

Először az adatbázis recepttáblájába fogjuk beszúrni azétel nevét, forrását és adagját.A pkID automatikusan ki leszosztva. A példa kedvéért te-gyünk úgy, mintha ez lenne alegelső rekord adatbázisunk-ban, tehát az adatbáziskezelőaz 1 értéket adná a pkID-nek.Ezt az értéket fogjuk használnia többi információ összekapcso-lására az adott receptnél. Az in-strukciók táblája nagyon egy-

szerű. Csak az elkészítési uta-sítások hosszú szövegét fogjatartalmazni, meg a saját pkID-jét, ami a recipe táblában lévőreceptre mutat. A hozzávalóktábla egy kicsit bonyolultabbannyiban, hogy minden hozzá-valónak egy külön rekordja vana saját pkID-je mellett, ami me-gintcsak a recipe táblára mutatvissza.

Tehát, a recipe tábla létreho-zásához először egy sql azono-sítójú string változót kell defini-álnunk, amihez a tábla létreho-zása utasítást rendeljük hozzá:sql = 'CREATE TABLE Recipes

(pkiD INTEGER PRIMARY KEY,

name TEXT, servings TEXT,

source TEXT)'

Ezután meg kell mondani azASPW-nek, hogy hajtsa végre azutasítást:cursor.execute(sql)

RECIPES INSTRUCTIONS INGREDIENTS

­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

pkID (Integer Primary Key) pkID(Integer Primary Key) pkID (Integer Primary Key)

name (Text) recipeID (Integer) recipeID (Integer)

source (Text) instructions (Text) ingredients (Text)

serves (Text)

Page 33: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 33 tartalom ^

Greg Walters a RainyDaySolutions tulajdonosa, ez egykorlátolt felelősségű tanácsadócég a colorado-i Aurorában.Programozással 1972 ótafoglalkozik. Szeret főzni, túrázni,zenét hallgatni és szabadidejétcsaládja körében eltölteni.

Programozzunk Pythonban - 7. részMost létrehozzuk a táblákat:

sql = 'CREATE TABLE Instruc­

tions (pkID INTEGER PRIMARY

KEY, instructions TEXT, reci­

peID NUMERIC)'

cursor.execute(sql)

sql = 'CREATE TABLE Ingredi­

ents (pkID INTEGER PRIMARY

KEY, ingredients TEXT, reci­

peID NUMERIC)'

cursor.execute(sql)

Amint létrejöttek a táblák, azINSERT INTO utasítást fogjukhasználni, hogy minden adatota megfelelő táblába felvigyünk.

Emlékezzünk arra, hogy apkID automatikusan be lesz ír-va számunkra, ezért nem vesz-szük bele az insert utasításba.Mivel mezőneveket fogunkhasználni, ezért tetszőlegessorrendben lehetnek, nem csakabban a sorrendben, amiben lét-rehoztuk őket. Mindaddig, amígtudjuk a mezők neveit, mindenhelyesen fog működni. A recipetábla insert utasítása ez:INSERT INTO Recipes (name,

serves, source) VALUES (“Spa­

nish Rice”,4,”Greg Walters”)

Következő lépésként ki kelltalálnunk a recipe táblához ren-delt pkID-t. Ezt egy egyszerűutasítással tehetjük meg:SELECT last_insert_rowid()

De ez nem egy olyan dolog,amit csak úgy használhatunk.Egy sor hasonló utasítást kellhasználnunk, mint itt:sql = "SELECT last_insert_­

rowid()"

cursor.execute(sql)

for x in cursor.execute(sql):

lastid = x[0]

Hogy mért is van ez? Nos,amikor adatot szeretnénk visz-szaszerezni az ASPW-ből, aztuple-ként (kb. vektor) jön visz-sza. Erről még nem beszéltünk.A rövid magyarázat az lenne,hogy a tuple (ha megnézzük afenti kódot) olyan, mint egy lis-ta, csak nem lehet módosítani.Sokan csak ritkán használják atuple-öket, vannak olyanok is,akik gyakran, ez egyedül rajtadmúlik. Az a lényeg, hogy az el-ső visszaadott értéket akarjukfelhasználni. A for ciklust arrahasználjuk, hogy az értéket el-tároljuk az x tuple változóban.

Érthető? Rendben. Folytassuk...Most, létrehozzuk az instruk-

ciók insert utasítását:sql = 'INSERT INTO Instructi­

ons (recipeID,instructions)

VALUES( %s,"Brown hamburger.

Stir in all other ingredi­

ents. Bring to a boil. Stir.

Lower to simmer. Cover and

cook for 20 minutes or until

all liquid is absorbed.")' %

lastid

cursor.execute(sql)

Figyeljük meg, hogy egy vál-tozó behelyettesítést (%s)használunk a recept pkID-jének(lastid) elhelyezéséhez az sqlutasításban. Végül, mindenegyes hozzávalót el kell helyez-nünk az ingredient táblában.Egyet meg is mutatok:sql = 'INSERT INTO Ingredi­

ents (recipeID,ingredients)

VALUES ( %s,"1 cup parboiled

Rice (uncooked)")' % lastid

cursor.execute(sql)

Ezen a ponton ezt már nemtúl nehéz megérteni. Következőalkalommal egy kicsit bonyo-lódni fognak a dolgok.

Ha el szeretnéd érni a teljesforráskódot, akkor azt a honla-pomon megtalálod. Menj awww.thedesignatedgeek.comoldalra és töltsd le.

Legközelebb fel fogjuk hasz-nálni a recept programunkhozmindazt, amit a sorozat alatttanultunk a menüközpontú fe-lületek létrehozásáról - segítsé-gével megnézhetjük a recepteklistáját, egyetlen egy receptet,kereshetünk a receptek közöttés bővithetjük, illetve törölhet-jük őket.

Azt javaslom, hogy egy kisidőt szánjunk az SQL progra-mozásról szóló dolgok utánol-vasására. Jól fogsz járni, hamegteszed.

Page 34: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 34 tartalom ^

HogyanokÍrta: Greg Walters

Programozzunk Pythonban - 8. rész

ELŐZŐ SZÁMOK:FCM 27-33 - Python 1-7. rész

ITT HASZNÁLHATÓ:

KATEGÓRIÁK:

ESZKÖZÖK:

GrafikaFejlesztés Internet M/média Rendszer

MerevlemezCD/DVD USB eszköz Laptop VezetéknélküliFolytassuk a hetedik rész-

ben elkezdett receptadatbázisunk programo-zását. Ez a cikk hosszú

lesz, és sok-sok kódot fog tartal-mazni. Szóval kössétek fel a ga-tyákat, és ne felejtsétek a keze-ket és lábakat mindvégig a ko-csiban tartani. Az adatbázisun-kat már létrehoztuk. Most márszeretnénk megjeleníteni a tar-talmát, hozzáadni, illetve törölnibelőle. De hogyan is fognakezek működni? Kezdésként egykonzolos alkalmazást fogunkelkészíteni, ehhez pedig egy

menüt kell összeraknunk. Mind-ezen felül az adatbázishoz tarto-zó eljárásokat tartalmazó osz-tályt is létre kell hoznunk. Vág-junk is neki a jobbra fent találha-tó programrészlettel.

Most pedig alakítsuk ki a me-nü szerkezetét. Erre azért vanszükségünk, mert így el tudjukhelyezni a program szerkezetétmeghatározó kódtöredékeket. Amenünk egy igen nagy cikluslesz, ami kiíratja a felhasználóáltal végrehajtható opciók listá-ját. Ehhez egy while ciklust fo-gunk használni. Módosítsuk amenu eljárásunkat úgy, hogy ajobb oldalon, lent lévő kódra ha-sonlítson.

A menut egy if|elif|else struk-túrával töltjük fel (következőoldal tetején látható).

Gyorsan fussuk át a menumetódusunkon. A felhasználó ál-tal választható opciók kiíratásá-val kezdünk. Egy változót (loop)True-ra (igaz) állítunk és a whileciklusban addig iterálunk amíg aloop=False nem lesz. Araw_input() parancsot használvavárunk arra, hogy a felhasználó

#!/usr/bin/python

#­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

# Cookbook.py

# Created for Beginning Programming Using Python #8

# and Full Circle Magazine

#­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

import apsw

import string

import webbrowser

class Cookbook:

def Menu():

cbk = Cookbook() # Initialize the class

Menu()

def Menu():

cbk = Cookbook() # Initialize the class

loop = True

while loop == True:

print

'==================================================='

print ' RECIPE DATABASE'

print

'==================================================='

print ' 1 ­ Show All Recipes'

print ' 2 ­ Search for a recipe'

print ' 3 ­ Show a Recipe'

print ' 4 ­ Delete a recipe'

print ' 5 ­ Add a recipe'

print ' 6 ­ Print a recipe'

print ' 0 ­ Exit'

print

'==================================================='

response = raw_input('Enter a selection ­> ')

Page 35: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 35 tartalom ^

Programozzunk Pythonban - 8. rész

kiválassszon egy menüelemet.Ezt követően az if lekezeli a ki-választott műveletet. Mielőttazonban tesztelni tudnánkmindezt, létre kell hoznunk azosztályunk __init__ eljárását:def __init__(self):

pass

A programunkat mentsükugyanoda, ahol múltkor az a-datbázist hoztuk létre és futtas-suk. A jobbra fent található kép-hez hasonlót kellene látnunk.

Egész egyszerűen csak kikell íratnia a menüt újra és újra,addig, amíg meg nem nyomjuka „0”-t. Ekkor kiíratjuk a „Good-

bye” szöveget és kilépünk.Ezen a ponton már elkezdhet-jük a Cookbook osztályban el-járásaink vázának létrehozását.Szükségünk lesz egy olyanfüggvényre, ami megjeleníti aRecipes tábla információit, egyolyanra amivel kereshetünk areceptek között, egy másikra,ami megjelenít egy teljes re-ceptet a három táblából, egyreami töröl egy receptet, mégegyre, amivel új receptet tu-dunk felvenni, és végül egyolyanra ami az alapértelmezettnyomtatóval kinyomtatja a re-ceptet. A PrintAllRecipes rutin-nak nincs szüksége a (self) pa-raméteren kívül másra, akár-csak a SearchforRecipe-nek és

az EnterNew eljárásnak sem. APrintSingleRecipe, DeleteRecipeés PrintOut metódusoknak tud-niuk kell melyik recepttel vandolguk, tehát szükségük vanegy olyan paraméterre, amitmost „which”-nek fogunk ne-vezni. Egyelőre mindegyik kód-törzsben használjuk a pass pa-rancsot. A Cookbook osztályalatt helyezzük el az eljárástör-zseket:def PrintAllRecipes(self):

pass

def SearchForRecipe(self):

pass

def

PrintSingleRecipe(self,which)

:

pass

def DeleteRecipe(self,which):

pass

def EnterNew(self):

pass

def PrintOut(self,which):

pass

Néhány menüelemnél ki sze-retnénk majd íratni a Recipetáblában lévő összes receptet,így a felhasználó képes lesz vá-lasztani a listából. Ezek az 1-es,3-as, 4-es és 6-os opciók lesz-nek. Módosítsuk hát ezeket amenüelmeket a pass parancscbk.PrintAllRecipes()-re valócseréjével. A felhasználói visz-szajelzést ellenőrző rutinunk akövetkező oldal tetején látható.

Van még egy dolog, amitmeg kell tennünk: be kell állí-tanunk az __init__ metódust. Akódtöredéket helyettesítsük azalábbi sorokkal:def __init__(self):

global connection

global cursor

self.totalcount = 0

connection=apsw.Connection

("cookbook.db3")

cursor=connection.cursor()

if response == '1': # Show all recipes

pass

elif response == '2': # Search for a recipe

pass

elif response == '3': # Show a single recipe

pass

elif response == '4': # Delete Recipe

pass

elif response == '5': # Add a recipe

pass

elif response == '6': # Print a recipe

pass

elif response == '0': # Exit the program

print 'Goodbye'

loop = False

else:

print 'Unrecognized command. Try again.'

/usr/bin/python ­u

"/home/greg/python_examples/APSW/cookbook/cookbook_stub.py"

===================================================

RECIPE DATABASE

===================================================

1 ­ Show All Recipes

2 ­ Search for a recipe

3 ­ Show a Recipe

4 ­ Delete a recipe

5 ­ Add a recipe

6 ­ Print a recipe

0 ­ Exit

===================================================

Enter a selection ­>

Page 36: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 36 tartalom ^

Programozzunk Pythonban - 8. rész

Először létrehozunk két glo-bális változót a kapcsolathoz(connection) és a kurzorhoz(cursor). Mindkettőt bárhon-nan el tudjuk érni a cookbook(szakácskönyv) osztályból.Ezután létrehozunk egyself.totalcount változót, amivelmegszámoljuk a recepteket. Ezta változót a későbbiekben ishasználni fogjuk. Végezetül lét-rehozzuk a kapcsolatot és akurzort.

A következő lépésben össze-rakjuk a Cookbook osztályPrintAllRecipes() eljárását. Mi-vel a connection és a cursorváltozók globálisak, ezért nemkell minden metódusban újra

létrehozni őket. Ezt követően,szeretnénk a képernyőre „csi-nosan kiíratni” a receptlista fej-lécét. A megfelelő szóközöléseléréséhez használni fogjuk a„%s” formázási parancsot, és abalra zárást. Valami ilyesmitszeretnénk kapni:Item Name Serves Source

­­­­­­­­­­­­­­­­­­­­­­­­­­­

Végül, létre kell hoznunk azSQL utasítást, ami lekérdezi azadatbázist és kiíratja a találato-kat. A múlthavi cikkben enneknagyját már tárgyaltuk.

sql = 'SELECT * FROM

Recipes'

cntr = 0

for x in

cursor.execute(sql):

cntr += 1

print '%s %s %s %s'

%(str(x[0]).rjust(5),x[1].lju

st(30),x[2].ljust(20),x[3].lj

ust(30))

print '­­­­­­­­­­­­­'

self.totalcount = cntr

A cntr változóban fogjuk szá-molni a képernyőn megjelení-tett receptek számát. Ezen aponton már készen is vagyunka metódussal. Ha esetleg ki-hagytál volna valamit, lentebbmegtalálod a szubrutin teljeskódját.

Figyeljük meg hogy használ-juk az ASPW cursor.execute el-járás által visszaadott vektort.A pkID-t, mint itemet írjuk ki,így a későbbiekben majd ki tud-

juk választani a megfelelő re-ceptet. Amikor a programotlefuttatjuk, meg kellene jelen-nie a menünek, illetve amikorkiválasztjuk az 1-est, akkor akövetkező oldal tetején levőképet fogjuk látni.

Épp ezt akartuk elérni. HaDr. Pythont vagy hasonlót hasz-nálunk, akkor csak annyi agond, hogy az alkalmazásunknem áll meg. Egyszerűen vára-kozzunk, amíg a felhasználómeg nem nyom egy gombot,így lesz pár perce a kimenet vé-gigbogarászására. Ha már ittvagyunk, akkor írassuk is ki azelőbb beállított változóból azösszes recept számát. Helyez-zük a menu 1-es választási le-hetősége alá:

if response == '1': # Show all recipes

cbk.PrintAllRecipes()

elif response == '2': # Search for a recipe

pass

elif response == '3': # Show a single recipe

cbk.PrintAllRecipes()

elif response == '4': # Delete Recipe

cbk.PrintAllRecipes()

elif response == '5': # Add a recipe

pass

elif response == '6': # Print a recipe

cbk.PrintAllRecipes()

elif response == '0': # Exit the program

print 'Goodbye'

loop = False

else:

print 'Unrecognized command. Try again.'

def PrintAllRecipes(self):

print '%s %s %s %s'

%('Item'.ljust(5),'Name'.ljust(30),'Serves'.ljust(20),

'Source'.ljust(30))

print '­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'

sql = 'SELECT * FROM Recipes'

cntr = 0

for x in cursor.execute(sql):

cntr += 1

print '%s %s %s %s'

%(str(x[0]).rjust(5),x[1].ljust(30),x[2].ljust(20),x[3

].ljust(30))

print '­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'

self.totalcount = cntr

Page 37: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 37 tartalom ^

Programozzunk Pythonban - 8. rész

print 'Total Recipes ­ %s'

%cbk.totalcount

print '­­­­­­­­­­­­­­­­­­­­­­

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

­'

res = raw_input('Press A Key

­> ')

A második elemet (Receptkeresése) ugorjuk egyelőre át,és foglalkozzunk a hármassal(egyetlen recept kiíratása). Elő-ször foglalkozzunk a menü ré-szével. Itt íratjuk ki a recepteklistáját, akárcsak, az első opci-ónál, majd megkérjük a felhasz-nálót, hogy válasszon. Ahhoz,hogy a hibás inputokkal szem-

ben bebiztosítsuk magunkat,használni fogjuk a Try|Exceptvezérlési szerkezetet. Meg fog-juk jeleníteni a felhasználó fe-lé a promptot (Select a recipe -->), majd, ha egy helyes választgépelnek be, meghívjuk aPrintSingle Recipe() rutint a Re-cipe táblabeli pkID-vel a Cook-book osztályból. Ha a megadottérték nem szám, akkor egy Va-lueError kivétel dobódik, melyeta ValueError: fog majd elkapni.

Következőnek, a Cookbookosztályban lévő PrintSingleReci-pe metóduson fogunk dolgozni.Ismét a kapcsolattal és a kur-zorral kezdünk, majd ezután lét-

rehozzuk az SQL utasítást is.Ebben az esetben a „SELECT *FROM Recipes WHERE pkID=%s"%str(which)” lekérdezésthasználjuk, ahol a where az azérték, amit meg szeretnénk ta-lálni. Ezt követően az outputot„csinosan kiíratjuk” az ASPWáltal visszaadott tuple-ből. Eb-

ben az esetben az x-et egy ál-talános változóként használjuk,és az egyes elemekre a záróje-lezett indexel hivatkozunk atuple-ban. Mivel a táblázat el-rendezése pkID/name/servings/source, az x[0], x[1], x[2] ésx[3] értékeket fogjuk megjelení-teni. Ezután a „wantot” fogjukhasználni ahhoz, hogy mindentkiválasszunk a hozzávalók táb-lájából, ahol a recipeID (a reci-pe adattábla kulcsa) megegye-zik azzal a pkID-vel, amit éppenhasználtunk. Végigiterálunk avisszaadott tuple-ön, mindegyikhozzávalót kiíratva, majd az in-structions táblából kivesszük azinstrukciókat - mint ahogy eztaz ingredients táblánál tettük.Végül, a felhasználó gombnyo-mására várakozunk, hogy aképernyőn meg tudjuk jeleníte-ni a receptet. A kód a következőoldalon látható.

Enter a selection ­> 1

Item Name Serves Source

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

1 Spanish Rice 4 Greg

2 Pickled Pepper­Onion Relish 9 half pints Complete Guide to Home Canning

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

===================================================

RECIPE DATABASE

===================================================

1 ­ Show All Recipes

2 ­ Search for a recipe

3 ­ Show a Recipe

4 ­ Delete a recipe

5 ­ Add a recipe

6 ­ Print a recipe

0 ­ Exit

===================================================

Enter a selection ­>

try:

res = int(raw_input('Select a Recipe ­> '))

if res <= cbk.totalcount:

cbk.PrintSingleRecipe(res)

elif res == cbk.totalcount + 1:

print 'Back To Menu...'

else:

print 'Unrecognized command. Returning to menu.'

except ValueError:

print 'Not a number...back to menu.'

Page 38: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 38 tartalom ^

Programozzunk Pythonban - 8. részMost már a hatból két metó-

dussal készen vagyunk. Foglal-kozzunk akkor a keresés rutin-nal, megint a menüvel kezdve.Szerencsénkre, csak a keresésutasítás meghívására van szük-ségünk az osztályban. Cseréljükle a pass parancsot:cbk.SearchForRecipe()

Rakjuk most össze a keresésalgoritmusát. A Cookbook osz-tályban, a SearchForRecipeautogenerált törzsét cseréljükle a következő oldalon láthatókódra.

Jó sok minden van itt. Miutánlétrehoztuk a kapcsolatunkat ésa kurzorunkat, megjelenítjük akeresés menüt. A felhasználó-nak három keresési lehetősé-get, illetve egy kilépés rutintfogunk felkínálni. A felhasználóegy szót kereshet a recept ne-vében, forrásában, vagy a hoz-závalók listájában. Emiatt nemtudjuk egyszerűen felhasználniaz imént megírt megjelenítésimetódust és létre kell hoznunkegy személyreszabott kiíratásirutint. Az első két opció egysze-rű SELECT utasításokat használ- egy kis csavarral megtoldva.Mégpedig a „like” minősítőt

használjuk. Ha egy „SQLite Da-tabase Browser” szerű lekérde-zés-szerkesztőt használunk, ak-kor a like utasításaink a „%”wildcardot fogják használni. Te-hát, amikor „rice”-t (rizs) tartal-mazó receptnévre keresünk,akkor a lekérdezés ilyen lenne:SELECT * FROM Recipes WHERE

name like '%rice%'

Mivel, a „%” karakter asztringeknél egy helyettesítésikarakter is, a %%-ot kell hasz-nálnunk a szövegünkben. Amimég rosszabb, az az, hogy egyhelyettesítő karaktert haszná-lunk a felhasználó által keresettszó beillesztésére is. Ezért, a„%%%s%%” karaktersorozat-hoz jutunk. Hát, nem éppenszép. A harmadik lekérdezéstJoin utasításnak nevezzük. Néz-zük meg egy kicsit közelebbről:sql = "SELECT

r.pkid,r.name,r.servings,r.so

urce,i.ingredients FROM

Recipes r Left Join

ingredients i on (r.pkid =

i.recipeid) WHERE

i.ingredients like '%%%s%%'

GROUP BY r.pkid" %response

Mindent kiválasztunk a reci-pe táblából és a hozzávalókataz ingredients táblából, a kap-

csolatot, vagy a hozzárendelésta recipeID és a pkID alapjánmegvalósítva. Ezután a like uta-sítással megkeressük a hozzá-valóinkat, majd végül az ered-ményeket csoportosítjuk a re-cepttáblabeli pkID szerint, ezzelelkerülve, hogy a többszörösadatok megjelenjenek. Emlé-kezzünk arra, hogy két paprikavan a második receptünkben(hagyma és paprika fűszerek),

egy zöld és egy piros. Ez meg-zavarhatja a felhasználónk fe-jét. A menünk asearchin = raw_input('Enter

Search Type ­> ')

if searchin != '4':

megoldást használja, ami aztmondja: ha a searchin (a fel-használó által begépelt érték)NEM egyenlő 4-gyel, akkor az

def PrintSingleRecipe(self,which):

sql = 'SELECT * FROM Recipes WHERE pkID = %s' %

str(which)

print

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

for x in cursor.execute(sql):

recipeid =x[0]

print "Title: " + x[1]

print "Serves: " + x[2]

print "Source: " + x[3]

print

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

sql = 'SELECT * FROM Ingredients WHERE RecipeID =

%s' % recipeid

print 'Ingredient List:'

for x in cursor.execute(sql):

print x[1]

print ''

print 'Instructions:'

sql = 'SELECT * FROM Instructions WHERE RecipeID

= %s' % recipeid

for x in cursor.execute(sql):

print x[1]

print

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

resp = raw_input('Press A Key ­> ')

Page 39: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 39 tartalom ^

def SearchForRecipe(self):

# print the search menu

print '­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'

print ' Search in'

print '­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'

print ' 1 ­ Recipe Name'

print ' 2 ­ Recipe Source'

print ' 3 ­ Ingredients'

print ' 4 ­ Exit'

searchin = raw_input('Enter Search Type ­> ')

if searchin != '4':

if searchin == '1':

search = 'Recipe Name'

elif searchin == '2':

search = 'Recipe Source'

elif searchin == '3':

search = 'Ingredients'

parm = searchin

response = raw_input('Search for what in %s (blank to exit) ­> ' % search)

if parm == '1': # Recipe Name

sql = "SELECT pkid,name,source,servings FROM Recipes WHERE name like '%%%s%%'" %response

elif parm == '2': # Recipe Source

sql = "SELECT pkid,name,source,servings FROM Recipes WHERE source like '%%%s%%'" %response

elif parm == '3': # Ingredients

sql = "SELECT r.pkid,r.name,r.servings,r.source,i.ingredients FROM Recipes r Left Join ingredients i

on (r.pkid = i.recipeid) WHERE i.ingredients like '%%%s%%' GROUP BY r.pkid" %response

try:

if parm == '3':

print '%s %s %s %s %s'

%('Item'.ljust(5),'Name'.ljust(30),'Serves'.ljust(20),'Source'.ljust(30),'Ingredient'.ljust(30))

print '­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'

else:

print '%s %s %s %s' %('Item'.ljust(5),'Name'.ljust(30),'Serves'.ljust(20),'Source'.ljust(30))

print '­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'

for x in cursor.execute(sql):

if parm == '3':

print '%s %s %s %s %s'

%(str(x[0]).rjust(5),x[1].ljust(30),x[2].ljust(20),x[3].ljust(30),x[4].ljust(30))

else:

print '%s %s %s %s' %(str(x[0]).rjust(5),x[1].ljust(30),x[3].ljust(20),x[2].ljust(30))

except:

print 'An Error Occured'

print '­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­'

inkey = raw_input('Press a key')

Page 40: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 40 tartalom ^

Programozzunk Pythonban - 8. részopciókkal foglalkozunk, ha 4, ak-kor nem csinálunk semmit, csaktúllépünk rajta. Vegyük észre,hogy a „!=” (nem egyenlő)operátort használtuk a „<>”operátor helyett. Bármelyik mű-ködik Python 2.x alatt, de Py-thon 3.x-ban szintaxishibátkapunk. A későbbiekben többPython 3.x-et érintő változássalis fogunk foglalkozni. Egyelőrehasználjuk a „!=” operátort,hogy a jövőben megkönnyítsükaz áttérést Python 3.x-ra. Vé-gül, „csinosan kiíratjuk” az out-putot. Jobbra láthatjuk, hogymit fog kapni a felhasználó.

Láthatjuk, hogy programunkmilyen szépen írja ki a kimene-tet. Most a felhasználó márvisszaléphet a menübe és hasz-nálhatja a 3-as opciót bárme-lyik recept kiíratásához. Követ-kezőnek recepteket fogunk azadatbázisunkhoz hozzáadni.Ismét csak egyetlen sort kell amenu rutinunkban elhelyezni.Ez az EnterNew eljárás:cbk.EnterNew()

Itt van a kód, melynek azEnterNew() kódtöredéket kellfelváltania:http://pastebin.com/f1d868e63.

Enter a selection ­> 2

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Search in

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

1 ­ Recipe Name

2 ­ Recipe Source

3 ­ Ingredients

4 ­ Exit

Enter Search Type ­> 1

Search for what in Recipe Name (blank to exit) ­> rice

Item Name Serves Source

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

1 Spanish Rice 4 Greg

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Press a key

Elég egyértelmű. Most, ami a hozzávalók keresését illeti...Enter a selection ­> 2

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Search in

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

1 ­ Recipe Name

2 ­ Recipe Source

3 ­ Ingredients

4 ­ Exit

Enter Search Type ­> 3

Search for what in Ingredients (blank to exit) ­> onion

Item Name Serves Source Ingredient

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

1 Spanish Rice 4 Greg 1 small

Onion chopped

2 Pickled Pepper­Onion Relish 9 half pints Complete Guide to Home Canning 6 cups

finely chopped Onions

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Press a key

Page 41: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 41 tartalom ^

Programozzunk Pythonban - 8. részAz „ings” nevű lista definiá-

lásával kezdünk - ami az ingre-dients rövidítése. Ezután meg-kérjük a felhasználót, hogy adjameg a nevet, forrást és adagokszámát. Ezután egy ciklusba lé-pünk be, ahol mindegyik hozzá-valót bekérjük, majd ezeketrendre az ing listához hozzáfűz-zük. Ha a felhasználó 0-t ír be,akkor kilépünk a ciklusból ésbekérjük az instrukciókat. Ezu-tán a recept tartalmát újramegmutatjuk és megkérjük afelhasználót, hogy ellenőrizze,mielőtt elmentenénk. Akárcsakmúltkor, megint INSERT INTOutasításokat használunk, mie-lőtt kilépünk a menübe. Egy do-logra azonban ügyelnünk kell: abejegyzéseknél lévő egyszeresidézőjelekre. ÁLTALÁBAN a hoz-závalók listájánál, illetve az in-strukcióknál ez nem okoz prob-lémákat, de a név és forrás me-zőknél előjöhetnek. Ezért min-den egyes idézőjelnél egy es-cape szekvenciát kell elhelyez-nünk. Ezt a string.replace eljá-rással tesszük meg. Ezért im-portáltuk be a string könyvtá-rat. Helyezzük el a menü rutin-ban a 4-es opció után a jobbrafent látható kódot.

Majd a Cookbook osztálybanhasználjuk a jobbra lent látható

kódot a DeleteRecipe() eljárás-hoz.

Gyorsan fussunk át a törlőmetóduson is. Először megkér-dezzük a felhasználótól, hogymelyik receptet szeretné törölni(még a menüben), majd átad-juk ezt a pkID-t a törlő eljárás-nak. Ezután megbizonyoso-dunk, hogy a felhasználó bizto-san szeretné-e törlni a receptet.Ha a válasz „Y”(string.upper(resp) == 'Y'), ak-kor létrehozzuk a törlő sql uta-sítást. Vegyük észre, hogy ez-úttal mind a három táblából tö-rölnünk kell rekordokat. Termé-szetesen törölhetnénk egyedülcsak a recipe táblából, de ekkorárva rekordjaink maradnának amásik kettőben. Ez pedig nemlenne jó. A pkID mezőket hasz-náljuk a rekord recipe táblábólvaló törlésekor, a másik kéttáblában pedig a recipeIDmezőket.

És végül foglalkozzunk arecept kinyomtató eljárásával.Egy NAGYON egyszerű HTMLfáljt hozunk majd létre. Ezt kö-vetően megnyitjuk az alapértel-mezett böngészőt, ahol már kitudják nyomtatni a receptet. Awebbrowser könyvtárat ezért

importáltuk be. A menü eljárás6-os opciójában helyezzük el akövetkező oldalon fent láthatókódot.

Ismét megjelenítjük a recep-tek listáját, és megengedjük,hogy kiválasszhassák azt, ame-lyiket ki szeretnék nyomtatni. A

Cookbook osztály PrintOut eljá-rását hívjuk meg. (Következőoldalon lent látható.)

A fi = open([filename],'w')utasítással kezdünk, ami létre-hoz egy fájlt. Ezután lekérdez-zük a recipe tábla adatait, majda fi.write-tal kiíratjuk a fájlba.

cbk.PrintAllRecipes()

print '0 ­ Return To Menu'

try:

res = int(raw_input('Select a Recipe to DELETE

or 0 to exit ­> '))

if res != 0:

cbk.DeleteRecipe(res)

elif res == '0':

print 'Back To Menu...'

else:

print 'Unrecognized command. Returning to

menu.'

except ValueError:

print 'Not a number...back to menu.'

def DeleteRecipe(self,which):

resp = raw_input('Are You SURE you want to Delete

this record? (Y/n) ­> ')

if string.upper(resp) == 'Y':

sql = "DELETE FROM Recipes WHERE pkID = %s" %

str(which)

cursor.execute(sql)

sql = "DELETE FROM Instructions WHERE

recipeID = %s" % str(which)

cursor.execute(sql)

sql = "DELETE FROM Ingredients WHERE recipeID

= %s" % str(which)

cursor.execute(sql)

print "Recipe information DELETED"

resp = raw_input('Press A Key ­> ')

else:

print "Delete Aborted ­ Returning to menu"

Page 42: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 42 tartalom ^

Programozzunk Pythonban - 8. részA <H1></H1> címsor tago-

kat használjuk a névhez, a<H2> tagot az adagokhoz ésforrásokhoz. A <li></li> tagota hozzávalók és instrukciók lis-tájánál használjuk. Ezektől elte-kintve, csak egyszerű, már ta-nult lekérdezéseket tartalmaz.Végül, a fi.close() utasítássalbezárjuk a fájlt, és meghívjuk awebbrowser.open([filename])függvényt az előbb létrehozottfáljra. A felhasználó ezután aböngészőböl ki tudja nyomtatnia receptet - ha szükséges.

HUHH!! Ez volt eddigi legna-gyobb alkalmazásunk. A teljesforráskódot kiraktam (a mintaadatbázist is, ha kihagytad vol-na az előző hónapot) a webla-pomra. Ha nem akarod az egé-szet begépelni, akkor ugorj el awww.thedesignatedgeek.comcímre, és töltsd le a kódot.

cbk.PrintAllRecipes()

print '0 ­ Return To Menu'

try:

res = int(raw_input('Select a Recipe to DELETE or 0 to exit ­> '))

if res != 0:

cbk.PrintOut(res)

elif res == '0':

print 'Back To Menu...'

else:

print 'Unrecognized command. Returning to menu.'

except ValueError:

print 'Not a number...back to menu.'

def PrintOut(self,which):

fi = open('recipeprint.html','w')

sql = "SELECT * FROM Recipes WHERE pkID = %s" % which

for x in cursor.execute(sql):

RecipeName = x[1]

RecipeSource = x[3]

RecipeServings = x[2]

fi.write("<H1>%s</H1>" % RecipeName)

fi.write("<H2>Source: %s</H2>" % RecipeSource)

fi.write("<H2>Servings: %s</H2>" % RecipeServings)

fi.write("<H3> Ingredient List: </H3>")

sql = 'SELECT * FROM Ingredients WHERE RecipeID = %s' % which

for x in cursor.execute(sql):

fi.write("<li>%s</li>" % x[1])

fi.write("<H3>Instructions:</H3>")

sql = 'SELECT * FROM Instructions WHERE RecipeID = %s' % which

for x in cursor.execute(sql):

fi.write(x[1])

fi.close()

webbrowser.open('recipeprint.html')

print "Done"

Greg Walters a RainyDaySolutions tulajdonosa, ez egykorlátolt felelősségű tanácsadócég a colorado-i Aurorában.Programozással 1972 ótafoglalkozik. Szeret főzni, túrázni,zenét hallgatni és szabadidejétcsaládja körében eltölteni.

Page 43: Programozzunk Pythonban – 1. rész

full circle magazin Python 1. kötet 43 tartalom ^

KKöözzrreemműűkkööddnnééll??A Full Circle Csapata

Szerkesztő - Ronnie [email protected] - Rob [email protected]ációs felelős - Robert [email protected] - Robert [email protected]

Ha hírt szeretnél közölni, megteheted a következő címen: [email protected]

Véleményed és Linuxos tapasztalataidat ide küldd: [email protected]

Hardver és szoftver elemzéseket ide küldhetsz: [email protected]

Kérdéseket a „Kérdések és Válaszok” rovatba ide küldd: [email protected]

Az én asztalom képeit ide küldd: [email protected]

... vagy látogasd meg fórumunkat: www.fullcirclemagazine.org

A FULL CIRCLE-NEK SZÜKSÉGE VAN RÁD!Egy magazin, ahogy a Full Circle is, nem magazin cikkek nélkül. Osszátok meg velünk véle-ményeiteket, desktopjaitok kinézetét és történeteiteket. Szükségünk van a Fókuszban ro-vathoz játékok, programok és hardverek áttekintő leírására, a Hogyanok rovatbanszereplő cikkekre (K/X/Ubuntu témával), ezenkívül, ha bármilyen kérdés, javaslat merül felbennetek, nyugodtan küldjétek a következő címre: [email protected]

Az olvasóközönségtől folyamatosan várjuk a magazinban megjelenítendő új cikkeket!További információkat a cikkek irányvonalairól, ötletekről és a kiadások fordításairól ahttp://wiki.ubuntu.com/UbuntuMagazine wiki oldalunkon olvashatsz.Cikkeidet az alábbi címre várjuk: [email protected] magyar fordítócsapat wiki oldalát itt találod:https://wiki.ubuntu.com/UbuntuMagazine/TranslateFullCircle/HungarianA magazin eddig megjelent magyar fordításait innen töltheted le: http://www.fullcircle.huHa email-t akarsz írni a magyar fordítócsapatnak, akkor erre a címre küldd:[email protected]

Köszönet a Canonical-nek és a fordítócsapa-toknak világszerte.

Palotás AnnaTömösközi Máté Ferenc

Imolai Gábor (külső felajánlás)

Full Circle MagazinMagyar Fordítócsapat

Szerkesztő, korrektor:Heim Tibor

Koordinátor:Pércsy Kornél

Fordítók: