Laboratorio V: 4-Nov-2005

Parte I Correzione degli errori sintattici e semantici segnalati dal compilatore
How to
Dopo aver scritto il codice di un metodo, si compili per verificarne la correttezza  ed eventualmete correggerlo.
La compilazione genera, tipicamente, molti errori anche nel codice di programmatori esperti, quindi non bisogna scoraggiarsi.

Come correggere?

1/ Leggere attentamente il primo messaggio d'errore del compilatore. Spesso e' difficile da interpretare perche' puo' riferirsi a errori commessi molte righe prima della riga in cui e' segnalato (ad esempio nel caso di parentesi graffe mancanti o accoppiate non correttamente, o di caratteri ';' mancanti alla fine di un enunciato).

2/ Correggere solo il primo errore, salvare il file sorgente e ricompilare. Non correggere piu' di un errore alla volta, perche' spesso un errore genera piu' di un messaggio di errore e la correzione di un errore fa scomparire parecchi messaggi d'errore (purtroppo non sempre e' cosi'!).

3/ Attenzione a dove memorizzate il file sorgente! Accade spesso di memorizzare il file modificato in una directory diversa da quella in cui poi si compila. Il risultato e' che si continua a modificare il file sorgente, ma gli errori rimangono sempre uguali. La ragione e' che non viene compilato il file modificato, ma un file diverso.

Parte II Linguaggio Java: cicli annidati e stringhe
Soluzioni possibili
massima comune sottostringa di due stringhe
Si scriva una classe eseguibile MaxSottostringa che individui la sottostringa comune di lunghezza massima fra due stringhe.
Esempio: se le stringhe sono "PlutoPippoPaperino" e "FlautoPifferoClarino"
utoPi è la stringa comune di lunghezza massima (anche rino è una sottostringa comune, ma ha solo quattro caratteri, mentre utoPi ne ha cinque).

Inserire nelle classi un contatore per contare quante iterazioni vengono effettuate per ottenere il risultato. Provare le tre soluzioni proposte e dire quale  soluzione e' piu' efficiente (cioe' ottiene il risultato con il minor numero di iterazioni).

Si provi la classe con le stringhe "TopolinoPlutoPippo" e "FlautoPifferoViolino".
Le soluzioni MaxSottostringa2 e MaxSottostringa3 forniscono una sola soluzione.
Capire come funzionano e modificarle in modo che gestiscano correttamente il caso di più sottostringhe di uguale lunghezza.
MaxSottostringa1.java
MaxSottostringa2.java
MaxSottostringa3.java

Parte III Linguaggio Java: semplici metodi ricorsivi
Una soluzione possibile
Inversione di una stringa
Si scriva la classe eseguibile RecursiveStringReverser capace di invertire una stringa in modo ricorsivo. La stringa sia passata come argomento nella riga di comando e il risultato dell'inversione visualizzato a standard output (o mediante la classe JOptionPane se volete eseguire il programma in BlueJ.). Esempio: l'inverso della stringa "Roma" e' la stringa "amoR".
Esempio di uso:
$java RecursiveStringReverser string
RecursiveStringReverser.java
Insieme delle sottostrunghe
Si scriva la classe eseguibile RecursiveSubstringGenerator capace di generare tutte le sottostringhe di una stringa. La stringa sia passata come argomento nella riga di comando e l'insieme delle sottostringhe visualizzato a standard output.
L'insieme delle sottostringhe della stringa "abc" e'  il seguente: {a, ab, abc, b, bc, c}.
Esempio di uso:
$java RecursiveSubstringGenerator string

Suggerimento: costruire l'insieme delle sottostringhe come unione:
- dell'insieme delle sottostringhe che contengono il primo carattere (n sottostringhe, se n e' il numero di caratteri della stringa). Esempio: se la stringa e' "Roma", gli elementi di questo sottoinsieme sono: "R" "Ro" "Rom" "Roma" (esattamente quattro come i caratteri della stringa)
- dell'insieme delle sottostringhe che non contengono il primo carattere. Sono le sottostringhe della stringa privata del primo carattere. Esempio: se la stringa e' "Roma", sono le sottostringhe della stringa "oma".
RecursiveSubstringGenerator.java

Parte IV
Consultare la documentazione di Java
Collegamenti
javaDoc
Nella documentazione di java in linea presso l'aula Taliercio consultare la documentazione relativa ai seguenti componenti della libreria standard:
- classe java.io.inputStream: che funzioni svolgono i metodi
   int read(byte[] b), long skip(long n)
- classe  java.util.Random: a che cosa serve e che metodi ha?
- classe java.awt.Graphics: che cosa fanno gli oggetti della classe? che cosa fa e che parametri ha il metodo void drawRect()?
- classe  java.io.DataInputStream:: a che cosa serve e che metodi ha? Che funzione svolgono i metodi readInt(), readDouble(), read(byte[] b) ?

Saper consultare rapidamente la documentazione java in linea nel sito dell'Aula Didattica Taliercio e' molto importante. Infatti in sede di prova pratica di esame, questa sarà la sola documentazione disponibile.
http://www.adt.unipd.it/guide/jdk1.4.1/docs/api/index.html

