Python clasa a 9-a · Manual Python
Laborator Python
LECȚIE

3.4. Proiectarea modulară

Descompunerea unei probleme și testarea independentă a subprogramelor

ANALIZĂ
→
PROIECTARE
→
IMPLEMENTARE
→
TESTARE
→
DEPANARE
01
OBIECTIVE

La finalul lecției vei putea...

  • să explici principiul proiectării modulare;
  • să descompui o problemă în subprobleme cu responsabilități clare;
  • să alegi subprogramele potrivite pentru o problemă algoritmică;
  • să stabilești datele de intrare și rezultatele fiecărui subprogram;
  • să utilizezi funcții definite în lecțiile anterioare pentru a construi o soluție mai mare;
  • să testezi independent subprogramele înainte de integrare;
  • să diferențiezi testarea unei funcții de testarea programului complet;
  • să identifici avantajele modularizării: claritate, reutilizare, depanare și modificare mai ușoară.
02
EXPLICAȚIE

Proiectarea modulară

2.1. Ce înseamnă proiectarea modulară?

O problemă complexă poate fi împărțită în probleme mai mici. Fiecare subproblemă este realizată de un subprogram. Această organizare se numește proiectare modulară. Programul complet este obținut prin colaborarea subprogramelor.

Un modul bun are o responsabilitate clară.

2.2. Cum descompunem o problemă?

  1. Citim enunțul și identificăm rezultatul cerut.
  2. Separăm operațiile care au un rol distinct.
  3. Pentru fiecare operație stabilim datele necesare și rezultatul.
  4. Definim funcțiile corespunzătoare.
  5. Testăm fiecare funcție separat.
  6. Combinăm funcțiile în programul principal.
  7. Testăm programul complet pe date reprezentative.

2.3. Interfața unui subprogram

Pentru a utiliza corect o funcție trebuie să știm ce primește și ce produce. Aceste informații formează interfața funcției: parametrii de intrare și valoarea returnată sau efectul produs.

SubprogramDate primiteRezultat/efect
cmmdc(a,b)două numere naturaleCMMDC-ul lor
suma_cifre(n)un număr naturalsuma cifrelor
este_prim(n)un număr naturaladevărat/fals
afiseaza_raport(...)datele analizateafișare

2.4. De ce testăm independent?

Dacă programul complet nu produce rezultatul așteptat, testarea separată a funcțiilor reduce zona în care căutăm eroarea. Dacă fiecare funcție a trecut testele proprii, integrarea devine mai ușor de verificat.

2.5. Testarea și verificarea

Testarea înseamnă executarea programului cu date alese pentru a observa comportamentul. Verificarea înseamnă justificarea faptului că algoritmul și rezultatul sunt corecte.

03
EXEMPLU INTUITIV

Responsabilități separate

Organizarea unui eveniment presupune mai multe roluri: invitați, program și logistică. Într-un program mare, nu vrem o singură funcție uriașă. Preferăm funcții mai mici, fiecare responsabilă de o operație.

Dacă o funcție de calcul al mediei este corectă, ea poate fi reutilizată în mai multe rapoarte.

Alege responsabilitatea

Care este o responsabilitate bună pentru o funcție?

04
PYTHON

Construim o soluție din funcții

def media(a, b, c):
    return (a + b + c) / 3

def interval(a, b, c):
    return max(a, b, c) - min(a, b, c)

def afiseaza_raport(a, b, c):
    print("Media =", media(a, b, c))
    print("Interval =", interval(a, b, c))

x = float(input("x = "))
y = float(input("y = "))
z = float(input("z = "))

afiseaza_raport(x, y, z)

Funcțiile media() și interval() calculează și returnează valori. Funcția afiseaza_raport() le reutilizează. Programul principal se ocupă de citire și apel.

Ce urmează?

Într-o soluție modulară, după ce ai testat funcțiile separat, ce faci?

05
ALGORITM / PSEUDOCOD

Separăm responsabilitățile

subprogram media(a, b, c) returnează
    returnează (a+b+c)/3
■

subprogram interval(a, b, c) returnează
    returnează maxim(a,b,c) - minim(a,b,c)
■

subprogram raport(a, b, c)
    m ← Apel media(a,b,c)
    d ← Apel interval(a,b,c)
    afișează m, d
■

citește a, b, c
Apel raport(a,b,c)

Două funcții calculează rezultate, iar a treia le folosește pentru prezentarea raportului.

06
ATENȚIE!

Reguli pentru o modularizare bună

  • Modularizarea nu înseamnă să transformăm fiecare linie într-o funcție. Un modul trebuie să aibă un rol clar.
  • O funcție nu trebuie să depindă inutil de variabile globale.
  • Înainte de integrare, testează fiecare funcție cu valori normale și cazuri-limită.
  • Un singur test nu este dovadă absolută a corectitudinii.
  • Testarea observă comportamentul pe date concrete; verificarea justifică metoda și rezultatul.
  • Dacă două funcții fac aproape aceeași prelucrare, analizează dacă una poate fi reutilizată de cealaltă.
  • Programul principal ar trebui să fie ușor de urmărit: citește date, apelează funcțiile potrivite și folosește rezultatele.
