Több módszer van arra, hogy kényelmesebben generáljunk szöveges kimenetet. Az egyik a format()
függvény. Ez egy stringből egy másik stringet készít úgy, hogy hogy a megadott paramétereket behelyettesíti a kapcsos zárójelek közé. A függvényekhez hasonlóan több féle paraméter átadás működik:
# default argumentumok
print("Kedves {}, az ön egyenlege {}.".format("Ádám", 230.2346))
# pozíció szerintei argumentumok
print("Kedves {1}, az ön egyenlege {0}.".format("Ádám", 230.2346))
# kucsszavas argumentumok
print("Kedves {nev}, az ön egyenlege {egyen}.".format(nev="Ádám", egyen=230.2346))
# vegyes
print("Kedves {0}, az ön egyenlege {egyen}.".format("Ádám",egyen= 230.2346))
Kedves Ádám, az ön egyenlege 230.2346. Kedves 230.2346, az ön egyenlege Ádám. Kedves Ádám, az ön egyenlege 230.2346. Kedves Ádám, az ön egyenlege 230.2346.
Ha az adatok egy dicitionaryben vannak, azt is használhatjuk.
person = {'eletkor': 23, 'nev': 'Ádam'}
print("{p[nev]} életkora: {p[eletkor]}".format(p=person))
Ádam életkora: 23
szam1 = 12
szam2 = 1
nev="Paprika Jancsi"
print(f"{nev}nak {szam1} almája és {szam2} kutyája van.")
Paprika Jancsinak 12 almája és 1 kutyája van.
Mi fog történni ha lefuttatjuk az alábbi kódot?
import random
for i in range(20):
print(1/random.randrange(10))
0.16666666666666666 0.125 0.5 0.25 0.14285714285714285
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-6-bee39ce313dd> in <module> 1 for i in range(20): ----> 2 print(1/random.randrange(10)) ZeroDivisionError: division by zero
Néhány tipikus hiba:
Hiba neve | Tipikusan miért történt |
---|---|
IndexError: string index out of range | Egy stringnél túlindexeltél |
KeyError: 'some_text_here' | Egy dictionaryben olyan kulcsot használtál, ami nincs benne |
ModuleNotFoundError: No module named 'some_text_here' | Egy olyan modult próbáltál importálni, ami nem található |
NameError: name 'some_text_here' is not defined | Olyan változó nevet próbáltál kiértékelni, ami még nem mutat objektumra |
SyntaxError: can't assign to literal | Egy stringet próbáltál meg változó névként használni. Pl 'a'=3 |
SyntaxError: EOL while scanning string literal | Valamelyik stringet rosszul adtad meg. |
IndentationError: expected an indented block | Elrontottad az indentálást. |
SyntaxError: invalid syntax | Szintaktikai hiba. Gyakran azért van, mert lemarad a : valahonnan. |
TypeError: can only concatenate str (not "int") to str | Stringként kezeltél valamit, ami nem string. Pl egy számot. |
TypeError: 'str' object is not callable | Függvényként kezeltél egy stringet. Pl: "asd"(5) |
ValueError: invalid literal for int() with base 10: 'some_text_here' | Számmá próbáltál konvertálni egy szöveget, ami nem számokból áll. |
ZeroDivisionError: division by zero | Nullával osztottál |
A futásidejű hibákat tudjuk futásidőben kezelni. Erre valók a try
és except
parancsok. Megadhatjuk, hogy hiba esetén mit tegyen a program, így nem fog rögtön elszállni. A try
és az except
közti részben figyel a program és ha olyan hibába ütközik, ami az except
után áll, akkor végrehajtja a megadott parancsokat.
for i in range(10):
try:
print(1/random.randrange(10))
except ZeroDivisionError as e:
print("nullával osztottál")
0.2 0.5 0.25 0.125 0.1111111111111111 0.3333333333333333 0.2 0.3333333333333333 nullával osztottál 0.25
try:
int("abc")
except ValueError as e:
print(type(e))
print(e)
<class 'ValueError'> invalid literal for int() with base 10: 'abc'
try:
eletkor = int(input())
if eletkor < 0:
raise Exception("Az életkor nem lehet negatív")
except ValueError as e:
print("ValueError")
except Exception as e:
print("Egy másik típusú kivétel: {}".format(type(e)))
print(e)
-1 Egy másik típusú kivétel: <class 'Exception'> Az életkor nem lehet negatív
Együtt:
def age_printer(age):
next_age = age + 1
print("Következő éveben a korod: " + next_age)
try:
your_age = input()
your_age = int(your_age)
age_printer(your_age)
except (ValueError, TypeError) as e:
print("{}ba futottunk".format(type(e).__name__))
asd ValueErrorba futottunk
try:
age = int(input())
if age < 0:
raise Exception("Az életkor nem lehet negatív")
except ValueError:
print("ValueError elkapva")
except:
print("Valamilyen más hibát kaptunk el")
asd ValueError elkapva
finally
kód rész mindenképpen lefut, ha volt hiba, ha nem. else
utáni rész csak akkor fut le ha nem volt hibatry:
age = int(input())
except ValueError as e:
print("Exception", e)
else:
print("Nem volt hiba")
finally:
print("Ez mindig lefut")
10 Nem volt hiba Ez mindig lefut
raise
kulcsszó¶raise
az utána megadott hibát dobja a program. try:
eletkor = int(input())
if eletkor < 0:
raise Exception("Az életkor nem lehet negatív")
except ValueError as e:
print("ValueError")
except Exception as e:
print("Egy másik típusú kivétel: "+ str(type(e)))
print(e)
Exception
(pontosabban a BaseException
) osztály leszármazotja, használható hiba objektumként. class NegativeAgeError(Exception):
def __init__(self, uzenet, adat):
self.uzenet = uzenet
self.adat = adat
def __str__(self):
return repr(self.uzenet)+repr(self.adat)
try:
age = int(input())
if age < 0:
raise NegativeAgeError("Az életkor nem lehet negatív:",age)
except NegativeAgeError as e:
print(e)
print(e.adat)
except Exception as e:
print("Valamilyen más hibát kaptunk el. Típus: {}, üzenet: {}".format(type(e), e))
asd Valamilyen más hibát kaptunk el. Típus: <class 'ValueError'>, üzenet: invalid literal for int() with base 10: 'asd'
Sokféle objektumot tudunk használni for ciklusokban:
for i in [1, 2, 3, 4]:
print(i)
1 2 3 4
for c in "python":
print(c)
p y t h o n
for k in {"x": 1, "y": 2}:
print(k)
x y
with open("pelda_fajl.txt", "r") as fajlobj:
for line in fajlobj:
print(line)
1,Donielle,Vickar,dvickar0@tmall.com,true 2,Perle,Claye,pclaye1@blogs.com,true 3,Flori,Wharf,fwharf2@zdnet.com,true 4,Kristen,Haryngton,kharyngton3@yelp.com,false 5,Bibby,Covill,bcovill4@psu.edu,true 6,Illa,D'Elias,idelias5@twitter.com,true 7,Genia,Woodyear,gwoodyear6@reuters.com,false 8,Patrice,Rhys,prhys7@meetup.com,false 9,Rich,Gavozzi,rgavozzi8@istockphoto.com,false 10,Elfie,Comben,ecomben9@un.org,true
Ezeket az osztályokat közösen iterálható osztályoknak hívjuk.
Az iterálható osztályokhoz tartozik egy-egy iterátor, amit megkaphatunk az iter
függvénnyel. A next()
függvény megadja az iterátor következő elemét. Ha már nincs több elem, StopIteration
hibát kapunk. (Emiatt egyszerhasználatosak az iterátorok.)
myiter=iter("Süsü")
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
S ü s ü
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-29-33e9e039eb89> in <module> 4 print(next(myiter)) 5 print(next(myiter)) ----> 6 print(next(myiter)) StopIteration:
Ez a két tulajdonság definiálja is az iterátorokat. Tehát egy iterátornak a következőket kell tudnia:
__next__
függvénye, ami visszadja sorban az elemeket ésStopIteration
hibát ad, ha nincs több elem.Egy osztály iterálható ha a van egy __iter__
függvénye ami visszatér egy iterátorral.
class MyIterator:
def __init__(self):
self.iter_no = 5
def __iter__(self):
return self
def __next__(self):
if self.iter_no <= 0:
raise StopIteration()
self.iter_no = self.iter_no- 1
print("Aktuális: {}".format(self.iter_no))
return self.iter_no
#return "itt tartunk:"+str(self.iter_no)
myiter = MyIterator()
for i in myiter:
print(i)
Aktuális: 4 4 Aktuális: 3 3 Aktuális: 2 2 Aktuális: 1 1 Aktuális: 0 0
class Sarkanyiterator:
def __init__(self,fejlista):
self.fejlista=fejlista
self.aktualis_sarkany=0
self.aktualis_fej=1
def __next__(self):
mostani_sarkany=self.aktualis_sarkany
mostani_fej=self.aktualis_fej
if self.aktualis_sarkany>=len(self.fejlista) or (self.aktualis_sarkany==len(self.fejlista)-1 and self.aktualis_fej>self.fejlista[-1][1]):
raise StopIteration()
if self.fejlista[self.aktualis_sarkany][1]>self.aktualis_fej:
self.aktualis_fej= self.aktualis_fej+1
else:
self.aktualis_sarkany=self.aktualis_sarkany+1
self.aktualis_fej=1
return [self.fejlista[ mostani_sarkany][0],mostani_fej]
class SarkanyBarlang:
def __init__(self):
self.sarkanyfejlista = [("Süsü",1),("Smaug",1),("Hétfejű",7),("Ghidorah",3)]
def __iter__(self):
return Sarkanyiterator(self.sarkanyfejlista)
barlang = SarkanyBarlang()
for fej in barlang:
print(fej)
for fej in barlang:
print(fej)
['Süsü', 1] ['Smaug', 1] ['Hétfejű', 1] ['Hétfejű', 2] ['Hétfejű', 3] ['Hétfejű', 4] ['Hétfejű', 5] ['Hétfejű', 6] ['Hétfejű', 7] ['Ghidorah', 1] ['Ghidorah', 2] ['Ghidorah', 3] ['Süsü', 1] ['Smaug', 1] ['Hétfejű', 1] ['Hétfejű', 2] ['Hétfejű', 3] ['Hétfejű', 4] ['Hétfejű', 5] ['Hétfejű', 6] ['Hétfejű', 7] ['Ghidorah', 1] ['Ghidorah', 2] ['Ghidorah', 3]
Rengeteg függvény van, ami elfogad bármilyen iterátort!
iter(barlang)
<__main__.Sarkanyiterator at 0x21ec0762c48>
list(barlang)
[['Süsü', 1], ['Smaug', 1], ['Hétfejű', 1], ['Hétfejű', 2], ['Hétfejű', 3], ['Hétfejű', 4], ['Hétfejű', 5], ['Hétfejű', 6], ['Hétfejű', 7], ['Ghidorah', 1], ['Ghidorah', 2], ['Ghidorah', 3]]
max(barlang,key=lambda x:x[1])
['Hétfejű', 7]
A generátorok speciális iterátorok. A fő gondolat mögöttük, hogy sokszor nincs szükség egy list összes elemének a legyártásához, ha csak végig akarunk haladni a listán, hanem elég, ha mindig ki tudjuk számítani a következő elemet. Így sokkal kevesebb memóriát használ a gép.
Több mód is van a generátorok létrehozására, az egyik a generátor kifejezések, amik a list comprehensionök általánosításai.
Egy generátor kifejezést megadhatunk úgy, hogy () zárójelek közé írjuk a list comprehension kódját a [] zárójelek helyett.
%%time
N = 8
s = sum([i*2 for i in range(int(10**N))])
print(s)
9999999900000000 Wall time: 18.3 s
%%time
s = sum((i*2 for i in range(int(10**N))))
print(s)
9999999900000000 Wall time: 11.6 s
Mivel a generátorok csak végéghaladnak a listán és nem gyártják azt le, így ezek is csak egyszerhasználatosak.
even_numbers = (2*n for n in range(10))
even_numbers
<generator object <genexpr> at 0x0000021EC0759A48>
for num in even_numbers:
print(num)
0 2 4 6 8 10 12 14 16 18
Második futásra már üres:
for num in even_numbers:
print(num)
Minden generátor objektum is egyben iterátor, tehát a next()
függvény megadja a következő elemet, ha pedig már nincs, StopIteration
hibát ad.
even_numbers = (2*n for n in range(10))
while True:
try:
print(next(even_numbers))
except StopIteration:
break
0 2 4 6 8 10 12 14 16 18
next(even_numbers) # StopIteration
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-48-6cda3138393a> in <module> ----> 1 next(even_numbers) # StopIteration StopIteration:
import itertools as it
Végtelen iterátorok:
gen=it.cycle('ABCD')
for _ in range(10):
print(next(gen))
A B C D A B C D A B
gen=it.count(3)
for _ in range(10):
print(next(gen))
3 4 5 6 7 8 9 10 11 12
c=it.chain.from_iterable(['ABC', range(10)])
for a in c:
print(a)
A B C 0 1 2 3 4 5 6 7 8 9
for i,j in it.product(range(3),"asd"):
print(i,j)
0 a 0 s 0 d 1 a 1 s 1 d 2 a 2 s 2 d
list(filter(lambda x: x%2, range(10)))
[1, 3, 5, 7, 9]
list(it.filterfalse(lambda x: x%2, range(10)))
[0, 2, 4, 6, 8]
a map
meghívja a megadott függvényt az iterátor minden elemére
def double(e):
return e + e
l = [2, 3, "abc"]
list(map(double, l))
[4, 6, 'abcabc']
m=map(double, l)
next(m)
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-70-8efa10874b95> in <module> ----> 1 next(m) StopIteration:
number_list = [1, 2, 3]
str_list = ['one', 'two', 'three']
str_list2 = ['one2', 'two2', 'three2']
result = zip(number_list, str_list,str_list2)
result_list = list(result)
print(result_list)
[(1, 'one', 'one2'), (2, 'two', 'two2'), (3, 'three', 'three2')]
coordinate = ['x', 'y', 'z']
value = [3, 4, 5]
result = zip(coordinate, value)
result_list = list(result)
print(result_list)
c, v = zip(*result_list)
print('c =', c)
print('v =', v)
[('x', 3), ('y', 4), ('z', 5)] c = ('x', 'y', 'z') v = (3, 4, 5)
A legfontosabb operációk:
open('fajlnev','r')
parancs megnyitva a fajlnev nevű fájlt olvasásra és visszatért a file objektummalopen('fajlnev','w')
parancs megnyitva a fajlnev nevű fájlt írásra és visszatért a file objektummalfajlobjektum.close()
parancs lezárja a fájlt, akár írtunk bele akár olvastunk A következő példa fájlt fogjuk használni, amit a pelda_fajl.txt
-be mentettem:
Egy sort beolvashatunk a .readline()
függvénnyel:
fajlobj = open("pelda_fajl.txt", "r")
line=fajlobj.readline()
print(line)
line=fajlobj.readline()
print(line)
print(repr(line))
fajlobj.close()
1,Donielle,Vickar,dvickar0@tmall.com,true 2,Perle,Claye,pclaye1@blogs.com,true '2,Perle,Claye,pclaye1@blogs.com,true\n'
fajlobj = open("pelda_fajl.txt", "r")
line=fajlobj.readline()
while line:
values = line.strip().split(",")
print("{} {} {} email: {}".format(*values))
line=fajlobj.readline()
fajlobj.close()
1 Donielle Vickar email: dvickar0@tmall.com 2 Perle Claye email: pclaye1@blogs.com 3 Flori Wharf email: fwharf2@zdnet.com 4 Kristen Haryngton email: kharyngton3@yelp.com 5 Bibby Covill email: bcovill4@psu.edu 6 Illa D'Elias email: idelias5@twitter.com 7 Genia Woodyear email: gwoodyear6@reuters.com 8 Patrice Rhys email: prhys7@meetup.com 9 Rich Gavozzi email: rgavozzi8@istockphoto.com 10 Elfie Comben email: ecomben9@un.org
Egy fájlon a for ciklus segítségével is végighaladhatunk:
fajlobj = open("pelda_fajl.txt", "r")
for line in fajlobj:
values = line.strip().split(",")
print(values)
fajlobj.close()
['1', 'Donielle', 'Vickar', 'dvickar0@tmall.com', 'true'] ['2', 'Perle', 'Claye', 'pclaye1@blogs.com', 'true'] ['3', 'Flori', 'Wharf', 'fwharf2@zdnet.com', 'true'] ['4', 'Kristen', 'Haryngton', 'kharyngton3@yelp.com', 'false'] ['5', 'Bibby', 'Covill', 'bcovill4@psu.edu', 'true'] ['6', 'Illa', "D'Elias", 'idelias5@twitter.com', 'true'] ['7', 'Genia', 'Woodyear', 'gwoodyear6@reuters.com', 'false'] ['8', 'Patrice', 'Rhys', 'prhys7@meetup.com', 'false'] ['9', 'Rich', 'Gavozzi', 'rgavozzi8@istockphoto.com', 'false'] ['10', 'Elfie', 'Comben', 'ecomben9@un.org', 'true']
fajlobj.read(n)
beolvas n karaktert, vagy ha paraméter nélkül hívjuk az egész fájlt. fajlobj.readlines()
visszaadja a fájl sorait egy listában. fajlobj = open("pelda_fajl.txt", "r")
tartalom=fajlobj.read()
print(tartalom)
fajlobj.close()
1,Donielle,Vickar,dvickar0@tmall.com,true 2,Perle,Claye,pclaye1@blogs.com,true 3,Flori,Wharf,fwharf2@zdnet.com,true 4,Kristen,Haryngton,kharyngton3@yelp.com,false 5,Bibby,Covill,bcovill4@psu.edu,true 6,Illa,D'Elias,idelias5@twitter.com,true 7,Genia,Woodyear,gwoodyear6@reuters.com,false 8,Patrice,Rhys,prhys7@meetup.com,false 9,Rich,Gavozzi,rgavozzi8@istockphoto.com,false 10,Elfie,Comben,ecomben9@un.org,true
A fajlobj.write(egy_string)
parancs a fájl végére írja a megadott stringet. Ehhez a fajlobj-nak egy írásra megnyitott fájlnak kell lennie.
fajlirni = open("pelda_fajl_irni.txt", "w") # ha nem létezik a fájl létrehozza azt.
fajlirni.write("Na ezt most kiírom egy fájlba! xxxx")
fajlirni.close()
fajlolvasni = open("pelda_fajl_irni.txt", "r")
tartalom=fajlolvasni.read()
print("Ezt találtam a fájlban: " + tartalom)
fajlolvasni.close()
Ezt találtam a fájlban: Na ezt most kiírom egy fájlba! xxxx
Ha nem zárjuk be, gondokat okozhat, hogy korábbi operációk még nem hajtódtak végre. Például:
fajlirni = open("pelda_fajl_irni.txt", "w")
fajlirni.write("Na ezt most kiírom egy fájlba!")
fajlirni.close()
fajlolvasni = open("pelda_fajl_irni.txt", "r")
tartalom=fajlolvasni.read()
print("Ezt találtam a fájlban: " + tartalom)
fajlolvasni.close()
Ezt találtam a fájlban: Na ezt most kiírom egy fájlba!
A with
kulcsszó automatikusan megoldja nekünk a lezárást és a hibakezelést. Használat:
with open(argumentumok) as valtozonev:
kód indentálva
Ha sikerül megnyitni a fájlt, lefuttatja az indentált részt, majd meghívja helyettünk a close() parancsot.
with open("pelda_fajl_irni.txt", "w") as fajlirni:
fajlirni.write("Na ezt most kiírom egy fájlba!")
with open("pelda_fajl_irni.txt", "r") as fajlolvasni:
tartalom=fajlolvasni.read()
print("Ezt találtam a fájlban: " + tartalom)
Ezt találtam a fájlban: Na ezt most kiírom egy fájlba!
with open("pelda_fajl_irni.txt", "w", encoding='utf-8') as fajlirni:
fajlirni.write("árvíztűrő tükörfúrógép")
with open("pelda_fajl_irni.txt", "r") as fajlolvasni:
tartalom=fajlolvasni.read()
print("Ezt találtam a fájlban: " + tartalom)
Ezt találtam a fájlban: árvĂztűrĹ‘ tĂĽkörfĂşrĂłgĂ©p
with open("pelda_fajl_irni.txt", "w", encoding='utf-8') as fajlirni:
fajlirni.write("árvíztűrő tükörfúrógép")
with open("pelda_fajl_irni.txt", "r",encoding='utf-8') as fajlolvasni:
tartalom=fajlolvasni.read()
print("Ezt találtam a fájlban: " + tartalom)
Ezt találtam a fájlban: árvíztűrő tükörfúrógép
json.dump(data, outfile)
, beolvasás: json.load(json_file)
import json
data = {}
data['sárkányok'] = []
data['sárkányok'].append({
'nev': 'Süsü',
'támadás': 'ölelés',
'lakhely': 'Magyarország'
})
data['sárkányok'].append({
'nev': 'Smaug',
'támadás': 'tűzokádás',
'lakhely': 'Középfölde'
})
data['sárkányok'].append({
'nev': 'Rhaegal',
'támadás': 'tűzokádás',
'lakhely': 'Westeros'
})
with open('data.txt', 'w') as outfile:
json.dump(data, outfile)
import json
with open('data.txt') as json_file:
adat = json.load(json_file)
for p in adat['sárkányok']:
print('Név: ' + p['nev'])
print('Támadás: ' + p['támadás'])
print('Lakóhely: ' + p['lakhely'])
print('')
Név: Süsü Támadás: ölelés Lakóhely: Magyarország Név: Smaug Támadás: tűzokádás Lakóhely: Középfölde Név: Rhaegal Támadás: tűzokádás Lakóhely: Westeros