Cum se folosește materialul
În prima parte a fiecărui capitol sunt prezentate cele 25 de enunțuri. Mai jos, fiecare problemă este reluată și explicată. Recomandarea este să citești doar enunțul, să încerci singur, apoi să deschizi problema pentru strategie și explicație.
Capitolul 4. Eficiența algoritmilor și notația O
25 de probleme dificile și foarte dificile. Tema este construită pe conceptele din pagina sursă: capitolul 4 și subtemele sale.
Partea I – Lista enunțurilor
- Parcurgere cu salturi — Se dă o listă cu n numere. Găsește cel mai mic element folosind o strategie care nu verifică fiecare poziție atunci când poate elimina simultan o porțiune de căutare.
- Două variante ale aceleiași probleme — Se cere să găsești dacă o valoare x apare într-o listă. Compară o soluție liniară cu una care folosește sortarea și căutarea binară. Precizează complexitatea fiecărei variante.
- Numărul de perechi distincte — Pentru n valori, determină numărul de perechi de indici i<j care satisfac o condiție dată. Proiectează o soluție mai bună decât enumerarea tuturor perechilor atunci când condiția permite numărare cumulativă.
- Triplete cu sumă fixă — Se dă o listă și o valoare S. Numără tripletele distincte cu suma S și urmărește o soluție mai eficientă decât trei bucle imbricate.
- Elementul majoritar — Găsește valoarea care apare strict mai mult decât n/2 ori sau precizează că nu există. Analizează memoria și timpul soluției.
- Prefixe și interogări — Se dau n numere și q întrebări de forma «care este suma elementelor din intervalul [l,r]?». Construiește o soluție care răspunde rapid la fiecare întrebare.
- Căutare într-o secvență ordonată — Se dă o listă crescătoare și q valori x. Pentru fiecare x, determină prima poziție unde poate fi inserat fără a strica ordinea. Evită parcurgerea completă pentru fiecare întrebare.
- Fereastră glisantă — Găsește lungimea celui mai lung subșir contiguu cu sumă cel mult S, presupunând că toate valorile sunt pozitive. Explică de ce două bucle nu sunt necesare.
- Subșir cu sumă maximă — Determină suma maximă a unui subșir contiguu. Compară metoda brută cu o metodă liniară.
- Sortare versus selecție — Pentru o listă, găsește al k-lea cel mai mic element. Compară sortarea completă cu o abordare bazată pe selecție și explică impactul asupra complexității.
- Eliminarea duplicatelor — Construiește o soluție care păstrează prima apariție a fiecărui element. Compară varianta cu listă auxiliară și varianta cu structură de tip mulțime.
- Două sume egale — Verifică dacă există două valori distincte a căror sumă este S. Explică de ce o structură auxiliară poate reduce timpul.
- Inversarea unei liste — Inversează o listă fără a construi o a doua listă. Analizează complexitatea temporală și spațială.
- Palindrom eficient — Verifică dacă o listă este palindrom folosind doi indici care se apropie din capete. Explică numărul maxim de comparații.
- Număr de inversiuni — Numără perechile i<j pentru care a[i]>a[j]. Discută de ce metoda directă este O(n²) și ce tip de idee ar putea reduce timpul.
- Intervale care se suprapun — Se dau intervale [a,b]. Determină câte perechi se suprapun. Propune o metodă bazată pe sortare și compară cu verificarea tuturor perechilor.
- Cea mai lungă secvență de valori egale — Găsește lungimea maximă a unei secvențe consecutive de valori identice. Explică de ce o singură parcurgere este suficientă.
- Drum minim pe grilă simplificată — Într-o grilă fără obstacole, calculează numărul minim de pași dintre două celule dacă sunt permise doar deplasările dreapta și jos. Analizează formula și memoria.
- Program cu bucle ascunse — Analizează complexitatea unui algoritm care are o buclă ce dublează i la fiecare pas și una care parcurge n elemente. Identifică termenul dominant.
- Complexitate recursivă — Un algoritm împarte problema în două subprobleme de dimensiune n/2 și apoi parcurge n elemente. Estimează complexitatea și justifică răspunsul.
- Memorie suplimentară — Compară două soluții pentru prelucrarea unei liste: una creează trei liste auxiliare de n elemente, cealaltă modifică lista în loc. Analizează memoria.
- Top k frecvențe — Găsește cele mai frecvente k valori dintr-o listă. Descrie o soluție prin frecvențe și ordonare și estimează complexitatea.
- Detectarea ciclului logic — Se dă o secvență generată printr-o regulă deterministă. Detectează repetarea fără a păstra toate valorile, folosind două viteze de avans.
- Benchmark conceptual — Pentru trei algoritmi de complexități O(n), O(n log n) și O(n²), explică ce se întâmplă când n crește de la 1.000 la 1.000.000 și justifică alegerea pentru date mari.
- Sinteză de eficiență — Proiectează un program care citește o listă, răspunde la întrebări de sumă, caută valori și raportează duplicatele. Impune condiția ca operațiile repetate să fie cât mai eficiente.
4. Eficiența algoritmilor și notația O
Exerciții axate pe alegerea algoritmului, numărarea operațiilor, preprocesare și reducerea complexității.
Partea I – Lista enunțurilor
- Parcurgere cu salturi — Se dă o listă cu n numere. Găsește cel mai mic element folosind o strategie care nu verifică fiecare poziție atunci când poate elimina simultan o porțiune de căutare.
- Două variante ale aceleiași probleme — Se cere să găsești dacă o valoare x apare într-o listă. Compară o soluție liniară cu una care folosește sortarea și căutarea binară. Precizează complexitatea fiecărei variante.
- Numărul de perechi distincte — Pentru n valori, determină numărul de perechi de indici i<j care satisfac o condiție dată. Proiectează o soluție mai bună decât enumerarea tuturor perechilor atunci când condiția permite numărare cumulativă.
- Triplete cu sumă fixă — Se dă o listă și o valoare S. Numără tripletele distincte cu suma S și urmărește o soluție mai eficientă decât trei bucle imbricate.
- Elementul majoritar — Găsește valoarea care apare strict mai mult decât n/2 ori sau precizează că nu există. Analizează memoria și timpul soluției.
- Prefixe și interogări — Se dau n numere și q întrebări de forma «care este suma elementelor din intervalul [l,r]?». Construiește o soluție care răspunde rapid la fiecare întrebare.
- Căutare într-o secvență ordonată — Se dă o listă crescătoare și q valori x. Pentru fiecare x, determină prima poziție unde poate fi inserat fără a strica ordinea. Evită parcurgerea completă pentru fiecare întrebare.
- Fereastră glisantă — Găsește lungimea celui mai lung subșir contiguu cu sumă cel mult S, presupunând că toate valorile sunt pozitive. Explică de ce două bucle nu sunt necesare.
- Subșir cu sumă maximă — Determină suma maximă a unui subșir contiguu. Compară metoda brută cu o metodă liniară.
- Sortare versus selecție — Pentru o listă, găsește al k-lea cel mai mic element. Compară sortarea completă cu o abordare bazată pe selecție și explică impactul asupra complexității.
- Eliminarea duplicatelor — Construiește o soluție care păstrează prima apariție a fiecărui element. Compară varianta cu listă auxiliară și varianta cu structură de tip mulțime.
- Două sume egale — Verifică dacă există două valori distincte a căror sumă este S. Explică de ce o structură auxiliară poate reduce timpul.
- Inversarea unei liste — Inversează o listă fără a construi o a doua listă. Analizează complexitatea temporală și spațială.
- Palindrom eficient — Verifică dacă o listă este palindrom folosind doi indici care se apropie din capete. Explică numărul maxim de comparații.
- Număr de inversiuni — Numără perechile i<j pentru care a[i]>a[j]. Discută de ce metoda directă este O(n²) și ce tip de idee ar putea reduce timpul.
- Intervale care se suprapun — Se dau intervale [a,b]. Determină câte perechi se suprapun. Propune o metodă bazată pe sortare și compară cu verificarea tuturor perechilor.
- Cea mai lungă secvență de valori egale — Găsește lungimea maximă a unei secvențe consecutive de valori identice. Explică de ce o singură parcurgere este suficientă.
- Drum minim pe grilă simplificată — Într-o grilă fără obstacole, calculează numărul minim de pași dintre două celule dacă sunt permise doar deplasările dreapta și jos. Analizează formula și memoria.
- Program cu bucle ascunse — Analizează complexitatea unui algoritm care are o buclă ce dublează i la fiecare pas și una care parcurge n elemente. Identifică termenul dominant.
- Complexitate recursivă — Un algoritm împarte problema în două subprobleme de dimensiune n/2 și apoi parcurge n elemente. Estimează complexitatea și justifică răspunsul.
- Memorie suplimentară — Compară două soluții pentru prelucrarea unei liste: una creează trei liste auxiliare de n elemente, cealaltă modifică lista în loc. Analizează memoria.
- Top k frecvențe — Găsește cele mai frecvente k valori dintr-o listă. Descrie o soluție prin frecvențe și ordonare și estimează complexitatea.
- Detectarea ciclului logic — Se dă o secvență generată printr-o regulă deterministă. Detectează repetarea fără a păstra toate valorile, folosind două viteze de avans.
- Benchmark conceptual — Pentru trei algoritmi de complexități O(n), O(n log n) și O(n²), explică ce se întâmplă când n crește de la 1.000 la 1.000.000 și justifică alegerea pentru date mari.
- Sinteză de eficiență — Proiectează un program care citește o listă, răspunde la întrebări de sumă, caută valori și raportează duplicatele. Impune condiția ca operațiile repetate să fie cât mai eficiente.
Partea II – Enunț + explicație detaliată + rezolvare efectivă
1. Parcurgere cu salturiDificil
Enunțul problemei
Se dă o listă cu n numere. Găsește cel mai mic element folosind o strategie care nu verifică fiecare poziție atunci când poate elimina simultan o porțiune de căutare.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def minim_fara_parcurgere_completa(a):
# Exemplu: folosim o idee de salt doar pentru o listă deja ordonată pe blocuri.
# Pentru o listă nesortată, minimul trebuie verificat în cel mai rău caz pe toate valorile.
minim = a[0]
for x in a[1:]:
if x < minim:
minim = x
return minim
a = [17, 8, 23, 4, 11]
print(minim_fara_parcurgere_completa(a))Explicația rezolvării: Pornim de la primul element ca minim provizoriu. Apoi comparăm fiecare valoare cu acesta și îl actualizăm când găsim una mai mică. Este important de observat că enunțul cere o strategie care poate elimina porțiuni doar dacă există informație suplimentară despre ordine; pentru o listă complet nesortată, nu există o metodă corectă care să ignore arbitrar elemente. Complexitatea soluției generale este O(n), iar memoria suplimentară este O(1).
2. Două variante ale aceleiași problemeDificil
Enunțul problemei
Se cere să găsești dacă o valoare x apare într-o listă. Compară o soluție liniară cu una care folosește sortarea și căutarea binară. Precizează complexitatea fiecărei variante.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def cauta_liniar(a, x):
return x in a
def cauta_binar(a, x):
st, dr = 0, len(a) - 1
while st <= dr:
m = (st + dr) // 2
if a[m] == x: return True
if a[m] < x: st = m + 1
else: dr = m - 1
return False
a = [1, 4, 7, 10, 15, 21]
print(cauta_liniar(a, 10))
print(cauta_binar(a, 10))Explicația rezolvării: Prima variantă verifică succesiv elementele și are O(n) în cel mai rău caz. A doua folosește faptul că lista este sortată: la fiecare pas eliminăm jumătate din intervalul de căutare, deci avem O(log n). Dacă lista nu este sortată, trebuie întâi sortată, ceea ce adaugă O(n log n); pentru o singură căutare, acest cost poate să nu merite.
3. Numărul de perechi distincteDificil
Enunțul problemei
Pentru n valori, determină numărul de perechi de indici i<j care satisfac o condiție dată. Proiectează o soluție mai bună decât enumerarea tuturor perechilor atunci când condiția permite numărare cumulativă.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def numara_perechi(a, S):
frec = {}
rezultat = 0
for x in a:
rezultat += frec.get(S - x, 0)
frec[x] = frec.get(x, 0) + 1
return rezultat
print(numara_perechi([1, 5, 3, 3, 7], 8))Explicația rezolvării: Dicționarul memorează câte valori am întâlnit înainte. Pentru x, orice valoare S-x văzută anterior formează o pereche validă. Astfel evităm două bucle imbricate. Fiecare acces în dicționar este în medie O(1), deci timpul este O(n), iar memoria O(n).
4. Triplete cu sumă fixăDificil
Enunțul problemei
Se dă o listă și o valoare S. Numără tripletele distincte cu suma S și urmărește o soluție mai eficientă decât trei bucle imbricate.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def triplete(a, S):
a = sorted(a)
n = len(a); nr = 0
for i in range(n - 2):
l, r = i + 1, n - 1
while l < r:
suma = a[i] + a[l] + a[r]
if suma == S:
nr += 1; l += 1; r -= 1
elif suma < S: l += 1
else: r -= 1
return nr
print(triplete([1,2,3,4,5,6], 10))Explicația rezolvării: Sortăm lista, apoi fixăm primul element al tripletului. Ceilalți doi indici se deplasează dinspre capete. Dacă suma este prea mică, creștem indicele din stânga; dacă este prea mare, îl micșorăm pe cel din dreapta. După sortare, timpul este O(n²), mai bun decât O(n³).
5. Elementul majoritarDificil
Enunțul problemei
Găsește valoarea care apare strict mai mult decât n/2 ori sau precizează că nu există. Analizează memoria și timpul soluției.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def majoritar(a):
candidat = None; cnt = 0
for x in a:
if cnt == 0: candidat, cnt = x, 1
elif x == candidat: cnt += 1
else: cnt -= 1
return candidat if a.count(candidat) > len(a)//2 else None
print(majoritar([2,2,1,2,3,2,2]))Explicația rezolvării: Algoritmul Boyer-Moore pentru majoritate păstrează un candidat și un contor. Valorile diferite se anulează conceptual. La final, candidatul trebuie verificat încă o dată, deoarece existența unui candidat nu garantează majoritatea. Timpul este O(n), memoria O(1).
6. Prefixe și interogăriDificil
Enunțul problemei
Se dau n numere și q întrebări de forma «care este suma elementelor din intervalul [l,r]?». Construiește o soluție care răspunde rapid la fiecare întrebare.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def pregateste_prefix(a):
p=[0]
for x in a: p.append(p[-1]+x)
return p
def suma_interval(p,l,r):
return p[r+1]-p[l]
a=[3,1,4,2,5]; p= pregateste_prefix(a)
print(suma_interval(p,1,3))Explicația rezolvării: Construim vectorul de sume prefixate, unde p[i] este suma primelor i elemente. Suma [l,r] devine p[r+1]-p[l], deci fiecare întrebare se rezolvă în O(1). Preprocesarea este O(n), iar q întrebări costă O(q).
7. Căutare într-o secvență ordonatăDificil
Enunțul problemei
Se dă o listă crescătoare și q valori x. Pentru fiecare x, determină prima poziție unde poate fi inserat fără a strica ordinea. Evită parcurgerea completă pentru fiecare întrebare.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
from bisect import bisect_left
a=[1,3,3,7,10,15]
for x in [0,3,6,20]:
print(x, bisect_left(a,x))Explicația rezolvării: bisect_left găsește primul indice la care x poate fi introdus păstrând ordinea. Căutarea binară elimină jumătate din interval la fiecare pas, deci fiecare interogare este O(log n). Pentru q întrebări obținem O(q log n).
8. Fereastră glisantăDificil
Enunțul problemei
Găsește lungimea celui mai lung subșir contiguu cu sumă cel mult S, presupunând că toate valorile sunt pozitive. Explică de ce două bucle nu sunt necesare.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def max_lungime(a,S):
st=suma=best=0
for dr,x in enumerate(a):
suma += x
while suma>S:
suma -= a[st]; st += 1
best=max(best,dr-st+1)
return best
print(max_lungime([2,1,3,2,1],6))Explicația rezolvării: Pentru valori pozitive, dacă suma ferestrei depășește S, micșorarea ferestrei din stânga poate doar să scadă suma. Fiecare element intră și iese cel mult o dată, deci timpul este O(n), nu O(n²).
9. Subșir cu sumă maximăDificil
Enunțul problemei
Determină suma maximă a unui subșir contiguu. Compară metoda brută cu o metodă liniară.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def max_subsir(a):
cur=best=a[0]
for x in a[1:]:
cur=max(x,cur+x)
best=max(best,cur)
return best
print(max_subsir([-2,3,-1,4,-5,2]))Explicația rezolvării: La fiecare poziție alegem între a începe un subșir nou cu x sau a continua subșirul anterior. Variabila cur reține cea mai bună sumă care se termină în poziția curentă, iar best reține maximul global. Este algoritmul lui Kadane, O(n) timp și O(1) memorie.
10. Sortare versus selecțieDificil
Enunțul problemei
Pentru o listă, găsește al k-lea cel mai mic element. Compară sortarea completă cu o abordare bazată pe selecție și explică impactul asupra complexității.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def kth(a,k):
b=sorted(a)
return b[k-1]
a=[9,2,7,4,5]
print(kth(a,3))Explicația rezolvării: Sortarea completă oferă direct al k-lea element, dar costă O(n log n). O alternativă este selecția/Quickselect, care are O(n) în medie și O(n²) în cel mai rău caz. Pentru claritate și robustețe, sortarea este soluția simplă prezentată aici.
11. Eliminarea duplicatelorDificil
Enunțul problemei
Construiește o soluție care păstrează prima apariție a fiecărui element. Compară varianta cu listă auxiliară și varianta cu structură de tip mulțime.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def fara_duplicate(a):
rezultat=[]; vazute=set()
for x in a:
if x not in vazute:
vazute.add(x); rezultat.append(x)
return rezultat
print(fara_duplicate([3,1,3,2,1,4]))Explicația rezolvării: Mulțimea vazute ne spune în O(1) mediu dacă elementul a mai apărut. Lista rezultat păstrează ordinea primei apariții. Timpul mediu este O(n), memoria O(n). Varianta doar cu listă auxiliară ar putea ajunge la O(n²).
12. Două sume egaleDificil
Enunțul problemei
Verifică dacă există două valori distincte a căror sumă este S. Explică de ce o structură auxiliară poate reduce timpul.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def exista_suma(a,S):
vazute=set()
for x in a:
if S-x in vazute: return True
vazute.add(x)
return False
print(exista_suma([10,4,7,2],9))Explicația rezolvării: Pentru fiecare x căutăm complementul S-x în mulțimea valorilor deja văzute. Astfel fiecare element este procesat o singură dată. Timp mediu O(n), memorie O(n).
13. Inversarea unei listeDificil
Enunțul problemei
Inversează o listă fără a construi o a doua listă. Analizează complexitatea temporală și spațială.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def inverseaza(a):
i,j=0,len(a)-1
while i<j:
a[i],a[j]=a[j],a[i]
i+=1; j-=1
return a
print(inverseaza([1,2,3,4,5]))Explicația rezolvării: Folosim doi indici și interschimbăm elementele simetrice. Nu creăm o a doua listă. Fiecare element este mutat cel mult o dată, deci O(n) timp și O(1) memorie suplimentară.
14. Palindrom eficientDificil
Enunțul problemei
Verifică dacă o listă este palindrom folosind doi indici care se apropie din capete. Explică numărul maxim de comparații.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def palindrom(a):
i,j=0,len(a)-1
while i<j:
if a[i]!=a[j]: return False
i+=1; j-=1
return True
print(palindrom([1,2,3,2,1]))Explicația rezolvării: Comparăm primul cu ultimul, apoi al doilea cu penultimul și continuăm spre centru. Ne oprim imediat la o diferență. În cel mai rău caz facem n//2 comparații, deci O(n) timp și O(1) memorie.
15. Număr de inversiuniDificil
Enunțul problemei
Numără perechile i<j pentru care a[i]>a[j]. Discută de ce metoda directă este O(n²) și ce tip de idee ar putea reduce timpul.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def inversiuni(a):
nr=0
for i in range(len(a)):
for j in range(i+1,len(a)):
if a[i]>a[j]: nr+=1
return nr
print(inversiuni([2,4,1,3,5]))Explicația rezolvării: Enumerăm fiecare pereche i<j și verificăm relația. Numărul de perechi este n(n-1)/2, deci O(n²). Pentru n mare, o idee mai avansată este numărarea inversiunilor prin merge-sort în O(n log n).
16. Intervale care se suprapunFoarte dificil
Enunțul problemei
Se dau intervale [a,b]. Determină câte perechi se suprapun. Propune o metodă bazată pe sortare și compară cu verificarea tuturor perechilor.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def se_suprapun(x,y):
a,b=x; c,d=y
return max(a,c)<=min(b,d)
def numara(intervale):
intervale=sorted(intervale)
nr=0
for i in range(len(intervale)):
for j in range(i+1,len(intervale)):
if se_suprapun(intervale[i],intervale[j]): nr+=1
return nr
print(numara([(1,5),(4,8),(10,12),(7,11)]))Explicația rezolvării: Condiția exactă de suprapunere este max(a,c) <= min(b,d). Sortarea ajută la organizarea intervalelor și la optimizări ulterioare, dar verificarea tuturor perechilor rămâne O(n²). Pentru un algoritm avansat se poate folosi sweep-line pentru a coborî complexitatea.
17. Cea mai lungă secvență de valori egaleFoarte dificil
Enunțul problemei
Găsește lungimea maximă a unei secvențe consecutive de valori identice. Explică de ce o singură parcurgere este suficientă.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def cea_mai_lunga(a):
if not a: return 0
best=cur=1
for i in range(1,len(a)):
if a[i]==a[i-1]: cur+=1
else: cur=1
best=max(best,cur)
return best
print(cea_mai_lunga([1,1,2,2,2,3]))Explicația rezolvării: Ținem lungimea secvenței curente și maximul întâlnit. La schimbarea valorii, cur revine la 1. O singură parcurgere este suficientă: O(n) timp și O(1) memorie.
18. Drum minim pe grilă simplificatăFoarte dificil
Enunțul problemei
Într-o grilă fără obstacole, calculează numărul minim de pași dintre două celule dacă sunt permise doar deplasările dreapta și jos. Analizează formula și memoria.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def pasi(r1,c1,r2,c2):
if r2<r1 or c2<c1: return None
return (r2-r1)+(c2-c1)
print(pasi(1,2,4,6))Explicația rezolvării: Dacă avem voie doar dreapta și jos, fiecare pas crește fie rândul, fie coloana cu 1. Prin urmare numărul minim de pași este diferența de rânduri plus diferența de coloane. Memoria este O(1).
19. Program cu bucle ascunseFoarte dificil
Enunțul problemei
Analizează complexitatea unui algoritm care are o buclă ce dublează i la fiecare pas și una care parcurge n elemente. Identifică termenul dominant.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def complexitate(n):
i=1; pasi=0
while i<n:
i*=2; pasi+=1
# bucla liniara este separata
return pasi,n
print(complexitate(1_000_000))Explicația rezolvării: O buclă în care i se dublează are O(log n) pași. Dacă există și o buclă care parcurge n elemente, totalul devine O(n + log n), iar termenul dominant este O(n).
20. Complexitate recursivăFoarte dificil
Enunțul problemei
Un algoritm împarte problema în două subprobleme de dimensiune n/2 și apoi parcurge n elemente. Estimează complexitatea și justifică răspunsul.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def T(n):
if n<=1: return 1
return T(n//2)+T(n//2)+n
print(T(16))Explicația rezolvării: Recurrența este T(n)=2T(n/2)+O(n). La fiecare nivel al arborelui recursiv avem în total O(n) lucru, iar numărul de niveluri este O(log n). Rezultatul este O(n log n).
21. Memorie suplimentarăFoarte dificil
Enunțul problemei
Compară două soluții pentru prelucrarea unei liste: una creează trei liste auxiliare de n elemente, cealaltă modifică lista în loc. Analizează memoria.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def memorie(a):
# Varianta in-place folosește doar câteva variabile temporare.
for i in range(len(a)):
a[i] *= 2
return a
a=[1,2,3,4]
print(memorie(a))Explicația rezolvării: Trei liste auxiliare de n elemente înseamnă O(n) memorie suplimentară, cu un factor constant mai mare. Modificarea în loc folosește O(1) memorie suplimentară, dar schimbă lista originală. Alegerea depinde de cerința de păstrare a datelor.
22. Top k frecvențeFoarte dificil
Enunțul problemei
Găsește cele mai frecvente k valori dintr-o listă. Descrie o soluție prin frecvențe și ordonare și estimează complexitatea.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
from collections import Counter
def top_k(a,k):
frec=Counter(a)
return sorted(frec.items(), key=lambda p:p[1], reverse=True)[:k]
print(top_k([1,2,2,3,3,3,2],2))Explicația rezolvării: Counter construiește frecvențele într-o singură parcurgere. Apoi sortăm valorile distincte după frecvență. Dacă d este numărul de valori distincte, costul este O(n + d log d), cu memorie O(d).
23. Detectarea ciclului logicFoarte dificil
Enunțul problemei
Se dă o secvență generată printr-o regulă deterministă. Detectează repetarea fără a păstra toate valorile, folosind două viteze de avans.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def ciclu(f,x0,limita=10000):
broasca=f(x0); iepure=f(f(x0))
while broasca!=iepure and limita>0:
broasca=f(broasca); iepure=f(f(iepure)); limita-=1
return broasca==iepure
print(ciclu(lambda x:(x*x+1)%10,2))Explicația rezolvării: Folosim ideea „tortului și iepurelui”: un indicator avansează cu un pas, altul cu doi. Dacă există un ciclu, se vor întâlni. Avantajul este memoria O(1), față de păstrarea tuturor valorilor într-un set.
24. Benchmark conceptualFoarte dificil
Enunțul problemei
Pentru trei algoritmi de complexități O(n), O(n log n) și O(n²), explică ce se întâmplă când n crește de la 1.000 la 1.000.000 și justifică alegerea pentru date mari.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def estimari(n):
return {'O(n)':n,'O(n log n)':n*(n.bit_length()-1),'O(n^2)':n*n}
for n in (1000,1_000_000): print(n,estimari(n))Explicația rezolvării: Când n crește de la 1.000 la 1.000.000, O(n) crește de 1.000 ori, O(n²) de aproximativ 1.000.000 ori, iar O(n log n) rămâne mult mai aproape de comportamentul liniar. Pentru date mari evităm, pe cât posibil, O(n²).
25. Sinteză de eficiențăFoarte dificil
Enunțul problemei
Proiectează un program care citește o listă, răspunde la întrebări de sumă, caută valori și raportează duplicatele. Impune condiția ca operațiile repetate să fie cât mai eficiente.
Explicație detaliată
Problema urmărește alegerea unei strategii eficiente și analiza complexității. Identifică datele, operația repetată, cazurile-limită și costul în timp și memorie. După stabilirea ideii, verifică soluția pe un exemplu mic și apoi compară complexitatea cu varianta directă.
- Identifică exact ce trebuie calculat.
- Alege structura de date potrivită.
- Elimină calculele sau parcurgerile repetate atunci când este posibil.
- Testează cazuri obișnuite și cazuri-limită.
- Calculează complexitatea temporală și spațială.
Rezolvare efectivă
Cod Python:
def cautari_eficiente(a, intrebari):
# Structura auxiliară permite căutare medie O(1).
valori=set(a)
return [x in valori for x in intrebari]
a=[4,8,2,9,5]
print(cautari_eficiente(a,[2,7,9]))Explicația rezolvării: Varianta naivă verifică lista pentru fiecare întrebare: O(nm). Prin construirea unui set în O(n), fiecare test de apartenență este în medie O(1), deci totalul devine O(n+m). Preprocesarea merită când numărul de întrebări este mare.
Capitolul 5. Funcții matematice și conversii
25 de probleme dificile și foarte dificile. Tema este construită pe conceptele din pagina sursă: capitolul 5 și subtemele sale.
Partea I – Lista enunțurilor
- Distanța minimă între numere — Dintr-o listă de numere reale, găsește două valori cu diferența absolută minimă. Folosește abs() și explică de ce sortarea simplifică problema.
- Rotunjire controlată — Calculează media unor valori reale și afișeaz-o cu exact două zecimale, dar păstrează intern valoarea nerotunjită. Explică diferența dintre round() și format.
- Conversie sigură — Citește un șir și decide dacă poate reprezenta un număr întreg. Pentru valori valide, convertește-l cu int(); pentru cele invalide, explică strategia de tratare.
- Baze de numerație — Citește un număr scris în baza 2, 8 sau 16 și convertește-l în zecimal. Folosește int(text,baza) și explică rolul celui de-al doilea argument.
- Trunchiere versus rotunjire — Pentru mai multe numere reale negative și pozitive, afișează separat int(x), round(x) și valoarea inferioară calculată cu floor(). Explică diferențele.
- Distanță euclidiană — Se dau două puncte în plan. Calculează distanța dintre ele folosind sqrt() și abs() acolo unde este util. Precizează cazurile-limită.
- Ecuație de gradul al doilea — Rezolvă o ecuație ax²+bx+c=0 pentru coeficienți reali. Folosește sqrt() pentru discriminant și tratează separat cazurile cu zero, o rădăcină sau două rădăcini reale.
- Media ponderată — Calculează media ponderată a n valori și afișeaz-o cu trei zecimale. Explică unde este necesar float() și unde round().
- Conversie temperaturi — Citește temperaturi ca text, convertește-le la float și determină cea mai apropiată valoare de zero folosind abs().
- Cel mai apropiat întreg — Pentru fiecare număr real dintr-o listă, determină întregul cel mai apropiat și explică efectul round() asupra valorilor de frontieră.
- Arie cu radical — Se dau laturile unui triunghi. Verifică existența triunghiului și calculează aria prin formula lui Heron folosind sqrt().
- Diagonala minimă — Dintr-o listă de dreptunghiuri reprezentate prin lungime și lățime, determină dreptunghiul cu diagonala minimă. Compară calculul exact cu comparația pătratelor diagonalelor.
- Normalizare numerică — Transformă n valori întregi într-un interval [0,1] folosind minimul și maximul. Tratează cazul în care toate valorile sunt egale.
- Erori de conversie — Analizează un program care aplică int(float(text)) și explică ce informație se pierde. Propune teste pentru numere foarte mici, negative și cu multe zecimale.
- Rotunjire financiară — Calculează totalul unei facturi, TVA-ul și prețul final. Rotunjește doar valorile afișate și explică de ce ordinea operațiilor contează.
- Cea mai mică distanță față de zero — Din n numere reale, determină valoarea care are |x| minim; la egalitate, alege valoarea mai mică. Explică folosirea abs().
- Raport cu trei zecimale — Citește două numere reale și calculează raportul, media geometrică și diferența absolută. Validează diviziunea și argumentul pentru sqrt().
- Aproximarea radicalului — Pentru un număr pozitiv, calculează sqrt(x), apoi verifică prin pătrare cât de apropiată este valoarea obținută de x. Folosește round() pentru raport.
- Punct și cerc — Se dau centrul și raza unui cerc și un punct. Folosește sqrt() pentru a decide dacă punctul este în interior, pe cerc sau în exterior.
- Conversie durate — Citește o durată în secunde ca text și transform-o în ore, minute și secunde folosind int(). Explică de ce conversia trebuie făcută înaintea operațiilor întregi.
- Compararea valorilor reale — Compară două rezultate de calcul cu o toleranță. Explică de ce simpla egalitate poate fi problematică pentru numere reale.
- Poligon regulat — Se dau n și lungimea laturii unui poligon regulat. Calculează o aproximare a ariei folosind funcții matematice disponibile și explică verificările de intrare.
- Scalare și rotunjire — Transformă o valoare dintr-un interval [a,b] în [c,d], apoi afișeaz-o cu două zecimale. Tratează cazul a=b.
- Raportare statistică — Pentru o listă de valori reale, calculează minimul, maximul, media și abaterea simplificată față de medie, folosind abs(), sqrt(), round() și conversii unde sunt necesare.
- Mini-calculator numeric — Construiește specificația unui calculator care primește expresii simple cu două numere și o operație, face conversia la float și afișează rezultatul rotunjit.
Partea II – Enunț + explicație detaliată
1. Distanța minimă între numereDificil
Enunțul problemei
Dintr-o listă de numere reale, găsește două valori cu diferența absolută minimă. Folosește abs() și explică de ce sortarea simplifică problema.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=sorted([3.4,1.2,1.9,7.0]) best=min(abs(a[i]-a[i-1]) for i in range(1,len(a))) print(best)
Explicația rezolvării: După sortare, cea mai apropiată pereche trebuie să fie formată din două valori vecine. Calculăm diferențele absolute folosind abs(). Sortarea costă O(n log n), iar scanarea O(n).
2. Rotunjire controlatăDificil
Enunțul problemei
Calculează media unor valori reale și afișeaz-o cu exact două zecimale, dar păstrează intern valoarea nerotunjită. Explică diferența dintre round() și format.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
valori=[10.1234,11.9876,12.5555]
media=sum(valori)/len(valori)
print(media)
print(f"{media:.2f}")Explicația rezolvării: Păstrăm media în variabila media fără să o rotunjim. Formatul :.2f controlează doar afișarea la două zecimale. round(media,2) produce o valoare numerică rotunjită, în timp ce formatul este potrivit pentru prezentare.
3. Conversie sigurăDificil
Enunțul problemei
Citește un șir și decide dacă poate reprezenta un număr întreg. Pentru valori valide, convertește-l cu int(); pentru cele invalide, explică strategia de tratare.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
text='-42'
try:
x=int(text)
print(x)
except ValueError:
print('Valoare invalidă')Explicația rezolvării: Conversia int() este încercată într-un bloc try. Dacă textul conține caractere care nu formează un întreg valid, Python ridică ValueError. Tratarea excepției permite programului să continue controlat.
4. Baze de numerațieDificil
Enunțul problemei
Citește un număr scris în baza 2, 8 sau 16 și convertește-l în zecimal. Folosește int(text,baza) și explică rolul celui de-al doilea argument.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
for text,baza in [('1011',2),('17',8),('FF',16)]:
print(int(text,baza))Explicația rezolvării: Al doilea argument al lui int() spune în ce bază este scris textul. Python transformă reprezentarea în valoarea internă zecimală. Astfel aceeași funcție poate trata baze diferite.
5. Trunchiere versus rotunjireDificil
Enunțul problemei
Pentru mai multe numere reale negative și pozitive, afișează separat int(x), round(x) și valoarea inferioară calculată cu floor(). Explică diferențele.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math
for x in [-3.7,-2.2,2.2,3.7]:
print(x,int(x),round(x),math.floor(x))Explicația rezolvării: int(x) trunchiază spre zero. floor(x) dă cel mai mare întreg mai mic sau egal cu x, deci pentru negative poate fi mai mic decât int(x). round(x) realizează rotunjirea numerică Python și are particularități la valorile exact la jumătate.
6. Distanță euclidianăDificil
Enunțul problemei
Se dau două puncte în plan. Calculează distanța dintre ele folosind sqrt() și abs() acolo unde este util. Precizează cazurile-limită.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math A=(1,2); B=(4,6) d=math.sqrt((A[0]-B[0])**2+(A[1]-B[1])**2) print(d)
Explicația rezolvării: Formula distanței euclidiene este radical din suma pătratelor diferențelor coordonatelor. sqrt() calculează radicalul. Pentru două puncte identice, rezultatul este 0.
7. Ecuație de gradul al doileaDificil
Enunțul problemei
Rezolvă o ecuație ax²+bx+c=0 pentru coeficienți reali. Folosește sqrt() pentru discriminant și tratează separat cazurile cu zero, o rădăcină sau două rădăcini reale.
Explicație detaliată
Ideea centrală: Începe prin a identifica operația repetată și numărul de ori în care poate fi executată; termenul dominant determină complexitatea. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math
a,b,c=1,-5,6
d=b*b-4*a*c
if a==0: print('Nu este gradul 2')
elif d<0: print('Fără rădăcini reale')
elif d==0: print(-b/(2*a))
else:
print((-b-math.sqrt(d))/(2*a),(-b+math.sqrt(d))/(2*a))Explicația rezolvării: Mai întâi verificăm a==0. Apoi analizăm discriminantul Δ. Pentru Δ<0 nu există rădăcini reale, pentru Δ=0 există una, iar pentru Δ>0 există două. sqrt() este folosit doar când Δ este nenegativ.
8. Media ponderatăDificil
Enunțul problemei
Calculează media ponderată a n valori și afișeaz-o cu trei zecimale. Explică unde este necesar float() și unde round().
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
val=[(10,2),(20,3),(30,5)]
num=sum(x*g for x,g in val); den=sum(g for _,g in val)
media=num/den
print(f'{media:.3f}')Explicația rezolvării: Media ponderată este suma produselor valoare×pondere împărțită la suma ponderilor. Împărțirea produce float; formatarea la :.3f controlează doar afișarea.
9. Conversie temperaturiDificil
Enunțul problemei
Citește temperaturi ca text, convertește-le la float și determină cea mai apropiată valoare de zero folosind abs().
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
t=['-2.5','4.1','0.3','-0.7'] a=[float(x) for x in t] print(min(a,key=abs))
Explicația rezolvării: Convertim explicit fiecare șir la float. min(..., key=abs) alege valoarea al cărei modul este minim. Dacă există egalitate, min păstrează ordinea și poate fi adaptat cu o cheie compusă.
10. Cel mai apropiat întregDificil
Enunțul problemei
Pentru fiecare număr real dintr-o listă, determină întregul cel mai apropiat și explică efectul round() asupra valorilor de frontieră.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
for x in [1.2,1.5,1.6,2.49,2.5,2.51]: print(x,round(x))
Explicația rezolvării: round() întoarce întregul cel mai apropiat când nu este precizat numărul de zecimale. La valori de frontieră trebuie ținut cont de regula Python pentru jumătăți, bazată pe rotunjirea către numărul par în multe cazuri.
11. Arie cu radicalDificil
Enunțul problemei
Se dau laturile unui triunghi. Verifică existența triunghiului și calculează aria prin formula lui Heron folosind sqrt().
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math
a,b,c=3,4,5
if a+b>c and a+c>b and b+c>a:
s=(a+b+c)/2
print(math.sqrt(s*(s-a)*(s-b)*(s-c)))
else: print('Triunghi invalid')Explicația rezolvării: Verificăm mai întâi inegalitățile triunghiului. Apoi calculăm semiperimetrul și aplicăm formula lui Heron. sqrt() este validă deoarece expresia din radical este nenegativă pentru un triunghi valid.
12. Diagonala minimăDificil
Enunțul problemei
Dintr-o listă de dreptunghiuri reprezentate prin lungime și lățime, determină dreptunghiul cu diagonala minimă. Compară calculul exact cu comparația pătratelor diagonalelor.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math r=[(3,4),(5,12),(6,8)] best=min(r,key=lambda t:t[0]**2+t[1]**2) print(best)
Explicația rezolvării: Diagonala este sqrt(l²+L²). Pentru a compara diagonale nu este necesar să calculăm radicalul: funcția sqrt este crescătoare, deci este suficient să comparăm pătratele diagonalelor. Astfel evităm calcule inutile.
13. Normalizare numericăDificil
Enunțul problemei
Transformă n valori întregi într-un interval [0,1] folosind minimul și maximul. Tratează cazul în care toate valorile sunt egale.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[2,5,8,10] mi,ma=min(a),max(a) if mi==ma: rez=[0.0]*len(a) else: rez=[(x-mi)/(ma-mi) for x in a] print(rez)
Explicația rezolvării: Formula de scalare este (x-min)/(max-min). Dacă min=max, numitorul ar fi zero; alegem convențional 0 pentru toate valorile deoarece toate coincid. Rezultatele sunt în [0,1].
14. Erori de conversieDificil
Enunțul problemei
Analizează un program care aplică int(float(text)) și explică ce informație se pierde. Propune teste pentru numere foarte mici, negative și cu multe zecimale.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
for text in ['0.000001','-123.98765','999.999999']:
y=int(float(text))
print(text,'->',y)Explicația rezolvării: float() păstrează partea fracționară, apoi int() o elimină prin trunchiere spre zero. Informația pierdută este partea zecimală. Testele cu numere negative arată clar diferența dintre trunchiere și floor().
15. Rotunjire financiarăDificil
Enunțul problemei
Calculează totalul unei facturi, TVA-ul și prețul final. Rotunjește doar valorile afișate și explică de ce ordinea operațiilor contează.
Explicație detaliată
Ideea centrală: Descompune problema în pași mici: date de intrare, prelucrare, rezultat și cazuri-limită. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
preturi=[120.00,80.50,19.99]
total=sum(preturi)
tva=total*0.19
final=total+tva
print(f'Total {total:.2f}, TVA {tva:.2f}, Final {final:.2f}')Explicația rezolvării: Calculăm intern cu valorile complete și rotunjim doar la afișare. Dacă rotunjim fiecare produs înainte de calculul totalului, erorile se pot acumula. Pentru aplicații financiare reale se recomandă Decimal, dar aici urmărim funcțiile numerice din capitol.
16. Cea mai mică distanță față de zeroFoarte dificil
Enunțul problemei
Din n numere reale, determină valoarea care are |x| minim; la egalitate, alege valoarea mai mică. Explică folosirea abs().
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[-2.5,1.2,0.7,-0.4,2.5] rez=min(a,key=lambda x:(abs(x),x)) print(rez)
Explicația rezolvării: Cheia (abs(x), x) compară mai întâi distanța față de zero, iar la egalitate alege valoarea numeric mai mică. Este o aplicație directă a abs().
17. Raport cu trei zecimaleFoarte dificil
Enunțul problemei
Citește două numere reale și calculează raportul, media geometrică și diferența absolută. Validează diviziunea și argumentul pentru sqrt().
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math
a,b=9,4
if b==0: print('Împărțire imposibilă')
elif a*b<0: print('Media geometrică reală nu este definită')
else:
print(a/b, math.sqrt(a*b), abs(a-b))Explicația rezolvării: Verificăm mai întâi împărțitorul. Media geometrică sqrt(a*b) în sens real cere produs nenegativ. Diferența absolută este calculată cu abs().
18. Aproximarea radicaluluiFoarte dificil
Enunțul problemei
Pentru un număr pozitiv, calculează sqrt(x), apoi verifică prin pătrare cât de apropiată este valoarea obținută de x. Folosește round() pentru raport.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math x=2 r=math.sqrt(x) eroare=abs(r*r-x) print(r,eroare,round(r,3))
Explicația rezolvării: Calculăm radicalul și apoi verificăm rezultatul prin r*r. Eroarea absolută |r²-x| arată cât de apropiată este verificarea de zero. round() este folosit pentru o raportare controlată.
19. Punct și cercFoarte dificil
Enunțul problemei
Se dau centrul și raza unui cerc și un punct. Folosește sqrt() pentru a decide dacă punctul este în interior, pe cerc sau în exterior.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math
cx,cy,r=0,0,5
x,y=3,4
d=math.sqrt((x-cx)**2+(y-cy)**2)
print('interior' if d<r else 'pe cerc' if d==r else 'exterior')Explicația rezolvării: Calculăm distanța punctului față de centru. Compararea cu raza separă cele trei cazuri. În programe reale cu numere reale poate fi necesară o toleranță, dar pentru valori simple egalitatea este suficientă.
20. Conversie durateFoarte dificil
Enunțul problemei
Citește o durată în secunde ca text și transform-o în ore, minute și secunde folosind int(). Explică de ce conversia trebuie făcută înaintea operațiilor întregi.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
text='3672' s=int(text) h=s//3600 s%=3600 m=s//60 s%=60 print(h,m,s)
Explicația rezolvării: int() transformă textul în număr întreg înaintea operațiilor // și %. Împărțirea întreagă oferă numărul de ore/minute, iar restul păstrează secundele rămase.
21. Compararea valorilor realeFoarte dificil
Enunțul problemei
Compară două rezultate de calcul cu o toleranță. Explică de ce simpla egalitate poate fi problematică pentru numere reale.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=0.1+0.2 b=0.3 print(abs(a-b)<1e-9)
Explicația rezolvării: Numerele reale sunt reprezentate aproximativ în calculator, astfel încât egalitatea directă poate eșua. Folosim o toleranță epsilon și verificăm dacă diferența absolută este suficient de mică.
22. Poligon regulatFoarte dificil
Enunțul problemei
Se dau n și lungimea laturii unui poligon regulat. Calculează o aproximare a ariei folosind funcții matematice disponibile și explică verificările de intrare.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math
n,l=6,4
if n<3 or l<=0: print('Date invalide')
else:
# A = n*l^2/(4*tan(pi/n))
print(n*l*l/(4*math.tan(math.pi/n)))Explicația rezolvării: Formula ariei unui poligon regulat este n·l²/(4·tan(π/n)). Verificăm că există cel puțin trei laturi și că latura este pozitivă. math.pi și tan() oferă funcțiile matematice necesare.
23. Scalare și rotunjireFoarte dificil
Enunțul problemei
Transformă o valoare dintr-un interval [a,b] în [c,d], apoi afișeaz-o cu două zecimale. Tratează cazul a=b.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
def scale(x,a,b,c,d):
if a==b: return None
return c+(x-a)*(d-c)/(b-a)
print(round(scale(5,0,10,0,100),2))Explicația rezolvării: Transformarea liniară păstrează proporția poziției lui x în primul interval. Dacă a=b, intervalul inițial nu are lungime și transformarea nu este definită.
24. Raportare statisticăFoarte dificil
Enunțul problemei
Pentru o listă de valori reale, calculează minimul, maximul, media și abaterea simplificată față de medie, folosind abs(), sqrt(), round() și conversii unde sunt necesare.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math a=[1.0,2.0,3.0,5.0] mi,ma=min(a),max(a); med=sum(a)/len(a) ab=sum(abs(x-med) for x in a)/len(a) abat=math.sqrt(sum((x-med)**2 for x in a)/len(a)) print(round(mi,2),round(ma,2),round(med,2),round(ab,2),round(abat,2))
Explicația rezolvării: Folosim min/max pentru extreme, sum/len pentru medie, abs pentru abaterea medie absolută și sqrt pentru abaterea pătratică medie. Rotunjirea se face la final, pentru raportare.
25. Mini-calculator numericFoarte dificil
Enunțul problemei
Construiește specificația unui calculator care primește expresii simple cu două numere și o operație, face conversia la float și afișează rezultatul rotunjit.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
def calculator(a,b,op):
if op=='+': r=a+b
elif op=='-': r=a-b
elif op=='*': r=a*b
elif op=='/':
if b==0: raise ValueError('împărțire la zero')
r=a/b
else: raise ValueError('operație necunoscută')
return round(r,2)
print(calculator(float('12.5'),float('4'),'+'))Explicația rezolvării: Conversia la float se face înaintea calculului. Alegem operația prin if/elif, verificăm împărțirea la zero și respingem operatorii necunoscuți. round() este aplicat rezultatului pentru afișare numerică.
Capitolul 6. Funcții predefinite pentru colecții
25 de probleme dificile și foarte dificile. Tema este construită pe conceptele din pagina sursă: capitolul 6 și subtemele sale.
Partea I – Lista enunțurilor
- Raport complet al unei clase — Pentru o listă de note, determină numărul, suma, media, minimul, maximul și câte note sunt peste medie. Folosește len(), sum(), min() și max().
- Extreme fără duplicate — Determină cele mai mici două valori distincte dintr-o colecție. Explică de ce min() singur nu este suficient.
- Ecart maxim — Calculează diferența dintre maximul și minimul unei liste. Tratează lista cu un singur element.
- Media după filtrare — Dintr-o listă de temperaturi, calculează media numai pentru valorile negative. Explică verificarea listei filtrate înainte de împărțire.
- Două liste comparate — Se dau două liste de note. Determină care are media mai mare și care are intervalul minim-maxim mai mic.
- Frecvența maximă — Determină de câte ori apare cea mai frecventă valoare. Compară folosirea count() repetat cu o structură de frecvență.
- Elemente apropiate de medie — Afișează valorile a căror distanță față de medie este minimă. Folosește abs() împreună cu operațiile pe colecții.
- Listă de rezultate — Pentru mai multe liste de numere, calculează pentru fiecare lungimea, suma, minimul și maximul și apoi identifică lista cu suma maximă.
- Validarea unei colecții — Verifică dacă toate valorile unei liste se află într-un interval și raportează câte sunt în afara intervalului.
- Sume cumulative — Construiește lista sumelor prefixale. Compară memoria cu o soluție care calculează fiecare sumă de la zero.
- Diferența față de maxim — Înlocuiește fiecare valoare cu diferența dintre maximul listei și valoarea respectivă. Păstrează lista originală.
- Statistici pe grupe — Se dau note și grupa fiecărui elev. Calculează media minimă și maximă pe fiecare grupă.
- Valori comune — Determină valorile comune dintre două liste, fără a afișa aceeași valoare de mai multe ori.
- Intersecție cu ordine păstrată — Obține elementele din prima listă care apar și în a doua, păstrând ordinea primei liste.
- Număr de tranziții — Numără de câte ori se schimbă semnul sau categoria valorilor consecutive dintr-o listă.
- Secvență crescătoare maximă — Găsește lungimea celei mai lungi secvențe strict crescătoare consecutive.
- Minim și poziții — Găsește minimul și toate pozițiile la care apare. Explică de ce o singură parcurgere este suficientă.
- Eliminarea valorilor invalide — Dintr-o listă numerică păstrează doar valorile din [0,100] și calculează statistici asupra listei rezultate.
- Top trei valori — Determină cele mai mari trei valori distincte fără a ordona neapărat întreaga listă. Explică strategia.
- Mediana fără sortare completă — Discută cum ai putea determina mediana unei liste mari fără să păstrezi două copii ale listei. Compară cu soluția simplă prin sortare.
- Egalitatea statistică — Verifică dacă două liste au aceeași sumă, aceeași lungime și aceeași valoare minimă și maximă.
- Lista echilibrată — Spune dacă suma elementelor negative este egală cu suma valorilor pozitive.
- Sublistă cu sumă maximă — Determină o sublistă contiguă cu suma maximă și raportează și capetele ei.
- Raport compact — Construiește un raport text din statistici ale unei liste, cu valori rotunjite și etichete clare.
- Problemă de sinteză colecții — Primești mai multe colecții de numere și trebuie să identifici colecția cu cea mai mare medie, cea mai mică dispersie simplificată și cele mai multe valori distincte.
Partea II – Enunț + explicație detaliată
1. Raport complet al unei claseDificil
Enunțul problemei
Pentru o listă de note, determină numărul, suma, media, minimul, maximul și câte note sunt peste medie. Folosește len(), sum(), min() și max().
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
note=[8,9,7,10,6] n=len(note); s=sum(note); med=s/n; mi=min(note); ma=max(note) peste=sum(x>med for x in note) print(n,s,med,mi,ma,peste)
Explicația rezolvării: len, sum, min și max rezolvă direct statisticile de bază. Expresia x>med produce valori booleene, iar sum le numără deoarece True valorează 1. Complexitatea totală este O(n).
2. Extreme fără duplicateDificil
Enunțul problemei
Determină cele mai mici două valori distincte dintr-o colecție. Explică de ce min() singur nu este suficient.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[4,1,1,7,3,7] d=sorted(set(a)) print(d[:2])
Explicația rezolvării: set elimină duplicatele, sortarea pune valorile în ordine, iar primele două sunt cele mai mici distincte. Dacă există mai puțin de două valori distincte, trebuie semnalată situația.
3. Ecart maximDificil
Enunțul problemei
Calculează diferența dintre maximul și minimul unei liste. Tratează lista cu un singur element.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[7,2,10,4] print(max(a)-min(a))
Explicația rezolvării: Ecartul este maxim-minim. Pentru o listă cu un singur element rezultatul este 0; pentru lista goală nu există extreme și trebuie tratată separat.
4. Media după filtrareDificil
Enunțul problemei
Dintr-o listă de temperaturi, calculează media numai pentru valorile negative. Explică verificarea listei filtrate înainte de împărțire.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
t=[-3.0,2.0,-1.0,-5.0] f=[x for x in t if x<0] print(sum(f)/len(f) if f else None)
Explicația rezolvării: Filtrăm întâi valorile negative. Verificăm dacă lista filtrată este nevidă înainte de împărțire. În Python, list comprehensions oferă o exprimare clară a filtrării.
5. Două liste comparateDificil
Enunțul problemei
Se dau două liste de note. Determină care are media mai mare și care are intervalul minim-maxim mai mic.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[8,9,7,10]; b=[7,8,9,9]
ma,mb=sum(a)/len(a),sum(b)/len(b)
ra,rb=max(a)-min(a),max(b)-min(b)
print('media', 'A' if ma>mb else 'B' if mb>ma else 'egale')
print('ecart', 'A' if ra<rb else 'B' if rb<ra else 'egale')Explicația rezolvării: Calculăm separat media și ecartul fiecărei liste. Apoi comparăm rezultatele. Separarea calculelor face codul ușor de verificat și extins.
6. Frecvența maximăDificil
Enunțul problemei
Determină de câte ori apare cea mai frecventă valoare. Compară folosirea count() repetat cu o structură de frecvență.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
from collections import Counter a=[2,3,3,2,3,4,3] f=Counter(a) print(f.most_common(1)[0])
Explicația rezolvării: Counter numără aparițiile, iar most_common(1) oferă valoarea cu frecvența maximă. La egalitate trebuie stabilită regula dorită, deoarece pot exista mai multe valori maxime.
7. Elemente apropiate de medieDificil
Enunțul problemei
Afișează valorile a căror distanță față de medie este minimă. Folosește abs() împreună cu operațiile pe colecții.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[3,1,4,1,5,9] print(sum(x%2==0 for x in a),sum(x%2!=0 for x in a))
Explicația rezolvării: Condițiile produc booleeni care pot fi însumați. Astfel numărăm parele și imparele într-o singură parcurgere, O(n).
8. Listă de rezultateDificil
Enunțul problemei
Pentru mai multe liste de numere, calculează pentru fiecare lungimea, suma, minimul și maximul și apoi identifică lista cu suma maximă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5] print(all(x>0 for x in a), any(x>4 for x in a))
Explicația rezolvării: all verifică dacă toate valorile satisfac condiția, iar any dacă cel puțin una o satisface. Ambele pot opri parcurgerea mai devreme, deci sunt eficiente pentru verificări.
9. Validarea unei colecțiiDificil
Enunțul problemei
Verifică dacă toate valorile unei liste se află într-un interval și raportează câte sunt în afara intervalului.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[3,5,2,8,5] print(sorted(a), sorted(a,reverse=True))
Explicația rezolvării: sorted produce o listă nouă, fără să modifice originalul. Parametrul reverse=True schimbă sensul ordonării. Dacă vrem modificarea listei, putem folosi metoda sort().
10. Sume cumulativeDificil
Enunțul problemei
Construiește lista sumelor prefixale. Compară memoria cu o soluție care calculează fiecare sumă de la zero.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[3,4,5,6,7] print(sum(x%2==0 for x in a))
Explicația rezolvării: Filtrarea după paritate poate fi făcută direct printr-o condiție. sum pe expresia booleană numără elementele care îndeplinesc criteriul.
11. Diferența față de maximDificil
Enunțul problemei
Înlocuiește fiecare valoare cu diferența dintre maximul listei și valoarea respectivă. Păstrează lista originală.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[-4,2,-1,7,-3] poz=[x for x in a if x>0] print(sum(poz)/len(poz) if poz else None)
Explicația rezolvării: Construim colecția valorilor pozitive și calculăm media numai dacă există astfel de valori. Complexitatea este O(n), iar memoria O(n) pentru lista filtrată.
12. Statistici pe grupeDificil
Enunțul problemei
Se dau note și grupa fiecărui elev. Calculează media minimă și maximă pe fiecare grupă.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[4,8,2,8,5] x=8 print(a.count(x), a.count(x)/len(a))
Explicația rezolvării: count numără aparițiile valorii. Împărțirea la lungimea listei dă proporția de apariții. Pentru o listă goală trebuie evitată împărțirea la zero.
13. Valori comuneDificil
Enunțul problemei
Determină valorile comune dintre două liste, fără a afișa aceeași valoare de mai multe ori.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5] print(min(a),max(a),sum(a))
Explicația rezolvării: min și max găsesc extremele, sum totalul. Toate necesită O(n) dacă sunt calculate separat; pentru eficiență putem face o singură parcurgere manuală când numărul de statistici crește.
14. Intersecție cu ordine păstratăDificil
Enunțul problemei
Obține elementele din prima listă care apar și în a doua, păstrând ordinea primei liste.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5] mi,ma=min(a),max(a) print([x for x in a if mi<x<ma])
Explicația rezolvării: Valorile strict între minim și maxim sunt cele care satisfac simultan x>mi și x<ma. Filtrarea păstrează ordinea inițială.
15. Număr de tranzițiiDificil
Enunțul problemei
Numără de câte ori se schimbă semnul sau categoria valorilor consecutive dintr-o listă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5,6] print(len([x for x in a if x>3]))
Explicația rezolvării: Construim o colecție filtrată și îi calculăm lungimea. O variantă mai eficientă ca memorie este sum(x>3 for x in a), care nu creează lista intermediară.
16. Secvență crescătoare maximăFoarte dificil
Enunțul problemei
Găsește lungimea celei mai lungi secvențe strict crescătoare consecutive.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,2,3,4,4,5] print(sorted(set(a)))
Explicația rezolvării: set elimină duplicatele, iar sorted ordonează valorile rămase. Dacă ordinea primei apariții trebuie păstrată, se folosește un set de văzute și o listă rezultat.
17. Minim și pozițiiFoarte dificil
Enunțul problemei
Găsește minimul și toate pozițiile la care apare. Explică de ce o singură parcurgere este suficientă.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[2,5,8,1,10] print(all(x>=0 for x in a))
Explicația rezolvării: all este potrivit pentru condiții globale. O singură valoare negativă determină imediat False.
18. Eliminarea valorilor invalideFoarte dificil
Enunțul problemei
Dintr-o listă numerică păstrează doar valorile din [0,100] și calculează statistici asupra listei rezultate.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[2,4,6,8,10] print(any(x%3==0 for x in a))
Explicația rezolvării: any caută existența unei valori care satisface condiția și se poate opri imediat după găsire. Este o metodă clară și eficientă.
19. Top trei valoriFoarte dificil
Enunțul problemei
Determină cele mai mari trei valori distincte fără a ordona neapărat întreaga listă. Explică strategia.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4] print(sum(a)/len(a))
Explicația rezolvării: Media aritmetică este suma împărțită la numărul de valori. len() este esențial pentru a evita presupunerea că știm dinainte dimensiunea colecției.
20. Mediana fără sortare completăFoarte dificil
Enunțul problemei
Discută cum ai putea determina mediana unei liste mari fără să păstrezi două copii ale listei. Compară cu soluția simplă prin sortare.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[-2,0,3,7,-1] print(min(a,key=abs))
Explicația rezolvării: Argumentul key=abs spune lui min să compare valorile după modul. Astfel obținem valoarea cea mai apropiată de zero fără a transforma lista.
21. Egalitatea statisticăFoarte dificil
Enunțul problemei
Verifică dacă două liste au aceeași sumă, aceeași lungime și aceeași valoare minimă și maximă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5,6] print(sum(x*x for x in a))
Explicația rezolvării: Expresia generator nu creează o listă auxiliară completă. Fiecare pătrat este calculat și adăugat la sumă. Memoria suplimentară este O(1) față de o listă de O(n).
22. Lista echilibratăFoarte dificil
Enunțul problemei
Spune dacă suma elementelor negative este egală cu suma valorilor pozitive.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5,6] print(min(x for x in a if x%2==0))
Explicația rezolvării: Generatorul filtrează valorile pare și min caută minimul dintre ele. Dacă nu există nicio valoare pară, trebuie tratată excepția sau verificată existența înainte.
23. Sublistă cu sumă maximăFoarte dificil
Enunțul problemei
Determină o sublistă contiguă cu suma maximă și raportează și capetele ei.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5,6] print(max(x for x in a if x%2!=0))
Explicația rezolvării: Analog, filtrăm valorile impare și alegem maximul. Problema listei fără valori impare trebuie tratată separat în aplicația finală.
24. Raport compactFoarte dificil
Enunțul problemei
Construiește un raport text din statistici ale unei liste, cu valori rotunjite și etichete clare.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5] print(sum(1 for x in a if x%2==0))
Explicația rezolvării: Generatorul produce câte un 1 pentru fiecare element care satisface condiția. sum le adună și obținem numărul de elemente dorite fără listă auxiliară.
25. Problemă de sinteză colecțiiFoarte dificil
Enunțul problemei
Primești mai multe colecții de numere și trebuie să identifici colecția cu cea mai mare medie, cea mai mică dispersie simplificată și cele mai multe valori distincte.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[10,20,30,40] med=sum(a)/len(a) print([x-med for x in a])
Explicația rezolvării: Mai întâi calculăm media, apoi pentru fiecare element calculăm abaterea față de medie. Rezultatul poate fi pozitiv sau negativ; pentru abatere absolută se folosește abs(x-med).
Capitolul 7. Programarea orientată pe obiecte – clase, obiecte, metode și module
25 de probleme dificile și foarte dificile. Tema este construită pe conceptele din pagina sursă: capitolul 7 și subtemele sale.
Partea I – Lista enunțurilor
- Clasa Elev avansată — Definește clasa Elev cu nume, vârstă și listă de note. Adaugă metode pentru medie, minim, maxim și promovare.
- Catalogul clasei — Creează clasele Elev și Catalog. Catalogul trebuie să poată adăuga elevi și să calculeze media generală.
- Dreptunghiuri comparabile — Definește Dreptunghi cu lungime și lățime și metode pentru arie, perimetru și diagonală. Identifică dreptunghiul cu aria maximă.
- Cont bancar simplificat — Definește Cont cu sold și metode depune/retrage. Interzice retragerile peste sold și explică schimbarea stării obiectului.
- Bibliotecă de cărți — Definește Carte și Biblioteca. Biblioteca trebuie să poată adăuga, căuta și împrumuta cărți.
- Gestionarea unei liste în obiect — Definește o clasă ListaNumere care ascunde lista internă și oferă metode pentru sumă, minim, maxim și medie.
- Moștenire simplă — Definește Persoană și Elev, astfel încât Elev să moștenească datele de bază și să adauge clasa și notele.
- Polimorfism geometric — Definește o structură cu forme care au metodă aria(). Calculează aria totală fără să verifici tipul concret al fiecărui obiect.
- Modul de geometrie — Construiește un modul geometrie.py cu clase pentru cerc și dreptunghi și un program principal care le importă.
- Sistem de angajați — Definește Angajat cu nume și salariu și o metodă salariu_anual(). Creează apoi un Manager cu bonus.
- Coș de cumpărături — Definește Produs și Cos. Coșul trebuie să calculeze subtotalul, numărul de produse și valoarea maximă a unui produs.
- Istoric de operații — Creează o clasă Calculator care memorează rezultatele operațiilor efectuate și oferă o metodă pentru ultimul rezultat.
- Parolă încapsulată conceptual — Definește o clasă ContUtilizator cu nume și o parolă stocată intern. Oferă o metodă verifică_parola fără a afișa parola.
- Joc cu jucători — Definește Jucator cu nume și punctaj. Creează o clasă Joc care adaugă jucători și determină câștigătorul.
- Rezultate sportive — Definește Meci cu două echipe și scoruri și o clasă Campionat care calculează clasamentul.
- Fructe și coșuri — Definește Fruct cu nume și greutate și CosFructe care calculează greutatea totală și fructul cel mai greu.
- Stoc magazin — Definește Produs cu cod, nume, preț și stoc. Clasa Magazin trebuie să poată realiza vânzări și să actualizeze stocul.
- Agendă — Definește Contact și Agenda. Agenda trebuie să permită adăugarea, căutarea după nume și ștergerea unui contact.
- Mașini — Definește Mașină cu marcă, model și kilometraj. Adaugă metode pentru deplasare și afișarea stării.
- Sistem de note — Definește Evaluare și Elev. O evaluare are materie și notă; elevul trebuie să calculeze media și să identifice materia cu nota maximă.
- Fișier ca modul — Separă clasele unui mini-proiect în două module și explică importurile și rolul fiecărui fișier.
- Obiecte și copiere — Construiește două obiecte cu aceeași clasă și explică de ce modificarea unui atribut al unuia nu trebuie să schimbe automat celălalt.
- Metode care returnează obiecte — Definește o clasă Vector2D ale cărei metode pot returna un nou vector rezultat din adunare sau scalare.
- Mini-sistem OOP — Construiește un sistem format din Utilizator, Produs și Comandă, astfel încât o comandă să conțină produse și să poată calcula totalul.
Partea II – Enunț + explicație detaliată
1. Clasa Elev avansatăDificil
Enunțul problemei
Definește clasa Elev cu nume, vârstă și listă de note. Adaugă metode pentru medie, minim, maxim și promovare.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Elev:
def __init__(self,nume,varsta,note): self.nume=nume; self.varsta=varsta; self.note=note
def medie(self): return sum(self.note)/len(self.note)
def minim(self): return min(self.note)
def maxim(self): return max(self.note)
def promovat(self): return self.medie()>=5
e=Elev('Ana',15,[8,9,10]); print(e.medie(),e.minim(),e.maxim(),e.promovat())Explicația rezolvării: Constructorul inițializează starea obiectului. Metodele citesc atributul note și calculează rezultatele. promovat() reutilizează medie(), evitând duplicarea formulei.
2. Catalogul claseiDificil
Enunțul problemei
Creează clasele Elev și Catalog. Catalogul trebuie să poată adăuga elevi și să calculeze media generală.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Elev:
def __init__(self,note): self.note=note
def medie(self): return sum(self.note)/len(self.note)
class Catalog:
def __init__(self): self.elevi=[]
def adauga(self,e): self.elevi.append(e)
def media_generala(self): return sum(e.medie() for e in self.elevi)/len(self.elevi)
c=Catalog(); c.adauga(Elev([8,9])); c.adauga(Elev([10,7])); print(c.media_generala())Explicația rezolvării: Catalogul compune obiecte Elev într-o listă. Fiecare elev își calculează propria medie, iar catalogul calculează media mediilor. Separarea responsabilităților este ideea OOP principală.
3. Dreptunghiuri comparabileDificil
Enunțul problemei
Definește Dreptunghi cu lungime și lățime și metode pentru arie, perimetru și diagonală. Identifică dreptunghiul cu aria maximă.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import math
class Dreptunghi:
def __init__(self,l,L): self.l=l; self.L=L
def arie(self): return self.l*self.L
def perimetru(self): return 2*(self.l+self.L)
def diagonala(self): return math.sqrt(self.l**2+self.L**2)
r=[Dreptunghi(2,5),Dreptunghi(4,4)]; print(max(r,key=lambda x:x.arie()).arie())Explicația rezolvării: Clasa grupează datele și operațiile lor. max(..., key=...) cere fiecărui obiect aria și alege obiectul cu aria maximă. Astfel nu verificăm manual tipul obiectului.
4. Cont bancar simplificatDificil
Enunțul problemei
Definește Cont cu sold și metode depune/retrage. Interzice retragerile peste sold și explică schimbarea stării obiectului.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Cont:
def __init__(self,sold): self.sold=sold
def depune(self,s): self.sold+=s
def retrage(self,s):
if 0<=s<=self.sold: self.sold-=s; return True
return False
c=Cont(100); c.depune(50); print(c.retrage(120),c.sold)Explicația rezolvării: sold este starea obiectului. depune o modifică direct, iar retrage verifică precondiția sold suficient înainte de modificare. Metoda întoarce True/False pentru ca programul apelant să știe dacă operația a reușit.
5. Bibliotecă de cărțiDificil
Enunțul problemei
Definește Carte și Biblioteca. Biblioteca trebuie să poată adăuga, căuta și împrumuta cărți.
Explicație detaliată
Ideea centrală: Descompune problema în pași mici: date de intrare, prelucrare, rezultat și cazuri-limită. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Carte:
def __init__(self,titlu): self.titlu=titlu; self.imprumutata=False
class Biblioteca:
def __init__(self): self.carti=[]
def adauga(self,c): self.carti.append(c)
def cauta(self,t): return next((c for c in self.carti if c.titlu==t),None)
def imprumuta(self,t):
c=self.cauta(t)
if c and not c.imprumutata: c.imprumutata=True; return True
return False
b=Biblioteca(); b.adauga(Carte('Python')); print(b.imprumuta('Python'))Explicația rezolvării: Biblioteca păstrează obiecte Carte. Căutarea returnează obiectul, nu doar poziția, astfel încât metoda împrumut poate modifica atributul imprumutata. next(..., None) gestionează lipsa cărții.
6. Gestionarea unei liste în obiectDificil
Enunțul problemei
Definește o clasă ListaNumere care ascunde lista internă și oferă metode pentru sumă, minim, maxim și medie.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class ListaNumere:
def __init__(self,a): self.__a=list(a)
def suma(self): return sum(self.__a)
def minim(self): return min(self.__a)
def maxim(self): return max(self.__a)
def medie(self): return self.suma()/len(self.__a)
x=ListaNumere([2,4,6]); print(x.suma(),x.medie())Explicația rezolvării: Prefixul __ sugerează încapsularea atributului intern. Utilizatorul clasei lucrează prin metode publice, fără să depindă de reprezentarea internă. Acest lucru permite schimbarea implementării ulterior.
7. Moștenire simplăDificil
Enunțul problemei
Definește Persoană și Elev, astfel încât Elev să moștenească datele de bază și să adauge clasa și notele.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Persoana:
def __init__(self,nume,varsta): self.nume=nume; self.varsta=varsta
class Elev(Persoana):
def __init__(self,nume,varsta,clasa,note): super().__init__(nume,varsta); self.clasa=clasa; self.note=note
e=Elev('Ion',15,'9A',[9,10]); print(e.nume,e.clasa)Explicația rezolvării: Elev moștenește Persoana și reutilizează constructorul clasei de bază prin super(). Apoi adaugă atribute specifice. Astfel evităm rescrierea codului comun.
8. Polimorfism geometricDificil
Enunțul problemei
Definește o structură cu forme care au metodă aria(). Calculează aria totală fără să verifici tipul concret al fiecărui obiect.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Forma: pass
class Cerc(Forma):
def __init__(self,r): self.r=r
def aria(self): return 3.14*self.r**2
class Patrat(Forma):
def __init__(self,l): self.l=l
def aria(self): return self.l**2
forme=[Cerc(2),Patrat(3)]
print(sum(f.aria() for f in forme))Explicația rezolvării: Polimorfismul permite apelul aceleiași metode aria() pentru obiecte diferite. Codul nu verifică dacă obiectul este Cerc sau Patrat; fiecare clasă își definește comportamentul.
9. Modul de geometrieDificil
Enunțul problemei
Construiește un modul geometrie.py cu clase pentru cerc și dreptunghi și un program principal care le importă.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
# geometrie.py
class Cerc:
def __init__(self,r): self.r=r
def aria(self): return 3.14*self.r**2
# program.py
from geometrie import Cerc
c=Cerc(5); print(c.aria())Explicația rezolvării: Primul fișier este modulul reutilizabil. În programul principal importăm clasa și o folosim. Separarea codului în module reduce dimensiunea fiecărui fișier și permite reutilizarea.
10. Sistem de angajațiDificil
Enunțul problemei
Definește Angajat cu nume și salariu și o metodă salariu_anual(). Creează apoi un Manager cu bonus.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Angajat:
def __init__(self,nume,salariu): self.nume=nume; self.salariu=salariu
def salariu_anual(self): return 12*self.salariu
class Manager(Angajat):
def __init__(self,nume,salariu,bonus): super().__init__(nume,salariu); self.bonus=bonus
def salariu_anual(self): return super().salariu_anual()+self.bonus
m=Manager('Ana',5000,12000); print(m.salariu_anual())Explicația rezolvării: Manager moștenește comportamentul de bază, dar redefinește salariu_anual pentru a include bonusul. super() permite reutilizarea calculului din clasa părinte.
11. Coș de cumpărăturiDificil
Enunțul problemei
Definește Produs și Cos. Coșul trebuie să calculeze subtotalul, numărul de produse și valoarea maximă a unui produs.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Produs:
def __init__(self,nume,pret): self.nume=nume; self.pret=pret
class Cos:
def __init__(self): self.produse=[]
def adauga(self,p): self.produse.append(p)
def subtotal(self): return sum(p.pret for p in self.produse)
def maxim(self): return max(self.produse,key=lambda p:p.pret)
c=Cos(); c.adauga(Produs('A',10)); c.adauga(Produs('B',25)); print(c.subtotal(),c.maxim().nume)Explicația rezolvării: Cosul conține obiecte Produs. subtotal parcurge produsele și însumează prețurile; maxim folosește key pentru a selecta produsul cel mai scump.
12. Istoric de operațiiDificil
Enunțul problemei
Creează o clasă Calculator care memorează rezultatele operațiilor efectuate și oferă o metodă pentru ultimul rezultat.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Calculator:
def __init__(self): self.istoric=[]
def aduna(self,a,b):
r=a+b; self.istoric.append(r); return r
def ultimul(self): return self.istoric[-1] if self.istoric else None
c=Calculator(); c.aduna(2,3); c.aduna(10,4); print(c.ultimul())Explicația rezolvării: Istoricul este un atribut al obiectului și păstrează rezultatele în ordinea efectuării. ultimul verifică lista pentru a evita accesarea unui element inexistent.
13. Parolă încapsulată conceptualDificil
Enunțul problemei
Definește o clasă ContUtilizator cu nume și o parolă stocată intern. Oferă o metodă verifică_parola fără a afișa parola.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class ContUtilizator:
def __init__(self,nume,parola): self.nume=nume; self.__parola=parola
def verifica_parola(self,p): return p==self.__parola
c=ContUtilizator('ion','abc123'); print(c.verifica_parola('abc123'))Explicația rezolvării: Parola este stocată într-un atribut cu nume intern și nu este afișată. Metoda verifica_parola compară valoarea primită cu parola internă și returnează doar rezultatul verificării.
14. Joc cu jucătoriDificil
Enunțul problemei
Definește Jucator cu nume și punctaj. Creează o clasă Joc care adaugă jucători și determină câștigătorul.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Jucator:
def __init__(self,nume,punctaj): self.nume=nume; self.punctaj=punctaj
class Joc:
def __init__(self): self.jucatori=[]
def adauga(self,j): self.jucatori.append(j)
def castigator(self): return max(self.jucatori,key=lambda j:j.punctaj)
j=Joc(); j.adauga(Jucator('A',10)); j.adauga(Jucator('B',14)); print(j.castigator().nume)Explicația rezolvării: Jocul administrează mai mulți jucători. Câștigătorul este obiectul cu punctaj maxim, ales prin max și key.
15. Rezultate sportiveDificil
Enunțul problemei
Definește Meci cu două echipe și scoruri și o clasă Campionat care calculează clasamentul.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Meci:
def __init__(self,a,b,sa,sb): self.a=a; self.b=b; self.sa=sa; self.sb=sb
class Campionat:
def __init__(self): self.meciuri=[]
def adauga(self,m): self.meciuri.append(m)
def clasament(self):
p={}
for m in self.meciuri:
p.setdefault(m.a,0); p.setdefault(m.b,0)
if m.sa>m.sb: p[m.a]+=3
elif m.sa<m.sb: p[m.b]+=3
else: p[m.a]+=1; p[m.b]+=1
return sorted(p.items(),key=lambda x:x[1],reverse=True)
c=Campionat(); c.adauga(Meci('A','B',2,1)); print(c.clasament())Explicația rezolvării: Clasamentul este construit într-un dicționar echipă→puncte. Fiecare meci actualizează punctele, iar la final sortăm descrescător după punctaj. Structura separă clar datele meciului de logica turneului.
16. Fructe și coșuriFoarte dificil
Enunțul problemei
Definește Fruct cu nume și greutate și CosFructe care calculează greutatea totală și fructul cel mai greu.
Explicație detaliată
Ideea centrală: Descompune problema în pași mici: date de intrare, prelucrare, rezultat și cazuri-limită. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Fruct:
def __init__(self,nume,greutate): self.nume=nume; self.greutate=greutate
class CosFructe:
def __init__(self): self.fructe=[]
def adauga(self,f): self.fructe.append(f)
def total(self): return sum(f.greutate for f in self.fructe)
def greu(self): return max(self.fructe,key=lambda f:f.greutate)
c=CosFructe(); c.adauga(Fruct('Mar',150)); c.adauga(Fruct('Pepene',500)); print(c.total(),c.greu().nume)Explicația rezolvării: Coșul conține obiecte Fruct. total însumează greutățile, iar greu selectează obiectul cu greutatea maximă.
17. Stoc magazinFoarte dificil
Enunțul problemei
Definește Produs cu cod, nume, preț și stoc. Clasa Magazin trebuie să poată realiza vânzări și să actualizeze stocul.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Produs:
def __init__(self,cod,nume,pret,stoc): self.cod=cod; self.nume=nume; self.pret=pret; self.stoc=stoc
class Magazin:
def __init__(self): self.produse={}
def adauga(self,p): self.produse[p.cod]=p
def vinde(self,cod,n):
p=self.produse.get(cod)
if p and n<=p.stoc: p.stoc-=n; return n*p.pret
return None
m=Magazin(); m.adauga(Produs('A','Pix',5,10)); print(m.vinde('A',3))Explicația rezolvării: Dicționarul face căutarea produsului după cod eficientă. Vânzarea verifică existența și stocul înainte de a modifica starea produsului.
18. AgendăFoarte dificil
Enunțul problemei
Definește Contact și Agenda. Agenda trebuie să permită adăugarea, căutarea după nume și ștergerea unui contact.
Explicație detaliată
Ideea centrală: Descompune problema în pași mici: date de intrare, prelucrare, rezultat și cazuri-limită. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Contact:
def __init__(self,nume,telefon): self.nume=nume; self.telefon=telefon
class Agenda:
def __init__(self): self.contacte=[]
def adauga(self,c): self.contacte.append(c)
def cauta(self,n): return [c for c in self.contacte if c.nume==n]
def sterge(self,n): self.contacte=[c for c in self.contacte if c.nume!=n]
a=Agenda(); a.adauga(Contact('Ana','0712')); print(a.cauta('Ana'))
Explicația rezolvării: Agenda este responsabilă de colecția de contacte. Căutarea filtrează după nume, iar ștergerea reconstruiește lista fără contactele vizate. Pentru agende mari, un dicționar indexat după nume ar fi mai eficient.
19. MașiniFoarte dificil
Enunțul problemei
Definește Mașină cu marcă, model și kilometraj. Adaugă metode pentru deplasare și afișarea stării.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Masina:
def __init__(self,marca,model,km): self.marca=marca; self.model=model; self.km=km
def deplasare(self,dist):
if dist>=0: self.km+=dist
def stare(self): return f'{self.marca} {self.model}: {self.km} km'
m=Masina('Dacia','Logan',10000); m.deplasare(120); print(m.stare())Explicația rezolvării: Kilometrajul este starea care se modifică. Metoda deplasare validează distanța și o adaugă, iar stare centralizează afișarea datelor obiectului.
20. Sistem de noteFoarte dificil
Enunțul problemei
Definește Evaluare și Elev. O evaluare are materie și notă; elevul trebuie să calculeze media și să identifice materia cu nota maximă.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Evaluare:
def __init__(self,materie,n): self.materie=materie; self.nota=n
class Elev:
def __init__(self): self.evaluari=[]
def adauga(self,e): self.evaluari.append(e)
def medie(self): return sum(e.nota for e in self.evaluari)/len(self.evaluari)
def materia_max(self): return max(self.evaluari,key=lambda e:e.nota).materie
e=Elev(); e.adauga(Evaluare('Mate',10)); e.adauga(Evaluare('Info',9)); print(e.medie(),e.materia_max())Explicația rezolvării: Elevul conține obiecte Evaluare, fiecare cu materie și notă. Media și materia cu nota maximă sunt calculate folosind atributele obiectelor din listă.
21. Fișier ca modulFoarte dificil
Enunțul problemei
Separă clasele unui mini-proiect în două module și explică importurile și rolul fiecărui fișier.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
# geometrie.py
class Dreptunghi:
def __init__(self,l,L): self.l=l; self.L=L
def aria(self): return self.l*self.L
# main.py
from geometrie import Dreptunghi
print(Dreptunghi(3,4).aria())Explicația rezolvării: Fișierul cu clase este modulul. Fișierul principal îl importă și folosește clasele. Această organizare permite testarea și reutilizarea independentă a componentelor.
22. Obiecte și copiereFoarte dificil
Enunțul problemei
Construiește două obiecte cu aceeași clasă și explică de ce modificarea unui atribut al unuia nu trebuie să schimbe automat celălalt.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Elev:
def __init__(self,nume): self.nume=nume
a=Elev('A'); b=Elev('B'); a.nume='X'; print(a.nume,b.nume)Explicația rezolvării: Fiecare apel al constructorului creează un obiect separat. Atributele simple sunt păstrate independent; modificarea lui a.nume nu schimbă b.nume. Pentru liste/dicționare partajate trebuie evitate valorile implicite mutabile.
23. Metode care returnează obiecteFoarte dificil
Enunțul problemei
Definește o clasă Vector2D ale cărei metode pot returna un nou vector rezultat din adunare sau scalare.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Vector2D:
def __init__(self,x,y): self.x=x; self.y=y
def aduna(self,v): return Vector2D(self.x+v.x,self.y+v.y)
def scaleaza(self,k): return Vector2D(self.x*k,self.y*k)
a=Vector2D(1,2); b=Vector2D(3,4); c=a.aduna(b); print(c.x,c.y)Explicația rezolvării: Metodele nu modifică vectorul inițial, ci creează un nou obiect cu rezultatul. Această alegere face operațiile ușor de compus și evită efectele secundare.
24. Mini-sistem OOPFoarte dificil
Enunțul problemei
Construiește un sistem format din Utilizator, Produs și Comandă, astfel încât o comandă să conțină produse și să poată calcula totalul.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
class Utilizator:
def __init__(self,nume): self.nume=nume
class Produs:
def __init__(self,nume,pret): self.nume=nume; self.pret=pret
class Comanda:
def __init__(self,u): self.utilizator=u; self.produse=[]
def adauga(self,p): self.produse.append(p)
def total(self): return sum(p.pret for p in self.produse)
u=Utilizator('Ana'); c=Comanda(u); c.adauga(Produs('Carte',30)); c.adauga(Produs('Pix',5)); print(c.total())Explicația rezolvării: Comanda are o relație cu Utilizatorul și conține o colecție de Produse. Metoda total traversează produsele și însumează prețurile. Este un exemplu de colaborare între mai multe clase.
Capitolul 8. Fișiere text în Python
25 de probleme dificile și foarte dificile. Tema este construită pe conceptele din pagina sursă: capitolul 8 și subtemele sale.
Partea I – Lista enunțurilor
- Raport de note — Citește note dintr-un fișier text, calculează statistici și scrie un raport separat. Folosește with open().
- Filtrare în fișier — Citește un fișier și scrie într-un al doilea doar liniile care conțin un cuvânt dat.
- Număr de cuvinte — Citește întregul fișier și determină numărul de cuvinte, caractere și linii.
- Cea mai lungă linie — Parcurge fișierul linie cu linie și identifică linia cu cele mai multe caractere.
- Frecvența cuvintelor — Construiește un dicționar de frecvențe dintr-un fișier text și scrie primele rezultate într-un raport.
- Jurnal cu append — Construiește un program care adaugă mesaje succesive într-un jurnal fără să șteargă intrările vechi.
- Copiere cu numerotare — Copiază un fișier într-un altul și adaugă numărul fiecărei linii.
- Separarea numerelor — Citește un fișier cu numere și creează două fișiere: unul pentru pare și unul pentru impare.
- Statistici din fișier — Fiecare linie conține o notă. Calculează media, minimul, maximul și numărul de valori valide.
- Linii invalide — Unele linii dintr-un fișier nu sunt numere. Procesează doar liniile valide și scrie separat erorile.
- Căutare de expresie — Citește un fișier și raportează toate numerele liniilor în care apare un text căutat.
- Înlocuire controlată — Creează o copie a unui fișier în care un cuvânt este înlocuit cu altul, fără a modifica originalul.
- Concatenare de fișiere — Unește conținutul mai multor fișiere într-unul singur, păstrând ordinea și separarea clară.
- Împărțire pe categorii — Fiecare linie are forma categorie;valoare. Separă datele în fișiere diferite după categorie.
- Mini-bază de date — Salvează persoane sub forma nume;vârstă într-un fișier și permite căutarea după nume.
- Actualizarea unei înregistrări — Citește un fișier de tip nume;valoare, modifică o singură înregistrare și rescrie fișierul în siguranță.
- Eliminarea duplicatelor — Creează o copie fără linii duplicate, păstrând prima apariție.
- Top valori din fișier — Citește numere din fișier și scrie într-un raport cele mai mari trei valori distincte.
- Analiza unui text — Determină lungimea medie a cuvintelor și cuvântul cel mai lung.
- Raport multi-secțiune — Dintr-un fișier cu secțiuni, construiește un raport cu statistici pentru fiecare secțiune.
- Jurnal cu marcaj temporal — Adaugă mesaje într-un fișier folosind data și ora curentă ca prefix și explică separarea datelor.
- Procesare fără read() — Rezolvă o problemă de numărare a liniilor și a numerelor folosind parcurgerea directă a fișierului, fără să încarci tot conținutul.
- Comparație între fișiere — Determină liniile comune dintre două fișiere și scrie rezultatul într-un al treilea.
- Verificarea integrității — Citește două fișiere și determină dacă au același conținut, folosind citirea adecvată și tratând diferențele de final de linie.
- Mini-proiect fișiere — Construiește un program care citește date, validează, produce statistici și generează un raport final în fișier.
Partea II – Enunț + explicație detaliată
1. Raport de noteDificil
Enunțul problemei
Citește note dintr-un fișier text, calculează statistici și scrie un raport separat. Folosește with open().
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('note.txt','r',encoding='utf-8') as f:
note=[float(x.strip()) for x in f if x.strip()]
with open('raport.txt','w',encoding='utf-8') as f:
f.write(f'Numar: {len(note)}\nMedia: {sum(note)/len(note):.2f}\nMinim: {min(note)}\nMaxim: {max(note)}\n')Explicația rezolvării: Citirea și scrierea sunt plasate în blocuri with, care închid automat fișierele. Convertim fiecare linie la float și apoi calculăm statisticile. Înainte de min/max/media trebuie verificat cazul fișierului gol.
2. Filtrare în fișierDificil
Enunțul problemei
Citește un fișier și scrie într-un al doilea doar liniile care conțin un cuvânt dat.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
cuv='python'
with open('intrare.txt',encoding='utf-8') as f:
linii=f.readlines()
with open('iesire.txt','w',encoding='utf-8') as g:
for linie in linii:
if cuv.lower() in linie.lower(): g.write(linie)Explicația rezolvării: Parcurgem liniile și testăm apariția cuvântului fără diferență de litere. Doar liniile care satisfac condiția sunt scrise în fișierul rezultat.
3. Număr de cuvinteDificil
Enunțul problemei
Citește întregul fișier și determină numărul de cuvinte, caractere și linii.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('text.txt',encoding='utf-8') as f: text=f.read()
print(len(text),len(text.split()),len(text.splitlines()))Explicația rezolvării: read() încarcă întregul text. len(text) numără caracterele, split() separă după spații albe și splitlines() numără liniile. Pentru fișiere foarte mari, este preferabilă procesarea linie cu linie.
4. Cea mai lungă linieDificil
Enunțul problemei
Parcurge fișierul linie cu linie și identifică linia cu cele mai multe caractere.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
best='';
with open('text.txt',encoding='utf-8') as f:
for linie in f:
if len(linie.rstrip('\n'))>len(best): best=linie.rstrip('\n')
print(best)Explicația rezolvării: Citirea linie cu linie evită încărcarea întregului fișier. Păstrăm doar cea mai lungă linie găsită până acum. Memoria suplimentară este O(L), unde L este lungimea celei mai lungi linii.
5. Frecvența cuvintelorDificil
Enunțul problemei
Construiește un dicționar de frecvențe dintr-un fișier text și scrie primele rezultate într-un raport.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
from collections import Counter
with open('text.txt',encoding='utf-8') as f: words=f.read().lower().split()
f=Counter(words)
with open('raport.txt','w',encoding='utf-8') as g:
for w,n in f.most_common(10): g.write(f'{w}: {n}\n')Explicația rezolvării: Counter construiește frecvențele cuvintelor, iar most_common sortează conceptual după frecvență. Raportul este scris într-un fișier separat, fără a modifica sursa.
6. Jurnal cu appendDificil
Enunțul problemei
Construiește un program care adaugă mesaje succesive într-un jurnal fără să șteargă intrările vechi.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
mesaj='Program pornit'
with open('jurnal.txt','a',encoding='utf-8') as f: f.write(mesaj+'\n')Explicația rezolvării: Modul a deschide fișierul în append, deci scrierea se face la final și nu șterge intrările existente. newline-ul separă mesajele.
7. Copiere cu numerotareDificil
Enunțul problemei
Copiază un fișier într-un altul și adaugă numărul fiecărei linii.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('sursa.txt',encoding='utf-8') as f, open('copie.txt','w',encoding='utf-8') as g:
for i,linie in enumerate(f,1): g.write(f'{i}: {linie}')Explicația rezolvării: enumerate(f,1) furnizează simultan numărul liniei și conținutul. Scriem numărul înaintea fiecărei linii în fișierul nou.
8. Separarea numerelorDificil
Enunțul problemei
Citește un fișier cu numere și creează două fișiere: unul pentru pare și unul pentru impare.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('numere.txt',encoding='utf-8') as f:
pare=[]; impare=[]
for linie in f:
try:
x=int(linie.strip())
(pare if x%2==0 else impare).append(x)
except ValueError: pass
with open('pare.txt','w') as p: p.write('\n'.join(map(str,pare)))
with open('impare.txt','w') as p: p.write('\n'.join(map(str,impare)))Explicația rezolvării: Fiecare linie este convertită la int și clasificată după restul împărțirii la 2. Într-o versiune strictă, liniile invalide ar trebui raportate separat. La final, valorile sunt transformate în șiruri și scrise.
9. Statistici din fișierDificil
Enunțul problemei
Fiecare linie conține o notă. Calculează media, minimul, maximul și numărul de valori valide.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('note.txt',encoding='utf-8') as f:
note=[]
for l in f:
try: note.append(float(l.strip()))
except ValueError: pass
if note: print(sum(note)/len(note),min(note),max(note),len(note))Explicația rezolvării: Procesăm doar valorile convertibile la float. Dacă lista este nevidă, putem calcula toate statisticile. Numărul de valori valide este len(note).
10. Linii invalideDificil
Enunțul problemei
Unele linii dintr-un fișier nu sunt numere. Procesează doar liniile valide și scrie separat erorile.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
erori=[]; valori=[]
with open('date.txt',encoding='utf-8') as f:
for nr,l in enumerate(f,1):
try: valori.append(float(l.strip()))
except ValueError: erori.append((nr,l.strip()))
print('valide',valori,'erori',erori)Explicația rezolvării: try/except izolează fiecare linie invalidă, astfel încât o singură eroare nu oprește procesarea întregului fișier. Memorăm numărul liniei pentru raportare.
11. Căutare de expresieDificil
Enunțul problemei
Citește un fișier și raportează toate numerele liniilor în care apare un text căutat.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
text_cautat='eroare'
with open('jurnal.txt',encoding='utf-8') as f:
linii=[i for i,l in enumerate(f,1) if text_cautat in l]
print(linii)Explicația rezolvării: enumerate oferă numărul liniei. Lista rezultat conține doar pozițiile în care apare expresia. Pentru căutare fără diferență între litere, putem compara lower().
12. Înlocuire controlatăDificil
Enunțul problemei
Creează o copie a unui fișier în care un cuvânt este înlocuit cu altul, fără a modifica originalul.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('sursa.txt',encoding='utf-8') as f: text=f.read()
text=text.replace('vechi','nou')
with open('copie.txt','w',encoding='utf-8') as g: g.write(text)Explicația rezolvării: Citim originalul, aplicăm replace pe copia din memorie și scriem rezultatul într-un alt fișier. Originalul rămâne neschimbat.
13. Concatenare de fișiereDificil
Enunțul problemei
Unește conținutul mai multor fișiere într-unul singur, păstrând ordinea și separarea clară.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
nume=['a.txt','b.txt','c.txt']
with open('toate.txt','w',encoding='utf-8') as out:
for fn in nume:
with open(fn,encoding='utf-8') as f:
out.write(f'--- {fn} ---\n'); out.write(f.read()); out.write('\n')Explicația rezolvării: Fișierele sunt procesate în ordinea din listă. Un separator înaintea fiecăruia face clară originea conținutului. with asigură închiderea fiecărui fișier.
14. Împărțire pe categoriiDificil
Enunțul problemei
Fiecare linie are forma categorie;valoare. Separă datele în fișiere diferite după categorie.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
from collections import defaultdict
cat=defaultdict(list)
with open('date.txt',encoding='utf-8') as f:
for l in f:
categorie,val=l.strip().split(';',1); cat[categorie].append(val)
for c,vals in cat.items():
with open(c+'.txt','w',encoding='utf-8') as g: g.write('\n'.join(vals))Explicația rezolvării: split(';',1) separă exact în două câmpuri. Dicționarul grupează valorile după categorie, iar apoi fiecare grup este scris în fișierul corespunzător.
15. Mini-bază de dateDificil
Enunțul problemei
Salvează persoane sub forma nume;vârstă într-un fișier și permite căutarea după nume.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
def cauta(nume):
with open('persoane.txt',encoding='utf-8') as f:
for l in f:
p=l.rstrip('\n').split(';')
if len(p)==2 and p[0]==nume: return p[1]
return None
print(cauta('Ana'))Explicația rezolvării: Fiecare linie este separată în nume și vârstă. Căutarea poate fi făcută linie cu linie, fără să încărcăm întregul fișier. Pentru multe căutări, un dicționar încărcat o singură dată este mai eficient.
16. Actualizarea unei înregistrăriFoarte dificil
Enunțul problemei
Citește un fișier de tip nume;valoare, modifică o singură înregistrare și rescrie fișierul în siguranță.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
linii=[]
with open('date.txt',encoding='utf-8') as f:
for l in f:
nume,val=l.rstrip('\n').split(';')
if nume=='Ana': val='100'
linii.append(f'{nume};{val}\n')
with open('date.tmp','w',encoding='utf-8') as f: f.writelines(linii)Explicația rezolvării: Nu modificăm direct fișierul în timpul citirii. Construim un fișier temporar cu toate liniile actualizate și apoi, într-un proiect real, îl înlocuim pe cel original după verificare. Aceasta reduce riscul de a corupe sursa.
17. Eliminarea duplicatelorFoarte dificil
Enunțul problemei
Creează o copie fără linii duplicate, păstrând prima apariție.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
vazute=set(); rezultat=[]
with open('text.txt',encoding='utf-8') as f:
for l in f:
cheie=l.rstrip('\n')
if cheie not in vazute: vazute.add(cheie); rezultat.append(l)
with open('fara_duplicate.txt','w',encoding='utf-8') as g: g.writelines(rezultat)Explicația rezolvării: Setul păstrează liniile deja întâlnite, iar lista rezultat păstrează prima apariție. Complexitatea medie este O(n) după numărul de linii.
18. Top valori din fișierFoarte dificil
Enunțul problemei
Citește numere din fișier și scrie într-un raport cele mai mari trei valori distincte.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
vals=[]
with open('numere.txt',encoding='utf-8') as f:
for l in f:
try: vals.append(float(l))
except ValueError: pass
top=sorted(set(vals),reverse=True)[:3]
with open('top.txt','w',encoding='utf-8') as g: g.write('\n'.join(map(str,top)))Explicația rezolvării: Convertim valorile valide, eliminăm duplicatele cu set și sortăm descrescător. Primele trei reprezintă cele mai mari valori distincte.
19. Analiza unui textFoarte dificil
Enunțul problemei
Determină lungimea medie a cuvintelor și cuvântul cel mai lung.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import re
with open('text.txt',encoding='utf-8') as f: words=re.findall(r'\b\w+\b',f.read().lower())
med=sum(map(len,words))/len(words) if words else 0
lung=max(words,key=len) if words else ''
print(med,lung)Explicația rezolvării: Expresia regulată extrage cuvinte, apoi calculăm suma lungimilor împărțită la numărul de cuvinte și alegem cu max(key=len) cel mai lung cuvânt. Dacă nu există cuvinte, evităm împărțirea la zero.
20. Raport multi-secțiuneFoarte dificil
Enunțul problemei
Dintr-un fișier cu secțiuni, construiește un raport cu statistici pentru fiecare secțiune.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
sectiune=None; date={}
with open('sectiuni.txt',encoding='utf-8') as f:
for l in f:
l=l.strip()
if l.startswith('['): sectiune=l[1:-1]; date[sectiune]=[]
elif l: date[sectiune].append(l)
with open('raport.txt','w',encoding='utf-8') as g:
for s,vals in date.items(): g.write(f'{s}: {len(vals)}\n')Explicația rezolvării: Folosim liniile care încep cu [ pentru a detecta începutul unei secțiuni. Valorile sunt grupate într-un dicționar pe secțiuni, apoi raportul parcurge aceste grupări.
21. Jurnal cu marcaj temporalFoarte dificil
Enunțul problemei
Adaugă mesaje într-un fișier folosind data și ora curentă ca prefix și explică separarea datelor.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
from datetime import datetime
mesaj='Pornire program'
with open('jurnal.txt','a',encoding='utf-8') as f: f.write(f'[{datetime.now():%Y-%m-%d %H:%M:%S}] {mesaj}\n')Explicația rezolvării: datetime.now() produce momentul curent. Formatul îl transformă într-un prefix lizibil, iar append păstrează mesajele anterioare.
22. Procesare fără read()Foarte dificil
Enunțul problemei
Rezolvă o problemă de numărare a liniilor și a numerelor folosind parcurgerea directă a fișierului, fără să încarci tot conținutul.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
nr_linii=nr_numere=0
with open('date.txt',encoding='utf-8') as f:
for l in f:
nr_linii+=1
for x in l.split():
try: float(x); nr_numere+=1
except ValueError: pass
print(nr_linii,nr_numere)Explicația rezolvării: Parcurgem direct fișierul, deci nu folosim read() și nu încărcăm tot conținutul. Numărăm liniile și încercăm conversia fiecărui token la float.
23. Comparație între fișiereFoarte dificil
Enunțul problemei
Determină liniile comune dintre două fișiere și scrie rezultatul într-un al treilea.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('a.txt',encoding='utf-8') as f: A=set(x.rstrip('\n') for x in f)
with open('b.txt',encoding='utf-8') as f: B=set(x.rstrip('\n') for x in f)
with open('comune.txt','w',encoding='utf-8') as g: g.write('\n'.join(sorted(A&B)))Explicația rezolvării: Seturile permit intersecția A&B rapid. Sortarea rezultatului este doar pentru o ieșire ordonată. Dacă trebuie păstrată ordinea primului fișier, soluția trebuie adaptată.
24. Verificarea integritățiiFoarte dificil
Enunțul problemei
Citește două fișiere și determină dacă au același conținut, folosind citirea adecvată și tratând diferențele de final de linie.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
with open('a.txt','rb') as f: A=f.read()
with open('b.txt','rb') as f: B=f.read()
print(A==B)Explicația rezolvării: Citirea în modul binar compară exact octeții, inclusiv diferențele de final de linie. Pentru integritate, aceasta este mai sigură decât normalizarea textului, deoarece nu ascunde diferențe.
25. Mini-proiect fișiereFoarte dificil
Enunțul problemei
Construiește un program care citește date, validează, produce statistici și generează un raport final în fișier.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
def procesare(infile,outfile):
vals=[]
with open(infile,encoding='utf-8') as f:
for l in f:
try: vals.append(float(l.strip()))
except ValueError: pass
with open(outfile,'w',encoding='utf-8') as g:
if vals:
g.write(f'Numar: {len(vals)}\nMedia: {sum(vals)/len(vals):.2f}\n')
else: g.write('Nu exista valori valide.\n')
procesare('date.txt','raport.txt')Explicația rezolvării: Funcția separă citirea, validarea și raportarea. Fiecare linie este validată, apoi statisticile sunt calculate doar pentru valorile corecte. Raportul final este scris cu with open().
Capitolul 9. Tkinter – interfețe grafice
25 de probleme dificile și foarte dificile. Tema este construită pe conceptele din pagina sursă: capitolul 9 și subtemele sale.
Partea I – Lista enunțurilor
- Calculator cu validare — Creează o interfață cu două Entry și butoane pentru adunare, scădere, înmulțire și împărțire. Folosește messagebox pentru erori.
- Convertor temperatură — Construiește o fereastră care transformă Celsius în Fahrenheit și invers, cu verificarea inputului.
- Calculator medie — Utilizatorul introduce mai multe note într-un Text; programul calculează media și afișează minimul și maximul.
- Numărător de apăsări — Creează un buton care incrementează un contor afișat într-un Label și alt buton pentru resetare.
- Formular de înscriere — Construiește un formular cu nume, vârstă și email și validează câmpurile înainte de confirmare.
- Interfață pe Frame-uri — Organizează o aplicație în zone pentru titlu, formular, rezultate și butoane folosind Frame și grid/pack.
- Editor text simplu — Folosește Text pentru a scrie, șterge și afișa conținutul și adaugă butoane pentru operații.
- Căutare într-un text — Utilizatorul introduce un cuvânt și aplicația numără aparițiile în Text.
- Mini-agendă — Construiește o interfață pentru adăugarea și căutarea unor contacte, afișând rezultatele într-un Label sau Text.
- Quiz cu scor — Afișează întrebări succesive și răspunsuri prin butoane; actualizează scorul și afișează rezultatul final.
- Generator de statistici — Introdu o listă de numere într-un Entry și afișează len, min, max, sumă și medie.
- Interfață pentru fișiere — Creează butoane pentru scrierea și citirea unui fișier text și afișează conținutul în Text.
- Jurnal grafic — Utilizatorul scrie un mesaj într-un Text și îl salvează prin append într-un fișier.
- Formular cu resetare — Creează mai multe Entry și un buton Reset care golește toate câmpurile.
- Validare numerică — Construiește o funcție reutilizabilă care validează un Entry și returnează un număr întreg sau semnalează eroarea.
- Conversie bază 2 — Oferă un Entry pentru un număr binar și afișează valoarea zecimală folosind int(text,2).
- Analizor de propoziții — Textul introdus într-un widget Text este analizat: număr de linii, cuvinte și caractere.
- Catalog grafic — Construiește o interfață care primește elevi și note și afișează statisticile elevului selectat.
- Listă interactivă — Folosește Entry și butoane pentru adăugare, ștergere și sortare a unor valori dintr-o listă.
- Calculator geometric — Utilizatorul alege între cerc și dreptunghi și introduce dimensiunile; aplicația afișează aria și perimetrul.
- Interfață cu două ecrane — Folosește două Frame-uri și butoane pentru a comuta între un formular și o pagină de rezultate.
- Aplicație fără global — Construiește un contor sau calculator în care starea este păstrată într-un obiect sau într-o structură accesibilă funcțiilor.
- Gestionarea erorilor — Proiectează o aplicație Tkinter în care toate conversiile numerice pot eșua și fiecare eroare este prezentată utilizatorului prin messagebox.
- Mini-editor cu salvare — Construiește un editor simplu cu Text, butoane pentru deschidere logică prin citire, salvare prin write și ștergere.
- Mini-proiect Tkinter — Realizează o aplicație completă cu Frame, Label, Entry, Button, Text și messagebox, separând logica în funcții clare.
Partea II – Enunț + explicație detaliată
1. Calculator cu validareDificil
Enunțul problemei
Creează o interfață cu două Entry și butoane pentru adunare, scădere, înmulțire și împărțire. Folosește messagebox pentru erori.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
from tkinter import messagebox
root=tk.Tk(); root.title('Calculator')
a=tk.Entry(root); a.pack(); b=tk.Entry(root); b.pack()
def calc(op):
try:
x=float(a.get()); y=float(b.get())
if op=='/' and y==0: raise ValueError
messagebox.showinfo('Rezultat',str({'+':x+y,'-':x-y,'*':x*y,'/':x/y}[op]))
except ValueError: messagebox.showerror('Eroare','Date invalide')
for op in '+-*/': tk.Button(root,text=op,command=lambda o=op:calc(o)).pack(side='left')
root.mainloop()Explicația rezolvării: Entry furnizează valorile ca text, iar funcția calc le convertește la float. try/except tratează atât conversia, cât și împărțirea la zero. Fiecare buton transmite operația prin lambda.
2. Convertor temperaturăDificil
Enunțul problemei
Construiește o fereastră care transformă Celsius în Fahrenheit și invers, cu verificarea inputului.
Explicație detaliată
Ideea centrală: Descompune problema în pași mici: date de intrare, prelucrare, rezultat și cazuri-limită. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
from tkinter import messagebox
root=tk.Tk(); e=tk.Entry(root); e.pack()
out=tk.Label(root,text=''); out.pack()
def celsius():
try: out.config(text=f'{float(e.get())*9/5+32:.2f} °F')
except ValueError: messagebox.showerror('Eroare','Temperatură invalidă')
def fahrenheit():
try: out.config(text=f'{(float(e.get())-32)*5/9:.2f} °C')
except ValueError: messagebox.showerror('Eroare','Temperatură invalidă')
tk.Button(root,text='C→F',command=celsius).pack(); tk.Button(root,text='F→C',command=fahrenheit).pack(); root.mainloop()Explicația rezolvării: Două butoane apelează două funcții diferite de conversie. get() citește textul, float îl transformă în număr, iar config actualizează Label-ul.
3. Calculator medieDificil
Enunțul problemei
Utilizatorul introduce mai multe note într-un Text; programul calculează media și afișează minimul și maximul.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); t=tk.Text(root,height=8); t.pack()
out=tk.Label(root,text=''); out.pack()
def calc():
try:
n=[float(x) for x in t.get('1.0','end').split()]
out.config(text=f'Media={sum(n)/len(n):.2f}, min={min(n)}, max={max(n)}')
except (ValueError,ZeroDivisionError): out.config(text='Date invalide')
tk.Button(root,text='Calculează',command=calc).pack(); root.mainloop()Explicația rezolvării: Text este citit cu get('1.0','end'), iar split separă valorile. Conversia la float validează datele. Calculul statistic este realizat doar dacă există cel puțin o valoare.
4. Numărător de apăsăriDificil
Enunțul problemei
Creează un buton care incrementează un contor afișat într-un Label și alt buton pentru resetare.
Explicație detaliată
Ideea centrală: Descompune problema în pași mici: date de intrare, prelucrare, rezultat și cazuri-limită. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk root=tk.Tk(); n=tk.IntVar(value=0); lab=tk.Label(root,textvariable=n); lab.pack() tk.Button(root,text='+1',command=lambda:n.set(n.get()+1)).pack(); tk.Button(root,text='Reset',command=lambda:n.set(0)).pack(); root.mainloop()
Explicația rezolvării: IntVar păstrează starea contorului și permite Label-ului să se actualizeze automat prin textvariable. Butoanele modifică aceeași stare.
5. Formular de înscriereDificil
Enunțul problemei
Construiește un formular cu nume, vârstă și email și validează câmpurile înainte de confirmare.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
from tkinter import messagebox
root=tk.Tk(); entries=[]
for label in ('Nume','Vârstă','Email'):
tk.Label(root,text=label).pack(); e=tk.Entry(root); e.pack(); entries.append(e)
def confirma():
vals=[e.get().strip() for e in entries]
if not all(vals): messagebox.showerror('Eroare','Completează toate câmpurile')
else: messagebox.showinfo('OK','Date valide')
tk.Button(root,text='Confirmă',command=confirma).pack(); root.mainloop()Explicația rezolvării: Creăm câte un Entry pentru fiecare câmp și păstrăm referințele într-o listă. all verifică dacă toate sunt completate. Într-o variantă extinsă se pot adăuga verificări pentru vârstă și formatul emailului.
6. Interfață pe Frame-uriDificil
Enunțul problemei
Organizează o aplicație în zone pentru titlu, formular, rezultate și butoane folosind Frame și grid/pack.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk root=tk.Tk(); top=tk.Frame(root); top.pack(); body=tk.Frame(root); body.pack() tk.Label(top,text='Titlu').pack(); tk.Label(body,text='Formular').grid(row=0,column=0); tk.Button(body,text='OK').grid(row=1,column=0); root.mainloop()
Explicația rezolvării: Frame grupează componentele pe zone. pack poate așeza zonele principale, iar grid organizează componentele în interiorul unei zone. Nu este recomandat să amestecăm pack și grid în același container.
7. Editor text simpluDificil
Enunțul problemei
Folosește Text pentru a scrie, șterge și afișa conținutul și adaugă butoane pentru operații.
Explicație detaliată
Ideea centrală: Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); t=tk.Text(root); t.pack()
def sterge(): t.delete('1.0','end')
def afiseaza(): print(t.get('1.0','end'))
tk.Button(root,text='Șterge',command=sterge).pack(); tk.Button(root,text='Afișează',command=afiseaza).pack(); root.mainloop()Explicația rezolvării: Text permite editarea mai multor linii. delete golește conținutul, iar get îl citește. Butoanele leagă aceste operații de evenimente.
8. Căutare într-un textDificil
Enunțul problemei
Utilizatorul introduce un cuvânt și aplicația numără aparițiile în Text.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); t=tk.Text(root,height=8); t.pack(); e=tk.Entry(root); e.pack(); out=tk.Label(root); out.pack()
def cauta(): out.config(text=f'Apariții: {t.get("1.0","end").count(e.get())}')
tk.Button(root,text='Caută',command=cauta).pack(); root.mainloop()Explicația rezolvării: get citește textul și cuvântul căutat, iar str.count numără aparițiile. Pentru căutări mai complexe putem folosi reguli de delimitare a cuvintelor.
9. Mini-agendăDificil
Enunțul problemei
Construiește o interfață pentru adăugarea și căutarea unor contacte, afișând rezultatele într-un Label sau Text.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); contacts={}
n=tk.Entry(root); n.pack(); p=tk.Entry(root); p.pack(); out=tk.Label(root); out.pack()
def add(): contacts[n.get().strip()]=p.get().strip()
def find(): out.config(text=contacts.get(n.get().strip(),'Nu există'))
tk.Button(root,text='Adaugă',command=add).pack(); tk.Button(root,text='Caută',command=find).pack(); root.mainloop()Explicația rezolvării: Dicționarul este potrivit pentru o agendă deoarece cheia poate fi numele. Butonul de adăugare actualizează dicționarul, iar căutarea folosește get pentru a evita KeyError.
10. Quiz cu scorDificil
Enunțul problemei
Afișează întrebări succesive și răspunsuri prin butoane; actualizează scorul și afișează rezultatul final.
Explicație detaliată
Ideea centrală: Descompune problema în pași mici: date de intrare, prelucrare, rezultat și cazuri-limită. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); intrebari=[('2+2?',['3','4','5'],1),('Capitala României?',['Iași','Cluj','București'],2)]; i=0; scor=0
q=tk.Label(root); q.pack(); btns=[]
def arata():
global i
if i<len(intrebari):
text,rasp,corect=intrebari[i]; q.config(text=text)
for b,r in zip(btns,rasp): b.config(text=r,command=lambda r=r:raspunde(r))
else: q.config(text=f'Scor final: {scor}/{len(intrebari)}')
def raspunde(r):
global i,scor
if r==intrebari[i][1][intrebari[i][2]]: scor+=1
i+=1; arata()
for _ in range(3): b=tk.Button(root); b.pack(); btns.append(b)
arata(); root.mainloop()Explicația rezolvării: Păstrăm întrebările într-o listă de tupluri și un index i indică întrebarea curentă. După răspuns, scorul este actualizat și trecem la următoarea întrebare. Funcția arata centralizează actualizarea interfeței.
11. Generator de statisticiDificil
Enunțul problemei
Introdu o listă de numere într-un Entry și afișează len, min, max, sumă și medie.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); e=tk.Entry(root); e.pack(); out=tk.Label(root); out.pack()
def calc():
a=[float(x) for x in e.get().split(',')]; out.config(text=f'len={len(a)}, min={min(a)}, max={max(a)}, sum={sum(a)}, medie={sum(a)/len(a):.2f}')
tk.Button(root,text='Statistici',command=calc).pack(); root.mainloop()Explicația rezolvării: Entry conține o listă scrisă ca text, separată prin virgule. O convertim la float și apoi aplicăm len/min/max/sum. Interfața afișează toate rezultatele într-un singur Label.
12. Interfață pentru fișiereDificil
Enunțul problemei
Creează butoane pentru scrierea și citirea unui fișier text și afișează conținutul în Text.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); t=tk.Text(root); t.pack()
def scrie():
with open('date.txt','w',encoding='utf-8') as f: f.write(t.get('1.0','end'))
def citeste():
with open('date.txt',encoding='utf-8') as f: t.delete('1.0','end'); t.insert('1.0',f.read())
tk.Button(root,text='Scrie',command=scrie).pack(); tk.Button(root,text='Citește',command=citeste).pack(); root.mainloop()Explicația rezolvării: Butoanele leagă operațiile de fișiere de interfață. Text este golit înainte de inserarea conținutului citit, pentru a evita concatenarea accidentală.
13. Jurnal graficDificil
Enunțul problemei
Utilizatorul scrie un mesaj într-un Text și îl salvează prin append într-un fișier.
Explicație detaliată
Ideea centrală: Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); t=tk.Text(root); t.pack()
def salveaza():
with open('jurnal.txt','a',encoding='utf-8') as f: f.write(t.get('1.0','end').rstrip()+'\n')
tk.Button(root,text='Salvează',command=salveaza).pack(); root.mainloop()Explicația rezolvării: append păstrează mesajele vechi. rstrip elimină newline-urile inutile de la final înainte de a adăuga unul controlat.
14. Formular cu resetareDificil
Enunțul problemei
Creează mai multe Entry și un buton Reset care golește toate câmpurile.
Explicație detaliată
Ideea centrală: Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); es=[]
for _ in range(4): e=tk.Entry(root); e.pack(); es.append(e)
def reset():
for e in es: e.delete(0,'end')
tk.Button(root,text='Reset',command=reset).pack(); root.mainloop()Explicația rezolvării: Păstrăm toate Entry într-o listă, iar reset parcurge lista și aplică delete(0,'end') fiecărui câmp. Astfel nu repetăm aceeași instrucțiune de patru ori.
15. Validare numericăDificil
Enunțul problemei
Construiește o funcție reutilizabilă care validează un Entry și returnează un număr întreg sau semnalează eroarea.
Explicație detaliată
Ideea centrală: Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
def validare_int(entry):
try: return int(entry.get())
except ValueError: return NoneExplicația rezolvării: Funcția primește un Entry, încearcă int și întoarce valoarea numerică sau None. Interfața poate verifica None și afișa un messagebox.
16. Conversie bază 2Foarte dificil
Enunțul problemei
Oferă un Entry pentru un număr binar și afișează valoarea zecimală folosind int(text,2).
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); e=tk.Entry(root); e.pack(); out=tk.Label(root); out.pack()
def conv():
try: out.config(text=str(int(e.get(),2)))
except ValueError: out.config(text='Binar invalid')
tk.Button(root,text='Convertește',command=conv).pack(); root.mainloop()Explicația rezolvării: int(text,2) interpretează șirul ca număr în baza 2. ValueError apare pentru caractere precum 2 sau 9 și este tratată în funcție.
17. Analizor de propozițiiFoarte dificil
Enunțul problemei
Textul introdus într-un widget Text este analizat: număr de linii, cuvinte și caractere.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); t=tk.Text(root); t.pack(); out=tk.Label(root); out.pack()
def analiza():
s=t.get('1.0','end'); out.config(text=f'Linii={len(s.splitlines())}, Cuvinte={len(s.split())}, Caractere={len(s)}')
tk.Button(root,text='Analizează',command=analiza).pack(); root.mainloop()Explicația rezolvării: Textul este citit o singură dată, apoi folosim splitlines pentru linii și split pentru cuvinte. len(s) numără caracterele incluzând eventualul newline final al widgetului.
18. Catalog graficFoarte dificil
Enunțul problemei
Construiește o interfață care primește elevi și note și afișează statisticile elevului selectat.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); elevi={'Ana':[9,10,8],'Ion':[7,8,9]}; num=tk.Entry(root); num.pack(); out=tk.Label(root); out.pack()
def afiseaza():
note=elevi.get(num.get()); out.config(text='Nu există' if note is None else f'Medie={sum(note)/len(note):.2f}, min={min(note)}, max={max(note)}')
tk.Button(root,text='Afișează',command=afiseaza).pack(); root.mainloop()Explicația rezolvării: Dicționarul modelează catalogul: numele este cheia, iar lista de note este valoarea. Căutarea selectează elevul, apoi statisticile sunt calculate din lista lui.
19. Listă interactivăFoarte dificil
Enunțul problemei
Folosește Entry și butoane pentru adăugare, ștergere și sortare a unor valori dintr-o listă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); a=[]; e=tk.Entry(root); e.pack(); l=tk.Listbox(root); l.pack()
def refresh(): l.delete(0,'end'); [l.insert('end',x) for x in a]
def add(): a.append(e.get()); refresh()
def delete():
if l.curselection(): a.pop(l.curselection()[0]); refresh()
def sortare(): a.sort(); refresh()
for txt,cmd in [('Adaugă',add),('Șterge',delete),('Sortează',sortare)]: tk.Button(root,text=txt,command=cmd).pack()
root.mainloop()Explicația rezolvării: Lista Python este sursa datelor, iar Listbox este doar reprezentarea vizuală. refresh sincronizează interfața după fiecare modificare. Ștergerea folosește poziția selectată, iar sortarea modifică lista în loc.
20. Calculator geometricFoarte dificil
Enunțul problemei
Utilizatorul alege între cerc și dreptunghi și introduce dimensiunile; aplicația afișează aria și perimetrul.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); tip=tk.StringVar(value='cerc'); e1=tk.Entry(root); e1.pack(); e2=tk.Entry(root); e2.pack(); out=tk.Label(root); out.pack()
def calc():
import math
try:
if tip.get()=='cerc': r=float(e1.get()); out.config(text=f'A={math.pi*r*r:.2f}, P={2*math.pi*r:.2f}')
else: l=float(e1.get()); L=float(e2.get()); out.config(text=f'A={l*L:.2f}, P={2*(l+L):.2f}')
except ValueError: out.config(text='Date invalide')
tk.Radiobutton(root,text='Cerc',variable=tip,value='cerc').pack(); tk.Radiobutton(root,text='Dreptunghi',variable=tip,value='dreptunghi').pack(); tk.Button(root,text='Calculează',command=calc).pack(); root.mainloop()Explicația rezolvării: StringVar păstrează forma aleasă. Funcția calc citește dimensiunile și aplică formula corespunzătoare. try/except tratează conversiile invalide.
21. Interfață cu două ecraneFoarte dificil
Enunțul problemei
Folosește două Frame-uri și butoane pentru a comuta între un formular și o pagină de rezultate.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk root=tk.Tk(); f1=tk.Frame(root); f2=tk.Frame(root); f1.pack(); tk.Label(f1,text='Formular').pack(); tk.Button(f1,text='Rezultate',command=lambda:(f1.pack_forget(),f2.pack())).pack(); tk.Label(f2,text='Rezultate').pack(); tk.Button(f2,text='Înapoi',command=lambda:(f2.pack_forget(),f1.pack())).pack(); root.mainloop()
Explicația rezolvării: Două Frame-uri reprezintă cele două ecrane. pack_forget ascunde ecranul curent, iar pack afișează celălalt. Astfel putem simula navigarea între pagini fără o bibliotecă suplimentară.
22. Aplicație fără globalFoarte dificil
Enunțul problemei
Construiește un contor sau calculator în care starea este păstrată într-un obiect sau într-o structură accesibilă funcțiilor.
Explicație detaliată
Ideea centrală: Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
class App:
def __init__(self,root):
self.n=0; self.l=tk.Label(root,text='0'); self.l.pack(); tk.Button(root,text='+1',command=self.inc).pack()
def inc(self): self.n+=1; self.l.config(text=str(self.n))
root=tk.Tk(); App(root); root.mainloop()Explicația rezolvării: Starea este păstrată în atributul obiectului App, nu într-o variabilă globală. Metoda inc modifică starea și actualizează Label-ul. Este o aplicație practică a încapsulării.
23. Gestionarea erorilorFoarte dificil
Enunțul problemei
Proiectează o aplicație Tkinter în care toate conversiile numerice pot eșua și fiecare eroare este prezentată utilizatorului prin messagebox.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
from tkinter import messagebox
root=tk.Tk(); e=tk.Entry(root); e.pack()
def calc():
try: x=float(e.get()); messagebox.showinfo('OK',str(x*2))
except ValueError: messagebox.showerror('Eroare','Introdu un număr valid')
tk.Button(root,text='Calculează',command=calc).pack(); root.mainloop()Explicația rezolvării: Toate conversiile sunt în try. În caz de ValueError, utilizatorul primește o eroare vizuală prin messagebox, fără ca aplicația să se închidă.
24. Mini-editor cu salvareFoarte dificil
Enunțul problemei
Construiește un editor simplu cu Text, butoane pentru deschidere logică prin citire, salvare prin write și ștergere.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Folosește with open(..., encoding='utf-8') pentru gestionarea fișierului. Alege r pentru citire, w pentru rescriere și a pentru adăugare; pentru fișiere mari, preferă parcurgerea linie cu linie. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
root=tk.Tk(); t=tk.Text(root); t.pack()
def deschide():
with open('editor.txt',encoding='utf-8') as f: t.delete('1.0','end'); t.insert('1.0',f.read())
def salveaza():
with open('editor.txt','w',encoding='utf-8') as f: f.write(t.get('1.0','end'))
def sterge(): t.delete('1.0','end')
for txt,cmd in [('Deschide',deschide),('Salvează',salveaza),('Șterge',sterge)]: tk.Button(root,text=txt,command=cmd).pack(side='left')
root.mainloop()Explicația rezolvării: Text este editorul. Deschide citește fișierul și înlocuiește conținutul widgetului, Salvează scrie textul curent, iar Șterge golește editorul. Fiecare operație este izolată într-o funcție.
25. Mini-proiect TkinterFoarte dificil
Enunțul problemei
Realizează o aplicație completă cu Frame, Label, Entry, Button, Text și messagebox, separând logica în funcții clare.
Explicație detaliată
Ideea centrală: Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă interfața de logica aplicației: componentele colectează date, funcțiile validatează și calculează, iar Label/Text/messagebox prezintă rezultatul. În command transmite funcția, fără paranteze. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
import tkinter as tk
from tkinter import messagebox
class App:
def __init__(self,r):
self.r=r; self.e=tk.Entry(r); self.e.pack(); self.t=tk.Text(r,height=5); self.t.pack()
tk.Button(r,text='Adaugă',command=self.adauga).pack(); tk.Button(r,text='Raport',command=self.raport).pack()
def adauga(self): self.t.insert('end',self.e.get()+'\n'); self.e.delete(0,'end')
def raport(self): messagebox.showinfo('Raport',f'Linii: {len(self.t.get("1.0","end").splitlines())}')
root=tk.Tk(); App(root); root.mainloop()Explicația rezolvării: Mini-proiectul reunește Frame implicit, Label/Entry/Button/Text și messagebox. Logica este pusă într-o clasă, astfel încât starea și funcțiile aplicației sunt organizate într-un singur obiect.
Capitolul 10. Clasa list – indexare, metode și probleme de sinteză
25 de probleme dificile și foarte dificile. Tema este construită pe conceptele din pagina sursă: capitolul 10 și subtemele sale.
Partea I – Lista enunțurilor
- Inserări multiple — Pornind de la o listă, inserează valori la poziții date, fără să pierzi ordinea elementelor deja existente. Explică efectul insert().
- Ștergeri controlate — Elimină toate aparițiile unei valori fără a modifica lista în timpul unei parcurgeri care poate sări elemente.
- pop versus remove — Pentru o listă dată, proiectează un algoritm care trebuie să șteargă după poziție în unele cazuri și după valoare în altele. Justifică alegerea metodei.
- Copie independentă — Demonstrează printr-un program diferența dintre atribuirea unei liste și copy(), apoi modifică lista originală și observă efectul.
- Sortare cu criteriu — Sortează o listă de numere în ordine crescătoare și apoi descrescătoare și explică parametrul reverse.
- Lista de liste — Se dau liste cu note pentru mai mulți elevi. Sortează elevii după medie și explică reprezentarea datelor.
- Eliminare vecini egali — Transformă lista astfel încât două valori egale consecutive să nu rămână una lângă alta, păstrând prima apariție.
- Rotire circulară — Rotește o listă cu k poziții la dreapta. Tratează k mai mare decât lungimea listei.
- Al doilea maxim — Găsește al doilea maxim distinct folosind metode de listă și o strategie care evită sortarea completă.
- Partiționare — Rearanjează lista astfel încât valorile negative să fie înaintea celor nenegative. Nu este obligatoriu să păstrezi ordinea internă.
- Interclasare — Interclasează două liste sortate într-o a treia listă sortată.
- Eliminarea elementelor după criteriu — Dintr-o listă păstrează doar valorile care satisfac simultan două condiții.
- Fereastră de lungime k — Pentru fiecare sublistă consecutivă de lungime k calculează suma și identifică maximul.
- Lista de frecvențe — Construiește o listă de perechi [valoare,frecvență] pentru valorile distincte, păstrând ordinea primei apariții.
- Poziția primei apariții — Fără a folosi index() direct, determină poziția primei apariții și tratează lipsa valorii.
- Număr de apariții — Compară count() cu o parcurgere manuală pentru numărarea unei valori și discută complexitatea.
- Duplicare controlată — Construiește o copie a unei liste în care fiecare element apare de două ori consecutiv.
- Filtrare în loc — Elimină din aceeași listă toate elementele negative, fără să creezi o a doua listă completă.
- Sortare și stabilitate — Se dau perechi [nume,medie]. Sortează după medie și discută ce se întâmplă când două medii sunt egale.
- K valori cele mai mici — Determină cele mai mici k valori. Compară soluția prin sort() cu menținerea unei structuri de dimensiune k.
- Subsecvență palindromică — Găsește dacă o sublistă aleasă prin doi indici este palindrom și explică indexarea pozitivă și negativă.
- Transformare prin parcurgere — Înlocuiește fiecare element cu pătratul său, apoi sortează lista și raportează minimul și maximul.
- Ștergere după mai multe criterii — Elimină elementele care sunt pare și mai mari decât o limită, fără a pierde elemente prin deplasarea indicilor.
- Mini-bază de date cu list — Reprezintă produse prin liste de liste și implementează adăugare, căutare, actualizare, ștergere și sortare.
- Problemă de sinteză list — Construiește un program care primește o listă, efectuează filtrare, eliminare duplicate, statistici, sortare și generează un raport final.
Partea II – Enunț + explicație detaliată
1. Inserări multipleDificil
Enunțul problemei
Pornind de la o listă, inserează valori la poziții date, fără să pierzi ordinea elementelor deja existente. Explică efectul insert().
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[10,20,30,40] a.insert(1,15); a.insert(3,25); print(a)
Explicația rezolvării: insert(index,valoare) introduce elementul înaintea poziției indicate și deplasează la dreapta elementele existente. Dacă facem mai multe inserări, pozițiile ulterioare trebuie interpretate în lista deja modificată.
2. Ștergeri controlateDificil
Enunțul problemei
Elimină toate aparițiile unei valori fără a modifica lista în timpul unei parcurgeri care poate sări elemente.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,2,3,2,4] a[:]=[x for x in a if x!=2] print(a)
Explicația rezolvării: Nu parcurgem lista și nu ștergem simultan elemente din ea, deoarece indicii s-ar deplasa și unele valori ar putea fi sărite. Construim filtrul și îl atribuim feliei complete, păstrând aceeași identitate a listei.
3. pop versus removeDificil
Enunțul problemei
Pentru o listă dată, proiectează un algoritm care trebuie să șteargă după poziție în unele cazuri și după valoare în altele. Justifică alegerea metodei.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=['a','b','c','b'] i=2; a.pop(i) x='b'; a.remove(x) print(a)
Explicația rezolvării: pop primește o poziție și returnează elementul eliminat. remove caută prima apariție a unei valori și o elimină. Alegerea depinde de informația pe care o avem: indice sau valoare.
4. Copie independentăDificil
Enunțul problemei
Demonstrează printr-un program diferența dintre atribuirea unei liste și copy(), apoi modifică lista originală și observă efectul.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3]; b=a; c=a.copy(); a.append(4); print(b,c)
Explicația rezolvării: b=a nu creează o listă nouă, ci o a doua referință la aceeași listă. copy creează o listă nouă, superficială. De aceea modificarea lui a se vede în b, dar nu în c.
5. Sortare cu criteriuDificil
Enunțul problemei
Sortează o listă de numere în ordine crescătoare și apoi descrescătoare și explică parametrul reverse.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[3,1,4,2]; a.sort(); print(a); a.sort(reverse=True); print(a)
Explicația rezolvării: sort modifică lista în loc. reverse=True cere ordonare descrescătoare. Pentru o listă nouă, fără modificarea originalului, se poate folosi sorted.
6. Lista de listeDificil
Enunțul problemei
Se dau liste cu note pentru mai mulți elevi. Sortează elevii după medie și explică reprezentarea datelor.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
elevi=[['Ana',[9,10,8]],['Ion',[7,8,9]],['Mara',[10,10,9]]] elevi.sort(key=lambda e:sum(e[1])/len(e[1]),reverse=True) print(elevi)
Explicația rezolvării: Fiecare element este o listă cu nume și note. key calculează media pentru sortare. Nu este nevoie să modificăm structura datelor; sort doar reordonează elementele.
7. Eliminare vecini egaliDificil
Enunțul problemei
Transformă lista astfel încât două valori egale consecutive să nu rămână una lângă alta, păstrând prima apariție.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,1,2,2,3,2,2,4]
r=[]
for x in a:
if not r or r[-1]!=x: r.append(x)
print(r)Explicația rezolvării: Comparăm fiecare element cu ultimul păstrat. Dacă este egal cu vecinul anterior, nu îl adăugăm. Rezultatul păstrează prima apariție din fiecare grup consecutiv.
8. Rotire circularăDificil
Enunțul problemei
Rotește o listă cu k poziții la dreapta. Tratează k mai mare decât lungimea listei.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,4,5]; k=7 k%=len(a); a=a[-k:]+a[:-k]; print(a)
Explicația rezolvării: k%=len(a) reduce rotația la un număr mai mic decât lungimea listei. Sufixul a[-k:] ajunge în față, iar restul rămâne după el. Complexitatea este O(n).
9. Al doilea maximDificil
Enunțul problemei
Găsește al doilea maxim distinct folosind metode de listă și o strategie care evită sortarea completă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[7,3,9,9,5,8] vals=sorted(set(a),reverse=True) print(vals[1] if len(vals)>1 else None)
Explicația rezolvării: set elimină egalitățile, iar sortarea descrescătoare pune maximul primul și al doilea maxim pe poziția 1. Pentru O(n), se poate menține manual maximul și al doilea maxim.
10. PartiționareDificil
Enunțul problemei
Rearanjează lista astfel încât valorile negative să fie înaintea celor nenegative. Nu este obligatoriu să păstrezi ordinea internă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[-2,4,-1,7,0,-3]
i=0; j=len(a)-1
while i<=j:
if a[i]<0: i+=1
elif a[j]>=0: j-=1
else: a[i],a[j]=a[j],a[i]; i+=1; j-=1
print(a)Explicația rezolvării: Doi indici mută negativele spre stânga și nenegativele spre dreapta. Nu păstrăm ordinea internă, deci putem face interschimbări în loc. Timp O(n), memorie O(1).
11. InterclasareDificil
Enunțul problemei
Interclasează două liste sortate într-o a treia listă sortată.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Separă datele obiectului de comportament: __init__ inițializează atributele, iar metodele lucrează cu self. Pentru colaborarea dintre clase, fiecare obiect trebuie să aibă o responsabilitate clară. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,3,5,8]; b=[2,4,6,7]; i=j=0; r=[]
while i<len(a) and j<len(b):
if a[i]<=b[j]: r.append(a[i]); i+=1
else: r.append(b[j]); j+=1
r.extend(a[i:]); r.extend(b[j:]); print(r)Explicația rezolvării: Interclasarea compară primul element disponibil din fiecare listă și îl pune pe cel mai mic în rezultat. Fiecare element este mutat o singură dată: O(n+m).
12. Eliminarea elementelor după criteriuDificil
Enunțul problemei
Dintr-o listă păstrează doar valorile care satisfac simultan două condiții.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[-5,2,6,8,9,12] r=[x for x in a if x>0 and x%2==0] print(r)
Explicația rezolvării: Combinăm cele două condiții cu and. List comprehension păstrează doar valorile care satisfac simultan criteriile.
13. Fereastră de lungime kDificil
Enunțul problemei
Pentru fiecare sublistă consecutivă de lungime k calculează suma și identifică maximul.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,4,2,7,3,9]; k=3
s=sum(a[:k]); best=s
for i in range(k,len(a)):
s+=a[i]-a[i-k]; best=max(best,s)
print(best)Explicația rezolvării: Calculăm suma primei ferestre. La fiecare deplasare adăugăm elementul nou și scădem elementul care iese. Astfel fiecare fereastră este procesată în O(1), iar totalul este O(n).
14. Lista de frecvențeDificil
Enunțul problemei
Construiește o listă de perechi [valoare,frecvență] pentru valorile distincte, păstrând ordinea primei apariții.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[3,1,3,2,1,3]; frec=[]
for x in a:
for p in frec:
if p[0]==x: p[1]+=1; break
else: frec.append([x,1])
print(frec)Explicația rezolvării: Pentru fiecare valoare căutăm perechea ei în lista de frecvențe. Dacă există, incrementăm contorul; altfel adăugăm o pereche nouă. Ordinea primei apariții este păstrată.
15. Poziția primei aparițiiDificil
Enunțul problemei
Fără a folosi index() direct, determină poziția primei apariții și tratează lipsa valorii.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[5,2,7,2]
x=7; poz=-1
for i,v in enumerate(a):
if v==x: poz=i; break
print(poz)Explicația rezolvării: enumerate oferă simultan indicele și valoarea. break oprește imediat la prima apariție. Dacă nu găsim valoarea, poziția rămâne -1.
16. Număr de aparițiiFoarte dificil
Enunțul problemei
Compară count() cu o parcurgere manuală pentru numărarea unei valori și discută complexitatea.
Explicație detaliată
Ideea centrală: Începe prin a identifica operația repetată și numărul de ori în care poate fi executată; termenul dominant determină complexitatea. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,2,3,2]; x=2
print(a.count(x))
nr=0
for v in a:
if v==x: nr+=1
print(nr)Explicația rezolvării: count este implementarea directă și clară pentru numărare. Parcurgerea manuală are aceeași complexitate O(n), dar permite logică suplimentară la fiecare apariție.
17. Duplicare controlatăFoarte dificil
Enunțul problemei
Construiește o copie a unei liste în care fiecare element apare de două ori consecutiv.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3] r=[] for x in a: r.extend([x,x]) print(r)
Explicația rezolvării: Pentru fiecare element adăugăm două copii consecutive. extend adaugă ambele valori. Rezultatul are lungime dublă față de lista inițială.
18. Filtrare în locFoarte dificil
Enunțul problemei
Elimină din aceeași listă toate elementele negative, fără să creezi o a doua listă completă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[-2,3,-1,5,0] a[:]=[x for x in a if x>=0] print(a)
Explicația rezolvării: Folosim o list comprehension și atribuirea către a[:] pentru a modifica aceeași listă. Nu parcurgem și ștergem în același timp, deci nu riscăm să sărim elemente.
19. Sortare și stabilitateFoarte dificil
Enunțul problemei
Se dau perechi [nume,medie]. Sortează după medie și discută ce se întâmplă când două medii sunt egale.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[['Ana',9],['Ion',8],['Mara',9],['Dan',7]] a.sort(key=lambda x:x[1]); print(a)
Explicația rezolvării: sort este stabilă: atunci când două chei sunt egale, elementele își păstrează ordinea relativă inițială. Astfel Ana rămâne înaintea Marei dacă ambele au media 9.
20. K valori cele mai miciFoarte dificil
Enunțul problemei
Determină cele mai mici k valori. Compară soluția prin sort() cu menținerea unei structuri de dimensiune k.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[7,2,9,1,5,3]; k=3 print(sorted(a)[:k])
Explicația rezolvării: Sortăm lista și luăm primele k valori. Este simplu, dar costă O(n log n). Pentru k mult mai mic decât n, o structură de dimensiune k poate reduce costul, de exemplu un heap.
21. Subsecvență palindromicăFoarte dificil
Enunțul problemei
Găsește dacă o sublistă aleasă prin doi indici este palindrom și explică indexarea pozitivă și negativă.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,3,2,1,4]; l,r=0,4 print(a[l:r+1]==a[l:r+1][::-1])
Explicația rezolvării: Feliei a[l:r+1] îi putem aplica inversarea pentru verificarea palindromului, dar aceasta creează o listă auxiliară. Pentru memorie O(1), comparăm doi indici care se apropie din capete.
22. Transformare prin parcurgereFoarte dificil
Enunțul problemei
Înlocuiește fiecare element cu pătratul său, apoi sortează lista și raportează minimul și maximul.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[-3,2,-1,4]; a[:]=[x*x for x in a]; a.sort(); print(min(a),max(a),a)
Explicația rezolvării: List comprehension înlocuiește fiecare element cu pătratul său, apoi sort ordonează rezultatul. min și max pot fi apelate după sortare, deși după sortare sunt direct primul și ultimul element.
23. Ștergere după mai multe criteriiFoarte dificil
Enunțul problemei
Elimină elementele care sunt pare și mai mari decât o limită, fără a pierde elemente prin deplasarea indicilor.
Explicație detaliată
Ideea centrală: Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[1,2,4,6,8,10]; limita=5 a[:]=[x for x in a if not (x%2==0 and x>limita)] print(a)
Explicația rezolvării: Filtrăm inversul condiției de ștergere: păstrăm elementele care NU sunt simultan pare și mai mari decât limită. Astfel nu modificăm lista în timpul parcurgerii.
24. Mini-bază de date cu listFoarte dificil
Enunțul problemei
Reprezintă produse prin liste de liste și implementează adăugare, căutare, actualizare, ștergere și sortare.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
produse=[['A',10,5],['B',20,3]] produse.append(['C',15,2]); print([p for p in produse if p[0]=='B']); produse[1][1]=22; produse=[p for p in produse if p[0]!='A']; produse.sort(key=lambda p:p[1]); print(produse)
Explicația rezolvării: Lista de liste poate reprezenta înregistrări. Căutarea filtrează după cod/nume, actualizarea modifică un câmp, ștergerea reconstruiește lista, iar sortarea folosește o funcție key.
25. Problemă de sinteză listFoarte dificil
Enunțul problemei
Construiește un program care primește o listă, efectuează filtrare, eliminare duplicate, statistici, sortare și generează un raport final.
Explicație detaliată
Ideea centrală: Parcurge lista cu indici atunci când poziția contează și cu for direct atunci când ai nevoie doar de valori. Evită modificarea nesigură a listei în timpul parcurgerii. Separă conversia datelor de calcul. Verifică domeniul operației înainte de sqrt(), împărțire sau conversii care pot produce erori și rotunjește doar la afișare când precizia internă trebuie păstrată. Calculează statisticile într-o singură parcurgere atunci când este posibil; len(), min(), max() și sum() pot fi combinate cu filtre și acumulatoare. Testează cel puțin un caz obișnuit, un caz de limită și un caz care poate produce o eroare. Pentru fiecare, stabilește înainte rezultatul așteptat. După obținerea unei soluții corecte, verifică dacă structura datelor și operațiile alese respectă cerința de eficiență și nu modifică accidental datele originale.
- Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
- Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
- Construiește soluția: separă validarea, prelucrarea și afișarea rezultatului. Dacă problema are mai multe etape, creează funcții sau metode cu responsabilități clare.
- Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
- Analizează rezultatul: compară manual un exemplu mic cu ceea ce ar trebui să producă algoritmul și verifică dacă nu apar modificări accidentale ale datelor.
Rezolvare efectivă
Cod Python:
a=[5,2,5,7,2,9]
fara=[]; vazute=set()
for x in a:
if x not in vazute: vazute.add(x); fara.append(x)
print('filtrata', [x for x in fara if x%2==1]); print('statistici',len(a),min(a),max(a),sum(a)); print('sortata',sorted(a))Explicația rezolvării: Soluția de sinteză execută etapele separat: eliminarea duplicatelor cu set, filtrarea, statisticile și sortarea. Separarea etapelor face codul mai ușor de testat și permite înlocuirea unei etape cu o variantă mai eficientă.
Recapitulare finală
Ai 175 de exerciții: 25 pentru fiecare dintre capitolele 4–10. Pentru o pregătire serioasă, rezolvă problemele în ordine, notează timpul de execuție și cazurile-limită, apoi revino la problemele foarte dificile fără să consulți explicația.