Parte V Linguaggio Java: array, gestione delle eccezioni, lettura e scrittura da file, argomenti sulla riga di comando
Una soluzione possibile
Archivio Studenti
Si scriva la classe ArchivioStudenti che realizza un archivio per la memorizzazione di dati relativi a studenti universitari. I dati memorizzati per ciascun studente siano: numero di matricola, nome, elenco di esami sostenuti con votazione conseguita.
Esempio di stampa dei dati di uno studente:
matr. 12345, nome: Marco Rossi
n. 2 esami sostenuti
1) Matematica A: 27
2) Fondamenti Informatica 1: 27
ArchivioStudenti.html fornisce l'interfaccia pubblica della classe.

Si scriva, poi, la classe di prova ProvaArchivioStudenti la quale:

1/ istanzi un archivio leggendo i dati da memorizzare nell'archivio da un file, detto file di input. .Il nome del file di input sia passato come argomento nella riga di comado. Nel file sia descritto uno studente per riga, con i vari campi separati dal carattere '/',  con il seguente formato:
numero matricola / nome / nomeEsame1 votoEsame1 / nomeEsame2  votoEsame2 /  ...
Nel caso la riga sia vuota non si elabori la riga. Nel casio  il  primo carattere della riga sia pari a '*', la riga sia interpretata come una riga di commento e non come una riga di dati.
Il file studenti.txt e' un esempio di file di input contenente dati relativi ad alcuni studenti.

2/ scriva in un file di output i dati relativi all'archivio. Il nome del file di output sia passato come argomento nella riga di comado.

3/ istanzi un nuovo archivio  e inserisca nell'archivio solo i dati degli studenti la cui media sia superiore a 27.
suggerimento.

L'invocazione della classe di prova sara', quindi:
$ java ProvaArchivioStudenti inputFile outputFile
dove:
inputFile: nome del file di input che contiene i dati degli studenti
outputFile: nome del file di output in cui il programma scrive

STRUTTURE DATI

I dati gestiti nella classe ArchivioStudenti si riferiscono ad un insieme di studenti. Sara', quindi, opportuno definire un oggetto che memorizzi i dati relativi a un singolo studente. Questi sono nella nostra applicazione:  numero di matricola, nome, lista di esami sostenuti.
Si proceda, quindi, a definire, la classe Studente, che sara' usata nella classe ArchivioStudenti. Se non riuscite da soli, consultate la parte pubblica della classe, descritta nell' interfaccia  Studente.html.

La classe Studente deve memorizzare una lista di esami sostenuti. Sara', quindi, opportuno definire un oggetto che memorizzi i dati relativi a un singolo esame. Questi sono: denominazione e votazione conseguita.
Si proceda, quindi, a definire, la classe Esame. Se non riuscite da soli, consultate la parte pubblica della classe, descritta nell' interfaccia  Esame.html.

Si usi nella classe ArchivioStudenti la tecnica degli array riempiti solo in parte con ridimensionamento dinamico.

GESTIONE DELLE ECCEZIONI

1/ Classe ArchivioStudenti
- il costruttore public ArchivioStudenti(String filename) lanci le due eccezioni a gestione obbligatoria: java.io.FileNotFoundException e  java.io.IOException.
- il metodo rimuovi() lanci l'eccezione java.util.NoSuchElementException nel caso l' archivio sia vuoto

2/ Classe ProvaArchivioStudenti
- Il metodo main() lanci l'eccezione a gestione obbligatoria java.io.IOException.

- L'eccezione java.io.FileNotFoundException sia, invece, gestita nel seguente modo:
2.1 - si invi a standard input un messaggio all'operatore per avvisarlo di inserire un nome di file da standard input:
messaggio: " file filename non trovato"
2.2 - si acquisisca il nuovo nome di file; in caso di nuova occorrenza dell'eccezione  FileNotFoundException,si  invii a standard input un messaggio all'operatore per avvisarlodi inserire di nuovo  un nome di file da standard input: messaggio: "di nuovo! file filename non trovato"
- acquisisca il nuovo nome di file; in caso di nuova occorrenza dell'eccezione  FileNotFoundException, si invii a standard input un messaggio all'operatore: messaggio: "non ci siamo!"; si termini successivamente il programma.

STRUTTURA DEI FILE
Si possono usare due alternative:

- usare un file per ciascuna classe. Nei file le classi sono definite pubbliche (come nelle soluzioni fornite). Si definiscono, quindi, quattro file: Esame.java, Studente.java, ArchivioStudenti.java, ProvaArchivioStudenti.java.

- definire le classi Studente ed Esame nel file ArchivioStudenti.java. In questo caso, la classe ArchivioStudenti viene definita pubblica, mentre le classi Studente ed Esame sono definite senza specificatore di accesso. In un file si puo', infatti,  definire una sola classe pubblica!

OSSERVAZIONE
Notare che il costruttore public ArchivioStudento(String filename) gestisce internamente la lettura da file!
Esame.java
Studente.java
ArchivioStudenti.java
ProvaArchivioStudenti.java