Laboratorul 2
(Deadline: -)
Daca nu sunteti logati exercitiile nu se mai afiseaza.
Functii - aprofundare
Valori default pentru parametri
def f(x=1,y=2,z=3):
Va afisa:
6
return x+y+z
print(f())
print(f(100))
print(f(100, 100))
print(f(100, 100, 100))
105
203
300
Apel cu numele parametrilor
def f(x=1,y=2,z=3):
Va afisa:
104
return x+y+z
print(f(y=100))
print(f(z=100, x=100))
202
Functii cu numar variabil de argumente
def inmultire(*args):
Va afisa:
300
r=1
for x in args:
r*=x
return r
print(inmultire(2,3,1,5,10))
Daca avevm o functie definita cu numar variabil de argumente si totusi argumentele pe care vrem sa le transmitem sunt intr-o lista, de exemplu lst=[2,3,1,5,10] vom apela functia cu *lst in locul enumerarii argumentelor. Deci pentru functia de mai sus, am apela inmultire(*lst).
Argumentele programului
Uneori dorim sa apelam programul cu anumite argumente. In acest caz scriem in linia de comanda ceva de genul: python programel.py arg1 arg2 arg3 ......
Pentru a accesa argumentele trebuie sa importam modulul sys:
import sys
si apoi iteram prin lista sys.argv. Atentie, primul argument este numele programului.
Consideram exemplul de mai jos:
import sys
Observam executia programului:
print("\nAfisaj executie program\n")
for i in range(len(sys.argv)):
print ("Argumentul {} are valoarea {} si tipul de date {}".format(i, sys.argv[i], type(sys.argv[i])))
Observam si ca tipul de date al tuturor argumentelor este str, deci daca vrem sa folosim o valoare numerica data ca parametru, trebuie sa o convertim la numar.
Instructiunea vida
Instructiunea vida este instructiunea pass
. Aceasta nu face nimic si adesea e folosita pe post de placeholder. De exemplu, pentru o functie pe care dorim sa o declaram ca sa nu uitam de ea dar inca nu dorim sa o definim am putea scrie:
def f():
pass
Multimi
Multimile sunt colectii in care elementele sunt distincte. Elementele se enumera intre acolade. Multimile pot fi definite si cu ajutorul constructorului set()
, dandu-se ca parametrul o lista de elemente
Multimea vida nu se poate defini doar prin acolade fara continut, fiindca este simbolul dictionarului vid. Asadar, pentru multime vida folosim constructorul fara parametri:
m=set()
E corect dar nu e indicat (deoarece avem versiunea mai scurta, fara parametri) sa scriem si asa:
m=set([])
Putem itera prin multimi astfel:
for elem in {1,2,3,4} :
Va afisa:
1 2 3 4
print(elem, end=' ')
Multimile pot contine elemente de tipuri diferite. O multime poate contine doar elemente immutable (de exemplu o multime poate contine un sir sau tuplu, insa nu poate contine o lista, un dictionar sau chiar altv multime). Mai jos aevti un exemplu cu o multime cu elementele enumerate:
m={2,1,"x",(1,2),2.3}
sau
m=set([2,1,"x",(1,2),2.3])
>>> m=set([1,2,1,2,2])
>>> m
{1, 2}
Operatii pe multimi
Consideram multimile:
m1={1,3,5,8,9}
m2={2,3,7,8}
Reuniune
>>> reuniune = m1 | m2>>> reuniune
{1, 2, 3, 5, 7, 8, 9}
Intersectie
>>> intersectie = m1 & m2>>> intersectie
{8, 3}
Diferenta
>>> diferenta = m1 - m2>>> diferenta
{9, 5, 1}
Diferenta simetrica
>>> diferenta_simetrica = m1 ^ m2>>> diferenta_simetrica
{1, 2, 5, 7, 9}
Teste pe multimi
Consideram multimile:
m2={2,3,7,8}
m3={2,3}
Apartenenta
>>> 2 in m3True
>>> 2 not in m3
False
Incluziune
>>>>>> m3<m2
True
>>> m3<=m2
True
>>> m2>=m2
True
Metode specifice
Consideram multimea:
m3={2,3}
Putem adauga un element cu metoda add() si sa stergem elementul cu discard() sau remove(). Diferenta intre discard si remove este ca remove arunca o exceptie daca elementul dat ca parametru nu exista
>>> m3.add(10) Putem sterge si un element arbitrar din multime cu ajutorul metodei pop():
>>> m={1,2,3,4,5}Cardinalul (functia len())
>>> len(m3)
2
Adaugare si stergere de elemente
>>> m3
{10, 2, 3}
>>> m3.discard(10)
>>> m3
{2, 3}
>>> m.pop()
1
>>> m
{2, 3, 4, 5}
Vidarea multimii (clear())
>>> m3.clear()
>>> m3
set()
Multimi immutable (frozenset)
Aceste multimi nu se pot modifica (nu putem adauga sau sterge elemente). Asadar pot fi elemente in alte multimi (immutable sau nu).
>>> m=frozenset(["Elsa","Anna","Olaf","Kristoff","Hans"])
>>> m
frozenset({'Olaf', 'Elsa', 'Hans', 'Anna', 'Kristoff'})
>>> mnr=frozenset([1,2,3])
>>> mm={m,mnr}
>>> mm
{frozenset({'Olaf', 'Elsa', 'Hans', 'Anna', 'Kristoff'}), frozenset({1, 2, 3})}
Cateva functii utile
Mai jos sunt enumerate cateva functii predefinite utile:Functia any()
Functia any() primeste ca parametru o colectie (iterabila) si returneaza True daca cel putin un element are valoarea True (sau poate fi convertit implicit la True). In caz contrar, returneaza False. Pentru o colectie vida va returna False.
>>> any({1,2,3,0})
True
>>> any([0,0,0])
False
>>> any([])
False
Functia all()
Functia all() primeste ca parametru o colectie (iterabila) si returneaza True daca toate elementele au valoarea True (sau pot fi convertite implicit la True). In caz contrar, returneaza False. Pentru o colectie vida va returna True.
>>> all({1,2,3,0})
False
>>> all({1,2,3})
True
>>> all([0,0,0])
False
>>> all([])
True
Functiile ord() si chr()
Functia ord primeste un caracter si returneaza codul ascii al acestuia. Functia chr primeste codul ascii si returneaza caracterul (sir de lungime 1) corespunzator.
>>> ord("a")
97
>>> chr(97)
'a'
Functia zip()
Functia zip primeste ca parametru una sau mai multe colectii si returneaza un iterator. Elemente iterabile rezultate sunt tupluri cu proprietatea ca tuplul de pe pozitia i contine elementele de pe pozitia i din colectiile date ca argumente (ordinea din tuplu e data de ordinea in care au fost transmise colectiile ca argumente).
>>> l1=["a","b","c"]
>>> zl1=zip(l1)
>>> zl1
<zip object at 0x0308A6E8>
>>> l_zl1=list(zl1)
>>> l_zl1
[('a',), ('b',), ('c',)]
>>>
>>> l3=[100,200,300,400]
>>> l_zl3=list(zip(l1,l3))
>>> l_zl3
[('a', 100), ('b', 200), ('c', 300)]
Functia eval()
Primeste ca parametru un sir pe care il evalueaza ca expresie.
>>> eval("1+2-4")
-1
Expresii lambda
Functiile lambda sunt functii anonime de dimesniune mica. Executa doar o expresie. Forma generala este:
lambda p1, p2, .. pn: expresie
Expresia, depinde, evident, de parametrii functiei.
Exemplu:
>>> q = lambda a : a**2
>>> q(10)
100
>>> w = lambda a, b, c: a+b+c
>>> w("xyz","uuu","hop")
'xyzuuuhop'
>>> type(w)
<class 'function'>
Un exemplu de folosire a functiilor lambda pentru sortarea listelor dupa alt criteriu decat cel default:
Exemplu:
>>> l=["abc","z","baubau","wwww",""]
>>> l.sort()
>>> l
['', 'abc', 'baubau', 'wwww', 'z']
>>> l.sort(key=lambda x: len(x))
>>> l
['', 'z', 'abc', 'wwww', 'baubau']
Comprehensions
List comprehensions
Sintaxa: [expresie_element for parametru in element_iterabil].
>>> [x for x in range(10,20,2)]
[10, 12, 14, 16, 18]
>>> [x for x in "abcd"]
['a', 'b', 'c', 'd']
Se poate adauga si o conditie pentru elemente adaugate in lista. Sintaxa: [expresie_element for parametru in element_iterabil if conditie]
>>> [x for x in "abracadabra" if x<"e"]
['a', 'b', 'a', 'c', 'a', 'd', 'a', 'b', 'a']
Pentru conditii putem folosi si expresii conditionale (diferenta este ca expresia pentru elementul generator - al carei rezultat se pune in lista - contine conditia):
>>> [ "a"+str(x) if x<5 else "b"+str(x) for x in range(10)]
['a0', 'a1', 'a2', 'a3', 'a4', 'b5', 'b6', 'b7', 'b8', 'b9']
Putem combina expresii conditionale cu conditiile puse pentru comprehension:
>>> [ "a"+str(x) if x<5 else "b"+str(x) for x in range(20) if x%3==0]
['a0', 'a3', 'b6', 'b9', 'b12', 'b15', 'b18']
Se pot pune mai multe expresii for in cazul in care elementele depind de mai multi parametri:
>>> [x*10+y for x in range(3,8) for y in range(1,10,2) if x<y ]
[35, 37, 39, 45, 47, 49, 57, 59, 67, 69, 79]
Putem genera astfel chiar si matrici:
>>> [0 for x in range(4)]
[0, 0, 0, 0]
>>> [[0 for x in range(4)] for y in range(4)]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Set comprehensions
Au aceeasi forma ca si pentru liste, doar ca se scriu intre acolade:
>>> {int(x) for x in str(100541)}
{0, 1, 4, 5}
>>> {(x,y) for x in [1,2,3,1] for y in [2,2,3]}
{(1, 2), (3, 2), (1, 3), (3, 3), (2, 3), (2, 2)}
>>> {(x,y) for x in [1,2,3,1] for y in [2,2,3] if x>=y}
{(3, 2), (3, 3), (2, 2)}
Dict comprehensions
Au aceeasi forma ca si pentru liste, doar ca se scriu intre acolade si elementul generator e de forma k:v
>>> {k:k**3 for k in range(0,10)}
{0: 0, 1: 1, 2: 8, 3: 27, 4: 64, 5: 125, 6: 216, 7: 343, 8: 512, 9: 729}
>>> {k:[k**y for y in range(0,4)] for k in range(1,10)}
{1: [1, 1, 1, 1], 2: [1, 2, 4, 8], 3: [1, 3, 9, 27], 4: [1, 4, 16, 64], 5: [1, 5, 25, 125], 6: [1, 6, 36, 216], 7: [1, 7, 49, 343], 8: [1, 8, 64, 512], 9: [1, 9, 81, 729]}
>>> [(x,y) for x in range(1,4) for y in range(7,10)]
[(1, 7), (1, 8), (1, 9), (2, 7), (2, 8), (2, 9), (3, 7), (3, 8), (3, 9)]
>>> {k:v for k,v in [(x,y) for x in range(1,4) for y in range(7,10)]}
{1: 9, 2: 9, 3: 9}
Exceptii
def impartire_supraunit(x,y):
try:
if x<y :
raise Exception("Primul argument trebuie sa fie mai mare sau egal decat al doilea.")
return x/y
except ZeroDivisionError:
print("Al doilea argument nu poate fi zero")
except TypeError as eroare:
print("Argumentele nu sunt numere:"+str(eroare))
except Exception as eroare:
print(eroare)
print(impartire_supraunit(8,0))
print(impartire_supraunit("x",10))
print(impartire_supraunit(5,10))
print(impartire_supraunit(10,5))
Fisiere
Fisierele se deschid cu functia open(cale_fisier, mod_deschidere). Modul de deschidere poate fi:
- r - pentru citire
- w - pentru scriere. In caz ca fisierul exista deja, se suprascrie.
- a - pentru adaugare. In caz ca fisierul exista deja, tot ce se scrie se adauga la finalul fisierului.
- r+ - si pentru citire si pentru scriere.
Metode I/O pentru fisiere
Pentru scriere folosim metoda write().
Pentru citirea intregului fisier folosim metoda read(). Ii putem da si un argument care reprezinta cate caractere sa citeasca (f.read(10)).
Pentru citirea unei anumite linii din fisier folosim metoda readLine(numar_linie).
Pentru citirea fisierului linie cu linie folosim metoda readLines() care va returna o lista cu toate liniile.
Putem itera prin liniile fisierului astfel:
fisier = open("fis.txt", "r")
for linie in fisier:
print(linie)
Metoda tell() returneaza pozitia cursorului in fisier, iar metoda seek() pozitioneaza cursorul in fisier intr-o anumita locatie.
Pentru a inchide fisierul folosim metoda close().