Refactorizare: jocul tău, tăiat în funcții
Jocul din laboratorul trecut funcționează, dar e un bloc de cod în care totul stă claie peste grămadă. Azi îl operezi: tai logica în funcții cu nume clare, adaugi un meniu de start și obții o versiune pe care o poți extinde fără frică. La finalul laboratorului vei avea ghiceste_v2.py — același joc la exterior, dar organizat înăuntru ca un program adevărat, plus un meniu cu cel puțin trei opțiuni funcționale.
Ce îți trebuie
- Python 3 și VS Code, deja instalate din laboratorul 1 (dacă ai lipsit, întoarce-te la el pentru instalare — durează 15 minute).
- Fișierul
ghiceste.pydin laboratorul trecut. Nu-l ai? Rescrii varianta de bază în 10 minute — o găsești în laboratorul 1, secțiunea „Bucla while". - Cont: niciunul. Timp: 20 minute pe funcții simple + 40 pe refactorizare + restul pe meniu și misiune.
Lecția „Subprograme și funcții" din modulul 5 ți-a dat ideea: o funcție e o bucată de program cu nume, pe care o definești o dată și o chemi de câte ori vrei. Acolo ai făcut-o pe blocuri; azi o faci în Python, pe cod care e deja al tău.
Încălzire: def, parametri, return
Creează ghiceste_v2.py în același folder și scrie doar atât:
def saluta(nume):
print("Salut,", nume + "!")
def dubleaza(n):
return n * 2
saluta("Maria")
rezultat = dubleaza(21)
print(rezultat)
Rulează. Două lucruri de fixat, pentru că pe ele se sprijină tot laboratorul:
- Definiția nu execută nimic. Liniile cu
defdoar pregătesc funcția. Abia apelul —saluta("Maria")— o pune în mișcare. Șterge apelurile și rulează din nou: nu se întâmplă nimic, și e normal. printarată,returndă înapoi.salutaafișează ceva și atât.dubleazareturnează o valoare, pe care o poți prinde într-o variabilă și folosi mai departe. Confuzia print/return e cea mai frecventă greșeală a începătorilor — ține-o sub observație.
Operația: jocul tăiat în trei funcții
Deschide ghiceste.py alături (în VS Code poți pune fișierele unul lângă altul: click dreapta pe tab → Split Right). Planul de tăiere:
| Funcția | Ce face | Primește | Returnează |
|---|---|---|---|
citeste_numar(minim, maxim) | cere un număr valid din interval, insistă până îl primește | limitele | numărul |
joaca_runda(minim, maxim) | o rundă completă de joc | limitele | numărul de încercări |
afiseaza_scor(incercari) | comentariul de final („Ca la carte!" etc.) | încercările | nimic |
- Începe cu
citeste_numar— e cea mai mică:
def citeste_numar(minim, maxim):
numar = int(input("Ghiceste: "))
while numar < minim or numar > maxim:
print("Am zis intre", minim, "si", maxim, "!")
numar = int(input("Ghiceste: "))
return numar
- Construiește
joaca_rundamutând bucla principală din vechiul joc în interiorul ei. Acolo unde vechiul cod aveaint(input(...)), noul cod cheamăciteste_numar(minim, maxim)— o funcție care folosește altă funcție, exact ca blocurile tale personalizate din Scratch care se apelau între ele.
import random
def joaca_runda(minim, maxim):
secret = random.randint(minim, maxim)
incercari = 0
raspuns = minim - 1
while raspuns != secret:
raspuns = citeste_numar(minim, maxim)
incercari = incercari + 1
if raspuns < secret:
print("Prea mic.")
elif raspuns > secret:
print("Prea mare.")
print("Corect!")
return incercari
- Scrie
afiseaza_scor(incercari)singur — muți acolo comentariile despre performanță din laboratorul 1. - La sfârșitul fișierului, programul principal devine trei linii:
print("M-am gandit la un numar intre 1 si 100.")
rezultat = joaca_runda(1, 100)
afiseaza_scor(rezultat)
Rulează și joacă o rundă completă. Jocul trebuie să se comporte identic cu versiunea veche — asta înseamnă refactorizare: schimbi organizarea, nu comportamentul.
Meniul: funcțiile devin opțiuni
Acum, recompensa pentru ordine. Pentru că jocul e o funcție, poți construi în jurul lui un meniu:
def meniu():
print()
print("=== GHICESTE NUMARUL ===")
print("1. Joc usor (1-50)")
print("2. Joc greu (1-1000)")
print("3. Iesire")
return citeste_numar(1, 3)
optiune = meniu()
while optiune != 3:
if optiune == 1:
afiseaza_scor(joaca_runda(1, 50))
elif optiune == 2:
afiseaza_scor(joaca_runda(1, 1000))
optiune = meniu()
print("Pe curand!")
Observă recircularea: meniu() refolosește citeste_numar (validarea de interval face exact ce trebuie și aici), iar afiseaza_scor(joaca_runda(...)) înlănțuie două funcții — rezultatul uneia intră direct în cealaltă. Niciun rând de logică nou pentru „joc ușor" vs „joc greu": doar alți parametri.
Dacă nu merge
NameError: name 'citeste_numar' is not defined: Python citește fișierul de sus în jos — definițiile funcțiilor trebuie să stea înaintea primului apel. Mută toate blocuriledefsus, programul principal jos.- Funcția „nu face nimic": ai definit-o, dar n-ai apelat-o — sau ai scris
joaca_rundafără paranteze. Fără()nu există apel. joaca_rundamerge, dar scorul e mereuNone: funcția ta nu arereturn incercarila final, iarafiseaza_scorprimește nimicul. Orice funcție fărăreturnreturneazăNonepe tăcute.- Meniul afișează opțiunile dar acceptă
7: ai apelatciteste_numar(1, 3)sau ai lăsat unint(input(...))gol, fără validare? Refolosește funcția — pentru asta ai scris-o. - Jocul greu se termină instant: verifică dacă
random.randintprimeșteminim, maxim(parametrii), nu1, 100scris cu mâna — altfel secreta e mereu în intervalul vechi.
Misiunea ta
Nivel de bază (obligatoriu): ghiceste_v2.py cu cele trei funcții din tabel + programul principal scurt; comportament identic cu jocul din laboratorul 1.
Extindere: meniul complet cu joc ușor, joc greu și ieșire, construit pe funcțiile existente.
Provocare: adaugă opțiunea „4. Rolurile se schimbă" — tu te gândești la un număr, iar calculatorul ghicește înjumătățind intervalul; tu îi răspunzi cu 1 (prea mic), 2 (prea mare), 3 (corect). Scrie-o, evident, ca funcție separată. Dacă totul e corect, calculatorul nu are nevoie niciodată de mai mult de 10 încercări pentru 1-1000 — verifică!
Ai terminat când:
- fiecare funcție face un singur lucru, iar numele ei spune care;
- schimbarea intervalului de joc se face modificând un singur apel, nu zece linii;
- opțiunea 3 chiar iese din program, iar 1 și 2 revin la meniu după rundă;
- colegul de bancă, citind doar programul principal (fără corpul funcțiilor), poate povesti ce face jocul.