Successione di Fibonacci
Pseudo Codice
Assegna il numero della successione
Assegna Fn1, Fn, Fn2 per N=2
Calcola la successione
Stampa la Somma=Fn1*Fn2-sqr(Fn)
FOR I=3 TO N
Aggiorna Fn1, Fn, Fn2 al variare di N
Calcola la successione
Fn1
1
Fn
2
Fn2
3
Somma
-1
2
3
5
1
3
5
8
-1
PROGRAM FibonacciSucc(input,output);
VAR
Precedente,Attuale:real;
N:integer;
PROCEDURE Inizializza(VAR Xn1,Xn:real;VAR Nx:integer);
BEGIN
writeln(' Calcolo della successione Fn1*Fn2-sqr(Fn) per i primi N valori');
write('Dammi il numero N: ');
readln(Nx);
Xn1:=1;
Xn:=2
END;
PROCEDURE NuovoNumero(VAR Prec,Att:real);
VAR
Temp:real;
BEGIN
Temp:=Prec+Att;
{*************** MAIN ********************}
Prec:=Att;
BEGIN
Att:=Temp
Inizializza(Precedente,Attuale,N);
END;
CalcolaSuccessione(Precedente,Attuale,N);
readln
END.
PROCEDURE CalcolaSuccessione(Prec,Att:real;Nx:integer);
VAR Fn1,Fn,Fn2,Somma:real;Conta:integer;
BEGIN
Somma:=0;
Fn1:=Prec;
Fn:=Att;
NuovoNumero(Prec, Att);
Fn2:=Att;
Somma:=Fn1*Fn2-sqr(Fn);
writeln('Per N=', 2,' valore successione: ',Somma:3:0);
FOR Conta := 3 TO N DO
BEGIN
Prec:=Fn;
Att:=Fn2;
Fn1:=Fn;
Fn:=Fn2;
NuovoNumero(Prec, Att);
Fn2:=Att;
Somma:=Fn1*Fn2-sqr(Fn);
writeln;
writeln('Per N=', Conta,' valore successione: ',Somma:3:0);
END;
{*************** MAIN ********************}
END;
BEGIN
Inizializza(Precedente,Attuale,N);
CalcolaSuccessione(Precedente,Attuale,N);
readln
END.
FUNZIONI
Una funzione può avere diversi argomenti ma restituisce uno e un
solo valore.
Esistono funzioni standard del Pascal
Nome
Funzione
Tipo
Argomento
Tipo
Risultato
abs
Valore
assoluto
dell’argo
mento
Quadrato
dell’argo
mento
Radice
quadrata
dell’argo
mento
Numerico
Come
ValAss=abs(-3)  3
l’argomento
Numerico
Come
Quadr=sqr(5)  25
l’argomento
Numerico
Reale
sqr
sqrt
Esempio
RadQuad=sqrt(16) )  4
ESEMPIO
Ipotenusa:=sqrt(sqr(Lato1)+sqr(Lato2));
Carattere12:=succ(Carattere11);
Differenza tra funzione e procedura.
PROCEDURE NomeProcedura (VAR Inp1,….., Out1,….:real);
……………………………………………………….
FUNCTION NomeFunzione (Arg1, Arg2, ……): type;
…………………………………….
BEGIN
……………………..
Inp1:= 33;
………..
NomeProcedura(Inp1,………,Out1,..);
X:=Out1*2;
……………
Y:=VariabileK + NomeFunzione(X,Arg2,….)*4 - VariabileZ;
…………….
END.
Sintassi di FUNCTION
FUNCTION
identificatore
(
FUNCTION NomeFunzione (
TYPE
identificatore
Blocco
Lista parametri
formali
Arg1,…
)
:
):
;
real ; BEGIN ………………………END.
Le chiamate delle variabili sono quasi sempre fatte per valore.
Chiamata di FUNCTION
identificatore
(
NomeFunzione (
Lista parametri
attuali
Arg1,…
)
)
Suggerimento:
Scrivere le funzioni in modo tale che l’ultima istruzione
rappresenti sempre il valore che la funzione deve assumere.
ESEMPIO
FUNCTION AreaCoronaCircolare(RaggioMax,RaggioMin: real):real;
BEGIN
AreaCoronaCircolare:=PiGreco*sqr(RaggioMax)-PiGreco(RaggioMin)
END;
PROGRAM
……
write(‘Dammi RaggioMax e RaggioMin: ‘);
readln(R1, R2);
Area:= AreaCoronaCircolare(R1,R2);
writeln(‘L’’area della corona circolare è: ‘, Area:4:2);
……….
N.B.
In ogni funzione deve sempre esserci una istruzione del tipo:
identificatore  espressione
Esercizio per il laboratorio
Trasformare l’esercizio sull’area di diverse
figure geometriche in una funzione.
ESEMPIO FUNZIONE COMBINAZIONI
Calcolare il numero di combinazioni di N oggetti presi M alla volta.
N!
Combinazioni =
( N  M )! M !
FUNCTION Combinazioni(N,M :integer) : integer;
{descrizione}
BEGIN
Combinazioni:=Fattoriale(N) DIV (Fattoriale(N-M)*Fattoriale(M)
END.
Attenzione:
Non usare il nome della funzione nel corso della elaborazione ma usarlo
solo per raccogliere il risultato finale
FATTORIALE
FUNCTION Fattoriale(N:integer):real;
VAR
Conta: integer;
Prodotto: real;
BEGIN
Prodotto:=1;
FOR Conta:=1 TO N DO
Prodotto:=Prodotto*Conta;
Fattoriale:=Prodotto
END;
Variabile locale usata
per il processo di
accumulazione. E’ detta
variabile dummy.
Non può essere usata in
questa posizione perché
qui rappresenta una chiamata
alla funzione e quindi necessita
di un argomento.
ERRORE DI COMPILAZIONE
FOR Conta:=1 TO N DO
Fattoriale := Fattoriale *Conta;
ESEMPIO FUNZIONE POTENZA
Problema - Calcolare la potenza di un numero reale con esponente intero
Risolviamo il problema mediante una funzione
Potenza(Base,Esponente)
Traccia della soluzione
metti in Prodotto il valore della Base elevato al
valore assoluto dell’Esponente)
Pseudo codice
Accumula la Base nella variabile Prodotto, usa come esponente il valore assoluto
dell’esponente, così da poter calcolare anche le potenze negative
IF Esponente >=0 THEN
Potenza  Prodotto
ELSE
Potenza  1/Prodotto
FUNCTION Potenza(Base:real; Esponente:integer):real;
VAR
Conta: integer; {conta quante volte Prodotto è moltiplicato per Base}
Prodotto: real;
BEGIN
Prodotto:=1;
FOR Conta:=1 TO abs(Esponente) DO
Prodotto:=Prodotto*Base;
IF Esponente>=0 THEN
Potenza:=Prodotto
ELSE
Potenza:=1/Prodotto
END;
ESEMPIO FUNZIONE MAIUSCOLE
Problema - Se abbiamo un carattere minuscolo trasformarlo in maiuscolo
Risolviamo il problema mediante una funzione
Maiuscolo(Carattere)
Traccia della soluzione
metti in Maiuscolo il valore di Carattere solo se esso è un carattere
alfabetico ed è minuscolo usando le funzioni su stringhe chr e ord.
FUNCTION Maiuscolo(Carattere:char):char;
BEGIN
IF Carattere IN [‘a’..’z’] THEN
Maiuscolo:=chr(ord(Carattere) + ord(’A’) - ord(‘a’))
ELSE
Maiuscolo:=Carattere
END;
GENERAZIONE DI NUMERI CASUALI
Un numero casuale è un numero generato da un evento non prevedibile.
Ad esempio l’uscita di un lancio di dadi.
Con il calcolatore possiamo generare solo numeri pseudo-casuali.
Essi si ottengono mediante funzioni che sono attivate sulla base di
un numero detto seme.
In PASCAL esiste la funzione Random(X) che produce numeri
casuali tra 0 e X.
Vi sono diverse maniere per generare numeri pseudo-casuali.
Dalla Teoria dei Numeri si ha che a partire da un valore detto
seme è possibile ottenere K numeri casuali compresi fra 0 e K.
GENERAZIONE DI NUMERI CASUALI
FUNCTION NumeroCasuale(Seme:integer):integer;
CONST
Modulo=2187;
Moltiplicatore=10;
Incremento=10891;
BEGIN
NumeroCasuale:=(Moltiplicatore*Seme+ Incremento) MOD Modulo
END;
Dalla Teoria dei Numeri si dimostra che il codice che segue produce
2187 diversi valori per il seme prima che la sequenza si ripete:
readln(Seme);
Seme:=abs(Seme MOD Modulo);
FOR Contatore:=1 TO Modulo DO
Seme:=NumeroCasuale(Seme);
ESEMPIO USO DEL GENERATORE DI NUMERI CASUALI
Problema - Simulare il lancio di un dado
Risolviamo il problema mediante il nostro generatore di numeri casuali.
Poiché esso opera nell’intervallo 0..2186 dobbiamo dividere questo
intervallo in sei sottointervalli. Ad ognuno dei sei sottointervalli
assegniamo un valore tra 1 e 6.
0-363
364-727
728-1091
1092-1455
1456-1819
1820-2183
1
2
3
4
5
6
Pseudo codice
Fornisci un valore del seme minore di 2184
Lancio  Seme DIV 364 + 1
PROCEDURE FaiUnLancio(VAR Seme, Lancio:integer);
CONST
NumeroMassimo=2183;
IntervalloLancio=364;
BEGIN
REPEAT
Seme:=NumeroRandom(Seme);
UNTIL Seme <= NumeroMassimo;
Lancio:=Seme DIV IntervalloLancio+1
END;
PROGRAM LancioDado(input,output);
VAR
Seme,Lancio:integer;
FUNCTION NumeroCasuale(Seme:integer):integer;
CONST
Modulo=2187;
Moltiplicatore=10;
Incremento=10891;
BEGIN
NumeroCasuale:=(Moltiplicatore*Seme+ Incremento) MOD Modulo
END;
PROCEDURE FaiUnLancio(VAR Seme, Lancio:integer);
CONST
NumeroMassimo=2183;
IntervalloLancio=364;
BEGIN
REPEAT
Seme:= NumeroCasuale(Seme);
UNTIL Seme <= NumeroMassimo;
Lancio:=Seme DIV IntervalloLancio+1
END;
{****
MAIN *****}
BEGIN
Write('Seme = ');
readln(Seme);
Seme:=abs(Seme) MOD 2187;
FOR Nprova:=1 TO 120 DO
BEGIN
FaiUnLancio(Seme,Lancio);
write(Lancio:2);
IF Nprova MOD 20=0 THEN
Writeln
END;
END.
ESERCIZIO E12
Gioco della Tombola
Simulare il gioco della tombola utilizzando una
funzione random.
Evitare che un numero venga estratto più di una
volta.
VARIABILI BOOLEANE
Una variabile booleana può assumere solo due valori
TRUE e FALSE
Esempio di dichiarazione:
VAR
Numero, Contatore: integer;
Alto, Basso, Bianco, Nero, NonColorato : boolean;
E’ possibile assegnare un valore ad una variabile booleana:
Nero:=FALSE
Se alla variabile Numero è stato assegnato un valore allora
potremo dire che la variabile Alto è vera solo se il valore di
numero è maggiore ad esempio di 2:
Alto:= Numero>2;
Se ad esempio Numero vale 5 allora Alto è TRUE.
VARIABILI BOOLEANE
Alle variabili booleane possono essere applicati gli operatori
booleani AND, OR, NOT.
Ad esempio variabili booleane e operatori possono essere usate
per il controllo decisionale o dei cicli.
IF Alto OR Basso THEN
Contatore:=Contatore+1;
WHILE Alto OR Basso DO
BEGIN
……………
END;
VARIABILI BOOLEANE
Una variabile booleana può anche essere istanziata con una istruzione
del tipo:
Bianco:= Alto OR Basso;
Nero:= Alto AND Basso;
Di solito le variabili booleane si usano come flag, cioè per memorizzare
un evento e poi controllare uno o più istruzioni decisionali o di ciclo.
VARIABILI BOOLEANE
Esempio: Supponiamo di voler ordinare in maniera crescente due
numeri interi Int1 e Int2.
PROCEDURE SortDue(VAR Int1,Int2:integer; OrdineErrato: boolean);
{Scambia i valori di Int1 e Int2 se OrdineErrato è vero}
BEGIN
If OrdineErrato THEN
Scambia(Int1,Int2)
END;
La chiamata alla procedura è la seguente:
SortDue(Int1, Int2, (Int1>Int2))
VARIABILI BOOLEANE
E’ possibile usare variabili booleane per controllare cicli e condizioni
di uscita da cicli.
Le variabili adoperate a questo scopo prendono il nome di Flag.
{Cicla e decidi usando una variabile Flag}
Flag  False;
WHILE NOT Flag AND NOT (una qualunque condizione di uscita) DO
esegui l’elaborazione prevista, nell’ambito della quale il Flag potrebbe
cambiare valore
IF Flag THEN
esegui altra elaborazione
{fine dell’algoritmo}
VARIABILI BOOLEANE
Problema
Supponiamo di voler calcolare la media dei voti che ogni studente
presenta sul suo libretto. Per essere sicuri di non commettere errori
grossolani dobbiamo evitare che nella lista dei voti non esistano
valori inferiori a 18 o superiori a 30. Se ciò accade interrompiamo
la lettura dei dati e non calcoliamo la media. Supponiamo infine che
il numero di esami superati sia N.
VARIABILI BOOLEANE
Pseudo-codice
Somma  0
Contatore  0
VotoErrato  false
WHILE NOT VotoErrato AND NOT (Contatore=N) DO
read(Voto)
IF (Voto<18) OR (Voto>30) THEN
VotoErrato  true
ELSE
Somma  Somma + Voto
Contatore  Contatore + 1
IF VotoErrato THEN
Media  0
ELSE
Media  Somma/Contatore
FUNZIONI BOOLEANE
L’uso delle funzioni booleane serve a realizzare meglio controlli
che potrebbero essere altrimenti molto complessi da implementare.
ESEMPIO
Controlla che tre Numeri siano in ordine crescente.
FUNCTION Ordinati(X1, X2, X3: real): boolean;
{è vera se X1<=X2<=X3}
BEGIN
Ordinati:=(X1<=X2) AND (X2<=X3)
END;
chiamata
IF NOT Ordinati(X1,X2,X3) THEN
Ordinare(X1,X2,X3);
ESEMPIO
Controlla che dati tre numeri essi costituiscano i lati di un triangolo.
FUNCTION NonTriangolo(Lato1, Lato2, Lato3: real): boolean;
{è vera se i tre lati non formano un triangolo}
BEGIN
NonTriangolo := (Lato1 > Lato2+Lato3) OR
(Lato2 > Lato1 +Lato3) OR
(Lato3 > Lato2 + Lato1)
END;
chiamata
readln(Lato1, Lato2, Lato3);
WHILE NonTriangolo (Lato1, Lato2, Lato3) DO
readln(Lato1, Lato2, Lato3);
FUNZIONI BOOLEANE
Problema:
Dato un Array di numeri interi realizzare una funzione che controlli che
questi numeri siano ordinati in maniera crescente.
Pseudo-codice
Chiamiamo con ArrayOrdinato la funzione, con ArrayC l’array da
controllare, con ElementiTotali il numero di elementi contenuti
nell’array.
Ordinato  true
WHILE sono richiesti altri confronti AND Ordinato DO
fai un altro confronto per cercare di rendere Ordinato FALSE
ArrayOrdinato  Ordinato
FUNCTION ArrayOrdinato(VAR ArrayC: IntsArray;
ElementiTotali: integer): boolean;
{è vera se l’ArrayC è ordinato }
VAR
Indice: integer;
Ordinato:boolean;
BEGIN
Indice:=1;
Ordinato:=TRUE;
WHILE (Indice <> ElementiTotali) AND Ordinato DO
IF ArrayC[Indice]> ArrayC[Indice+1] THEN
Ordinato:=FALSE;
ELSE
Indice:=Indice+1;
ArrayOrdinato:=Ordinato
END;
FUNCTION ArrayOrdinato(VAR ArrayC: IntsArray;
ElementiTotali: integer): boolean;
{è vera se l’ArrayC è ordinato }
VAR
Indice: integer;
BEGIN
ArrayOrdinato :=TRUE;
FOR Indice :=1 TO ElementiTotali DO
IF ArrayC[Indice]> ArrayC[Indice+1] THEN
ArrayOrdinato:=FALSE;
END;
Codice corretto ma da non usare perché con
FOR si fanno più confronti in media e perché
il valore della funzione cambia continuamente.
TIPI ENUMERATIVI
I tipi standard previsti dal Pascal non coprono tutte le possibili esigenze di un
programmatore.
Ad esempio una variabile potrebbe voler assumere solo un valore nell’ambito di una
lista finita.
Es. colore (blu, giallo, verde, rosso).
Si definisce Tipo Enumerativo (Enumerated Type) un insieme ordinato di valori
necessari al programmatore.
TYPE
TipoColore = (NessunColore, Rosso, Grigio, Blu)
VAR
Colore : TipoColore
Colore:=Rosso;
Colore:=succ(Colore);
Colore:=‘Blu’;
{Grigio}
SINTAX ERROR!
Perché il type di Colore non è
una stringa
TIPI ENUMERATIVI
Se si deve assegnare un valore ad una variabile il cui tipo è enumerativo
bisogna usare solo i valori della lista del tipo mai una stringa.
Le funzioni Pascal ord, pred e succ sono applicabili ai tipi enumerativi.
Esempio
FOR Colore:=Rosso TO Blu DO
write(ord(Colore):5);
writeln:
1
2
3
Se le funzioni pred e succ vengono applicate rispettivamente al
primo o all’ultimo elemento della lista dei tipi si ha un ERRORE.
TIPI ENUMERATIVI
Poiché non tutti i dialetti Pascal permettono istruzioni del tipo
writeln(Colore) dove colore è di tipo enumerativo allora è necesssario
scrivere una procedura del tipo:
PROCEDURE MostraColore(Colore: TipoColore);
{in: Colore -- Valore del TipoColore che si vuole avere a video
out: la stringa corrispondente a Colore viene mostrata}
BEGIN
CASE Colore OF
Rosso: write(‘rosso’);
Grigio: write(‘grigio’);
Blu: write(‘blu’);
END
END;
N.B. Un enumerated type è un ordinal type, cioè un tipo per il quale è
noto il successore e il predecessore di ogni valore escluso il primo e
l’ultimo.
TIPI ENUMERATIVI
Esempio
Leggere un carattere e mostrare il colore corrispondente.
PROCEDURE LeggiColore(VAR Colore: TipoColore);
{restituisce un valore per Colore in funzione di un carattere letto}
VAR
TYPE
Ch:char;
TipoColore = (NessunColore, Rosso, Grigio, Blu)
BEGIN
VAR
readln(Ch);
Colore : TipoColore
Ch:=Maiuscolo(Ch);
IF Ch IN [‘R’, ‘G’, ‘B’] THEN
CASE Ch OF
‘R’: Colore:=Rosso;
‘G’: Colore:= Grigio;
E’ sempre opportuno mettere nei tipi
‘B’: Colore:= Blu;
enumerativi un valore “nullo” per
END
poter gestire le condizioni di errore.
ELSE
Colore:=NessunColore
END;
TIPI ENUMERATIVI
Altri Esempi
Funzione per controllare che il Colore appartenga ai tipi previsti
FUNCTION ColoreValido(Colore: TipoColore): boolean;
{restituisce vero se Colore<>NessunColore}
BEGIN
ColoreValido:=Colore<>NessunColore
END;
Mostriamo un frammento di programma che usa le procedure e
funzioni sopra definite
REPEAT
write(‘Introduci un colore (Rosso, Grigio, Blu): ‘;
LeggiColore(Colore);
UNTIL ColoreValido(Colore);
ESEMPIO
TIPI ENUMERATIVI
Problema: si vogliono mostrare i giorni di un mese, settimana per
settimana, conoscendo con quale giorno della settimana inizia il mese.
Esempio di input output:
Dammi il numero di giorni del mese: 30
Dammi il primo giorno del mese: Martedì
DOM LUN MAR
1
6
7
8
13
14
15
20
21
22
27
28
29
MER
2
9
16
23
30
GIO
3
10
17
24
VEN
4
11
18
25
SAT
5
12
19
26
ESEMPIO
TIPI ENUMERATIVI
Pseudo-codice
PrendiDati
MostraIntestazione
MostraMese
FINE
PROGRAM CalendarioMensile(input;output);
CONST
Spazi=8;
TYPE
TipoGiorno= (Niente, DOM, LUN, MAR, MER, GIO, VEN, SAB);
VAR
GiorniTotali: integer;
GiornoIniziale:TipoGiorno;
RAPPRESENTAZIONE GRAFICA
RAPPRESENTAZIONE GRAFICA
GiorniTotali
GiornoIniziale
GiorniTotali
GiornoIniziale
PrendiDati
MostraIntestazione
GiornoIniziale
GiornoValido
MostraMese
Oggi
GiornoIniziale
LeggiGiornoIniziale
Carattere
Maiuscolo
Domani
Domani
ESEMPIO
TIPI ENUMERATIVI
PrendiDati
REPEAT
readln(GiorniTotali)
UNTIL GiorniTotali IN [28..31]
REPEAT
prompt
LeggiGiornoIniziale(GiornoIniziale)
UNTIL GiornoValido(GiornoIniziale)
Si vuole introdurre il giorno della settimana usando solo i primi
due caratteri del nome del giorno come abbreviazione.
Es. ME sta per Mercoledì; VE sta per Venerdì
MostraIntestazione
PROCEDURE MostraIntestazione;
{mostra l'intestazione del mese}
BEGIN
writeln(' DOM ':Spazi, ' LUN ':Spazi, ' MAR ':Spazi, ' MER
':Spazi, ' GIO ':Spazi, ' VEN ':Spazi, ' SAB ':Spazi);
writeln
END;
ESEMPIO
TIPI ENUMERATIVI
MostraMese
write 1
usa il valore Oggi per determinare il giorno di partenza
FOR Data  2 TO GiorniTotali
Oggi  Domani(Oggi)
write(Data)
IF Oggi = SAB THEN
writeln;
writeln
PROCEDURE PrendiDati(VAR GiorniTotali: integer; VAR
GiornoIniziale: TipoGiorno);
{legge i giorni totali del mese e il primo giorno}
BEGIN
REPEAT
write(' Di quanti giorni e'' composto il mese? ');
readln(GiorniTotali)
UNTIL GiorniTotali IN [28..31];
REPEAT
write(' Primo giorno del mese: ');
LeggiGiornoIniziale(GiornoIniziale)
UNTIL GiornoValido(GiornoIniziale)
END;
PROCEDURE MostraMese(GiorniTotali: integer; Oggi: TipoGiorno);
{................................}
VAR
Data: integer;
BEGIN
write (1 : ord(Oggi)*Spazi);
IF Oggi=Sab THEN
Writeln;
FOR Data:=2 TO GiorniTotali DO
BEGIN
Oggi:=Domani(Oggi);
Write(Data:Spazi);
IF Oggi=Sab THEN
Writeln
END;
END;
FUNCTION Domani(Giorno: TipoGiorno);
{ritorna il giorno successivo a quello di input}
BEGIN
IF Giorno<> SAB THEN
Domani:=succ(Giorno)
ELSE
Domani:=DOM
END;
PROCEDURE LeggiGiornoIniziale(VAR Giorno: TipoGiorno);
VAR
Carat1, Carat2: char; {primo e secondo carattere letto}
BEGIN
readln(Carat1,Carat2);
maiuscolo(Carat1);
maiuscolo(Carat2);
IF (Carat1='D') AND (Carat2='O') THEN
Giorno:=Dom
ELSE IF (Carat1='L') AND (Carat2='U')
Giorno:=Lun
ELSE IF (Carat1='M') AND (Carat2='A')
Giorno:=Mar
ELSE IF (Carat1='M') AND (Carat2='E')
Giorno:=Mer
ELSE IF (Carat1='G') AND (Carat2='I')
Giorno:=Gio
ELSE IF (Carat1='V') AND (Carat2='E')
Giorno:=Ven
ELSE IF (Carat1='S') AND (Carat2='A')
Giorno:=Sab
END;
THEN
THEN
THEN
THEN
THEN
THEN
FUNCTION GiornoValido(Giorno: TipoGiorno);
{ritorna vero se il giorno è <> Niente}
BEGIN
GiornoValido:=Giorno<>Niente
END;
SUGGERIMENTI E CONSIGLI
• Non usare nelle FUNCTION la chiamata per VAR perché può
generare side effects pericolosi.
• Se si deve usare una chiamata per VAR allora scrivere un
PROCEDURE invece di una FUNCTION
•Usare i Flag con criterio
read(Numero);
Finito:=Numero<=0;
WHILE NOT Finito DO
BEGIN
read(Numero)
Finito:=Numero<=0
END;
PESSIMO STILE
read(Numero);
WHILE Numero>0 DO
BEGIN
read(Numero)
END;
Quando si usa un FLAG per controllare un evento che capita all’interno
di un ciclo assicurarsi di aver posto il FLAG fuori del ciclo uguale al
valore complementare a quello interno al ciclo.
In alcuni calcolatori se una variabile booleana non è aggiornata per
default assume il valore FALSE.
Usare sempre una istruzione IF per controllare con un FLAG eventi
che capitano all’interno di un ciclo.
FUNCTION ArrayOrdinato(VAR ArrayC: IntsArray;
ElementiTotali: integer): boolean;
{è vera se l’ArrayC è ordinato }
VAR
Indice: integer;
BEGIN
ArrayOrdinato :=TRUE;
FOR Indice :=1 TO ElementiTotali-1 DO
ArrayOrdinato:= ArrayC[Indice]> ArrayC[Indice+1]
END;
Essendoci il FOR la funzione potrebbe diventare prima
false e poi true.
DOMANDA
Il codice che segue è corretto?
FUNCTION NonValido(VAR AnArrayC: IntsArray; Basso,Alto:integer;
ElementiAssegnati : integer): boolean;
{è vera se almeno uno degli elementi in AnArray è minore di Basso o maggiore di Alto }
VAR
Indice: integer;
BEGIN
NonValido :=FALSE;
FOR Indice :=1 TO ElementiTotali DO
IF ( AnArray[Indice] < Basso) OR AnArray[Indice] > Alto) THEN
NonValido :=TRUE
END;
{è vera se nessuno degli elementi in AnArray è minore di Basso o maggiore di Alto }
Esercizi
pag. 357 n. 20, 21, 25
Gestione vendite in euro
Progetto a.a. 2001-2002
( Modulo A ).
Un file di testo ARTICOLI.DAT contiene dei prodotti da vendere (max 10) con le seguenti caratteristiche:
ogni riga rappresenta un articolo; i primi caratteri rappresentano la descrizione ( fino al simbolo ^),
i due successivi l’unità di misura (PZ per pezzo, KG per chilogrammo),
gli ultimi due numeri rappresentano rispettivamente il costo in lire e la percentuale d’iva.
Esempio:
bicchiere di plastica^PZ 8 20
piatto di plastica^PZ 24 20
arance ^KG 2500 4
patate ^KG 3000 4
Si vuole implementare un programma che mostri a video il corpo di una fattura riportando i dati sia in lire che in
euro secondo le seguenti modalità:

Il sistema stampa ogni prodotto presente nel file, chiedendo all’utente la quantità desiderata.

In seguito viene stampato il corpo di una fattura: la descrizione, la quantità, il prezzo unitario in lire ed
in euro, il totale in lire ed in euro, e la percentuale iva presente nell'articolo.

Totale in lire = Quantità per prezzo unitario in lire

Totale in euro = Quantità per prezzo unitario in euro

L’ultima riga conterrà il totale della spesa senza iva (detto Totale Imponibile), il Totale dell’imposta Iva
e il Totale della fattura.

Totale Imponibile in euro= Somma di tutti i totali in euro

Totale Imposta in euro= Somma di tutti le imposte in euro

Totale generale in euro= Somma dei due totali precedenti
•Nel passaggio da lire ad euro tenere presente la seguente circolare ministeriale ( 1 euro=1936,27 lire ).
Circolare del 23/12/1998 n. 291 - Emanato da Ministero delle Finanze
…………………………..
In presenza delle condizioni sopra evidenziate l'articolo in rassegna
impone di utilizzare l'importo convertito in euro con almeno:
- cinque cifre decimali per gli importi originariamente espressi in unita' di lire (da 1 a 9 lire);
- quattro cifre decimali per gli importi originariamente espressi in decine di lire (da 10 a 99 lire);
- tre cifre decimali per gli importi originariamente espressi in centinaia di lire (da 100 a 999 lire);
- due cifre decimali per gli importi originariamente espressi in migliaia di lire (da 1.000 lire in poi).
Si simuli ancora il pagamento della fattura mediante contanti presso una cassa.
Al momento del pagamento il cliente può pagare a fronte del totale fattura con le seguenti modalità:
·
Totale esatto in euro (aggiornare solo i tagli in cassa)
·
Cifra superiore in euro (calcolare il resto e aggiornare i tagli in cassa)
·
Totale esatto in lire (aggiornare una cassa in lire solo per totali e non per tagli)
·
Cifra superiore in lire (calcolare il resto in euro e aggiornare i tagli in cassa euro e il totale cassa lire)
Prevedere i casi di mancanza di resto per mancanza dei tagli giusti invitando il cliente a cambiare lui o a
comprare altri prodotti.
A fine giornata (dopo ad esempio 5 clienti) fare il bilancio di cassa mostrando:
Valore di partenza
N° Pezzi
Tagli in Euro
Totale acquisti
10
200
Valore finale (Questo valore deve essere esposto anche per tagli)
10
100
La cassa ogni giorno è dotata delle seguenti quantità di tagli in euro:
10
50
50
100
200
200
200
50
10
5
1
0.5
0.1
0.05
Esempio di esecuzione.
Apertura Cassa:
N° Pezzi
Tagli in Euro
I prodotti in vendita oggi sono:
bicchiere di plastica^PZ 8 20
piatto di plastica^PZ 24 20
arance ^KG 2500 4
patate ^KG 3000 4
Acquisti Cliente N.1
bicchiere di plastica PZ: quantità=500
piatto di plastica PZ: quantità=200
arance 100 KG: quantità=0
arance 120 KG: quantità=10
FATTURA N.1
Descrizione
Quantità Prezzo U L Prezzo U E
bicchiere di plastica
500
8
0,00413
piatto di plastica
200
24
0,0124
arance 120
10
3000
1,55
Totale Imponibile=20,05 €
Imposta Iva=1,53 €
Totale L Totale E IVA %
4000
2,07
20
4800
2,48
20
30000
15,50
4
N° Pezzi
10
10
10
50
50
100
200
200
200
200
50
50
10
10
Totale Fattura=21,58 €
Acquisti Cliente N.2
………………………..
FATTURA N.2
Descrizione
Quantità Prezzo U L Prezzo U E
Totale L Totale E IVA %
…………………………………………………………………………………………………………..
Totale Imponibile=….. €
Imposta Iva=….. €
Totale Fattura=….. €
…………………………………………………………………………………………………………..
Tagli in Euro
200
100
50
20
10
5
2
1
0.5
0.2
0.1
0.05
0.02
0.01
Chiusura Cassa:
Totale apertura Cassa= xxxxxxxxx
Situazione Cassa
N° Pezzi
…...
…...
…...
…...
…...
…...
…...
…...
…...
Tagli in Euro
200
100
50
10
5
1
0.5
0.1
0.05
Totale Lire in cassa= wwwwww
Totale fatturato= yyyyyyyyy
Totale chiusura cassa= zzzzzz
Scarica

END - Virgilio