PROGRAMMA COMPLETO
Questo è il programma ottenuto ricombinando i vari moduli nel
seguente modo:
- le
costanti,
tutti i tipi e le variabili dei vari moduli sono messe assieme
- le procedure e le funzioni;
sono elencate modulo per modulo;
- il blocco principale ` dato dal modulo main.
Il programma è poi stato controllato staticamente usando il
compilatore del PASCAL.
program DATAB;
const
MAX = 100;
type
COMANDO = (INSERISCI, CANCELLA, CAMBIA_GRUPPO, VOTO_ORALE, VOTO_SCRITTO,
VOTO_PROGETTO, PASSATO, STAMPA_GRUPPI, STAMPA_MATRICOLA,
STAMPA_COGNOME, STAMPA_PASSATI, STATISTICHE, FINE);
GRUPPO = 1..30;
MATRICOLA = 100000..999999;
VOTO = -1..33;
PAROLA = record
LUN: 0..30;
CARS: array[1..30] of char;
end;
SCHEDA = record
nome, cognome: PAROLA;
gruppo: GRUPPO;
matricola: MATRICOLA;
orale, scritto, progetto: VOTO
end;
STATO = array[1..MAX] of SCHEDA;
var
ARCHI: STATO;
LIBERO: integer;
COM: COMANDO; {MAIN}
C: CHAR; {MAIN}
{********************************************************************}
{ COMANDI }
{********************************************************************}
procedure LEGGI_COMANDO (var COM: COMANDO); {COMANDO}
var
N: integer;
begin
writeln('I comandi possibili sono:');
writeln('1: inserisci studente');
writeln('2: cancella studente');
writeln('3: cambia gruppo');
writeln('4: registra voto orale');
writeln('5: registra voto scritto');
writeln('6: registra voto progetto');
writeln('7: controlla e'' passato ');
writeln('8: stampa gruppi ');
writeln('9: stampa matricole ');
writeln('10: stampa nomi ');
writeln('11: stampa passati ');
writeln('12: statistiche ');
writeln('13: fine ');
readln(N);
case N of
1:
COM := INSERISCI;
2:
COM := CANCELLA;
3:
COM := CAMBIA_GRUPPO;
4:
COM := VOTO_ORALE;
5:
COM := VOTO_SCRITTO;
6:
COM := VOTO_PROGETTO;
7:
COM := PASSATO;
8:
COM := STAMPA_GRUPPI;
9:
COM := STAMPA_MATRICOLA;
10:
COM := STAMPA_COGNOME;
11:
COM := STAMPA_PASSATI;
12:
COM := STATISTICHE;
13:
COM := FINE;
end;
end;
function E_FINE (COM: COMANDO): boolean; {COMANDO}
begin
E_FINE := COM = FINE;
end;
{********************************************************************}
{ GRUPPO }
{********************************************************************}
procedure LEGGI_GRUPPO (var G: GRUPPO);
begin
read(G)
end;
procedure SCRIVI_GRUPPO (G: GRUPPO);
begin
write(G : 2)
end;
{********************************************************************}
{ MATRICOLA }
{********************************************************************}
procedure LEGGI_MAT (var M: MATRICOLA);
begin
read(M)
end;
procedure SCRIVI_MAT (M: MATRICOLA);
begin
write(M : 6)
end;
{********************************************************************}
{ VOTO }
{********************************************************************}
procedure LEGGI_VOTO (var V: VOTO);
begin
read(V)
end;
procedure SCRIVI_VOTO (V: VOTO);
begin
if V < 31 then
write(V : 2)
else
write('30 e lode');
end;
{********************************************************************}
{ PAROLA }
{********************************************************************}
function UGUALE_P (P1, P2: PAROLA): boolean;
var
UG: boolean;
I: integer;
begin
if P1.LUN <> P2.LUN then
UGUALE_P := false
else
begin
UG := true;
I := 1;
while UG and (I < P1.LUN) do
if P1.CARS[I] <> P2.CARS[I] then
UG := false
else
I := I + 1;
UGUALE_P := UG;
end;
end;
function MINORE_P (P1, P2: PAROLA): boolean;
var
FINE: boolean;
I: integer;
begin
FINE := false;
I := 1;
while (not FINE) and (I <= P1.LUN) and (I <= P2.LUN) do
if P1.CARS[I] = P2.CARS[I] then
I := I + 1
else
begin
MINORE_P := P1.CARS[I] < P2.CARS[I];
FINE := true
end;
if not FINE then
MINORE_P := P1.LUN < P2.LUN;
end;
procedure LEGGI_PAROLA (var P: PAROLA);
{legge tutti i caratteri, che costituiranno la parola, fino al primo blank}
var
C: char;
begin
P.LUN := 0;
read(C);
while C <> ' ' do
begin
P.LUN := P.LUN + 1;
P.CARS[P.LUN] := C;
read(C);
end;
end;
procedure SCRIVI_PAROLA (P: PAROLA);
var
I: integer;
begin
for I := 1 to P.LUN do
write(P.CARS[I]);
end;
{********************************************************************}
{ SCHEDA }
{********************************************************************}
function ESTRAI_GRUPPO (S: SCHEDA): GRUPPO;
begin
ESTRAI_GRUPPO := S.gruppo;
end;
procedure NOME (S: SCHEDA;
var N: PAROLA);
begin
N := S.nome;
end;
procedure COGNOME (S: SCHEDA;
var C: PAROLA);
begin
C := S.cognome;
end;
function MATRIC (S: SCHEDA): MATRICOLA;
begin
MATRIC := S.matricola;
end;
function VOTO_O (S: SCHEDA): VOTO;
begin
VOTO_O := S.orale;
end;
function VOTO_S (S: SCHEDA): VOTO;
begin
VOTO_S := S.scritto;
end;
function VOTO_P (S: SCHEDA): VOTO;
begin
VOTO_P := S.progetto;
end;
procedure SCHEDA_INIZIALE (N, C: PAROLA;
MAT: MATRICOLA;
G: GRUPPO;
var S: SCHEDA);
begin
S.nome := N;
S.cognome := C;
S.matricola := MAT;
S.gruppo := G;
S.orale := -1;
S.scritto := -1;
S.progetto := -1;
end;
function VOTO_FINALE (S: SCHEDA): VOTO;
begin
if ((VOTO_O(S) >= 15) and ((VOTO_S(S) >= 15) and (VOTO_P(S) >= 15))) then
VOTO_FINALE :=
round((((VOTO_O(S) + VOTO_S(S)) / 2) * 3 / 5) + (VOTO_P(S) * 2 / 5))
else
VOTO_FINALE := -1
end;
{********************************************************************}
{ STATO }
{********************************************************************}
procedure RECUPERA_STATO;
{ recupero lo stato corrente dalla memoria di massa e lo mette in ARCHI }
{ lo stato e' conservato in un file di nome STATO_SALVATO }
var
F: file of SCHEDA;
begin
reset(F, 'STATO_SALVATO');
LIBERO := 1;
while (not eof(F)) do
begin
read(F, ARCHI[LIBERO]);
LIBERO := LIBERO + 1;
end;
end;
procedure SALVA_STATO;
{salva lo stato corrente, contenuto nella variabile ARCHI, sulla memoria di massa}
var
F: file of SCHEDA;
I: integer;
begin
rewrite(F, 'STATO_SALVATO');
for I := 1 to LIBERO - 1 do
write(F, ARCHI[LIBERO]);
end;
procedure STATO_VUOTO;
{assegna alla variabile ARCHI l'archivio vuoto}
begin
LIBERO := 1;
end;
procedure AGGIUNGI_SCHEDA (S: SCHEDA);
{aggiunge la scheda S all'archivio contenuto nella variabile ARCHI }
begin
ARCHI[LIBERO] := S;
LIBERO := LIBERO + 1;
end;
procedure CANCELLA_SCHEDA (M: MATRICOLA);
{cancella la scheda relativa allo studente di matricola M dall'archivio contenuto nella variabile ARCHI }
var
I: integer;
begin
I := 1;
while I < LIBERO do
if MATRIC(ARCHI[I]) <> M then
I := I + 1
else
begin
if I < LIBERO - 1 then
ARCHI[I] := ARCHI[LIBERO - 1];
LIBERO := LIBERO - 1;
I := LIBERO;
end;
end;
procedure MODIFICA_G (M: MATRICOLA;
NUOVO_G: GRUPPO);
{ modifica il gruppo nella scheda relativa allo studente}
{ di matricola M nell'archivio contenuto nella variabile ARCHI }
var
I: integer;
begin
I := 1;
while I < LIBERO do
if MATRIC(ARCHI[I]) <> M then
I := I + 1
else
begin
ARCHI[I].gruppo := NUOVO_G;
I := LIBERO;
end;
end;
procedure MODIFICA_O (M: MATRICOLA;
NUOVO_V: VOTO);
{ modifica il voto orale nella scheda relativa allo studente}
{ di matricola M nell'archivio contenuto nella variabile ARCHI }
var
I: integer;
begin
I := 1;
while I < LIBERO do
if MATRIC(ARCHI[I]) <> M then
I := I + 1
else
begin
ARCHI[I].orale := NUOVO_V;
I := LIBERO;
end;
end;
procedure MODIFICA_S (M: MATRICOLA;
NUOVO_V: VOTO);
{ modifica il voto scritto nella scheda relativa allo studente}
{ di matricola M nell'archivio contenuto nella variabile ARCHI }
var
I: integer;
begin
I := 1;
while I < LIBERO do
if MATRIC(ARCHI[I]) <> M then
I := I + 1
else
begin
ARCHI[I].scritto := NUOVO_V;
I := LIBERO;
end;
end;
procedure MODIFICA_P (M: MATRICOLA;
NUOVO_V: VOTO);
{ modifica il voto progetto nella scheda relativa allo studente}
{ di matricola M nell'archivio contenuto nella variabile ARCHI }
var
I: integer;
begin
I := 1;
while I < LIBERO do
if MATRIC(ARCHI[I]) <> M then
I := I + 1
else
begin
ARCHI[I].progetto := NUOVO_V;
I := LIBERO;
end;
end;
function E_PASSATO (M: MATRICOLA): boolean;
{ controlla se lo studente di matricola M ha passato l'esame secondo i dati }
{ presenti nell'archivio contenuto nella variabile ARCHI }
var
I: integer;
begin
I := 1;
while I < LIBERO do
if MATRIC(ARCHI[I]) <> M then
I := I + 1
else
begin
E_PASSATO := VOTO_FINALE(ARCHI[I]) >= 18;
I := LIBERO;
end;
end;
procedure ORDINA_ARCHIVIO (function ORD (S1, S2: SCHEDA): boolean);
{ ordina l'archivio contenuto nella variabile ARCHI secondo ORD }
var
C, J: integer;
SCAMBIO: SCHEDA;
begin
for C := 1 to LIBERO - 1 do
{scambio l'elemento C-esimo con il piu' piccolo degli elementi }
{ tra il C+1-esimo e l'ultimo (che sta in posto LIBERO-1) }
for J := C + 1 to LIBERO - 1 do
if ORD(ARCHI[J], ARCHI[C]) then
begin
SCAMBIO := ARCHI[C];
ARCHI[C] := ARCHI[J];
ARCHI[J] := SCAMBIO;
end;
end;
procedure STAMPA_ARCHIVIO (procedure STAMPA_SCHEDA (S: SCHEDA));
{ stampa le schede appartenenti all'archivio contenuto nella variabile ARCHI }
{ come richiesto dalla procedura STAMPA_SCHEDA }
var
I: integer;
begin
for I := 1 to LIBERO - 1 do
STAMPA_SCHEDA(ARCHI[I]);
end;
function NUM_STUD: integer;
{ ritorna il numero di schede presenti nell'archivio }
begin
NUM_STUD := LIBERO - 1;
end;
function NUM_OR: integer;
{ ritorna il numero di schede con voto orale presenti nell'archivio }
var
I, ORALI: integer;
begin
ORALI := 0;
for I := 1 to LIBERO - 1 do
if ARCHI[I].orale > -1 then
ORALI := ORALI + 1;
NUM_OR := ORALI;
end;
function NUM_SCR: integer;
{ ritorna il numero di schede con voto scritto presenti nell'archivio }
var
I, SCRITTI: integer;
begin
SCRITTI := 0;
for I := 1 to LIBERO - 1 do
if ARCHI[I].scritto > -1 then
SCRITTI := SCRITTI + 1;
NUM_SCR := SCRITTI;
end;
function NUM_PRO: integer;
{ ritorna il numero di schede con voto progetto presenti nell'archivio }
var
I, PROG: integer;
begin
PROG := 0;
for I := 1 to LIBERO - 1 do
if ARCHI[I].progetto > -1 then
PROG := PROG + 1;
NUM_PRO := PROG;
end;
function NUM_PAS: integer;
{ ritorna il numero di schede con esame passato presenti nell'archivio }
var
I, PASSATI: integer;
begin
PASSATI := 0;
for I := 1 to LIBERO - 1 do
if VOTO_FINALE(ARCHI[I]) > 17 then
PASSATI := PASSATI + 1;
NUM_PAS := PASSATI;
end;
{********************************************************************}
{ ATTIVITA' PRINCIPALE }
{********************************************************************}
procedure ESEGUI (COM: COMANDO); {ATTIVITA' BASE}
{ Usa la variabile globale ARCHI }
procedure INSER;
var
NOME, COGNOME: PAROLA;
M: MATRICOLA;
G: GRUPPO;
S: SCHEDA;
begin
LEGGI_PAROLA(NOME);
LEGGI_PAROLA(COGNOME);
LEGGI_MAT(M);
LEGGI_GRUPPO(G);
SCHEDA_INIZIALE(NOME, COGNOME, M, G, S);
AGGIUNGI_SCHEDA(S);
end; {INSER}
procedure CANC;
var
M: MATRICOLA;
begin
LEGGI_MAT(M);
CANCELLA_SCHEDA(M);
end; {CANC}
procedure CAMBIA_G;
var
M: MATRICOLA;
G: GRUPPO;
begin
LEGGI_MAT(M);
LEGGI_GRUPPO(G);
MODIFICA_G(M, G);
end; {CAMBIA_G}
procedure VOTO_O;
var
M: MATRICOLA;
V: VOTO;
begin
LEGGI_MAT(M);
LEGGI_VOTO(V);
MODIFICA_O(M, V);
end; {CAMBIA_O}
procedure VOTO_S;
var
M: MATRICOLA;
V: VOTO;
begin
LEGGI_MAT(M);
LEGGI_VOTO(V);
MODIFICA_S(M, V);
end; {CAMBIA_S}
procedure VOTO_P;
var
M: MATRICOLA;
V: VOTO;
begin
LEGGI_MAT(M);
LEGGI_VOTO(V);
MODIFICA_P(M, V);
end; {CAMBIA_P}
procedure PASS;
var
M: MATRICOLA;
begin
LEGGI_MAT(M);
write('Lo studente di matricola ');
SCRIVI_MAT(M);
write(' ');
if E_PASSATO(M) then
writeln(' e'' passato.')
else
writeln(' non e'' passato.')
end; {PASS}
procedure STAMPA_G;
function ORDINE_G (S1, S2: SCHEDA): boolean;
var
N1, C1, N2, C2: PAROLA;
G1, G2: GRUPPO;
begin
NOME(S1, N1);
COGNOME(S1, C1);
NOME(S2, N2);
COGNOME(S2, C2);
G1 := ESTRAI_GRUPPO(S1);
G2 := ESTRAI_GRUPPO(S2);
if G1 = G2 then
if UGUALE_P(C1, C2) then
ORDINE_G := MINORE_P(N1, N2)
else
ORDINE_G := MINORE_P(C1, C2)
else
ORDINE_G := G1 < G2;
end;
procedure VISTA_G (S: SCHEDA);
var
N, C: PAROLA;
begin
SCRIVI_GRUPPO(ESTRAI_GRUPPO(S));
write(' ');
COGNOME(S, C);
SCRIVI_PAROLA(C);
write(' ');
NOME(S, N);
SCRIVI_PAROLA(N);
writeln;
end;
begin
ORDINA_ARCHIVIO(ORDINE_G);
STAMPA_ARCHIVIO(VISTA_G);
end; {STAMPA_G}
procedure STAMPA_M;
function ORDINE_M (S1, S2: SCHEDA): boolean;
begin
ORDINE_M := MATRIC(S1) < MATRIC(S2);
end;
procedure VISTA_M (S: SCHEDA);
var
N, C: PAROLA;
begin
SCRIVI_MAT(MATRIC(S));
write(' ');
COGNOME(S, C);
SCRIVI_PAROLA(C);
write(' ');
NOME(S, N);
SCRIVI_PAROLA(N);
writeln;
end;
begin
ORDINA_ARCHIVIO(ORDINE_M);
STAMPA_ARCHIVIO(VISTA_M);
end; {STAMPA_M}
procedure STAMPA_C;
function ORDINE_C (S1, S2: SCHEDA): boolean;
var
N1, C1, N2, C2: PAROLA;
begin
NOME(S1, N1);
COGNOME(S1, C1);
NOME(S2, N2);
COGNOME(S2, C2);
if UGUALE_P(C1, C2) then
ORDINE_C := MINORE_P(N1, N2)
else
ORDINE_C := MINORE_P(C1, C2)
end;
procedure VISTA_C (S: SCHEDA);
var
N, C: PAROLA;
begin
COGNOME(S, C);
SCRIVI_PAROLA(C);
write(' ');
NOME(S, N);
SCRIVI_PAROLA(N);
writeln;
end;
begin
ORDINA_ARCHIVIO(ORDINE_C);
STAMPA_ARCHIVIO(VISTA_C);
end; {STAMPA_C}
procedure STAMPA_PAS;
function ORDINE_PAS (S1, S2: SCHEDA): boolean;
var
N1, C1, N2, C2: PAROLA;
V1, V2: VOTO;
begin
NOME(S1, N1);
COGNOME(S1, C1);
NOME(S2, N2);
COGNOME(S2, C2);
V1 := VOTO_FINALE(S1);
V2 := VOTO_FINALE(S2);
if V1 = V2 then
if UGUALE_P(C1, C2) then
ORDINE_PAS := MINORE_P(N1, N2)
else
ORDINE_PAS := MINORE_P(C1, C2)
else
ORDINE_PAS := V1 < V2;
end;
procedure VISTA_PAS (S: SCHEDA);
var
N, C: PAROLA;
V: VOTO;
begin
V := VOTO_FINALE(S);
if V >= 18 then
begin
COGNOME(S, C);
SCRIVI_PAROLA(C);
write(' ');
NOME(S, N);
SCRIVI_PAROLA(N);
write(' voto finale = ');
SCRIVI_VOTO(V);
writeln;
end
end;
begin
ORDINA_ARCHIVIO(ORDINE_PAS);
STAMPA_ARCHIVIO(VISTA_PAS);
end; {STAMPA_PAS}
procedure STA;
var
NS: integer;
begin
NS := NUM_STUD;
Writeln('Totale studenti = ', NS);
Writeln('Percentuale superato esame = ', ((NUM_PAS * 100) / NS) : 2);
Writeln('Percentuale superato scritto = ', ((NUM_SCR * 100) / NS) : 2);
Writeln('Percentuale superato orale = ', ((NUM_OR * 100) / NS) : 2);
Writeln('Percentuale superato progetto = ', ((NUM_PRO * 100) / NS) : 2);
end; {STA}
begin {ESEGUI}
case COM of
INSERISCI:
INSER;
CANCELLA:
CANC;
CAMBIA_GRUPPO:
CAMBIA_G;
VOTO_ORALE:
VOTO_O;
VOTO_SCRITTO:
VOTO_S;
VOTO_PROGETTO:
VOTO_P;
PASSATO:
PASS;
STAMPA_GRUPPI:
STAMPA_G;
STAMPA_MATRICOLA:
STAMPA_M;
STAMPA_COGNOME:
STAMPA_C;
STAMPA_PASSATI:
STAMPA_PAS;
STATISTICHE:
STA;
FINE:
end;
end; {ESEGUI}
begin {MAIN}
writeln('Vuoi recuperare lo stato iniziale ? (S/N)?');
readln(C);
if C = 'S' then
RECUPERA_STATO
else
STATO_VUOTO;
repeat
LEGGI_COMANDO(COM);
ESEGUI(COM);
until E_FINE(COM);
SALVA_STATO;
end. {MAIN}