Agenda clasei — programe care nu uită
Toate programele tale de până acum au avut amnezie: închideai fereastra, datele dispăreau. Azi rupi blestemul. Construiești o agendă a clasei — nume și ceva de contact pentru fiecare coleg — care își salvează conținutul într-un fișier pe disc și îl încarcă la loc la fiecare pornire. La finalul laboratorului vei avea agenda.py plus fișierul agenda.txt pe care programul tău îl creează, îl citește și îl actualizează singur.
Ce îți trebuie
- Python 3 + VS Code, configurate în laboratorul 1.
- Un folder de lucru nou,
agenda-clasei, deschis în VS Code cu File → Open Folder. E important să lucrezi cu folderul deschis, nu cu un fișier singuratic — programul va crea fișiere lângă el. - Cont: niciunul. Timp: 25 minute pe scriere/citire + 40 pe agendă + restul pe misiune.
Primul fișier scris de un program al tău
- Creează
test_fisiere.pyși scrie:
with open("mesaj.txt", "w") as f:
f.write("Scris de programul meu!\n")
f.write("A doua linie.\n")
print("Gata, am scris fisierul.")
- Rulează, apoi uită-te în panoul de fișiere din stânga: a apărut
mesaj.txt. Deschide-l. Liniile alea nu le-a tastat nimeni — le-a produs codul tău.
Descifrăm formula, pentru că o vei scrie de multe ori de acum înainte:
open("mesaj.txt", "w")deschide fișierul pentru scriere (wde la write). Dacă nu există, îl creează. Dacă există — atenție — îi șterge tot conținutul înainte.with ... as f:îi dă fișierului numele scurtfși garantează că se închide corect la finalul blocului indentat, orice s-ar întâmpla.\ne caracterul „linie nouă" — fără el, totul s-ar înghesui pe un singur rând.
- Acum citirea inversă. Alt fișier,
test_citire.py:
with open("mesaj.txt", "r") as f:
linii = f.readlines()
print("Fisierul are", len(linii), "linii:")
for linie in linii:
print("-", linie.strip())
r înseamnă read, readlines() îți aduce tot fișierul ca listă de linii, iar strip() curăță \n-ul de la capăt (fără el, fiecare print ar lăsa un rând gol în plus).
Agenda: datele trăiesc în listă, dorm în fișier
Strategia programului e simplă și merită ținută minte, pentru că așa lucrează și aplicațiile mari: la pornire încarci fișierul într-o listă, lucrezi tot timpul cu lista în memorie, la fiecare modificare salvezi lista înapoi în fișier.
Creează agenda.py:
FISIER = "agenda.txt"
def incarca():
try:
with open(FISIER, "r") as f:
return [linie.strip() for linie in f.readlines()]
except FileNotFoundError:
return []
def salveaza(contacte):
with open(FISIER, "w") as f:
for contact in contacte:
f.write(contact + "\n")
def afiseaza(contacte):
if len(contacte) == 0:
print("Agenda e goala.")
for i, contact in enumerate(contacte):
print(i + 1, "-", contact)
contacte = incarca()
print("Am incarcat", len(contacte), "contacte.")
Trei detalii noi, pe scurt:
try/except FileNotFoundErrorrezolvă elegant prima pornire: fișierul nu există încă, deci pornim cu lista goală în loc să crăpăm.[linie.strip() for linie in ...]e o listă construită dintr-o bucată — citește-o ca „lista strip-urilor tuturor liniilor".enumeratenumără elementele în timp ce le parcurgi, ca să afișezi „1 -", „2 -" fără contor separat.
Acum meniul — și aici îți culegi roadele din laboratorul 2, pentru că structura o știi deja:
while True:
print()
print("1. Afiseaza 2. Adauga 3. Sterge 4. Iesire")
optiune = input("Alege: ")
if optiune == "1":
afiseaza(contacte)
elif optiune == "2":
nume = input("Nume: ")
telefon = input("Contact: ")
contacte.append(nume + " | " + telefon)
salveaza(contacte)
elif optiune == "3":
afiseaza(contacte)
pozitie = int(input("Numarul de sters: "))
contacte.pop(pozitie - 1)
salveaza(contacte)
elif optiune == "4":
break
Observă disciplina: orice modificare a listei e urmată imediat de salveaza(contacte). Lista și fișierul nu au voie să se contrazică.
Dacă nu merge
FileNotFoundErrordeși fișierul „e acolo": Python caută fișierul în folderul din care rulezi, nu neapărat lângă script. De-asta ai deschis folderul în VS Code, nu doar fișierul. Verifică în terminal cupwd(sau uită-te la calea din prompt) că ești înagenda-clasei.- Agenda se golește singură: undeva ai deschis fișierul cu
"w"doar ca să-l citești."w"șterge tot la deschidere — pentru citit e"r", întotdeauna. - Fiecare contact apare cu un rând gol după el: ai uitat
strip()la încărcare sau ai pus\nde două ori la salvare. Alege un singur loc pentru\n: la scriere. IndexError: pop index out of range: utilizatorul a cerut ștergerea contactului 9 dintr-o agendă cu 3. Validează poziția înainte depop— ai deja o funcție bună pentru citit numere în interval, din laboratorul 2.- Diacriticele apar ca semne ciudate în fișier: deschide fișierul cu
open(FISIER, "r", encoding="utf-8")și la fel la scriere. Codificarea caracterelor — o veche cunoștință din lecția despre ASCII.
Misiunea ta
Nivel de bază (obligatoriu): agenda funcțională cu afișare, adăugare și persistență reală (datele supraviețuiesc închiderii programului).
Extindere: ștergerea cu validarea poziției + opțiunea „5. Cauta": utilizatorul dă un fragment de nume, programul afișează toate contactele care îl conțin (îți ajunge operatorul in pe șiruri).
Provocare: o opțiune „6. Statistici" care raportează: câte contacte există, cel mai lung nume și — mai greu — contactele sortate alfabetic, fără să strice ordinea din fișier (indiciu: sorted(contacte) produce o copie sortată).
Ai terminat când:
- pornirea programului pe un calculator „curat" (fără
agenda.txt) nu produce nicio eroare; - ciclul adaugă → închide → repornește → afișează arată datele intacte, demonstrat colegului de bancă;
- fișierul
agenda.txt, deschis manual, e lizibil pentru un om — un contact pe linie; - nu există nicio cale prin meniu care să lase fișierul diferit de lista din memorie.