Διευκρινήσεις κώδικα Hy240b project 2014 phase 1
Parsers (1/4) • Οι parsers γενικά, στη μορφή που θα τους συναντήσετε, είναι ο κώδικας που εξάγει δομημένη πληροφορία από strings (σειρά από χαρακτήρες). Στη δική μας περίπτωση οι parsers είναι αυτοί που θα πάρουν την πληροφορία από τα αρχεία και θα μας τα δώσουν έτοιμα με τη μορφή των class/struct. • Στον κώδικα που σας δίνεται, υπάρχει μία κλάση FileParsers (και είναι αυτή που μας ενδιαφέρει), και δύο κλάσεις/structs MovieData, EventData. • Η κλάση FileParsers περιέχει κώδικα που ανοίγει τα αρχεία, τα διαβάζει, και επιστρέφει τη πληροφορία που υπάρχει στα αρχεία με την μορφή των κλάσεων/structs MovieData, EventData. • Οι κλάσεις/structs MovieData, EventData υπάρχουν μόνο για να πακετάρουν την πληροφορία των ταινιών και του event και δεν κάνουν κάτι ιδιαίτερο.
Parsers (2/4) • H κλάση FileParsers περιέχει 6 μεθόδους(συναρτήσεις). – initialize() : αρχικοποιεί τους parsers και ανοίγει τα αρχεία για διάβασμα – finalize(): κλείνει τα αρχεία που και τερματίζει τους parsers – hasNextMovie() / hasNextEvent() : επιστρέφουν true/false ανάλογα με το αν υπάρχει άλλη ταινία/event στο αρχείο – getNextMovie() / getNextEvent() : επιστρέφει το επόμενο MovieData / EventData που υπάρχει στο αρχείο ή null αν δεν υπάρχει επόμενο • Αρχικά θα πρέπει να καλέσετε FileParsers.initialize( [path1], [path2] ); για να αρχικοποιηθούν οι parsers και να ορίσετε από ποια αρχεία θα διαβάσουν τις πληροφορίες, όπου: – [path1] : ένα string με το file path του αρχείου των movies – [path2] : ένα string με το file path του αρχείου των events
Parsers (3/4) • Στη συνέχεια, θα εξετάζετε με την συνάρτηση hasNextMovie() αν υπάρχει επόμενο στοιχείο ταινίας στο αρχείο, και αν ναι, τότε καλώντας getNextMovie() θα παίρνετε την επόμενη ταινία με την μορφή της class/struct MovieData. (Αντίστοιχα γίνεται και για τα events). • Αυτό που σας ενδιαφέρει σε αυτό το κομμάτι είναι να καταλάβετε με ποιο τρόπο θα καλείτε τις μεθόδους(συναρτήσεις) της κλάσης FileParsers για να παίρνετε τα δεδομένα από τα αρχεία. • Υπάρχει παράδειγμα στην main() που σας δίνεται όπου μπορείτε να δείτε πως ακριβώς χρησιμοποιούνται.
Parsers (4/4) Τα πεδία των κλάσεων/structs MovieData, EventData που παίρνουμε από τον FileParser περιγράφονται παρακάτω: • MovieData – Id : το id της ταινίας – Title : ο τίτλος της ταινίας – Year : η χρονιά που προβλήθηκε η ταινία – Rating : η βαθμολογία της ταινίας – Votes: ο αριθμός των ψήφων που πήρε η ταινία – Duration : η διάρκεια της ταινίας σε λεπτά – Genres : μία λίστα με τις κατηγορίες τις οποίες ανήκει η ταινία • EventData – Operation : είναι το γράμμα “I” ή το γράμμα “D” που περιγράφει αν θα πρέπει να γίνει Insert ή Delete από τη λίστα αντίστοιχα. – Username : το όνομα του χρήστη – movieId : το id της ταινίας που θέλει να παρακολουθήσει ή παρακολούθησε ο χρήστης
Movies List (1/5) Οι κλάσεις (λίστες) που πρέπει να υλοποιήσετε είναι οι : UnsortedMovieList, SortedMovieList, SelfAdjustingMovieList και περιέχουν: • Τα πεδία: – size : το μέγεθος της λίστας – head : περιέχει/δείχνει στον πρώτο κόμβο της λίστας – tail : περιέχει/δείχνει στον τελευταίο κόμβο της λίστας • Τις μεθόδους(συναρτήσεις): – clear() – getSize() – isEmpty() – insert() – remove() – get()
Movies List (2/5) • Όμως τα πεδία size, head, tail και οι συναρτήσεις clear(), getSize(), isEmpty() είναι κοινά και για τις 3 λίστες. Οπότε τα πεδία και ο κώδικας της υλοποίησης των συναρτήσεων μπήκαν σε μια abstract(java)/virtual(C++) class με όνομα MovieList. • Το abstract/virtual σημαίνει ότι δεν μπορείτε να δημιουργήσετε instance/στιγμιότυπο(”μεταβλητή”) της κλάσης MovieList. Αυτή η κλάση υπάρχει μόνο για να ορίζει κάποια βασικά στοιχεία που πρέπει να υπάρχουν. • Οι κλάσεις UnsortedMovieList, SortedMovieList, SelfAdjustingMovieList είναι επεκτάσεις της κλάσης MovieList (κληρονομούν τα στοιχεία της). Αυτό σημαίνει ότι οι 3 κλάσεις θα έχουν τα δικά τους πεδία, μεθόδους(συναρτήσεις) + τα πεδία και μεθόδους της κλάσης MovieList
Movies List (3/5) • Οι 3 κλάσεις που επεκτείνουν την MovieList, σχηματικά είναι κάπως έτσι:
Movies List (4/5) • Πρακτικά, αυτό που πρέπει να κάνετε εδώ είναι η υλοποίηση των μεθόδων (συναρτήσεων) που υπάρχουν μέσα στις MovieList, UnsortedMovieList, SortedMovieList, SelfAdjustingMovieList. • Αυτό που πρέπει να γνωρίζετε είναι ότι τα πεδία και οι μεθόδοι(συναρτήσεις) που υπάρχουν στην MovieList είναι σαν να υπήρχαν στην κάθε μια από τις UnsortedMovieList, SortedMovieList, SelfAdjustingMovieList. • Εκτός από τις 4 κλάσεις που είδαμε προηγουμένως, υπάρχει και η κλάση/struct MovieListNode που περιγράφει έναν κόμβο της λίστας. (Για τη Java: οι μεθόδοι(συναρτήσεις) get… /set… που υπάρχουν στην κλάση MovieListNode το μόνο που πρέπει να κάνουν είναι να επιστρέφουν /θέτουν τιμές από/στα πεδία της κλάσης αντίστοιχα)
Movies List (5/5) • Σχηματικά, η λίστα των ταινιών είναι κάπως έτσι:
Users List (1/5) • Για τη λίστα των Users, υπάρχουν 3 classes: – UserList: η λίστα των users – UserListNode: o κόμβος της λίστας των users ΚΑΙ η λίστα των ταινιών που θέλει να παρακολουθήσει ο χρήστης – WatchMovieListNode: ο κόμβος της λίστας των ταινιών που θέλει να παρακολουθήσει ο κάθε χρήστης
Users List (2/5) H class UsersList περιέχει: • Τα πεδία: – head: που περιέχει το πρώτο στοιχείο της λίστας • Τις μεθόδους(συναρτήσεις) : – insert() : εισάγει ένα νέο κόμβο στη λίστα – remove() : διαγράφει τον κόμβο από τη λίστα αν υπάρχει – get() : επιστρέφει τον κόμβο από τη λίστα αν υπάρχει, αλλιώς επιστρέφει null – isEmpty() : επιστρέφει true/false ανάλογα με το αν η λίστα είναι άδεια ή όχι.
Users List (3/5) H class UsersListNode περιέχει: • Τα πεδία: – username: που περιέχει όνομα του χρήστη – next: που δείχνει στο επόμενο στοιχείο της λίστας των Users – watchMovieList: που περιέχει το πρώτο στοιχείο της λίστας των ταινιών που θέλει να παρακολουθήσει ο χρήστης • Τις μεθόδους(συναρτήσεις) : – get()/set() : επιστρέφουν/θέτουν τα ανάλογα πεδία της κλάσης – insertMovie() : εισάγει ένα καινούργιο κόμβο στη λίστα των ταινιών – removeMovie() : διαγράφει τον κόμβο από τη λίστα των ταινιών αν υπάρχει – containsMovie() : επιστρέφει true/false ανάλογα με το αν η λίστα των ταινιών περιέχει την ταίνια με παράμετρο – isMoviesListEmpty() : επιστρέφει true/false ανάλογα με το αν η λίστα των ταινιών είναι άδεια ή όχι.
Users List (4/5) H class WatchMovieListNode περιέχει: • Τα πεδία: – movieId: το id της ταινίας που θέλει να δει ο χρήστης – next: που δείχνει στο επόμενο στοιχείο της λίστας του watchMovieList • Τις μεθόδους(συναρτήσεις) : – get()/set() : επιστρέφουν/θέτουν τα ανστίστοιχα πεδία της κλάσης
Users List (5/5) • Σχηματικά η λίστα των Users έχει ως εξής:
Μετρήσεις χρόνων (1/1) • Java: – long currTime = System.currentTimeMillis(); (Επιστρέφει το χρόνο του συστήματος σε ms) • C++: – #include – int time_in_millis = (std::clock()) / (double)(CLOCKS_PER_SEC / 1000); • Για να πάρετε μετρήσεις χρόνων που ζητείται στην εκφώνηση πχ. για την αρχικοποίηση της λίστας των ταινιών. 1.Παίρνετε το χρόνο του συστήματος πριν αρχίσετε να εισάγετε στοιχεία στη λίστα. 2.Παίρνετε το χρόνο μετά το τέλος όλων των εισαγωγών. 3.Κάνετε τη διαφορά των 2 και βλέπετε πόση ώρα πέρασε.
Java Comparators (1/4) (Definition) • Οι Comparators είναι ένα generic interface στην Java. – Interface: μία “κλάση” που δεν έχει πεδία και δεν μπορείς να δημιουργήσεις στιγμιότυπο. Δηλαδή απλά περιγράφει υπογραφές μεθόδων έτσι ώστε άλλες κλάσεις να τα υλοποιήσουν. – Generic: μία generic κλάση/interface είναι μία κλάση που έχει παραμέτρους κάποιους τύπους δεδομένων. Για παράδειγμα η κλάση ArrayList είναι generic επειδή υπάρχει η παράμετρος Τ που περιγράφει τον τύπο των δεδομένων που θα έχει το ArrayList. Πχ : ArrayList. • Ορίζουν μόνο μία μέθοδο, την compare, που υλοποιεί έναν τρόπο να συγκρίνουμε 2 αντικείμενα ίδιου τύπου, και επιστρέφει (σύμφωνα με τη σύμβαση): – Ένα θετικό αριθμό αν m1>m2 – 0 αν m1 = m2 – Ένα αρνητικό αριθμό αν m1<m2
Java Comparators (2/4) (Practice) • Η κλάση που θα χρειαστούμε και θα ορίσουμε εμείς είναι η παρακάτω: • Αυτή η κλάση είναι η παράμετρος που περιμένει η SortedMovieList(). Δηλαδή αν κάνουμε: SortedMovieList l = new SortedMovieList(new MovieListNodeComparatorByYear()); Από κει και πέρα αρκεί να καλέσουμε: comparator.compare(newNode, currNode); και να δούμε ποιος κόμβος είναι μεγαλύτερος με βάση το year. • Η compare θα θεωρεί σαν μεγαλύτερη ταινία αυτή με το μεγαλύτερο year αφού: m1.getYear() > m2.getYear() m1.getYear() – m2.getYear() > 0
Java Comparators (3/4) (Theory) • Το Interface λέγεται Comparator επειδή το μόνο που κάνει είναι να έχει μια μέθοδο να κάνει compare. • Το “implements Comparator ” απλά μας λέει ότι κλάση που ορίσαμε υλοποιεί όλες τις μεθόδους του interface Comparator με τύπο MovieListNode (την compare για 2 MovieListNode δηλαδή). Αυτό θα μπορούσαμε να μην το βάλουμε καθόλου, και η MovieListNodeComparatorByYear να ήταν μια απλή κλάση. Υπάρχει η σύμβαση στη Java να χρησιμοποιούνται τέτοιες κλάσεις όταν θέλουμε να ορίσουμε πώς να συγκρίνουμε 2 αντικείμενα ενός τύπου. Για παράδειγμα τα Collections της Java ( ArrayList, SortedMap, SortedTree κτλ) χρησιμοποιούν τους comparators για να ταξινομούν τις δομές. • Για τον κώδικα μας όλα αυτά πρακτικά δεν μας ενδιαφέρουν. Είναι για τη θεωρία (γι αυτό και σας δόθηκαν έτοιμα). Εμάς μας ενδιαφέρει ότι υπάρχει η κλάση που ορίσαμε.
Java Comparators (4/4) (Code: inline definition) • Υπάρχει ένα ειδικό συντακτικό στη Java που επιτρέπει να ορίζουμε ανώνυμες κλάσεις την ώρα που τις δημιουργούμε, αρκεί να κάνουν implement κάποιο interface (όπως στη περίπτωση μας) ή να είναι υποκλάσεις κάποιας άλλης. Δηλαδή η κλάση που δείξαμε προηγουμένως μπορούμε να την γράψουμε (κάνοντας και new κατευθείαν):