ΑΕΜ ΒΑΘΜΟΣ ΣΧΟΛΙΑ 812 Καλή δουλειά 887 926 FAIL 1040 FAIL Μη αναγνωρίσιµο φορµατ 1060 1138 FAIL Ηµιτελές - Άσχηµα ονόµατα µεταβλητών/πεδίων που κάνουν δυσνόητο τον κώδικα. Μη χρησιµοποιείτε µεταβλητές του ενός γράµµατος. - Η srand πρέπει να καλείται µόνο µια φορά για να θέσει αρχικά το seed. Εποµένως δεν έπρεπε να την έχετε µέσα σε loop. - Σε µερικά σηµεία έχετε σχόλια σε κάθε γραµµή κώδικα, και σε µερικά δεν έχετε καθόλου ενώ θα έπρεπε. Τι ακριβώς προσπαθεί να κάνει η συνάρτηση Copy_Available_Words_From_List_To_List_Function, γιατί έχει ένα µάλλον βασικό κοµµάτι της commented-out, κι εφόσον δε χρησιµοποιείται πουθενά στο πρόγραµµα, γιατί υπάρχει? Στην Add_To_Not_Sorted_List γιατί (σωστά) δεν κάνετε return από την περίπτωση Root == NULL? - Κάποιες φορές το πρόγραµµα πετάει segfault στη γραµµή strcpy (Target_Word, Select_N_Word_From_List_Function(LengthList, Rand2)); Αυτό συµβαίνει γιατί υπάρχει περίπτωση το Ν να είναι µηδέν, οπότε το πρόγραµµα βγαίνει από το loop χωρίς να έχει βρει την περίπτωση counter == N. ΔΕΝ έχετε βάλει κάποιο return σε αυτή την περίπτωση (και µάλιστα γκρινιάζει και ο compiler γι αυτό), µε αποτέλεσµα τελικά η "λέξη" να είναι σκουπίδια ή NULL. - Άσχηµα ονόµατα µεταβλητών/πεδίων που κάνουν δυσνόητο τον κώδικα. Μη χρησιµοποιείτε µεταβλητές του ενός γράµµατος. - Η srand πρέπει να καλείται µόνο µια φορά για να θέσει αρχικά το seed. Εποµένως δεν έπρεπε να την έχετε µέσα σε loop. - Σε µερικά σηµεία έχετε σχόλια σε κάθε γραµµή κώδικα, και σε µερικά δεν έχετε καθόλου ενώ θα έπρεπε. Τι ακριβώς προσπαθεί να κάνει η συνάρτηση Copy_Available_Words_From_List_To_List_Function, γιατί έχει ένα µάλλον βασικό κοµµάτι της commented-out, κι εφόσον δε χρησιµοποιείται πουθενά στο πρόγραµµα, γιατί υπάρχει? Στην Add_To_Not_Sorted_List γιατί (σωστά) δεν κάνετε return από την περίπτωση Root == NULL? - Κάποιες φορές το πρόγραµµα πετάει segfault στη γραµµή strcpy (Target_Word, Select_N_Word_From_List_Function(LengthList, Rand2)); Αυτό συµβαίνει γιατί υπάρχει περίπτωση το Ν να είναι µηδέν, οπότε το πρόγραµµα βγαίνει από το loop χωρίς να έχει βρει την περίπτωση counter == N. ΔΕΝ έχετε βάλει κάποιο return σε αυτή την περίπτωση (και µάλιστα γκρινιάζει και ο compiler γι αυτό), µε αποτέλεσµα τελικά η "λέξη" να είναι σκουπίδια ή NULL. 1185 1279 - Χρησιµοποιείς διευθύνσεις µνήµης τις οποίες προηγούµενα έχεις ελευθερώσει. - Η λίστα των προτεινόµενων λέξεων είναι ελλιπής. - Το πρόγραµµα δεν υπακούει στις προδιαγραφές τις εκφώνησης αναφορικά µε την επανάληψη του παιχνιδιού µετά από ερώτηση του χρήστη. - Όταν η αρχική λίστα είναι άδεια το πρόγραµµα "crash-άρει". - Υπάρχουν κάποια αλγοριθµικά λάθη. Για παράδειγµα, αν ο χρήστης βάλει οποιαδήποτε λέξη που δεν είναι στις προτεινόµενες αλλά έχει το ίδιο µήκος αν και δεν την εµφανίζει στο PATH των επιλεγµένων λέξεων την λαµβάνει ως την επόµενη προς εξέταση λέξη µε αποτέλεσµα να αναθεωρεί τη λιστα προτεινόµενων λέξεων. 1329 Το πρόγραµµα φαίνεται να κολλάει όταν ζητείται µέγεθος λέξης που δεν υπάρχει. Καλή δουλειά κατά τα άλλα, αλλά προσπάθησε να χρησιµοποιείς καλύτερα ονόµατα µεταβλητών (για παράδειγµα, το f δε σηµαίνει τίποτα). 1370 Καλή δουλειά 1399 Το πρόγραµµα φαίνεται να κολλάει όταν ζητείται µέγεθος λέξης που δεν υπάρχει. Καλή δουλειά κατά τα άλλα, αλλά προσπάθησε να χρησιµοποιείς καλύτερα ονόµατα µεταβλητών (για παράδειγµα, το f δε σηµαίνει τίποτα).
1422 FAIL - Segmentation fault αν δε δοθούν ορίσµατα προγράµµατος. Πρέπει πάντα να ελέγχεις το argc πριν προσπελάσεις το argv (γρ. 466). Βασικά έπρεπε στην αρχή της main, πριν κάνεις οτιδήποτε άλλο, να καλείς την commence, σκοπός της οποίας είναι να δει αν και τι ορίσµατα δόθηκαν. Δεν έπρεπε να διαβάζεις τα ορίσµατα πριν την καλέσεις. - Τι ακριβώς προσπαθείς να κάνεις στις γραµµές 471-486? Ανοίγεις το αρχείο-λεξικό, βλέπεις το µέγεθός του, και κατασκευάζεις ένα δυναµικό πίνακα όσο το αρχείο. Μετά καλείς επαναληπτικά την getword µε παράµετρο αυτόν τον πίνακα. Αυτό είναι τελείως λάθος. Η getword, όπως έλεγε και στα σχόλιά της, παίρνει ως παράµετρο το όνοµα του αρχείου, το ανοίγει, διαβάζει µία-µία λέξη και το επιστρέφει. Η µεταβλητή library που περνάς έπρεπε να ήταν το argv[3] όχι ένα string τόσο µεγάλο όσο το αρχείο. - Κάνεις το λάθος να καλείς την srand µέσα σε loop. Δεν το κάνουµε ποτέ αυτό. Η srand πρέπει να καλείται µία φορά µόνο στο πρόγραµµα (συνήθως στη main) - Στο σηµείο printf("enter Selection: \n"); scanf("%s", userinput); το userinput δε δείχνει κάπου. Έπρεπε να είχες δεσµεύσει µνήµη γι αυτό. - Η commence επιστρέφει 0 χωρίς να πρέπει: έχεις if (library == NULL); { return 0; } Το ερωτηµατικό µετά τη συνθήκη έχει ως αποτέλεσµα να τερµατίζει η if. Το παραπάνω είναι ισοδύναµο µε: if (library == NULL) { } return 0; 1444 Καλή δουλειά 1447 Καλή δουλειά Όλα τα παραπάνω προβλήµατα συµβαίνουν στο ξεκίνηµα του προγράµµατος. Ακόµη κι αν διορθωθούν, το πρόγραµµα σκάει µε segmentation fault στη γραµµή checksame = strcmp(checknode->stats.phrase, keynode->stats.phrase); γιατί το phrase περιέχει σκουπίδια. Πέρα από τα προβλήµατα µε δέσµευση µνήµης, είναι λάθος και η αποδέσµευση. Κάνεις free(curr) αλλά αµέσως µετά στην επανάληψη του loop προσπελάζεις το curr->next ενώ το curr δεν είναι πια έγκυρο. Όχι µόνο αυτό, αλλά και πριν το free(curr) είχες κάνει curr->next = curr, οπότε ακόµη κι αν το πρόγραµµα φτάσει µέχρι εκεί, θα κολήσει σε ατέρµονο βρόχο. Ακόµη κι αν δεν κόλαγε εκεί, θα κόλαγε λόγω της συνθήκης τερµατισµού, η οποία συγκρίνει το curr->stats.totalwords µε τη µεταβλητή checker, χωρίς να αλλάζει τιµή κάποια από αυτές τις δύο µέσα στο loop. Στην κατασκευή της λίστας δε θέτεις όλους τους pointers. Είναι διπλή λίστα, άρα κάθε φορά που εισάγεται κόµβος, πρέπει να χειριστούµε 4 δείκτες. Τα next/prev του κόµβου προς εισαγωγή, το next του προηγούµενο και το prev του επόµενου. Στην createfullwordlist, θέτεις το next και το prev του κόµβου προς εισαγωγή (curr), θέτεις το next της κεφαλής (sent) αλλά δε θέτεις το prev του κόµβου που θα πρέπει να είναι ο επόµενος του curr. Αυτό είναι ουσιαστικό λάθος. 1448 - Το πρόγραµµα πετάει άµεσα segmentation fault. Έχετε βάλει ένα τερµατικό κόµβο στο τέλος της λίστας και η συνάρτηση που επιλέγει την τυχαία λέξη δεν τον παρακάµπτει µε αποτέλεσµα κάποιες φορές να επιλέγει τον sentinel (ο οποίος δεν περιέχει έγκυρη λέξη).γενικά ο κώδικας για την κατασκευή της λίστας είναι πολύ µπερδεµένος και ο µεγάλος αριθµός κενών γραµµών που έχετε τον κάνει δύσκολο στο διάβασµα. - Το πρόγραµµα πετάει segmentation fault αν ζητηθεί µήκος για το οποίο δεν υπάρχουν λέξεις στο λεξικό. - Πριν το playagain, αντί να καλείτε την destroylist ώστε να καταστρέψετε ολόκληρες τις λίστες, απλά κάνετε free τις κεφαλές. - Γενικά έχετε πρόβληµα µε το free: δεν αποδεσµεύετε ούτε τις λέξεις που αποθηκεύονται στους κόµβους. - Δε χρησιµοποιείτε srand για να θέσετε το seed. - Τι διαφορά έχουν τα δύο µέρη της παρακάτω συνθήκης? if(str1[i]!= str2[i] str2[i]!= str1[i] ) 1451 Καλή δουλειά 1460 - Segmentation fault αφού ο χρήστης µαντέψει τη λέξη του. - Αφού βάλεις το tmp να δείχνει σε κόµβο της λίστας στη γραµµή 403, καταστρέφεις τη λίστα, µε αποτέλεσµα το tmp να µη δείχνει πια σε έγκυρη µνήµη. - Οι µονογραµµατικές µεταβλητές/ονόµατα κάνουν πολύ δυσνόητο τον κώδικα. Για παράδειγµα, τι είναι αυτό: print_node(n, f, f, t, f, f); 1462 FAIL Δεν κάνει compile 1472 Καλή δουλειά 1473 - Το πρόγραµµα πετάει άµεσα segmentation fault. Έχετε βάλει ένα τερµατικό κόµβο στο τέλος της λίστας και η συνάρτηση που επιλέγει την τυχαία λέξη δεν τον παρακάµπτει µε αποτέλεσµα κάποιες φορές να επιλέγει τον sentinel (ο οποίος δεν περιέχει έγκυρη λέξη).γενικά ο κώδικας για την κατασκευή της λίστας είναι πολύ µπερδεµένος και ο µεγάλος αριθµός κενών γραµµών που έχετε τον κάνει δύσκολο στο διάβασµα. - Το πρόγραµµα πετάει segmentation fault αν ζητηθεί µήκος για το οποίο δεν υπάρχουν λέξεις στο λεξικό. - Πριν το playagain, αντί να καλείτε την destroylist ώστε να καταστρέψετε ολόκληρες τις λίστες, απλά κάνετε free τις κεφαλές. - Γενικά έχετε πρόβληµα µε το free: δεν αποδεσµεύετε ούτε τις λέξεις που αποθηκεύονται στους κόµβους. - Δε χρησιµοποιείτε srand για να θέσετε το seed. - Τι διαφορά έχουν τα δύο µέρη της παρακάτω συνθήκης? if(str1[i]!= str2[i] str2[i]!= str1[i] ) 1479 Καλή δουλειά
1494 Καλή δουλειά. Πρόσεχε µόνο τα ονόµατα των µεταβλητών σου (να είναι περιγραφικά και να µη σηµαίνουν άσχετα πράγµατα στα αγγλικά). 1523 Καλή δουλειά 1527 FAIL - Ηµιτελής. - Χρησιµοποιεί globals. 1596 1597 - η επιλογή της ονοµατολογίας των συναρτήσεων δεν είναι ικανοποιητική. - την 2η φορά που πάει να τρέξει το πρόγραµµα επιχειρεί να ξαναδιαβάσει τις λέξεις από το αρχείο πράγµα περιττό, αλλά και µη εφικτό καθώς έχουµε φτάσει ήδη στο τέλος του αρχείου. - Το loop επιλογής των λέξεων αφετηρίας/προορισµού είναι τελείως λάθος. Μπορεί να διαλέξει τον τερµατικό κόµβο, µπορεί και να µη διαλέξει καµία λέξη-προορισµό. Το πιο απλό θα ήταν να βρίσκατε 2 διαφορετικούς τυχαίους αριθµούς από το 1 µέχρι το µήκος της λίστας, και µετά να βρείτε τις λέξεις που αντιστοιχούν σε αυτές τις θέσεις. Ακοµη κι αν διορθωθεί αυτό το λάθος, το πρόγραµµα εξακολουθεί να µη λειτουργεί (εµφανίζονται λέξεις-σκουπίδια) - Κάθε φορά που φτιάχνετε νέο κόµβο για µια λίστα, θέτετε τον δείκτη data.word να δείχνει σε ήδη υπάρχουσα λέξη σε κόµβο άλλης λίστας. Ως αποτέλεσµα, αν η αρχική λίστα γίνει free, θα χάσετε πρόσβαση στη λέξη. Έπρεπε να δεσµεύετε νέα µνήµη και να αντιγράφετε τα περιεχόµενα. 1598 FAIL Δεν κάνει compile 1606 - Καλή δουλειά. 1617 - η επιλογή της ονοµατολογίας των συναρτήσεων δεν είναι ικανοποιητική. - την 2η φορά που πάει να τρέξει το πρόγραµµα επιχειρεί να ξαναδιαβάσει τις λέξεις από το αρχείο πράγµα περιττό, αλλά και µη εφικτό καθώς έχουµε φτάσει ήδη στο τέλος του αρχείου. 1629 Καλή δουλειά 1637 Καλή δουλειά 1642 FAIL Μη ικανοποιητική απόδοση στην προφορική εξέταση. 1643 FAIL - τραγική στοίχιση. - το struct του κόµβου της δοµής δεν υπακούει στους κανόνες που έχουµε θέσει (enum, union). - το πρόγραµµα δέχεται ως λέξεις στο path και λέξεις που έχουν λιγότερα γράµµατα από το απαιτητό. - τα ορίσµατα λαµβάνονται ανάποδα από ότι ορίζεται στην εκφώνηση. Πρώτα ο αριθµός των βηµάτων και µετά το µήκος της λέξης. - η εκτύπωση των λέξεων και των µηνυµάτων δεν υπακούει τους κανόνες της εκφώνησης. - Γενικά πρόχειρη δουλειά. 1646 Καλή δουλειά 1665 FAIL Μη ικανοποιητική απόδοση στην προφορική εξέταση. 1670 - Το loop επιλογής των λέξεων αφετηρίας/προορισµού είναι τελείως λάθος. Μπορεί να διαλέξει τον τερµατικό κόµβο, µπορεί και να µη διαλέξει καµία λέξη-προορισµό. Το πιο απλό θα ήταν να βρίσκατε 2 διαφορετικούς τυχαίους αριθµούς από το 1 µέχρι το µήκος της λίστας, και µετά να βρείτε τις λέξεις που αντιστοιχούν σε αυτές τις θέσεις. Ακοµη κι αν διορθωθεί αυτό το λάθος, το πρόγραµµα εξακολουθεί να µη λειτουργεί (εµφανίζονται λέξεις-σκουπίδια) - Κάθε φορά που φτιάχνετε νέο κόµβο για µια λίστα, θέτετε τον δείκτη data.word να δείχνει σε ήδη υπάρχουσα λέξη σε κόµβο άλλης λίστας. Ως αποτέλεσµα, αν η αρχική λίστα γίνει free, θα χάσετε πρόσβαση στη λέξη. Έπρεπε να δεσµεύετε νέα µνήµη και να αντιγράφετε τα περιεχόµενα. 1678 Καλή δουλειά. Πρόσεχε µόνο τα ονόµατα των µεταβλητών σου (να είναι περιγραφικά και να µη σηµαίνουν άσχετα πράγµατα στα αγγλικά). 1680 Καλή δουλειά 1682 FAIL - τραγική στοίχιση. - το struct του κόµβου της δοµής δεν υπακούει στους κανόνες που έχουµε θέσει (enum, union). - το πρόγραµµα δέχεται ως λέξεις στο path και λέξεις που έχουν λιγότερα γράµµατα από το απαιτητό. - τα ορίσµατα λαµβάνονται ανάποδα από ότι ορίζεται στην εκφώνηση. Πρώτα ο αριθµός των βηµάτων και µετά το µήκος της λέξης. - η εκτύπωση των λέξεων και των µηνυµάτων δεν υπακούει τους κανόνες της εκφώνησης. - Γενικά πρόχειρη δουλειά.
1683 Γενικά: φαίνεται να έχεις κάποιες ελλείψεις αναφορικά µε λίστες και δυναµική δέσµευση µνήµης. Ειδικά το λάθος µε το newnode που αναφέρουµε πιο κάτω είναι σοβαρό. Επίσης πρόσεχε τις οδηγίες - πάντα απαγορεύουµε τη χρήση καθολικών µεταβλητών. - Δεν καθαρίζεις τις λίστες όταν ξεκινά νέος γύρος. - Αν δε δοθεί αρχείο, το πρόγραµµα εξακολουθεί να καλεί την getword µε αποτέλεσµα να βγαίνει µήνυµα λάθους. - Τα head είναι όλα global που απαγορευόταν, αλλά (ευτυχώς) τα περνάς στις συναρτήσεις κανονικά ως παραµέτρους! - Φαίνεται να έχεις δυο δείκτες (head, sentinel) για τον ίδιο κόµβο. - Εισαγωγή δείχνει οκ, αν και φαίνεται να ξεχνάς ότι είναι διπλή κυκλική λίστα και τη διατρέχεις όλη για να βρεις τον τελευταίο κόµβο (ενώ αρκούσε να προσπελάσεις head->prev). Επίσης, θέτεις head = newnode πριν κάνεις malloc για τον newnode, το οποίο είναι σοβαρό λάθος. Έχει ως αποτέλεσµα το head να δείχνει σε σκουπίδια. - Magic numbers - Κάνεις το λάθος να καλείς την srand µέσα σε loop. Δεν το κάνουµε ποτέ αυτό. Η srand πρέπει να καλείται µία φορά µόνο στο πρόγραµµα (συνήθως στη main) 1694 1737 - Καλή δουλειά. - Ικανοποικητική δουλειά. 1744 Καλή δουλειά 1747 Καλή δουλειά 1753 Καλή δουλειά 1758 Καλή δουλειά 1782 Γενικά ικανοποιητική δουλειά µε εξαίρεση την αδυναµία σας να καταστρέψετε άδεια λίστα. 1801 1806 Καλή δουλειά - segmentation fault στη γραµµή 253 µε το που ξεκινά το πρόγραµµα. Ο κόµβος node_curr δεν περιέχει έγκυρη λέξη (πιθανώς έχετε επιτρέψει να επιλεγεί ο τερµατικός κόµβος ως αφετηρία). - Γιατί χρησιµοποιείτε strncpy και µια ακόµη εντολή για το \0 αντί για strcpy? - Τι είναι η µεταβλητή z? Όταν χρησιµοποιείτε µη-περιγραφικά ονόµατα, ο κώδικάς σας είναι δυσνόητος. - Στην add_new_node δεσµεύετε µνήµη για τις µεταβλητές new, prv αλλά µετά τις χρησιµοποιείτε για να διατρέξετε τη λίστα και δε φαίνεται να κάνετε κάπου εισαγωγή κόµβου. Κάνετε και σε άλλα σηµεία το ίδιο λάθος και µάλιστα µετά κάνετε free αυτούς τους δείκτες (αφότου τους έχετε βάλει να δείχνουν σε έγκυρους κόµβους λίστας). - Στη delete_list κάνετε free(cur_w) και αµέσως µετά στη συνθήκη του while ελέγχετε αν cur_w!= root_node. Μα το cur_w δεν περιέχει πια έγκυρα δεδοµένα. Αν υποθέσουµε ότι εννοούσατε free(cur), τότε θα έχετε πρόβληµα µετά το τέλος του loop που ξανακάνετε free(cur). Ίσως αν είχατε πιο καλά ονόµατα µεταβλητών δε θα είχατε µπλεχτεί τόσο σε αυτό το σηµείο. Μετά, επιστρέφοντας από τη συνάρτηση κάνετε free την κεφαλή, ενώ κανονικά θα είχε γίνει µέσα στη συνάρτηση (αν υποθέσουµε ότι είχατε τη σωστή µεταβλητή σε κάθε free). 1817 FAIL Απουσία από προφορική εξέταση. 1822 1831 1832 Προσοχή στις αρχικοποιήσεις: η µεταβλητή counter στη συνάρτηση print_list3 δεν έχει αρχικοποιηθεί και τελικά περιέχει σκουπίδια. Μη δηλώνετε prototypes συναρτήσεων µέσα σε άλλες συναρτήσεις (το κάνετε στη main). Πέρα από το ότι δεν είναι κάτι που συνηθίζεται, δε χρειάζεται κιόλας γιατί έχετε ορίσει όλες αυτές τις συναρτήσεις πριν τη main. Μη δηλώνετε prototypes συναρτήσεων µέσα σε άλλες συναρτήσεις (το κάνετε στη main). Πέρα από το ότι δεν είναι κάτι που συνηθίζεται, δε χρειάζεται κιόλας γιατί έχετε ορίσει όλες αυτές τις συναρτήσεις πριν τη main. 1833 FAIL - Το πρόγραµµα δεν υλοποιεί τα ζητούµενα. Έπρεπε να βρίσκει µόνο του την αρχική και τελική λέξη, όχι να τις ζητά από τον χρήστη. - Όταν διαγράφουµε µια λίστα, κάνουµε free έναν-έναν τους κόµβους της, όχι µόνο την κεφαλή - Απαγορευόταν αυστηρά η χρήση καθολικών µεταβλητών. - Δε χρησιµοποιείς srand για να θέσεις το seed, ή rand για να βρεις τις αρχικές λέξεις. - Για να µετατρέψουµε όρισµα σε ακέραιο χρησιµοποιούµε την atoi. Η σύγκριση *argv[1] < '0' είναι λάθος γιατί συγκρίνει τον ASCII κωδικό του χαρακτήρα που γράψαµε µε τον ASCII κωδικό του '0'. Αν γράψω A, που έχει µεγαλύτερο ASCII κωδικό από το '0', το πρόγραµµά σου θα το θεωρήσει έγκυρο, ενώ δεν πρέπει. 1842 Καλή δουλειά 1846 FAIL 1852 - H srand() δεν χρειάζετια να καλείται κάθε φορά που καλείται η rand(). Μία φορά αρκεί στην αρχή του προγράµµατος. - Αντί για την isprior που έφτιαξες µπορείς να χρησιµοποιείς strcmp. - Αντί για την iswordsuitable που έφτιαξες µπορείς να χρησιµοποιείς strlen. - Καλή ιδέα ο διαχωρισµός σε αρχεία των συναρτήσεων ανάλογα µε την λειτουργία τους. - Πρόσεξε την στοίχιση σου και την µίξη tab και spaces στον editor για στοίχιση (δες το list.h)
1865 FAIL Απουσία από προφορική εξέταση. 1867 FAIL 1880 Καλή δουλειά 1900 Γενικά ικανοποιητική δουλειά µε εξαίρεση την αδυναµία σας να καταστρέψετε άδεια λίστα. 1968 FAIL Μη ικανοποιητική απόδοση στην προφορική εξέταση. 2004 - Ο χειρισµός του argv δεν είναι σωστός. Το *argv[1]-'0' θα σου δώσει σωστό αποτέλεσµα µόνο αν το όρισµα είναι µονοψήφιος ακέραιος. Έπρεπε να είχες χρησιµοποιήσει atoi. - Στην free_list δε χρειάζεται να θέτεις τους prev pointers. - Καλή δουλειά κατά τα άλλα. 2018 FAIL 2024 FAIL Ηµιτελές 2032 FAIL Ηµιτελές 2057 Καλή δουλειά 2090 Καλή δουλειά 2093 FAIL Μη ικανοποιητική απόδοση στην προφορική εξέταση.