„Python kezdőknek kurzus 4. lecke” változatai közötti eltérés
A Ubuwiki wikiből
Grus (vitalap | szerkesztései) (→Shebang!) |
Grus (vitalap | szerkesztései) (→A "sys" modul, parancssori paraméterekhez) |
||
52. sor: | 52. sor: | ||
=== A "sys" modul, parancssori paraméterekhez === | === A "sys" modul, parancssori paraméterekhez === | ||
− | A <code>sys</code> modul az, amire | + | A <code>sys</code> modul az, amire elég gyakran szükség van, mert ezzel kezelhetjük például a parancssori paramétereket. |
− | kezelhetjük a parancssori paramétereket. | + | |
Íme egy program, ami kiírja az paramétereit, amiket a parancssorban kapott: | Íme egy program, ami kiírja az paramétereit, amiket a parancssorban kapott: |
A lap 2019. április 26., 13:50-kori változata
Tartalomjegyzék
A mai lecke során a modulokról és a parancssori paraméterekről fogunk tanulni, melyek segítségével egy nagyobb programot fogunk részletekbe menően megírni.
De előbb néhány kisebb kitérő:
Megjegyzések (kommentek)
Pythonban a megjegyzéseket hash markkal, vagyis a # karakterrel kezdjük. Akárhol látunk #-ot a programkódban, az ezt követő része a sor már nem a program része. Azért hasznos használni, mert így megjegyzéseket tudunk hagyni magunknak vagy bárki másnak, aki olvassa a programunkat.
Kommentek lehetnek írni akár külön sorba
# Nyomtassuk ki a "99 uveg sor" cimu dalt
vagy egy sorba a Python kóddal
Python 2.x | Python 3.x |
---|---|
for i in range(99, 0, -1) : # ciklus 99-tol lefele print i, "üveg sör" # kiirja a dal kovetkezo sorat |
for i in range(99, 0, -1) : # ciklus 99-tol lefele print(i, "üveg sör") # kiirja a dal kovetkezo sorat |
Ha hosszabb programokat írunk, kommentek segítségével a bonyolultabb kódrészleteket elmagyarázhatjuk, ezzel egyszerűbbé téve a kód olvasását.
Shebang!
Most nézzük hogyan futtathatjuk egyszerűbben programjainkat. Páran már bizonyára láttak is olyat, hogy egyes python fájlok első sorában az alábbi szerepel
#!/usr/bin/env python
Ez a sor azt mondja meg az operációs rendszernek, hogy egy python programról van szó. Ha így írjuk a kódunkat, akkor nem szükséges a "python programnev"
formában futtatnunk, elegendő pusztán a fájl nevét megadnunk a futtatáshoz.
A #!
neve "shebang", mert a # neve angolul hash (vagy sharp), a !-t pedig bangként szokták kiejteni, de a shebang viccesebben hangzik, mint a hashbang vagy sharpbang. (Magyar nevet nem találtam erre.) Más szkriptek - például perl, ruby, bash, stb. - írásakor is előfordul a shebang. További infók:
http://en.wikipedia.org/wiki/Shebang_%28Unix%29#Portability
Ha Windowst használsz, a shebang sor nem segít, de nem is árt, vagyis egyszerűbb, ha ott van az első sorban, így Linuxon és Mac-en egyszerűbb lesz a futtatás.
Modulok importálása (betöltése)
A Python nyelv egyik nagy előnye, hogy rengeteg beépített könyvtár van hozzá, ezeket "moduloknak" hívjuk. Szinte bármire készült már modul, ezzel megkönnyítve a dolgunkat. Ha szeretnél esetleg írni egy böngészőt vagy videó szerkesztőt, vagy csak keresnél a Twitteren, esetleg kíváncsi vagy hol van az égen a Jupiter? Mindre van Python modul.
Randall Munroe (az XKCD-n) szintén így gondolja: http://xkcd.com/353/
Hogy használjuk a modulokat? Egyszerűen: amikor megtaláltad melyik modulra van szükséged, csak ki kell adni az "import modulnév" parancsot a program elején.
A "sys" modul, parancssori paraméterekhez
A sys
modul az, amire elég gyakran szükség van, mert ezzel kezelhetjük például a parancssori paramétereket.
Íme egy program, ami kiírja az paramétereit, amiket a parancssorban kapott:
Python 2.x | Python 3.x |
---|---|
#! /usr/bin/env python import sys for arg in sys.argv : print arg |
#! /usr/bin/env python import sys for arg in sys.argv : print(arg) |
Mentsük el args
néven (csak Windows esetén lehet szükséges a .py kiterjesztés) és tegyük futtathatóvá:
chmod +x args
Futtassuk párszor, különböző paraméterekkel:
$ args 1 2 3 args 1 2 3 $ args hello, vilag args hello, vilag
Amikor a sys
modult importáljuk, automatikusan "megkapjuk" a sys.argv
változót, ami a parancsori paramétereket tárolja - beleértve a program nevét is.
Általában persze olyan ciklust szeretnénk használni, ami a parancs nevét kivéve minden más paramétert végigjárt -- az előbbi példát nézve, csak a 'hello' és 'vilag' szavakra vagyunk kíváncsiak nem, az 'args', 'hello' és 'world' szavakra.
Hogy is csináljuk ezt? A sys.argv egy lista, amit darabolhatunk is. Gondoljunk csak vissza az előző (3.) leckére. A mostani esetben a 0. paraméter a program neve, a többi az egyestől kezdődik. Így tehát a sys.argv[1:]
re van szükségünk. Változtassuk meg a fenti programot:
Python 2.x | Python 3.x |
---|---|
for arg in sys.argv[1:] : print arg |
for arg in sys.argv[1:] : print(arg) |
és pontosan azt kapjuk, amire szükségünk van: az összes paramétert kiírva, a program neve nélkül.
Szövegből egészt (átalakítás)
A sys.argv
egy lista, elemei sztringek. Tehát ha számokként szeretnénk a paramétereket használni, szükségünk lehet átalakításra. Ezt az int()
paranccsal tehetjük meg. Ha lebegőpontos számra van szükségünk, használjuk a float()
ot.
Python 2.x | Python 3.x |
---|---|
import sys szam = int(sys.argv[1]) for i in range(0, szam): print i |
import sys szam = int(sys.argv[1]) for i in range(0, szam): print(i) |
Fájlok olvasása
Nagyon gyakran a megadott paraméterek fájlnevek, amiket szeretnénk megnyitni.
Emlékszünk például a szószámláló programunkra? Mennyivel hasznosabb lenne, ha megadhatnánk programunknak egy fájlnevet, és a program kiírná hány szó található a fájlban? Nézzük hogy olvasunk be fájlokat Pythonban. Tegyük fel, hogy args
a fájlunk neve, az aktuális könyvtárban.
Python 2.x | Python 3.x |
---|---|
fajl = open("args") for sor in fajl: print "Sor beolvasasa:", sor fajl.close() |
fajl = open("args") for sor in fajl: print("Sor beolvasasa:", sor) fajl.close() |
Az open(fajlnev)
egy fájl objektumot ad. Ha egy for ciklussal végigjárjuk(for sor in fajl), akkor sorról-sorra olvashatjuk úgy, hogy minden sor egy sztring lesz.
Mindig zárjuk be a megnyitott fájlokat, miután nem dolgozunk többé vele. A Python minden programfutás végén bezár minden fájlt, de nagyon programok esetén jobb, ha bezárjuk azokat a fájlokat, amikre már nincs szükségünk (ne foglaljuk ezekkel a memóriát).
Természetesen nem szükséges mindig az args
fájlt olvasni, bármilyen paraméterként átadott fájlnevet is használhatunk az open-nél:
Python 2.x | Python 3.x |
---|---|
import sys fajl = open(sys.argv[1]) for sor in fajl: print "Kovetkezo sor: ", sor fajl.close() |
import sys fajl = open(sys.argv[1]) for sor in fajl: print("Kovetkezo sor: ", sor) fajl.close() |
Gyakorló feladatok
1. Ha kiadjuk a
szam = int(sys.argv[1]):
parancsot úgy, hogy nem adunk meg paramétert, hibát kapunk. Vajon miért? Van-e vajon mód arra, hogy leellenőrizzük, hogy a felhasználó adott-e meg paramétert és ha nem, kiírjunk erről egy hibaüzenetet?
2. Írjunk programot, ami paraméterként egy fájlnevet várj és kiírja a sorok számát a fájlban. (Linuxon a wc -l
program is épp ezt csinálja.)
3. Bővítsük az előző programot úgy, hogy több paraméter esetén minden fájlra számolja meg a sorokat
$ sorszamlalo fajl1 fajl2 fajl3
4. És végül itt egy nehezebb probléma, hibakeresés (ami sajnos a programozás egy része):
4a. Írjunk programot, amely megszámolja a szavak számát egy fájlban (vagy több fájlban). Használjuk a split()
és len()
függvényeket.
4b. Hasonlítsuk össze az a. pontban írt program eredményét azzal, amit a wc -w
ad. (Ha nem tudjuk a wc parancsot használni, futtassuk a saját programunkat egy olyan fájlon, amiben kevés szó van és számoljuk meg magunk is a szavakat.) Ugyanazt az eredményt kaptuk?
4c. Itt következik a hibakeresés rész: miért nem egyezik? (Nem szükséges kijavítani a hibát, csak próbáljunk meg rájönni, hol lehet a gond.)
Tipp: ha a split segítségével minden sort listává alakítunk, nézzük meg mit tartalmaz a lista. Pythonban, ha van például egy szavak nevű listánk, elég ha kiadjuk a print szavak [print(szavak)] parancsot.
4d. és végül egy még nehezebb: javítsuk ki a programot, hogy ugyanazt az eredményt kapjuk, mint a wc -w
programmal.
Tipp 1: a Python strip()
parancsa segíthet a megoldásban: eltávolít minden szóközt a sztring elejéről és végéről. Például ha az s sztring a " hello vilag "
, akkor a s.strip()
eredménye "hello, vilag"
.
Fontos megjegyeznem, hogy nagyon hasznos a Python dokumentációja, főleg modulok használatakor. http://docs.python.org/library/string.html#string.strip
Tipp 2: Ha cikluson belül vagyunk, például sorokon haladunk végig, akkor dönthetünk úgy, hogy az adott sorral nem foglalkozunk. Ilyenkor átugorhatjuk azt, a continue használatával.
Például, ha van egy ciklus, ahol a negatív számokat át szeretnénk ugrani, akkor ezt az alábbi módon tehetjük.
for i in szamok_listaja : if i < 0 : continue csinaljon_valamit_a_pozitiv_szamokkal(i)
A break
utasítás segítségével pedig kiléphetünk a ciklusból.
Ne kergessük magunkat őrületbe azzal, hogy a wc-vel pontos egyezést próbáljunk elérni. Van náhány speciális eset, ahol a szóközökkel való szétdarabolás nem ugyanazt az eredményt adja, mint a wc -w parancs, és van néhány Python modul (konkrétabban re, reguláris kifejezések), melyekkel könnyebben megoldható a fenti feladat. A feladat célja, hogy gyakoroljük a hibakaresést, problémák kijavítását és hogy átgondoljunk minden speciális esetet.