Python kezdőknek kurzus 4. lecke

A Ubuwiki wikiből

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, "uveg sor"  # kiirja a dal kovetkezo sorat
for i in range(99, 0, -1) :     # ciklus 99-tol lefele
    print(i, "uveg sor")  # 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 leggyakrabban szokott szükség lenni, mert ezzel kezelhetjük 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.


További leckék

Személyes eszközök