Questa pagina descrive il progetto per il corso di Informatica della Laurea in Matematica per le sessioni dell'anno accademico 2016/2017.
Il progetto è costituito da due mini-esercizi.
Si consideri un
contatore
meccanico, come quello che misura l'acqua o il gas in casa, o i
chilometri percorsi in un'automobile. Questo è formato da
n
cilindri, ognuno dei quali rappresenta una cifra,
usualmente espressa in base b = 10
.
Nel normale utilizzo di un contatore, questo enumera tutte le possibili
b
n
combinazioni di cifre, partendo da
0,0,0,...
e arrivando a b-1,b-1,b-1,...
.
Nell'enumerazione, il numero rappresentato dalla sequenza di cifre
viene incrementato di una unità alla volta. Ogni incremento può modificare
l'intero contatore di un numero di cifre variabile a seconda
di quante cifre finali b-1
sono già presenti
(ovvero, di quanti riporti servono).
Vi si chiede di scrivere un programma Java che, dati b,n
enumeri tutte le possibili combinazioni di cifre, in un qualunque ordine
che rispetti quanto segue.
b
n
combinazioni,
tutte distinte)
0,0,0,...
.
Il numero di cifre è un naturale qualunque (quindi, maggiore o uguale
a zero). La base b
è un intero maggiore o uguale a 2 e
minore o uguale a 10.
Trovate qui sotto un possibile generatore di enumerazioni. Potete riprodurne il funzionamento precisamente, così come inventare un altro modo di enumerare le combinazioni.
Risultato: esegui il test
Il programma deve leggere da un file chiamato input1.txt
la base in cui eseguire il calcolo e il numero di cifre che deve avere
il risultato. Il file contiene questi due numeri su un'unica riga,
separati da uno spazio. Per esempio, per un contatore in base 10 e un
risultato a 3 cifre:
10 3
Il risultato deve essere scritto in un file output1.txt
.
Tutte le combinazioni del risultato vanno scritte su un’unica riga, la
prima, separate tra loro da uno spazio (non virgole, non punti, non
nessun altro simbolo di punteggiatura). Ogni combinazione è una
sequenza di cifre, senza nulla tra loro. Ogni combinazione deve avere
un numero di cifre uguale al numero dato in input alla seconda
posizione del file input1.txt
, anche se queste sono zeri
iniziali. Per esempio, considerando l’input dato sopra
(10 3
), l'inizio dell'output potrebbe essere:
000 001 002 003 004 005 006 007 008 009 019 …
Per un input base 5, con 2 cifre:
5 2
un possibile risultato che deve essere calcolato e salvato nel file
output1.txt
potrebbe essere:
00 01 02 03 04 14 13 12 11 10 20 21 22 23 24 34 33 32 31 30 40 41 42 43 44
In un sistema di gestione ordini di un certo esercizio commerciale,
gli ordini vengono memorizzati in un file
di testo (input21.txt
) secondo il modello seguente:
#IDOrdine IDUtente DataOrdine 98941 79559 1930-10-06 8406 2157 1906-07-24 81547 2157 1904-08-26 77166 87794 1900-10-02 90867 79559 1911-01-28 28914 2157 1945-09-24
Nella prima riga si trova un cancelletto #
seguito dai
nomi dei campi, separati da uno spazio. Nelle righe successive, si
trovano, separati da uno spazio: il numero di ordine (un intero), il
numero di utente che ha ordinato (un intero), e la data (in formato
AAAA-MM-GG). Ogni numero di ordine compare in una riga sola (mentre
ordini diversi possono avere stesso numero di utente e/o data).
La lista degli utenti viene invece memorizzata in un altro file di
testo (input22.txt
) secondo il modello seguente:
#IDUtente NomeUtente Nazione 2157 Adeline Colombia 87794 Scarlett TurksAndCaicosIslands 79559 Jackson Bulgaria
Nella prima riga si trova un cancelletto #
seguito dai
nomi dei campi, separati da uno spazio. Nelle righe successive, si
trovano, separati da uno spazio: il numero di utente (un intero), il
nome utente (una stringa, senza spazi all'interno), e la nazione (una
stringa, senza spazi all'interno). Ogni numero di utente compare in
una riga sola (mentre utenti diversi possono avere lo stesso nome e/o
nazione).
Si richiede di scrivere un programma Java che, dati due file di input
come sopra, produca un file di output (output2.txt
) che
elenchi, per ogni ordine, il nome dell'acquirente e la data
dell'ordine. Il formato del file di output deve seguire questo
modello:
#IDOrdine NomeUtente DataOrdine 8406 Adeline 1906-07-24 28914 Adeline 1945-09-24 81547 Adeline 1904-08-26 77166 Scarlett 1900-10-02 90867 Jackson 1911-01-28 98941 Jackson 1930-10-06
I campi sono gli stessi dei file di input, nello stesso formato.
Si chiede di scrivere un programma Java per ognuno dei due esercizi del progetto. Vi viene fornito un scheletro di progetto eclipse.
Lo scheletro è composto dai seguenti file e cartelle:
bin/
files/
src/main/java/Esercizio1.java
src/main/java/Esercizio2.java
È obbligatorio utilizzare lo scheletro associato al progetto. Questo
vuol dire che bisogna utilizzare le
classi Esercizio1.java
e Esercizio2.java
che
si trovano nello scheletro, modificandole in modo opportuno. È
consentito (e consigliabile) definire delle funzioni addizionali
all'interno di tali classi ed è ugualmente consentito (e
consigliabile) utilizzare della classi addizionali, quando il problema
si può risolvere più chiaramente usandole.
È importante che si utilizzi il main
delle classi dello
scheletro (Esercizio1.java
e Esercizio2.java
) come punto di esecuzione del
programma. L'esecuzione di tale metodo deve leggere i dati dal/dai
file di input (chiamati come detto sopra) e scrivere il risultato nel
file di output (chiamato come detto sopra). I file di input e output
si devono leggere/scrivere all'interno della cartella files
presente all'interno dello scheletro.
Durante la correzione, verranno eseguiti i metodi main
di
tali classi, eseguendo (anche) test automatizzati. Ogni programma
verrà eseguito più volte con input diversi che conterranno dati
diversi da quelli dati negli esempi sopra ma che seguiranno lo stesso
formato.
Il progetto verrà valutato secondo i seguenti criteri, che formano un insieme di requisiti sul codice consegnato. Ogni requisito primario è condizione necessaria per il superamento della prova: anche se uno di questi non viene rispettato, la prova non è superata. I requisiti secondari devono essere generalmente rispettati. Nel caso ci siano solo minori violazioni di tali requisiti, la prova è comunque superata. Violazioni gravi possono comunque causare il non superamento della prova.
Requisiti tecnici (primario). L'algoritmo deve essere implementato seguendo lo scheletro di progetto fornito sopra, modificato nel modo descritto sopra.
Devono inoltre essere rispettati questi requisiti:
Esercizio1.java
o Esercizio2.java
(package…
).main
ma invece usatelo
come punto di partenza per scrivere il vostro codice. Chiamate le
vostre funzioni ed istanziate i vostri oggetti (quando serve)
all'interno del main
.Esercizio1.java
o
Esercizio2.java
dalla cartella in cui si trovano
src/main/java
.files
e non altrove. Per farlo basta
utilizzare come nome file un percorso relativo
come "./files/input21.txt"
(questo funziona sotto
Windows, linux e MacOS). Non utilizzate percorsi assoluti
come "/home/zunino/progetto/files/input21.txt"
o
come "c:\Users\zunino\progetto\files\input21.txt"
.
Il non rispettare questi requisiti tecnici può causare il fallimento dei nostri test automatizzati, ed in tal caso la prova non sarà superata.
Correttezza (primario).
Non ci devono essere errori a tempo di compilazione: il programma deve
compilare. Non ci devono essere errori a tempo di esecuzione: il
programma non deve generare eccezioni (per
esempio, DivisionByZero
oppure ArrayIndexOutOfBounds
) quando eseguito su un input
valido. Il programma deve dare l'output desiderato su qualunque
input compatibile con la specifica.
Nota bene:
Nel caso il programma sia scorretto, non è compito di chi corregge
fare il debugging,
ovvero identificare la causa dell'errore e suggerire una modifica
per rimuoverla. Anche quando tale causa fosse nota a chi corregge,
non verrà comunicata allo studente, in quanto sarebbe come suggerire
una parte non banale della soluzione della prova. Infatti, capita
frequentemente che correggere l'errore dopo averlo
individuato diventi banale ("devo usare x
, e non
x+1
"), e che la prova di conseguenza consista prevalentemente
nella ricerca dell'errore.
Corollario:
se provando il programma su un insieme di input campione si riscontrano
già errori di correttezza, chi corregge non è tenuto ad esaminare
il codice del programma.
Leggibilità (secondario). Il codice deve essere scritto in modo tale da permettere ad un altro programmatore di comprenderne la logica. Non è sufficiente che il codice "funzioni", o che sia chiaro a chi lo ha scritto. Per aiutare la lettura del codice da parte di altri, si consiglia di usare dei nomi di variabili appropriati, strutturare il codice adeguatamente (dove ha senso, meglio dividere una funzione lunga in più funzioni ausiliarie), e di inserire dei commenti.
Non commentate come state calcolando qualcosa, commentate piuttosto cosa state calcolando. Per esempio, il seguente commento è altamente inutile:
// incremento i i++;
Al contrario, il seguente aiuta a comprendere il codice:
// passo a coordinate polari rho = Math.sqrt(x*x + y*y); theta = Math.atan(y/x);
Per potere partecipare allo scritto di una sessione di esame, il progetto deve essere consegnato entro le date indicate nell'elenco delle sessioni di esame. La consegna si svolge mandando una email avente esattamente le seguenti caratteristiche.
zunino_555555/src/main/java/Esercizio1.java
zunino_555555/src/main/java/Esercizio2.java
zunino_555555/src/main/java/RiemannZetaSolver.java
zunino_555555/src/main/java/GoldbachConjectureCounterexampleGenerator.java
zunino_555555/src/main/java/FastestFourierTransformInTheWest.java
zunino_555555/src/main/java/FluxCapacitorSimulator.java
zunino_555555/src/main/java/TardisKernel.java
zunino_555555/files/
zunino_555555/bin/
zunino_555555/README.txt
Se avete dubbi sul testo del progetto, ovvero su che cosa vi sta venendo chiesto, chiedete pure delucidazioni per email o a ricevimento. Se invece avete dubbi sulla soluzione dell'esercizio, ovviamente non possiamo suggerirvi nulla.
Il progetto non viene svolto in un ambiente "controllato" come per esempio avviene per un esame scritto, ma vi viene lasciata libertà di svolgerlo dove e quando preferite (compatibilmente con le scadenze). Per esempio, potete usare i laboratori quando liberi, o farlo su un vostro computer personale.
Il progetto è individuale, non di gruppo. Tuttavia, vi è consentito discutere del progetto con altre persone per scambiarsi opinioni a riguardo. Non è consentita, ovviamente, la copia di pezzi di codice inerenti al progetto da uno studente all'altro. Allo stesso modo, farsi fare il progetto da un'altra persona è considerato equivalente a copiare. In caso di dubbi sull'autenticità del progetto, ci riserviamo la possibilità di convocarvi per un colloquio sul codice che avete consegnato, anche dopo l'esame scritto.
Vi è consentito di "copiare" invece pezzi di codice che vi abbiamo fornito noi, o di "tradurre in Java" dei pezzi di codice che potreste trovare su qualche libro o tutorial online. In questo caso, però, dovete obbligatoriamente citare la fonte in un commento nel codice.
Il discutere del progetto su forum di discussione su Internet o simili non è vietato a prescindere, ma è soggetto alle stesse regole della comunicazione tra altri studenti. Inoltre, se iniziate una discussione su un forum riguardo al progetto, dovete obbligatoriamente dichiarare 1) che l'esercizio in questione è un progetto di esame, e 2) che non desiderate che qualcuno vi scriva una soluzione al posto vostro. Se anche chiarendo ciò qualcuno vi risponde includendo del codice, voi non potete includerlo nel progetto.
Se preferite, potete usare anche caratteristiche di Java non viste a lezione (costrutti, librerie, ...), anche se il progetto si può svolgere benissimo anche senza. Dovete però comprendere il codice che state usando: se venite chiamati ad un colloquio (vedi sopra) vi può essere chiesto di spiegarlo.
Potete aggiungere altre funzioni nelle classi Esercizio1
e
Esercizio2
dello scheletro.
Potete aggiungere altre classi nella stessa cartella di quelle esistenti.
Queste devono avere lo stesso package
per potere compilare.
Eclipse dovrebbe automaticamente mettervi il package
giusto.
Nell'esercizio 2, il campo data ha un formato di lunghezza fissa AAAA-MM-GG.
Gli altri campi (nomi, ID, ...) sono di lunghezza variabile. I campi interi
sono memorizzabili in un int
di Java.
La cartella dello scheletro ProgettoFinale
va rinominata in
nome_matricola
per la consegna. Nello zip consegnato, non va
inclusa una cartella di nome ProgettoFinale
.
Nell'esercizio 2, non si richiede nessun ordinamento particolare per le righe del file di output -- possono essere in una qualunque permutazione, a parte per la primissima riga (intestazione) che contine i nomi dei campi.
Informatica - Teaching - Home
Roberto Zunino, 2015