Cuprins
1. Subprograme / funcții
funcții def apel reutilizare1.1. Ce este un program?
Un program este o succesiune de instrucțiuni pe care calculatorul le execută într-o anumită ordine.
De exemplu:
a = 5
b = 7
c = a + b
print(c)
Calculatorul execută instrucțiunile în ordine:
a primește valoarea 5.
b primește valoarea 7.
c.
print(c) afișează 12.
1.2. De ce avem nevoie de funcții?
Imaginăm-ne că avem un program foarte mare în care trebuie să efectuăm aceeași operație de zeci de ori.
Dacă scriem de fiecare dată toate instrucțiunile, programul devine lung și greu de înțeles.
1.3. Prima funcție
def salut():
print("Salut!")
Să analizăm fiecare element:
def— spune lui Python că definim o funcție;salut— numele funcției;()— locul în care pot apărea parametrii;:— marchează începutul corpului funcției;print("Salut!")— instrucțiunea executată de funcție.
1.4. Apelarea unei funcții
def salut():
print("Salut!")
salut()
Linia:
salut()
este un apel de funcție.
Prin acest apel îi spunem calculatorului:
„Execută instrucțiunile funcției salut”.
def mesaj():
print("Buna ziua!")
mesaj()
Mai întâi funcția este definită.
Apoi, prin mesaj(), ea este executată.
def salut():
print("Salut!")
salut()
salut()
salut()
Nu a trebuit să rescriem instrucțiunea
print("Salut!") de trei ori.
Am definit funcția o singură dată și am apelat-o de trei ori.
def calculeaza():
a = 4
b = 7
print(a + b)
calculeaza()
Funcția execută cele două atribuiri, apoi calculează suma și afișează rezultatul.
1.5. Funcții cu parametri
Uneori vrem ca funcția să primească informații din exterior.
De exemplu, nu vrem o funcție care salută mereu aceeași persoană. Vrem să putem spune:
salut("Ana")
salut("Mihai")
salut("Ioana")
Pentru aceasta folosim parametri.
def salut(nume):
print("Salut", nume)
Aici nume este parametrul funcției.
def salut(nume):
print("Salut", nume)
salut("Ana")
salut("Mihai")
1.6. Funcții care returnează valori
O funcție poate nu doar să afișeze ceva, ci și să producă o valoare pe care restul programului să o poată folosi.
Pentru aceasta folosim instrucțiunea return.
def suma(a, b):
return a + b
Dacă apelăm:
x = suma(4, 7)
funcția calculează 11 și transmite această valoare înapoi. Prin urmare:
x = 11
def suma(a, b):
return a + b
x = suma(4, 7)
print(x)
1.7. Diferența dintre print() și return
print() |
return |
|---|---|
| Afișează ceva pe ecran. | Trimite o valoare înapoi din funcție. |
| Este destinat afișării. | Este destinat transmiterii rezultatului. |
| Rezultatul nu poate fi folosit direct ca valoare returnată. | Rezultatul poate fi memorat într-o variabilă. |
def suma(a, b):
return a + b
x = suma(4, 7)
y = x * 2
print(y)
Prima funcție produce 11.
Valoarea este memorată în x.
Apoi putem face alte calcule cu ea.
2. Parametri și argumente
parametru argument local global return2.1. Ce este un parametru?
def salut(nume):
print("Salut", nume)
În acest exemplu, nume este parametrul.
Parametrul poate fi privit ca un „loc” în care funcția va primi o valoare.
2.2. Ce este un argument?
salut("Ana")
Aici:
numeeste parametrul;"Ana"este argumentul.
def patrat(x):
return x * x
print(patrat(6))
x este parametrul.
6 este argumentul.
În timpul apelului:
x = 6
Funcția calculează:
6 * 6 = 36
def suma(a, b):
return a + b
print(suma(10, 3))
Avem doi parametri:
a și b.
Avem două argumente:
10 și 3.
Asocierea se face în ordine:
a = 10
b = 3
def maxim3(a, b, c):
m = a
if b > m:
m = b
if c > m:
m = c
return m
print(maxim3(7, 12, 9))
La apel:
a = 7
b = 12
c = 9
Funcția compară cele trei valori și returnează 12.
2.3. Parametrii sunt locali funcției
Un parametru există în cadrul execuției funcției în care a fost definit.
De exemplu:
def dublu(x):
return 2 * x
print(dublu(5))
x este un parametru al funcției dublu.
El este disponibil în interiorul funcției.
2.4. Variabile locale
def calcul():
x = 5
y = 7
suma = x + y
print(suma)
calcul()
Variabilele x, y și suma
sunt create în interiorul funcției.
def patrat(n):
rezultat = n * n
return rezultat
print(patrat(4))
n este parametrul.
rezultat este o variabilă locală.
La apel:
n = 4
rezultat = 16
def dublu(x):
y = 2 * x
return y
print(dublu(3))
print(dublu(10))
La primul apel:
x = 3
y = 6
La al doilea apel:
x = 10
y = 20
2.5. Variabile globale
x = 10
def afisare():
print(x)
afisare()
Variabila x este creată în afara funcției.
De aceea este globală.
x = 5
def f():
print(x)
def g():
print(x * 2)
f()
g()
x = 100
def f(x):
print(x)
f(5)
print(x)
Există două variabile diferite:
x global = 100
x local = 5
În interiorul funcției este folosit parametrul local.
return.
2.6. Recomandarea practică
def suma(a, b):
return a + b
print(suma(10, 20))
print(suma(3, 8))
print(suma(-5, 10))
Această funcție nu depinde de variabile globale. Primește datele de care are nevoie prin parametri și returnează rezultatul.
3. Domeniul variabilelor
local global vizibilitate3.1. Ce înseamnă domeniul unei variabile?
O variabilă nu este neapărat disponibilă în orice loc al programului.
3.2. Variabilă locală
def test():
x = 10
print(x)
test()
Variabila x este creată în funcție.
Ea este locală funcției.
3.3. Ce se întâmplă dacă încercăm să o folosim în exterior?
def test():
x = 10
test()
print(x)
Aici apare o problemă deoarece x nu a fost definită
în zona în care încercăm să o folosim.
3.4. Cum trimitem rezultatul în exterior?
Folosim return.
def test():
x = 10
return x
y = test()
print(y)
Variabila locală x este folosită în funcție,
iar valoarea ei este transmisă în exterior prin return.
3.5. De ce este recomandat acest stil?
Funcțiile devin mai ușor de înțeles dacă:
- primesc datele necesare prin parametri;
- folosesc variabile locale pentru calcule;
- returnează rezultatul.
def patrat(n):
rezultat = n * n
return rezultat
Aceasta este o funcție simplă, clară și reutilizabilă.
4. Tupluri
tuple index despachetare4.1. Ce este un tuplu?
De exemplu:
persoana = ("Ana", 17, 9.50)
Tuplul conține trei elemente:
"Ana"179.50
4.2. Indexarea
Elementele sunt numerotate începând de la 0.
persoana = ("Ana", 17, 9.50)
print(persoana[0])
print(persoana[1])
print(persoana[2])
4.3. Tuplu versus listă
| Listă | Tuplu |
|---|---|
[1, 2, 3] |
(1, 2, 3) |
| Este modificabilă. | Este destinată unei colecții care nu trebuie modificată. |
| Utilă când datele se schimbă. | Util când vrem să grupăm valori fixe. |
punct = (10, 20)
x = punct[0]
y = punct[1]
print(x)
print(y)
culori = ("rosu", "verde", "albastru")
for culoare in culori:
print(culoare)
punct = (5, 8)
x, y = punct
print(x)
print(y)
Python face automat:
x = 5
y = 8
5. Mulțimi
set elemente distincte in reuniune intersecție5.1. Ce este o mulțime?
s = {2, 4, 2, 7, 4}
print(s)
Valorile repetate sunt eliminate conceptual.
Mulțimea reprezintă valorile distincte:
{2, 4, 7}
5.2. Verificarea apartenenței
s = {2, 4, 7}
print(4 in s)
print(5 in s)
5.3. Reuniunea
Operatorul | realizează reuniunea a două mulțimi.
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b)
Rezultatul conține elementele care apar în cel puțin una dintre cele două mulțimi.
{1, 2, 3, 4, 5}
5.4. Intersecția
Operatorul & realizează intersecția.
a = {1, 2, 3}
b = {3, 4, 5}
print(a & b)
Elementul comun este 3.
{3}
a = [2, 5, 2, 7, 5, 2]
s = set(a)
print(s)
Lista conține repetări, dar mulțimea păstrează doar valorile distincte.
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
comune = a & b
print(comune)
a = {1, 2, 3}
b = {4, 5}
toate = a | b
print(toate)
6. Dicționare
dict cheie valoare frecvențe6.1. Ce este un dicționar?
De exemplu:
note = {
"Ana": 10,
"Mihai": 8,
"Dan": 7
}
Putem interpreta datele astfel:
"Ana" → 10
"Mihai" → 8
"Dan" → 7
6.2. Cheia și valoarea
În:
"Ana": 10
"Ana"este cheia;10este valoarea.
6.3. Accesarea unei valori
print(note["Ana"])
Python caută cheia "Ana" și returnează valoarea
asociată acesteia.
note = {
"Ana": 10,
"Mihai": 8
}
print(note["Ana"])
print(note["Mihai"])
6.4. Adăugarea unei perechi
note = {}
note["Ana"] = 10
note["Mihai"] = 8
Acum dicționarul conține două perechi.
note = {}
note["Ana"] = 10
note["Mihai"] = 8
note["Ana"] = 9
print(note)
A doua atribuire pentru "Ana" modifică nota.
Nu creează o a doua cheie "Ana".
6.5. Verificarea existenței unei chei
if "Mihai" in note:
print(note["Mihai"])
Operatorul in verifică dacă cheia există în dicționar.
6.6. Parcurgerea unui dicționar
for nume in note:
print(nume, note[nume])
La fiecare pas, variabila nume primește o cheie.
Cu note[nume] obținem valoarea asociată.
a = [2, 3, 2, 5, 3, 2]
frecvente = {}
for x in a:
if x in frecvente:
frecvente[x] = frecvente[x] + 1
else:
frecvente[x] = 1
print(frecvente)
Dicționarul va memora:
2 → 3
3 → 2
5 → 1
Astfel putem afla de câte ori apare fiecare valoare.
6.7. Funcție care calculează frecvențele
def frecvente(a):
f = {}
for x in a:
if x in f:
f[x] = f[x] + 1
else:
f[x] = 1
return f
a = [2, 3, 2, 5, 3, 2]
print(frecvente(a))
Aici folosim simultan:
- funcții;
- parametri;
- variabile locale;
- liste;
- dicționare;
- structuri repetitive;
- condiții;
return.
7. Recursivitate
recursivitate caz de bază apel recursiv factorial7.1. Ce este recursivitatea?
De exemplu:
def f(n):
f(n - 1)
Funcția f apelează din nou funcția f.
7.2. Cazul de bază
O funcție recursivă are nevoie de o situație în care se oprește. Aceasta se numește caz de bază.
def f(n):
if n == 0:
return
f(n - 1)
Când n devine 0, nu mai facem un apel recursiv.
7.3. Cazul recursiv
Partea:
f(n - 1)
este cazul recursiv.
Pentru ca recursivitatea să funcționeze, trebuie ca fiecare apel să se apropie de cazul de bază.
7.4. Exemplul 1 — Factorial
Factorialul unui număr natural pozitiv este:
De asemenea:
Putem observa relația:
Această formulă este potrivită pentru recursivitate.
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
print(factorial(5))
Urmărim apelurile:
factorial(5)
↓
5 * factorial(4)
↓
5 * 4 * factorial(3)
↓
5 * 4 * 3 * factorial(2)
↓
5 * 4 * 3 * 2 * factorial(1)
↓
5 * 4 * 3 * 2 * 1 * factorial(0)
Ajungem la cazul de bază:
factorial(0) = 1
Apoi rezultatele se întorc:
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
7.5. Exemplul 2 — Suma numerelor de la 1 la n
Dorim:
1 + 2 + 3 + ... + n
Putem scrie:
Cazul de bază:
def suma(n):
if n == 0:
return 0
return n + suma(n - 1)
print(suma(5))
Calculul este:
5 + 4 + 3 + 2 + 1 + 0 = 15
7.6. Exemplul 3 — Numărul de cifre
Pentru numărul:
52731
avem 5 cifre.
Dacă eliminăm ultima cifră folosind:
n // 10
obținem:
52731 → 5273 → 527 → 52 → 5
Putem defini funcția:
def numar_cifre(n):
if n < 10:
return 1
return 1 + numar_cifre(n // 10)
print(numar_cifre(52731))
7.7. Exemplul 4 — Suma cifrelor
Pentru:
527
dorim:
5 + 2 + 7 = 14
Ultima cifră poate fi obținută cu:
n % 10
Iar numărul fără ultima cifră:
n // 10
Prin urmare:
def suma_cifre(n):
if n == 0:
return 0
return n % 10 + suma_cifre(n // 10)
print(suma_cifre(527))
Urmărirea:
527 % 10 = 7
52 % 10 = 2
5 % 10 = 5
Deci:
7 + 2 + 5 = 14
7.8. Cele două întrebări obligatorii la orice recursivitate
Când întâlnim o problemă recursivă, trebuie să ne întrebăm:
Dacă nu putem răspunde la aceste două întrebări, probabil că soluția recursivă nu este încă bine construită.
7.9. Greșeală: recursivitate infinită
def f(n):
return f(n)
Funcția se apelează cu exact aceeași valoare și nu se apropie niciodată de un caz de bază.
O altă problemă:
def f(n):
if n == 0:
return 0
return f(n + 1)
Dacă pornim cu 5:
5 → 6 → 7 → 8 → 9 → ...
Ne îndepărtăm de cazul de bază 0.
8. Probleme de sinteză
În problemele reale, noțiunile nu apar separat. Este foarte posibil să trebuiască să folosim mai multe concepte în aceeași problemă.
Problema 1 — Suma elementelor unui vector
Se dă o listă de numere. Să se calculeze suma elementelor.
def suma_vector(a):
s = 0
for x in a:
s = s + x
return s
a = [2, 5, 7, 1]
print(suma_vector(a))
Funcția primește lista prin parametrul a.
Variabila s este locală.
Pentru fiecare element x, acesta este adăugat la sumă.
La final, return s trimite rezultatul.
Problema 2 — Maximul unui vector
def maxim_vector(a):
m = a[0]
for x in a:
if x > m:
m = x
return m
a = [4, 9, 2, 8]
print(maxim_vector(a))
Pornim de la primul element ca valoare maximă presupusă.
Apoi verificăm fiecare element.
Dacă găsim unul mai mare, actualizăm maximul.
Problema 3 — Numărul de vocale
def numar_vocale(s):
nr = 0
for c in s:
if c in "aeiouAEIOU":
nr = nr + 1
return nr
s = input()
print(numar_vocale(s))
Funcția primește un șir de caractere. Parcurgem fiecare caracter și verificăm dacă este vocală.
Problema 4 — Funcție care verifică dacă un număr este par
def este_par(n):
return n % 2 == 0
n = int(input())
if este_par(n):
print("DA")
else:
print("NU")
Funcția nu afișează nimic.
Ea returnează True sau False.
Programul principal decide apoi ce mesaj afișează.
Problema 5 — Factorial
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
n = int(input())
print(factorial(n))
Aici avem o funcție recursivă.
Cazul de bază este:
n == 0
iar cazul recursiv este:
n * factorial(n - 1)
Recapitulare — ce trebuie să știm din Partea 3?
Funcții
- Știm ce este o funcție.
- Știm să definim o funcție folosind
def. - Știm să apelăm o funcție.
- Știm că definirea și apelarea sunt lucruri diferite.
Parametri și argumente
- Știm ce este un parametru.
- Știm ce este un argument.
- Știm diferența dintre ele.
- Știm să folosim mai mulți parametri.
Variabile
- Știm ce este o variabilă locală.
- Știm ce este o variabilă globală.
- Înțelegem domeniul unei variabile.
- Știm de ce parametrii sunt locali funcției.
return
- Știm că
returntransmite o valoare din funcție. - Știm diferența dintre
returnșiprint(). - Știm să folosim rezultatul unei funcții într-un alt calcul.
Tupluri
- Știm ce este un tuplu.
- Știm să accesăm elementele prin index.
- Știm să parcurgem un tuplu.
- Știm ce este despachetarea.
Mulțimi
- Știm că mulțimile păstrează elemente distincte.
- Știm operatorul
in. - Știm reuniunea
|. - Știm intersecția
&.
Dicționare
- Știm ce este o cheie.
- Știm ce este o valoare.
- Știm să accesăm o valoare folosind cheia.
- Știm să adăugăm și să modificăm perechi.
- Știm să verificăm existența unei chei.
- Știm să folosim dicționare pentru frecvențe.
Recursivitate
- Știm ce este o funcție recursivă.
- Știm ce este cazul de bază.
- Știm ce este cazul recursiv.
- Știm de ce recursivitatea trebuie să se apropie de cazul de bază.
- Știm să construim funcții recursive simple.
return transmite rezultatele înapoi.
Tuplurile, mulțimile și dicționarele ne permit să reprezentăm
diferite tipuri de date, iar recursivitatea ne permite să rezolvăm
anumite probleme prin reducerea lor la versiuni mai mici ale aceleiași probleme.