07
EXEMPLU REZOLVAT

Analizator modular de numere

Problemă

Se citește un număr natural n. Să se construiască un program modular care determină suma cifrelor, numărul de cifre și dacă numărul este palindrom. Fiecare prelucrare trebuie realizată într-o funcție separată, iar funcțiile care calculează rezultate trebuie să le returneze.

Ideea de rezolvare

Descompunem problema în trei subprobleme: suma cifrelor, numărul de cifre și testul de palindrom. Fiecare funcție primește n și returnează un rezultat.

Algoritm

subprogram suma_cifre(n) returnează
    s ← 0
    cât timp n > 0 execută
        s ← s + n % 10
        n ← [n/10]
    ■
    returnează s
■

subprogram numar_cifre(n) returnează
    dacă n = 0 atunci
        returnează 1
    ■
    c ← 0
    cât timp n > 0 execută
        c ← c + 1
        n ← [n/10]
    ■
    returnează c
■

subprogram palindrom(n) returnează
    copie ← n
    inv ← 0
    cât timp n > 0 execută
        inv ← inv*10 + n%10
        n ← [n/10]
    ■
    returnează inv = copie
■

citește n
s ← Apel suma_cifre(n)
c ← Apel numar_cifre(n)
p ← Apel palindrom(n)
afișează s, c, p

Python

def suma_cifre(n):
    s = 0
    while n > 0:
        s = s + n % 10
        n = n // 10
    return s

def numar_cifre(n):
    if n == 0:
        return 1
    c = 0
    while n > 0:
        c = c + 1
        n = n // 10
    return c

def palindrom(n):
    copie = n
    inv = 0
    while n > 0:
        inv = inv * 10 + n % 10
        n = n // 10
    return inv == copie

n = int(input("n = "))
s = suma_cifre(n)
c = numar_cifre(n)
p = palindrom(n)
print("Suma cifrelor =", s)
print("Număr de cifre =", c)
print("Palindrom =", p)

Testare

TipnRezultate așteptate
normal12216, 4, True
limită00, 1, True
particular77, 1, True
nepalindrom1236, 3, False

Verificare

Pentru n = 1221, suma este 6, numărul de cifre este 4, iar inversul este tot 1221. Testul cu 0 este important.

08
EXERCIȚII DE BAZĂ

Construim module simple

  1. Descompune problema „determinarea mediei și a maximului a trei valori” în două funcții.
  2. Construiește o funcție care returnează minimul a trei numere și testeaz-o separat.
  3. Construiește o funcție care returnează suma cifrelor și una care returnează produsul cifrelor.
  4. Scrie un program care utilizează două funcții independente pentru CMMDC și CMMC.
  5. Pentru un număr natural, creează funcții separate pentru numărul de cifre și cifra maximă.
  6. Pentru fiecare funcție de la exercițiile anterioare, propune câte trei teste: normal, limită și particular.
09
EXERCIȚII DE APROFUNDARE

Proiectare și testare modulară

  1. Descompune o problemă de analiză a unui număr în cel puțin patru funcții și justifică responsabilitatea fiecăreia.
  2. Construiește o funcție care returnează cel mai mare divizor propriu și reutilizeaz-o într-o funcție care verifică dacă numărul este perfect.
  3. Construiește o funcție pentru conversia din baza 10 în baza 2 și o funcție separată pentru verificarea reprezentării obținute.
  4. Realizează un program modular care citește trei numere și raportează: minim, maxim, CMMDC, CMMC și media. Evită variabilele globale.
  5. Analizează un program cu o singură funcție foarte lungă și propune o descompunere în cel puțin trei funcții. Explică avantajele.
  6. Proiectează o strategie de testare pentru un program modular: ce testezi mai întâi, ce testezi după integrare și ce verifici matematic?
10
VERIFICARE

Verifică-ți înțelegerea

Mini-quiz

1. Ce înseamnă proiectare modulară?

2. De ce testăm funcțiile separat?

3. Ce trebuie stabilit pentru un subprogram?

4. Testarea înseamnă...

5. Programul principal ar trebui să...

11
MINI-PROIECT

Analizator modular de numere

Analizator modular de numere

Construiește o aplicație modulară care primește un număr natural și generează un raport cu mai multe proprietăți: numărul de cifre, suma cifrelor, cifra maximă, numărul de divizori, primalitatea, CMMDC cu o a doua valoare și conversia în baza 2. Fiecare operație importantă trebuie realizată printr-o funcție separată.

  • stabilește înainte de programare responsabilitatea fiecărei funcții;
  • folosește parametri pentru datele de intrare și return pentru rezultate;
  • testează independent fiecare funcție;
  • integrează apoi funcțiile într-un program principal simplu;
  • include cel puțin un caz-limită: n = 0 sau n = 1, după caz;
  • documentează într-un tabel cel puțin cinci teste și rezultatele așteptate;
  • alege funcțiile astfel încât aceeași prelucrare să nu fie implementată de două ori.