175 de exerciții dificile și foarte dificile

Python – capitolele 4–10. Pentru fiecare problemă: enunțul apare întâi în lista capitolului, apoi este reluat integral într-o secțiune de rezolvare care păstrează explicația detaliată existentă și adaugă rezolvarea efectivă în Python, cu cod și explicația codului.

Structură: 25 exerciții pentru fiecare dintre cele 7 capitole, de la probleme dificile la probleme foarte dificile.

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

  1. 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.
  2. 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.
  3. 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ă.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. Subșir cu sumă maximă — Determină suma maximă a unui subșir contiguu. Compară metoda brută cu o metodă liniară.
  10. 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.
  11. 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.
  12. Două sume egale — Verifică dacă există două valori distincte a căror sumă este S. Explică de ce o structură auxiliară poate reduce timpul.
  13. Inversarea unei liste — Inversează o listă fără a construi o a doua listă. Analizează complexitatea temporală și spațială.
  14. Palindrom eficient — Verifică dacă o listă este palindrom folosind doi indici care se apropie din capete. Explică numărul maxim de comparații.
  15. 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.
  16. 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.
  17. 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ă.
  18. 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.
  19. 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.
  20. Complexitate recursivă — Un algoritm împarte problema în două subprobleme de dimensiune n/2 și apoi parcurge n elemente. Estimează complexitatea și justifică răspunsul.
  21. 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.
  22. 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.
  23. 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.
  24. 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.
  25. 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

  1. 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.
  2. 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.
  3. 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ă.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. Subșir cu sumă maximă — Determină suma maximă a unui subșir contiguu. Compară metoda brută cu o metodă liniară.
  10. 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.
  11. 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.
  12. Două sume egale — Verifică dacă există două valori distincte a căror sumă este S. Explică de ce o structură auxiliară poate reduce timpul.
  13. Inversarea unei liste — Inversează o listă fără a construi o a doua listă. Analizează complexitatea temporală și spațială.
  14. Palindrom eficient — Verifică dacă o listă este palindrom folosind doi indici care se apropie din capete. Explică numărul maxim de comparații.
  15. 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.
  16. 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.
  17. 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ă.
  18. 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.
  19. 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.
  20. Complexitate recursivă — Un algoritm împarte problema în două subprobleme de dimensiune n/2 și apoi parcurge n elemente. Estimează complexitatea și justifică răspunsul.
  21. 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.
  22. 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.
  23. 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.
  24. 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.
  25. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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ă.

  1. Identifică exact ce trebuie calculat.
  2. Alege structura de date potrivită.
  3. Elimină calculele sau parcurgerile repetate atunci când este posibil.
  4. Testează cazuri obișnuite și cazuri-limită.
  5. 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. Distanță euclidiană — Se dau două puncte în plan. Calculează distanța dintre ele folosind sqrt() și abs() acolo unde este util. Precizează cazurile-limită.
  7. 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.
  8. Media ponderată — Calculează media ponderată a n valori și afișeaz-o cu trei zecimale. Explică unde este necesar float() și unde round().
  9. Conversie temperaturi — Citește temperaturi ca text, convertește-le la float și determină cea mai apropiată valoare de zero folosind abs().
  10. 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ă.
  11. Arie cu radical — Se dau laturile unui triunghi. Verifică existența triunghiului și calculează aria prin formula lui Heron folosind sqrt().
  12. 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.
  13. Normalizare numerică — Transformă n valori întregi într-un interval [0,1] folosind minimul și maximul. Tratează cazul în care toate valorile sunt egale.
  14. 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.
  15. 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ă.
  16. 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().
  17. Raport cu trei zecimale — Citește două numere reale și calculează raportul, media geometrică și diferența absolută. Validează diviziunea și argumentul pentru sqrt().
  18. 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.
  19. 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.
  20. 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.
  21. Compararea valorilor reale — Compară două rezultate de calcul cu o toleranță. Explică de ce simpla egalitate poate fi problematică pentru numere reale.
  22. 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.
  23. 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.
  24. 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.
  25. 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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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

  1. 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().
  2. Extreme fără duplicate — Determină cele mai mici două valori distincte dintr-o colecție. Explică de ce min() singur nu este suficient.
  3. Ecart maxim — Calculează diferența dintre maximul și minimul unei liste. Tratează lista cu un singur element.
  4. Media după filtrare — Dintr-o listă de temperaturi, calculează media numai pentru valorile negative. Explică verificarea listei filtrate înainte de împărțire.
  5. Două liste comparate — Se dau două liste de note. Determină care are media mai mare și care are intervalul minim-maxim mai mic.
  6. Frecvența maximă — Determină de câte ori apare cea mai frecventă valoare. Compară folosirea count() repetat cu o structură de frecvență.
  7. 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.
  8. Listă de rezultate — Pentru mai multe liste de numere, calculează pentru fiecare lungimea, suma, minimul și maximul și apoi identifică lista cu suma maximă.
  9. Validarea unei colecții — Verifică dacă toate valorile unei liste se află într-un interval și raportează câte sunt în afara intervalului.
  10. Sume cumulative — Construiește lista sumelor prefixale. Compară memoria cu o soluție care calculează fiecare sumă de la zero.
  11. Diferența față de maxim — Înlocuiește fiecare valoare cu diferența dintre maximul listei și valoarea respectivă. Păstrează lista originală.
  12. Statistici pe grupe — Se dau note și grupa fiecărui elev. Calculează media minimă și maximă pe fiecare grupă.
  13. Valori comune — Determină valorile comune dintre două liste, fără a afișa aceeași valoare de mai multe ori.
  14. Intersecție cu ordine păstrată — Obține elementele din prima listă care apar și în a doua, păstrând ordinea primei liste.
  15. Număr de tranziții — Numără de câte ori se schimbă semnul sau categoria valorilor consecutive dintr-o listă.
  16. Secvență crescătoare maximă — Găsește lungimea celei mai lungi secvențe strict crescătoare consecutive.
  17. Minim și poziții — Găsește minimul și toate pozițiile la care apare. Explică de ce o singură parcurgere este suficientă.
  18. Eliminarea valorilor invalide — Dintr-o listă numerică păstrează doar valorile din [0,100] și calculează statistici asupra listei rezultate.
  19. Top trei valori — Determină cele mai mari trei valori distincte fără a ordona neapărat întreaga listă. Explică strategia.
  20. 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.
  21. Egalitatea statistică — Verifică dacă două liste au aceeași sumă, aceeași lungime și aceeași valoare minimă și maximă.
  22. Lista echilibrată — Spune dacă suma elementelor negative este egală cu suma valorilor pozitive.
  23. Sublistă cu sumă maximă — Determină o sublistă contiguă cu suma maximă și raportează și capetele ei.
  24. Raport compact — Construiește un raport text din statistici ale unei liste, cu valori rotunjite și etichete clare.
  25. 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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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

  1. Clasa Elev avansată — Definește clasa Elev cu nume, vârstă și listă de note. Adaugă metode pentru medie, minim, maxim și promovare.
  2. Catalogul clasei — Creează clasele Elev și Catalog. Catalogul trebuie să poată adăuga elevi și să calculeze media generală.
  3. Dreptunghiuri comparabile — Definește Dreptunghi cu lungime și lățime și metode pentru arie, perimetru și diagonală. Identifică dreptunghiul cu aria maximă.
  4. Cont bancar simplificat — Definește Cont cu sold și metode depune/retrage. Interzice retragerile peste sold și explică schimbarea stării obiectului.
  5. Bibliotecă de cărți — Definește Carte și Biblioteca. Biblioteca trebuie să poată adăuga, căuta și împrumuta cărți.
  6. Gestionarea unei liste în obiect — Definește o clasă ListaNumere care ascunde lista internă și oferă metode pentru sumă, minim, maxim și medie.
  7. Moștenire simplă — Definește Persoană și Elev, astfel încât Elev să moștenească datele de bază și să adauge clasa și notele.
  8. 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.
  9. Modul de geometrie — Construiește un modul geometrie.py cu clase pentru cerc și dreptunghi și un program principal care le importă.
  10. Sistem de angajați — Definește Angajat cu nume și salariu și o metodă salariu_anual(). Creează apoi un Manager cu bonus.
  11. 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.
  12. Istoric de operații — Creează o clasă Calculator care memorează rezultatele operațiilor efectuate și oferă o metodă pentru ultimul rezultat.
  13. 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.
  14. Joc cu jucători — Definește Jucator cu nume și punctaj. Creează o clasă Joc care adaugă jucători și determină câștigătorul.
  15. Rezultate sportive — Definește Meci cu două echipe și scoruri și o clasă Campionat care calculează clasamentul.
  16. Fructe și coșuri — Definește Fruct cu nume și greutate și CosFructe care calculează greutatea totală și fructul cel mai greu.
  17. Stoc magazin — Definește Produs cu cod, nume, preț și stoc. Clasa Magazin trebuie să poată realiza vânzări și să actualizeze stocul.
  18. Agendă — Definește Contact și Agenda. Agenda trebuie să permită adăugarea, căutarea după nume și ștergerea unui contact.
  19. Mașini — Definește Mașină cu marcă, model și kilometraj. Adaugă metode pentru deplasare și afișarea stării.
  20. 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ă.
  21. Fișier ca modul — Separă clasele unui mini-proiect în două module și explică importurile și rolul fiecărui fișier.
  22. 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.
  23. Metode care returnează obiecte — Definește o clasă Vector2D ale cărei metode pot returna un nou vector rezultat din adunare sau scalare.
  24. 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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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

  1. Raport de note — Citește note dintr-un fișier text, calculează statistici și scrie un raport separat. Folosește with open().
  2. Filtrare în fișier — Citește un fișier și scrie într-un al doilea doar liniile care conțin un cuvânt dat.
  3. Număr de cuvinte — Citește întregul fișier și determină numărul de cuvinte, caractere și linii.
  4. Cea mai lungă linie — Parcurge fișierul linie cu linie și identifică linia cu cele mai multe caractere.
  5. Frecvența cuvintelor — Construiește un dicționar de frecvențe dintr-un fișier text și scrie primele rezultate într-un raport.
  6. Jurnal cu append — Construiește un program care adaugă mesaje succesive într-un jurnal fără să șteargă intrările vechi.
  7. Copiere cu numerotare — Copiază un fișier într-un altul și adaugă numărul fiecărei linii.
  8. Separarea numerelor — Citește un fișier cu numere și creează două fișiere: unul pentru pare și unul pentru impare.
  9. Statistici din fișier — Fiecare linie conține o notă. Calculează media, minimul, maximul și numărul de valori valide.
  10. Linii invalide — Unele linii dintr-un fișier nu sunt numere. Procesează doar liniile valide și scrie separat erorile.
  11. Căutare de expresie — Citește un fișier și raportează toate numerele liniilor în care apare un text căutat.
  12. Înlocuire controlată — Creează o copie a unui fișier în care un cuvânt este înlocuit cu altul, fără a modifica originalul.
  13. Concatenare de fișiere — Unește conținutul mai multor fișiere într-unul singur, păstrând ordinea și separarea clară.
  14. Împărțire pe categorii — Fiecare linie are forma categorie;valoare. Separă datele în fișiere diferite după categorie.
  15. Mini-bază de date — Salvează persoane sub forma nume;vârstă într-un fișier și permite căutarea după nume.
  16. Actualizarea unei înregistrări — Citește un fișier de tip nume;valoare, modifică o singură înregistrare și rescrie fișierul în siguranță.
  17. Eliminarea duplicatelor — Creează o copie fără linii duplicate, păstrând prima apariție.
  18. Top valori din fișier — Citește numere din fișier și scrie într-un raport cele mai mari trei valori distincte.
  19. Analiza unui text — Determină lungimea medie a cuvintelor și cuvântul cel mai lung.
  20. Raport multi-secțiune — Dintr-un fișier cu secțiuni, construiește un raport cu statistici pentru fiecare secțiune.
  21. Jurnal cu marcaj temporal — Adaugă mesaje într-un fișier folosind data și ora curentă ca prefix și explică separarea datelor.
  22. 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.
  23. Comparație între fișiere — Determină liniile comune dintre două fișiere și scrie rezultatul într-un al treilea.
  24. 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.
  25. 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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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

  1. 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.
  2. Convertor temperatură — Construiește o fereastră care transformă Celsius în Fahrenheit și invers, cu verificarea inputului.
  3. Calculator medie — Utilizatorul introduce mai multe note într-un Text; programul calculează media și afișează minimul și maximul.
  4. Numărător de apăsări — Creează un buton care incrementează un contor afișat într-un Label și alt buton pentru resetare.
  5. Formular de înscriere — Construiește un formular cu nume, vârstă și email și validează câmpurile înainte de confirmare.
  6. Interfață pe Frame-uri — Organizează o aplicație în zone pentru titlu, formular, rezultate și butoane folosind Frame și grid/pack.
  7. Editor text simplu — Folosește Text pentru a scrie, șterge și afișa conținutul și adaugă butoane pentru operații.
  8. Căutare într-un text — Utilizatorul introduce un cuvânt și aplicația numără aparițiile în Text.
  9. Mini-agendă — Construiește o interfață pentru adăugarea și căutarea unor contacte, afișând rezultatele într-un Label sau Text.
  10. Quiz cu scor — Afișează întrebări succesive și răspunsuri prin butoane; actualizează scorul și afișează rezultatul final.
  11. Generator de statistici — Introdu o listă de numere într-un Entry și afișează len, min, max, sumă și medie.
  12. Interfață pentru fișiere — Creează butoane pentru scrierea și citirea unui fișier text și afișează conținutul în Text.
  13. Jurnal grafic — Utilizatorul scrie un mesaj într-un Text și îl salvează prin append într-un fișier.
  14. Formular cu resetare — Creează mai multe Entry și un buton Reset care golește toate câmpurile.
  15. Validare numerică — Construiește o funcție reutilizabilă care validează un Entry și returnează un număr întreg sau semnalează eroarea.
  16. Conversie bază 2 — Oferă un Entry pentru un număr binar și afișează valoarea zecimală folosind int(text,2).
  17. Analizor de propoziții — Textul introdus într-un widget Text este analizat: număr de linii, cuvinte și caractere.
  18. Catalog grafic — Construiește o interfață care primește elevi și note și afișează statisticile elevului selectat.
  19. Listă interactivă — Folosește Entry și butoane pentru adăugare, ștergere și sortare a unor valori dintr-o listă.
  20. Calculator geometric — Utilizatorul alege între cerc și dreptunghi și introduce dimensiunile; aplicația afișează aria și perimetrul.
  21. Interfață cu două ecrane — Folosește două Frame-uri și butoane pentru a comuta între un formular și o pagină de rezultate.
  22. 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.
  23. Gestionarea erorilor — Proiectează o aplicație Tkinter în care toate conversiile numerice pot eșua și fiecare eroare este prezentată utilizatorului prin messagebox.
  24. Mini-editor cu salvare — Construiește un editor simplu cu Text, butoane pentru deschidere logică prin citire, salvare prin write și ștergere.
  25. 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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

