RICORDARSI DI PRENOTARE GLI SCRITTI
NOTE SUL PROGETTO LA FRASE CHIAVE DEVE POTER CONTENERE SIA SPAZI CHE LETTERE MAIUSCOLE. QUANDO SI MOSTRA IL CONTENUTO DI UN FILE, PREVEDERE OLTRE AL RETURN PER AVANZARE ANCHE UN TASTO PER TERMINARE LA LETTURA. METTERE I CONTROLLI SUGLI INPUT DEI DATI
Problema: Supponiamo si vogliano scrivere delle procedure per la gestione del Centro Storico di una città. Quali sono i dati da usare e come sono legati fra loro? Quartiere Edificio Piani Nuclei familiari …………..
RECORD Record: una struttura in cui sono contenuti dati di tipo diverso, interi, stringhe, reali. Si può accedere ai dati di un record facendo riferimento al nome del dato.
Definizione di RECORD TYPE NomeRecord = RECORD Campo1: integer, ……….. CampoN: real END; = Lista dei campi RECORD identificatore END AnagraficaRecord = RECORD Cognome, Nome : Stringa20 END;
ESEMPIO Studente Anagrafe Nascita Matricola CognomeNome GiornoMeseAnno AnnoCorsoRisultatiMedia Studente AnagrafeNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia RossiUgo /8796 BianchiCarlo /8746 II I
StudenteRecord = RECORD Anagrafe:AnagraficaRecord; Nascita:DataRecord; Matricola:StringaNome; AnnoCorso:StringaNome; Risultati:RisultatiArray; Media:real; END; Studente AnagrafeNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia TYPE Stringa20 = STRING[20] RisultatiArray=ARRAY[1..TotaleProve] OF integer; AnagraficaRecord = RECORD Cognome, Nome : Stringa20 END; DataRecord = RECORD Giorno, Mese, Anno : integer END;
TYPE Stringa20 = STRING[20] RisultatiArray=ARRAY[1..TotaleProve] OF integer; AnagraficaRecord = RECORD Cognome, Nome : Stringa20 END; DataRecord = RECORD Giorno, Mese, Anno : integer END; StudenteRecord = RECORD Anagrafe:AnagraficaRecord; Nascita:DataRecord; Matricola:StringaNome; AnnoCorso:StringaNome; Risultati:RisultatiArray; Media:real; END; VAR Compleanno:DataRecord; DatiStudente:StudenteRecord; UnoStudente:AnagraficaRecord ;
E possibile trattare i dati usando i nome dei campi. writeln(Lo studente, Studente.Anagrafe.Cognome, e nato il, Studente.Nascita.Giorno:1, Studente.Nascita.Mese:1, Studente.Nascita.Anno:1) Studente AnagrafeNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia RossiUgo /8796 BianchiCarlo /8746 II° I°
5 Rossi Carlo /564 II Rossi Lucio /884 I Bianchi Ugo /741 I Verdi Carlo /88 II Esposito Franco /524 I INPUT
REPEAT writeln( Introduci la data ); readln(DataOdierna.Giorno, DataOdierna.Mese, DataOdierna.Anno) UNTIL DataValida(DataOdierna); FUNCTION DataValida(Data:DataRecord):boolean; BEGIN DataValida:=(Data.Mese IN [1..12]) AND (Data.Giorno IN [1..31]) END; DataRecord = RECORD Giorno, Mese, Anno : integer END; VAR DataOdierna : DataRecord ; USO DELLE VARIABILI RECORD
Problema Assegnato un file del tipo prima descritto, scrivere una procedura che mostri i dati di tutti gli studenti. STRUTTURA DATI AnagraficaRecord = RECORD Cognome, Nome : Stringa20 END; DatataRecord = RECORD Giorno, Mese, Anno : integer END; StudenteRecord = RECORD Anagrafe:AnagraficaRecord; Nascita:DataRecord; Matricola:StringaNome; AnnoCorso:StringaNome; Risultati:RisultatiArray; Media:real; END; Pseudo Codice Main Apri il file dati in lettura Carica i dati e mostrali Pseudo Codice Carica dati Per ogni studente Carica record studente Pseudo Codice CaricaRecordStudente Leggi Cognome Leggi Nome Leggi Data Nascita Leggi Matricola, AnnoCorso Leggi Risultati
RAPPRESENTAZIONE GRAFICA Apri il file dati in lettura StudentiFile Carica Dati Iscritti Costruisci Record Studenti Leggi Cognome Leggi Nome Leggi Giorno Leggi Mese Leggi Anno Leggi Matr Leggi Corso Leggi Risultati StudentiFile Scrivi CognomeNome Giorno Mese Anno MatrCorsoRisultati Cognome Nome Giorno Mese Anno Matr Corso Risultati
PROGRAM Txtrecord(output,Studenti); CONST Sentinella=' '; LunMax=40; TotaleProve=4; MassimoStud=150; VAR Iscritti,IndiceArray:IndiceTipo; StudentiFile:text; UnoStudente:StudenteRecord; TYPE StringaNome=STRING[LunMax]; RisultatiArray=ARRAY[1..TotaleProve] OF integer; AnagraficaRecord=RECORD Cognome, Nome:StringaNome; END; NascitaRecord=RECORD Giorno, Mese, Anno:integer; END; StudenteRecord=RECORD Anagrafe:AnagraficaRecord; Nascita:NascitaRecord; Matricola:StringaNome; AnnoCorso:StringaNome; Risultati:RisultatiArray; Media:real; END; IndiceTipo=0..MassimoStud;
MAIN BEGIN assign(StudentiFile,'C:\TP\ESEMPI\moda\cap12\STUDREC.TXT'); reset(StudentiFile); CaricaDati(Iscritti,UnoStudente,StudentiFile); readln END.
PROCEDURE CaricaDati(VAR Iscritti:IndiceTipo; VAR UnoStudente:StudenteRecord; VAR StudentiFile:text); VAR Indice:IndiceTipo; BEGIN readln(StudentiFile,Iscritti); FOR Indice:=1 TO Iscritti DO CostruisciRecordStudente(UnoStudente,StudentiFile) END;
PROCEDURE CostruisciRecordStudente(VAR UnoStudente:StudenteRecord; VAR StudentiFile:text); VAR NumeroProva:integer; BEGIN LeggiParola(' ',Unostudente.Anagrafe.Cognome, StudentiFile); LeggiParola(' ', Unostudente.Anagrafe.Nome, StudentiFile); read(StudentiFile,Unostudente.Nascita.Giorno); read(StudentiFile,Unostudente.Nascita.Mese); read(StudentiFile,Unostudente.Nascita.Anno); readln(StudentiFile); LeggiParola(' ',Unostudente.Matricola, StudentiFile); LeggiParola(' ',Unostudente.AnnoCorso, StudentiFile); FOR NumeroProva:=1 TO TotaleProve DO read(StudentiFile,Unostudente.Risultati[NumeroProva]); readln(StudentiFile); writeln('Lo studente ',Unostudente.Anagrafe.Cognome,' ', Unostudente.Anagrafe.Nome,' Matr. ', Unostudente.Matricola); writeln(' Nato il ',Unostudente.Nascita.Giorno,'/', Unostudente.Nascita.Mese,'/', Unostudente.Nascita.Anno,' e'' iscritto al ', Unostudente.AnnoCorso,'ø anno di corso'); END; writeln END;
PROCEDURE LeggiParola(Sentinella:char;VAR Parola:StringaNome; VAR Studenti:text); VAR Carattere:char; BEGIN Parola:=''; read(Studenti,Carattere); WHILE (Carattere<>Sentinella) DO BEGIN Parola:=Parola+Carattere; read(Studenti,Carattere); END END;
LISTRUZIONE WITH Seleziona diversi campi di un record usando solo un riferimento. variabile WITHDO istruzioni. BEGIN WITH Nome1,Nome2,… DO BEGIN ………………... END;
PROCEDURE CostruisciRecordStudente(UnoStudente:StudenteRecord; VAR StudentiFile:text); VAR NumeroProva:integer; BEGIN WITH UnoStudente DO BEGIN LeggiParola(' ',Matricola, StudentiFile); LeggiParola(' ',AnnoCorso, StudentiFile); END END; USO DI WITH Studente AnagrafeNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia
Studente AnagrafeNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia WITH ANNIDATI PROCEDURE CostruisciRecordStudente(UnoStudente:StudenteRecord; VAR StudentiFile:text); VAR NumeroProva:integer; BEGIN WITH UnoStudente DO WITH Anagrafe DO BEGIN LeggiParola(' ',Cognome, StudentiFile); LeggiParola(' ',Nome, StudentiFile); END END;
PROCEDURE CostruisciRecordStudente(UnoStudente:StudenteRecord; VAR StudentiFile:text); VAR NumeroProva:integer; BEGIN WITH UnoStudente, Anagrafe, Nascita DO BEGIN LeggiParola(' ',Cognome, StudentiFile); LeggiParola(' ',Nome, StudentiFile); read(StudentiFile,Giorno); read(StudentiFile,Mese); read(StudentiFile,Anno); readln(StudentiFile); LeggiParola(' ',Matricola, StudentiFile); LeggiParola(' ',AnnoCorso, StudentiFile); END END; Studente AnagrafeNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia
ATTENZIONE luso del WITH produce codici meno leggibili (es. non è sempre chiaro se una variabile è il nome di un campo o una variabile globale) e quindi aumenta la probabilità di errore. PROCEDURE CostruisciRecordStudente(UnoStudente:StudenteRecord; VAR StudentiFile:text); VAR NumeroProva:integer; BEGIN WITH UnoStudente, Anagrafe, Nascita DO BEGIN LeggiParola(' ',Cognome, StudentiFile); LeggiParola(' ',Nome, StudentiFile); read(StudentiFile,Giorno); read(StudentiFile,Mese); read(StudentiFile,Anno); readln(StudentiFile); LeggiParola(' ',Matricola, StudentiFile); LeggiParola(' ',AnnoCorso, StudentiFile); END END;
ARRAY Corso AnagraficaNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia AnagraficaNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia AnagraficaNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia AnagraficaNascitaMatricola CognomeNomeAnnoMeseGiorno AnnoCorsoRisultatiMedia ARRAY Risultati 1234 Rossi Carlo /564 II
5 Rossi Carlo /564 II Rossi Lucio /884 I Bianchi Ugo /741 I Verdi Carlo /88 II Esposito Franco /524 I INPUT
PROBLEMA Dato il file testo STUDREC.TXT Scrivere un programma che: a- elenca gli studenti con i loro dati b- se richiesto mostra la media di un preassegnato studente c- se richiesto mostra lo studente con la media migliore ALGORITMO Costruisci un array (Corso) con i dati contenuti nel file Stampa i dati a partire dallarray (Corso) Chiedi cosa si desidera e esegui: CercaMediaStudente CercaMigliorStudente Cerca gli studenti con media superiore a un prefissato valore 5 Rossi Carlo /564 II Rossi Lucio /884 I Bianchi Ugo /741 I Verdi Carlo /88 II Esposito Franco /524 I
5 Rossi Carlo /564 II Rossi Lucio /884 I Bianchi Ugo /741 I Verdi Carlo /88 II Esposito Franco /524 I Lo studente Rossi Carlo Matr. 480/564 Nato il 30/11/1968 iscritto al II° anno di corso ha una media di Lo studente Rossi Lucio Matr. 050/884 Nato il 12/10/1969 iscritto al I° anno di corso ha una media di Lo studente Bianchi Ugo Matr. 050/741 Nato il 5/4/1965 iscritto al I° anno di corso ha una media di Lo studente Verdi Carlo Matr. 480/88 Nato il 14/12/1970 iscritto al II° anno di corso ha una media di Lo studente Esposito Franco Matr. 050/524 Nato il 2/8/1969 iscritto al I° anno di corso ha una media di INPUT OUTPUT
RAPPRESENTAZIONE GRAFICA Apri il file dati in lettura StudentiFile Leggi Array Risultati StudentiFile Risultati Media Risultati Media Scrivi Cognome Nome Giorno Mese Anno Matr AnnoCorso Media Risultati StudentiFile CostruisciCorso Corso Iscritti CercaMedia Studente Corso Iscritti CercaMigliore Corso Iscritti Leggi Dati StudentiFile Cognome Nome Giorno Mese Anno Matr AnnoCorso StudentiFile UnoStudente Costruisci Record Studenti StudentiFile Corso[I] IndiceMigliore Corso Iscritti IndiceMigliore IndiceStudente Corso NomeCercato Indice Array CercaNome Anagrafe1 Anagrafe2 boolean CercaInsieme Corso Iscritti
PROGRAM Txtrecord(output,Studenti); CONST Sentinella=' '; LunMax=40; TotaleProve=3; MassimoStud=250; TYPE StringaNome=STRING[LunMax]; RisultatiArray=ARRAY[1..TotaleProve] OF integer; AnagraficaRecord=RECORD Cognome, Nome:StringaNome; END; NascitaRecord=RECORD Giorno, Mese, Anno:integer; END; StudenteRecord=RECORD Anagrafe:AnagraficaRecord; Nascita:NascitaRecord; Matricola:StringaNome; AnnoCorso:StringaNome; Risultati:RisultatiArray; Media:real; END; IndiceTipo=0..MassimoStud; CorsoArray=ARRAY[IndiceTipo] OF StudenteRecord;
MAIN BEGIN assign(StudentiFile,'C:\TP\ESEMPI\moda\cap12\STUD2001.TXT'); reset(StudentiFile); CostruisciCorso(Iscritti,Corso,StudentiFile); writeln('1 - Mostra la media di un dato studente '); writeln('2 - Mostra il miglior studente del corso '); writeln('3 - Mostra tutti gli studenti che hanno una media superiore a un dato valore'); readln(Scelta); CASE Scelta OF 1:CercaMediaStudente(Iscritti,Corso); 2:CercaMigliore(Corso,Iscritti); 3:CercaInsieme(Corso,Iscritti) END; readln END.
CostruisciCorso Inserisci nellarray monodimensionale Corso i record studenti mediante la procedura CostruisciRecordStudente CostruisciRecordStudente Leggi lanagrafica con la procedura LeggiParola Leggi Giorno, Mese, Anno Leggi Matricola Leggi AnnoCorso Leggi ArrayRisultati Fai la media delle prove Mostra i dati dello studente
PROCEDURE CostruisciCorso(VAR Iscritti:IndiceTipo;VAR Corso:CorsoArray; VAR StudentiFile:text); VAR Indice:IndiceTipo; BEGIN readln(StudentiFile,Iscritti); FOR Indice:=1 TO Iscritti DO CostruisciRecordStudente(Corso[Indice],StudentiFile) END;
PROCEDURE CostruisciRecordStudente(UnoStudente:StudenteRecord; VAR StudentiFile:text); VAR NumeroProva:integer; BEGIN WITH UnoStudente, Anagrafe, Nascita DO BEGIN LeggiParola(' ',Cognome, StudentiFile); LeggiParola(' ',Nome, StudentiFile); read(StudentiFile,Giorno); read(StudentiFile,Mese); read(StudentiFile,Anno); readln(StudentiFile); LeggiParola(' ',Matricola, StudentiFile); LeggiParola(' ',AnnoCorso, StudentiFile); FOR NumeroProva:=1 TO TotaleProve DO read(StudentiFile,Risultati[NumeroProva]); readln(StudentiFile); Media:=MediaProve(Risultati); writeln('Lo studente ',Cognome,' ',Nome,' Matr. ',Matricola); writeln(' Nato il ',Giorno,'/',Mese,'/',Anno,' iscritto al ', AnnoCorso,'ø anno di corso',' ha una media di ',Media:3:2); writeln END END;
FUNCTION MediaProve(Risultati:RisultatiArray):real; VAR NumProva, Somma:integer; Media:real; BEGIN Somma:=0; FOR NumProva:=1 TO TotaleProve DO Somma:=Somma+Risultati[NumProva]; MediaProve:=Somma/TotaleProve END;
PROCEDURE LeggiParola(Sentinella:char;VAR Parola:StringaNome; VAR Studenti:text); VAR Carattere:char; BEGIN Parola:=''; read(Studenti,Carattere); WHILE (Carattere<>Sentinella) DO BEGIN Parola:=Parola+Carattere; read(Studenti,Carattere); END END;
CercaMediaStudente Leggi Nome e Cognome dello studente Usando larray Corso cerca il record con i suoi dati Stampa la media richiesta ricavata dallarray Corso
PROCEDURE CercaMediaStudente(VAR Iscritti:IndiceTipo;VAR Corso:CorsoArray); VAR NomeCercato:AnagraficaRecord; BEGIN writeln; writeln('Cerca lo studente: Cognome '); readln(NomeCercato.Cognome); writeln('Nome '); readln(NomeCercato.Nome); IndiceArray:=IndiceStudente(Iscritti,Corso,NomeCercato); IF IndiceArray<>0 THEN writeln('Lo studente ',Corso[IndiceArray].Anagrafe.Nome,' ', Corso[IndiceArray].Anagrafe.Cognome,' ha una media di ', Corso[IndiceArray].Media:3:2) END;
FUNCTION CercaNome(Anagrafe1,Anagrafe2:AnagraficaRecord):boolean; BEGIN CercaNome:=(Anagrafe1.Cognome=Anagrafe2.Cognome) AND (Anagrafe1.Nome=Anagrafe2.Nome) END; FUNCTION IndiceStudente(VAR Iscritti:IndiceTipo; VAR Corso:CorsoArray;NomeCercato:AnagraficaRecord):IndiceTipo; VAR Sonda:IndiceTipo; BEGIN Corso[0].Anagrafe:=NomeCercato; Sonda:=Iscritti; WHILE NOT CercaNome(Corso[Sonda].Anagrafe,NomeCercato) DO Sonda:=Sonda-1; CercaStudente:=Sonda END;
CercaMigliorStudente Usando larray Corso cerca il record dello studente con la MediaMigliore Stampa i dati dello studente trovato MediaMigliore Fai una ricerca lineare sullarray Corso nel campo Media e memorizza lindice per il quale la media è massima.
FUNCTION MediaMigliore(VAR Corso:CorsoArray;VAR Iscritti:IndiceTipo):IndiceTipo; VAR TempMigliore,Indice:IndiceTipo; BEGIN TempMigliore:=1; FOR Indice:=2 TO Iscritti DO IF Corso[Indice].Media > Corso[TempMigliore].Media THEN TempMigliore:=Indice; MediaMigliore:=TempMigliore END; PROCEDURE CercaMigliore(VAR Corso:CorsoArray;VAR Iscritti:IndiceTipo); VAR IndiceMax:IndiceTipo; BEGIN IndiceMax:=MediaMigliore(Corso,Iscritti); WITH Corso[IndiceMax],Anagrafe DO BEGIN write(Nome,' ',Cognome); writeln(' e'' il migliore del corso con una media di ', Media:3:2) END END;
PROCEDURE CercaInsieme(VAR Corso:CorsoArray; Iscritti:IndiceTipo); VAR Indice:integer; Range:real; BEGIN write('La media minima richiesta e'': '); readln(Range); FOR Indice:=1 TO Iscritti DO BEGIN WITH Corso[Indice],Anagrafe DO IF Media > Range THEN BEGIN write(Nome,' ',Cognome); writeln(' rientra nell''intervallo con una media di ',Media:3:2) END; END END;
PROGRAM Txtrecord(output,Studenti); ……………………………………………………………. VAR Corso:CorsoArray; Iscritti,IndiceArray:IndiceTipo; StudentiFile:text; UnoStudente:StudenteRecord; NomeCercato:AnagraficaRecord; Scelta:integer; Range:real; FUNCTION MediaProve(Risultati:RisultatiArray):real; PROCEDURE LeggiParola(Sentinella:char;VAR Parola:StringaNome; VAR Studenti:text); PROCEDURE CostruisciRecordStudente(VAR UnoStudente:StudenteRecord; VAR StudentiFile:text); PROCEDURE CostruisciCorso(VAR Iscritti:IndiceTipo;VAR Corso:CorsoArray; VAR StudentiFile:text); FUNCTION CercaNome(Anagrafe1,Anagrafe2:AnagraficaRecord):boolean; FUNCTION IndiceStudente(VAR Iscritti:IndiceTipo; VAR Corso:CorsoArray;NomeCercato:AnagraficaRecord):IndiceTipo; PROCEDURE CercaMediaStudente(VAR Iscritti:IndiceTipo; VAR Corso:CorsoArray); FUNCTION MediaMigliore(VAR Corso:CorsoArray; Iscritti:IndiceTipo):IndiceTipo; PROCEDURE CercaMigliore(VAR Corso:CorsoArray; Iscritti:IndiceTipo); PROCEDURE CercaInsieme(VAR Corso:CorsoArray; Iscritti:IndiceTipo);
OSSERVAZIONI Usare lalgoritmo giusto per la variabile giusta. Es. Se si vuole fare una ricerca dello studente con la media più alta, lalgoritmo deve prevedere di trattare dati reali. Per accedere ai dati di un record messo in un array basta conoscere lindice dellarray in cui il recor è contenuto.
SUGGERIMENTI Scegliere la struttura dei dati in funzione del tipo di dati da gestire. per una lista di oggetti omogenei (che hanno cioè lo stesso significato es. i voti di uno studente) si può scegliere un array monodimensionale. per una lista di oggetti omogenei ma caratterizzati da proprietà diverse si possono usare array multidimensionali (es. pezzi degli scacchi e coordinate X,Y sulla scacchiera).
per oggetti diversi tra loro ma legati da una struttura unica (es. dati anagrafici: nome, cognome, età,..) si possono usare array di record. Si ricordi lesempio in lezione 11: Si vuole costruire un array in cui ogni colonna rappresenta un piccolo paese, massimo mille abitanti, e per ogni paese vogliamo registrare il nome degli abitanti. Larray quindi è di tipo stringa per cui nelle caselle vuote ci sarà la stringa nulla. CONST MassimoAbitanti=1000; TYPE TipoStringa=STRING[50]; SubrangeAbitanti=1.. MassimoAbitanti; NomePaesi=(Nessuno, Acerra, Afragola, Capri, Casoria, Ischia, Procida); NomeArray: ARRAY[SubrangeAbitanti,NomePaesi] OF TipoStringa; VAR Abitanti: NomeArray;
AcerraAfragolaCapriIschiaProcida Esposito A. Bianchi G. Rossi A.Russo T. Annibale T.Cesare G. Tirchio F. Ricco S.Orofino T. Esca T. Argento T.Diamante A.Orazio P. Romeo A. Rendina A.
CittadiniPaesi1000Abitanti Città Anagrafe CognomeNome Struttura array di record del tipo
Indice:=3; WITH Corso DO BEGIN ………………… END SYNTAX ERROR Corso[Indice] IF Corso[Indice].Anagrafe=UnUomo.AnagrafeTHEN BEGIN ……………………. END SYNTAX ERROR Non è possibile fare un FOR sui campi di un record: FOR I:=Anagrafe TO Età DO …………………
WITH Corso[Indice].Anagrafe DO BEGIN ………………… END Si selezionano solo i campi Nome e Cognome WITH Corso[Indice],Anagrafe DO BEGIN ………………… END Si selezionano i campi Nome e Cognome e tutti I campi di Corso[I]
WITH Corso[Indice],Anagrafe DO FOR J:=1 TO Iscritti DO Writeln(Cognome, Nome) ERRORE !!!!!!!!!!! FOR J:=1 TO Iscritti DO WITH Corso[J],Anagrafe DO Writeln(Cognome, Nome)