Appelli
di Giugno,
Luglio e Settembre 2004 |
MP3 |
|
Laurea
Triennale in Comunicazione Digitale Laboratorio
di Informatica Generale |
1 Descrizione
Il progetto
consiste nel realizzare un programma per gestire la catalogazione di una serie
di file MP3 e conseguentemente la ricerca allinterno del catagolo costruito.
Per chi non lo sapesse, lMP3 è un formato di file audio. Oltre che dallalta
qualità di riproduzione dei brani memorizzati in questo formato e dallelevato
indice di compressione, il formato MP3 è anche caratterizzato dalla possibilità
di inserire allinterno del brano informazioni relative al brano stesso.
Proprio queste informazioni aggiuntive saranno loggetto del progetto.
Nel
nostro caso le informazioni che considereremo caratterizzanti per un brano sono
esclusivamente: titolo, artista, titolo dellalbum da cui è tratto il brano,
numero di tracce allinterno dellalbum, anno di uscita dellalbum e genere del
brano.
Pertanto
a partire da un insieme di file MP3 il programma dovrà essere in grado di
costruire un catalogo contenente le informazioni caratterizzanti i brani a
disposizione.
2 Struttura del Catalogo
Il
catalogo degli MP3 gode delle seguenti proprietà:
deve essere permanente, cioè quando si esce
dal programma il catalogo non viene perso,
deve essere ordinabile, su richiesta, per
artisti, album, numero di traccia e titolo del brano;
Su
disco ogni singola riga del catalogo si riferisce ad un brano mp3 e conterrà i
seguenti dati (rigorosamente in questordine e tutti in formato testuale):
una stringa, rappresentante il nome
dellartista o del gruppo che interpreta il brano;
una stringa, rappresentante il titolo del
brano;
una stringa, rappresentante il titolo
dellalbum da cui è tratto il brano;
un intero compreso tra 1900 e 2100,
rappresentante lanno in cui è stato prodotto lalbum;
un intero compreso tra 1 e 30, rappresentante
la traccia del CD a cui corrisponde il brano; e
una stringa, rappresentante il genere musicale
di appartenenza del brano.
Le singole
informazioni contenute in una generica riga del file sono separate tra loro dal
carattere di barra verticale (|).
La
seguente riga è un esempio di riga che può essere contenuta nel file:
Eurythmics|Sex Crime|1984 for the Love of Big Brother|1984|2|Rock
Notate
che, potenzialmente, le stringhe presenti sul file non hanno limite in
lunghezza e non viene usata nessuna convenzione per i titoli.
3 Classi da Realizzare
È
obbligatorio realizzare in Java il
programma descritto nelle sezioni precedenti utilizzando le seguenti classi:
Song
Descrive
un file MP3 in termini delle informazioni che lo caratterizzano: titolo,
artista, album, traccia, anno e genere. La classe implementa linterfaccia Comparable per semplificare
lordinamento del catalogo.
Attributi
private String title: variabile di istanza contenente il titolo del
brano;
private String artist: variabile di istanza contenente il nome
dellartista che ha interpretato il brano;
private String album: variabile di istanza contenente il titolo
dellalbum da cui è tratto il brano;
private int track: variabile di istanza contenente la posizione del brano
allinterno del CD da cui è tratto;
private int year: variabile di istanza contenente lanno di pubblicazione
dellalbum da cui è tratto il brano;
private String genre: variabile di istanza contenente il riferimento al
genere di musica del brano, ad esempio: jazz, pop, raggae, metal e così via.
Notare che per poter accedere
agli attributi di Song, definiti (giustamente)
come privati, occorrerà definire i classici metodi accessori di set e get
anche se non specificati, ad es. dovrete definire "public void setTrack(int
t)" e "public int
getTrack()"
per manipolare la traccia di una canzone.
Metodi
e Costruttori Pubblici
Song(String t, String a, String l, int n, int
y, String g):
costruttore che interpreta i parametri come le informazioni caratterizzanti un
brano;
public String toString(): metodo che crea e ritorna una stringa rapresentante la
canzone;
public int compareTo(Song a): metodo che confronta il brano corrente (this) con il brano passato come
parametro (a). Il confronto è basato
su: nome artista, titolo album, numero di traccia e titolo del brano; perciò i
due brani sono uguali ed il metodo ritorna zero se e solo se sono interpretati
dallo stesso artista, sono tratti dallo stesso album, hanno stesso numero di
traccia e hanno lo stesso titolo. Per il resto il confronto è lessicografico
(similarmente al dizionario), se i due brani sono interpretati dallo stesso
artista si passa a confrontare il titolo dellalbum, se anche questo è uguale
si confronta il numero di traccia ed infine il titolo del brano, nel momento in
cui uno degli attributi risulta diverso il metodo ritornerà -1 se lattributo
di this è minore del corrispondente
attributo di a, 1 altrimenti.
Ad
esempio, considerando il due brani:
U2|With or Without You|The Joshua
Tree|1987|3|Rock
U2|Exit|The JOSHUA Tree|1987|10|Rock
il
primo è rappresentato dalloggetto this mentre il secondo è rappresentato dalloggetto a, allora la chiamata:
this.compareTo(a);
ritornerà
-1.
Notare che "The Joshua Tree" e "The JOSHUA Tree" sono considerati uguali,
il confronto deve essere fatto trascurando il numero di spazi che separano le
parole che compongono i vari titoli e indipendentemente dalluso di minuscole e
maiscole nelle parole stesse.
DB
La
classe DB rappresenta il cuore del catalogo e dovrà permettere sia la
costruzione del catalogo, che la sua manutenzione ed interrogazione. Gli mp3
vengono aggiunti in testa al catalogo, senza mantenere un ordine, gli elementi
già presenti nel catalogo vengono spostati in avanti di una posizione.
Attributi
private int nsongs: variabile di istanza contenente il numero di canzoni presenti
in catalogo;
private Song[] songs: variabile di istanza contenente le canzoni
presenti in catalogo, songs è realizzato tramite un
array ed avrà dimensione fissata pari a 1000 elementi;
private String filename: variabile di istanza contenente il nome del file
su cui viene salvato e da cui viene ripristinato il catalogo.
Metodi
e Costruttori Pubblici
DB(String fn): costruttore che inizializza il catalogo, fn è il nome del file su disco contenente il
catalogo, se fn non è vuoto il contenuto
del file corrispondente viene usato per inizializzare lo stato del catalogo (le
variabili di istanza nsongs e songs);
public String toString(): metodo che crea e ritorna una stringa contenente lintero
catalogo;
public void write(): metodo che scrive il contenuto del catalogo nel file
corrispondente, cancellando il contenuto precedente;
public void reload(): metodo che ricarica dal file i contenuti del catalogo
nelloggetto;
public Object clone():
metodo che crea una copia delloggetto e la ritorna;
public void backup(String): metodo che effettua una copia di backup del
catalogo, salvandola in un file il cui nome è specificato nella stringa passata
come argomento;
public Song[] query(Query q): metodo pubblico che estrae dal catalogo tutte le canzoni che
verificano la ricerca q; il metodo sfrutta il late
binding per realizzare il confronto (vedi metodo match(Song) della classe Query introdotta successivamente). Il risultato è un array contente
i brani selezionati;
public void squeeze(): metodo pubblico che comprime il catalogo eliminando i brani
potenzialmente doppi cioè quei brani che hanno stesso autore, titolo ed
appartengono allo stesso album, al solito trascurando spazi e differenze
maiuscolo/minuscolo; ad esempio, i brani:
U2|With or Without You|The Joshua Tree|1987|3|Rock
U2|With or Without You|The JOSHUA Tree|1987|5|Rock
sono da
considerarsi lo stesso brano (notare che il numero di traccia e lanno di
pubblicazione sono ininfluenti), il primo brano incontrato deve essere
mantenuto in catalogo;
public void sort(): metodo pubblico che ordina il catalogo per artisti, album e
titolo brano.
Notare che per definizione Song implementa linterfaccia Comparable è pertanto possibile
sfruttare i metodi della classe Arrays per ordinare in modo agevole il catalogo.
public void squeezeSpaces(): metodo pubblico che permette di eliminare gli
spazi e tabulazioni multipli (cioè adiacenti), rimpiazzare i caratteri di
tabulazione con uno spazio, e rimuovere gli spazi inutili allinizio o alla
fine dei titoli degli album e dei brani presenti in catalogo.
public void capitalizeTitles(): metodo pubblico che formatta i titoli dei brani e
degli album in catalogo in modo che ogni parola abbia liniziale (e solo
liniziale) maiuscola.
public void addSong(Song s): metodo pubblico che aggiunge al catalogo presente
in memoria il brano mp3 specificato come parametro, SENZA aggiornare la
versione salvata su disco. Il nuovo brano va inserito allinizio del catalogo
senza rispettare un eventuale ordinamento del catalogo stesso; linserimento
comporterà lo spostamento dei dati contenuti nel catalogo;
public void removeSong(Song s): metodo pubblico che cerca e rimuove dal catalogo
tutte le occorrenze del brano passato come parametro; luguaglianza tra il
brano passato come parametro e i brani contenuti nel catalogo è verificata con
gli stessi criteri usati per il metodo squeeze().
Query
La
classe astratta Query rappresenta una generica
ricerca allinterno del catalogo. Fornisce la struttura di base per richieste
polimorfe sul catalogo.
abstract boolean match(Song s): metodo astratto che verifica che la canzone s rispetti i criteri di ricerca selezionati.
ArtistQuery
La
classe ArtistQuery estende la classe Query. Rappresenta la ricerca
per i brani in catalogo attribuiti ad un certo artista.
private String artist: variabile di istanza contenente il nome
dellartista di cui si vuole estrarre i brani dal catalogo.
ArtistQuery(String a): costruttore della query, si limita ad
inizializzare i campi privati della classe.
boolean match(Song s): controlla se la canzone s è interpretata dallartista specificato
dalla variabile di istanza artist;
ritornerà true se è effettivamente
interpretata da tale artista, false altrimenti.
TrackAndAlbumQuery
La
classe TrackAndAlbumQuery estende la classe Query. Rappresenta la ricerca di
un brano in catalogo che sia presente in un certo album ed abbia una specifica
posizione in quellalbum.
private String album: variabile di istanza contenente il nome
dellalbum di cui si sta cercando una traccia.
private int track: variabile di istanza contenente il numero di traccia a cui
corrisponde il brano cercato.
TrackAndAlbumQuery(String l, int n): costruttore della query,
si limita ad inizializzare, di conseguenza, i campi privati della classe.
boolean match(Song s): controlla se la canzone s appartiene allalbum specificato dalla
variabile di istanza album ed è la traccia di
posizione specificata dalla variabile di istanza track; ritornerà true se è effettivamente il brano cercato, false altrimenti.
TitleSubstringQuery
La
classe TitleSubstringQuery estende la classe Query. Rappresenta la ricerca,
in catalogo, dei brani i cui titoli contengono la stringa specificata. Ad
esempio, dato il catalogo:
U2|With or Without You|The Joshua
Tree|1987|3|Rock
Oldfield, Mike|Moonlight
Shadow|Crises|1982|2|Ambient
Springsteen, Bruce|I'm on Fire|Born in the
U.S.A.|1984|6|Rock
Police, The|Walking on the Moon|Every Breath
You Take|2003|4|Pop
Scorpions, The|Crossfire|Love at First
Sting|1984|8|Heavy Metal
se
definiamo una query per ricercare i brani contenenti la parola "Fire" otterremo:
Springsteen, Bruce|I'm on Fire|Born in the
U.S.A.|1984|6|Rock
Scorpions, The|Crossfire|Love at First
Sting|1984|8|Heavy Metal
Fate
attenzione che la stringa deve essere trovata indipendentemente dagli spazi nel
titolo, dalle differenze maiuscolo/minuscolo ed ovviamente dal fatto che sia
parte di una stringa più grande.
private String substring: variabile di istanza contenente la stringa che si
vuole cercare nei titoli dei brani presenti nel catalogo.
TitleSubstringQuery(String s): costruttore della query,
si limita ad inizializzare, di conseguenza, i campi privati della classe.
boolean match(Song s): controlla se la stringa contenuta nella variabile
di istanza substring è presente nel titolo
della canzone s; ritornerà true se è effettivamente il
brano cercato, false altrimenti.
BeforeYearQuery
La
classe BeforeYearQuery estende la classe Query. Rappresenta la ricerca,
in catalogo, dei brani prodotti prima dellanno specificato indipendentemente
dal loro autore.
private int year: variabile di istanza contenente lanno interessato dalla
ricerca.
BeforeYearQuery(int y): costruttore della query,
si limita ad inizializzare, di conseguenza, i campi privati della classe.
boolean match(Song s): controlla se la canzone s è stata prodotta prima dellanno
specificato dalla variabile di istanza year;
ritornerà true se è effettivamente il
brano cercato, false altrimenti.
DJ
La
classe DJ, tramite un menù testuale
permette di effettuare le seguenti operazioni, tramite una o più chiamate ai
metodi delle classi sopra descritte:
creazione di un nuovo catalogo o ripristino di
un catalogo salvato su disco;
aggiunta di un brano al catalogo;
rimozione di un brano dal catalogo;
salvataggio del contenuto corrente del
catalogo su disco;
ricarica del contenuto del catalogo da disco,
con conseguente eliminazione del contenuto corrente;
visualizzazione dei contenuti del catalogo;
creazione di una copia del catalogo in un
altro file di testo il cui nome viene specificato dallutente;
ricerca brani allinterno del catalogo in base
al nome dellartista, a parte di testo nel titolo, allaccoppiata album e
traccia, e in base allanno di produzione;
ordinamento del catalogo;
pulizia del catalogo; la pulizia consiste
nelleliminare i doppioni dal catalogo, nel capitalizzare correttamente i
titoli degli album e dei brani ed infine nelleliminare gli spazi superflui dai
titoli stessi (il catalogo non viene ordinato).
A parte
quanto espressamente richiesto, è lasciata piena libertà sullimplementazione
delle singole classi e sulleventuale introduzione di altre classi, a patto di
seguire le regole del paradigma ad oggetti ed i principi di buona
programmazione.
Non
è richiesto e non verrà valutato lutilizzo di particolari modalità grafiche di
visualizzazione: è sufficiente una qualunque modalità di visualizzazione basata
sulluso dei caratteri.
Non
è richiesta lintroduzione di nuove eccezioni definite dallutente, mentre ci
si aspetta il trattamento, nel modo migliore, delle eccezioni sollevate durante
lesecuzione ed introdotte dai package utilizzati.
È
invece espressamente richiesto di non utilizzare package non standard di Java (si possono quindi utilizzare java.util, java.io e così via), con lunica
eccezione del package prog.io incluso nel libro di testo
per gestire linput da tastiera e loutput a video e di rispettare
linterfaccia fornita.
4 Modalità di Consegna
Il
progetto deve essere svolto a gruppi di al massimo tre persone che intendono
sostenere lintero esame di Informatica Generale e Laboratorio negli appelli di
Giugno, Luglio o Settembre 2004, e deve essere consegnato entro mezzanotte di
lunedì 14 giugno 2004, utilizzando il sito di sottoposizione delle
esercitazioni (allindirizzo http://infogen.dsi.unimi.it). Per poter effettuare la sottoposizione è
necessario autenticarsi utilizzando un nome di login e una password. Nella
pagina principale del sito stesso è spiegato come ottenere questi dati. Nel
caso il progetto venga svolto da più di una persona, dovrà essere fatta in ogni
caso una sola sottoposizione, indicando chiaramente in un commento allinizio
dei sorgenti consegnati nome, cognome e matricola dei vari componenti del
gruppo.
Dovranno
essere consegnati tutti i sorgenti Java che permettano al programma di essere
eseguito correttamente, compressi in un archivio di tipo ZIP che estragga i
file nella directory in cui si trova larchivio stesso (altri tipi di
sottoposizioni verranno automaticamente rifiutate dal sito). Nellarchivio
dovrà anche essere accluso un breve documento in formato txt o rtf in cui:
verrà descritto il modo in cui interfacciarsi
con il programma;
saranno illustrate le principali scelte
implementative e le strategie utilizzate per svolgere il progetto
Il
sistema rifiuterà automaticamente le sottoposizioni i cui sorgenti contengano
errori rilevati in fase di compilazione.
È
inoltre richiesto di consegnare una copia cartacea della stampa del codice sorgente
prodotto in portineria del DSI indicando chiaramente nome, cognome e numero di
matricola di tutti i componenti del gruppo, nonchè il turno e il docente di
riferimento.
5 Valutazione
Durante
la prova orale con i singoli studenti saranno discusse le modalità
implementative adottate e la padronanza di alcuni dei concetti necessari per
preparare il progetto e/o spiegati a lezione. La valutazione del progetto sarà
fatta in base alla:
conformità dellimplementazione scelta per
risolvere il problema con il paradigma di programmazione a oggetti;
conformità del codice presentato alle regole
di buona programmazione;
adeguatezza del manuale utente presentato a
descrivere il modo in cui un utente può utilizzare il programma;
assenza di errori nel programma;
usabilità del programma;
Durante
lappello di febbraio si sono verificati numerosi fenomeni di copiatura, che ci
hanno costretto ad ammettere allesame un numero molto ridotto di studenti.
Anche senza fare appello al buon senso e al codice donore, è evidente a tutti
che situazioni di questo tipo sono sgradevoli sia per i docenti che per gli
studenti. Ovviamente non mancheremo di verificare di nuovo, in modo minuzioso,
leventuale ripetersi delle suddette, e di trarne le ovvie conseguenze.
Walter Cazzola
Dip.to
di Informatica e Comunicazione
Via Comelico 39/41 20135
Milano
Stanza S233 Tel.
+39.010.353.6637
e-mail: cazzola@dico.unimi.it
Dario Malchiodi
Dip.to di Scienze
dellInformazione
Via Comelico 39/41 20135
Milano
Stanza T304
Tel. +39.02.503.16338
e-mail: malchiodi@dsi.unimi.it