Rezolvare efectivă

Cod Python:

def validare_int(entry):
    try: return int(entry.get())
    except ValueError: return None

Explicaț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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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

  1. 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().
  2. Ștergeri controlate — Elimină toate aparițiile unei valori fără a modifica lista în timpul unei parcurgeri care poate sări elemente.
  3. 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.
  4. Copie independentă — Demonstrează printr-un program diferența dintre atribuirea unei liste și copy(), apoi modifică lista originală și observă efectul.
  5. Sortare cu criteriu — Sortează o listă de numere în ordine crescătoare și apoi descrescătoare și explică parametrul reverse.
  6. Lista de liste — Se dau liste cu note pentru mai mulți elevi. Sortează elevii după medie și explică reprezentarea datelor.
  7. 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.
  8. Rotire circulară — Rotește o listă cu k poziții la dreapta. Tratează k mai mare decât lungimea listei.
  9. Al doilea maxim — Găsește al doilea maxim distinct folosind metode de listă și o strategie care evită sortarea completă.
  10. Partiționare — Rearanjează lista astfel încât valorile negative să fie înaintea celor nenegative. Nu este obligatoriu să păstrezi ordinea internă.
  11. Interclasare — Interclasează două liste sortate într-o a treia listă sortată.
  12. Eliminarea elementelor după criteriu — Dintr-o listă păstrează doar valorile care satisfac simultan două condiții.
  13. Fereastră de lungime k — Pentru fiecare sublistă consecutivă de lungime k calculează suma și identifică maximul.
  14. Lista de frecvențe — Construiește o listă de perechi [valoare,frecvență] pentru valorile distincte, păstrând ordinea primei apariții.
  15. Poziția primei apariții — Fără a folosi index() direct, determină poziția primei apariții și tratează lipsa valorii.
  16. Număr de apariții — Compară count() cu o parcurgere manuală pentru numărarea unei valori și discută complexitatea.
  17. Duplicare controlată — Construiește o copie a unei liste în care fiecare element apare de două ori consecutiv.
  18. Filtrare în loc — Elimină din aceeași listă toate elementele negative, fără să creezi o a doua listă completă.
  19. Sortare și stabilitate — Se dau perechi [nume,medie]. Sortează după medie și discută ce se întâmplă când două medii sunt egale.
  20. K valori cele mai mici — Determină cele mai mici k valori. Compară soluția prin sort() cu menținerea unei structuri de dimensiune k.
  21. Subsecvență palindromică — Găsește dacă o sublistă aleasă prin doi indici este palindrom și explică indexarea pozitivă și negativă.
  22. Transformare prin parcurgere — Înlocuiește fiecare element cu pătratul său, apoi sortează lista și raportează minimul și maximul.
  23. Ș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.
  24. Mini-bază de date cu list — Reprezintă produse prin liste de liste și implementează adăugare, căutare, actualizare, ștergere și sortare.
  25. 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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

  1. Înțelege datele: notează exact ce primești, ce trebuie calculat și ce condiții trebuie respectate.
  2. Alege reprezentarea: folosește variabile simple pentru valori individuale și liste/obiecte/fișiere/interfață, în funcție de cerința capitolului.
  3. 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.
  4. Verifică cazurile-limită: testează minimum, maximum, valori egale, colecții mici, intrări goale sau date invalide acolo unde sunt posibile.
  5. 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.

Observație: problema este intenționat mai dificilă decât exemplele introductive din lecție și urmărește transferul conceptelor către o situație nouă.

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.

↑ Înapoi sus

25. Mini-sistem OOP avansatFoarte 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ă: folosim mai multe clase care colaborează: Utilizatorul identifică persoana, Produsul descrie un articol, iar Comanda păstrează produsele și calculează totalul. Fiecare clasă are o responsabilitate clară.

Rezolvare efectivă

Cod Python:

class Sistem:
    def __init__(self): self.utilizatori=[]; self.produse=[]; self.comenzi=[]
    def raport(self): return len(self.utilizatori),len(self.produse),len(self.comenzi)
print(Sistem().raport())

Explicația rezolvării: Într-un sistem OOP mai mare, un obiect coordonator poate administra colecțiile de entități. Important este ca fiecare clasă să rămână responsabilă de datele și operațiile sale.

>