Προγραμματισμός II

Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr

Εισαγωγή στο μάθημα

Καλώς ήρθατε

Προγραμματισμός II

Αυτοαξιολόγηση

Πόσο άνετα προγραμματίζετε στη Java;

Στόχοι του μαθήματος

Στόχος του μαθήματος είναι όσοι το παρακολουθήσουν να είναι σε θέση να:

Τρόπος διδασκαλίας

Οι σημειώσεις

Επικοινωνία

Βαθμολογία

Ο τελικός βαθμός κάθε φοιτήτριας ή φοιτητή θα βασίζεται σε 3 κριτήρια: Προσοχή:

Ασφαλιστικές δικλίδες

Βαθμολογία χωρίς ομαδική εργασία

Σε περίπτωση μη συμμετοχής στην ομαδική εργασία, για να είναι δίκαιος ο βαθμός για τα άτομα που κάνουν την ομαδική εργασία, υπολογίζεται διαφορετικά:

Αξιολόγηση συμμετοχής

HMAC QR participation token

Στατιστικά στοιχεία

Επιδόσεις στις εξετάσεις στο τέλος του εξαμήνου.
ΈτοςΕξετάσειςΑσκήσειςΒαθμόςΕπιτυχία
20267.28.97.782%
20257.58.77.883%
20236.98.87.682%
20226.98.37.578%
20217.79.17.580%
20187.79.18.593%
20178.08.88.390%
20167.29886%
20157.69.18.194%
20146.597.381%
20136.29.37.574%
20126.59.37.383%
20117.39.38.389%
20107.69.38.390%
200979.18.190%

Οι ασκήσεις

Χρήση του συστήματος των ασκήσεων jarpeb

Για να χρησιμοποιήσετε το σύστημα πρέπει:

Παράδοση της βαθμολογίας

Καθυστερημένη παράδοση

Χρήση ΠΤΝ

Για τη χρήση παραγωγικής τεχνητής νοημοσύνης (π.χ. ChatGPT, Claude, Bard, GitHub Copilot) ισχύουν τα εξής.

Διαθέσιμα συγγράμματα

Πρόσθετα δωρεάν συγγράμματα

Επίσης διαθέσιμα στις φοιτήτριες και στους φοιτητές του ΟΠΑ μέσω του HEAL-Link:

Βιβλιογραφία για προγραμματισμό

Βιβλιογραφία για τη Java

Επισκόπηση θεωρίας

Επισκόπηση των ασκήσεων

  1. εξοικείωση με τις ασκήσεις
  2. ορίσματα, εκφράσεις, βρόχοι και αποφάσεις
  3. δημιουργία αντικειμένων και πρόσβαση στις μεθόδους τους
  4. δημιουργία μιας κλάσης
  5. κληρονομικότητα
  6. παραγωγή και έλεγχος εξαιρέσεων
  7. προγραμματισμός με συμβολοσειρές
  8. μετασχηματισμός αρχείου κειμένου
  9. μια απλή γραφική εφαρμογή
  10. επεξεργασία XML
  11. επικοινωνία πελάτη-εξυπηρετητή
  12. χρήση νημάτων και παραμετρικών τύπων
  13. προγραμματισμός σε ζεύγη
  14. αναδρομικές συναρτήσεις
  15. μορφοποίηση
  16. διεπαφές

Δουλειά για το επόμενο μάθημα

Γλώσσες και περιβάλλοντα ανάπτυξης

Ιστορική ανασκόπηση

Διαδικασιακές γλώσσες

Σε μια αλγοριθμική (imperative) (ή προστακτική ή επιτακτική ή διαδικαστική (procedural)) γλώσσα το πρόγραμμα εκφράζει άμεσα τα βήματα που επιθυμούμε να εκτελέσει ο υπολογιστής.

Τιμές, τύποι και μεταβλητές

Εκφράσεις και τελεστές

Μηχανισμοί αφαίρεσης

Μηχανισμοί ελέγχου της ροής

Αντικειμενοστρεφείς γλώσσες

  • Χαρακτηριστικές γλώσσες: Smalltalk, Squeak, C++, Java, C#, Python, Ruby, JavaScript, TypeScript, Swift

    Συναρτησιακός προγραμματισμός

    Χαρακτηριστικά συναρτησιακού προγραμματισμού

    Γλώσσες ολοκλήρωσης

    Θέματα για μελέτη

    1. Τι κάνει μια γλώσσα κατάλληλη για την υλοποίηση επιχειρηματικών εφαρμογών;
    2. Με ποιον τύπο δεδομένων θα παραστήσετε στη Java χρηματικά ποσά; Δώστε παραδείγματα.

    Άσκηση: εξοικείωση με τις ασκήσεις

    Άσκηση 1

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Τεχνολογίες μεταγλώττισης και εκτέλεσης

    Το χάσμα υλικού και λογισμικού

    Οι δυνατότητες που προσφέρει το υλικό και το λογισμικό έρχονται συχνά σε αντίθεση ή αλληλοσυμπληρώνονται. Οι γλώσσες προγραμματισμού και τα λειτουργικά συστήματα είναι δύο τεχνολογίες που επιτρέπουν τη βέλτιστη συνύπαρξη του υλικού με το λογισμικό.

    Υλοποίηση γλωσσών προγραμματισμού

    Μια γλώσσα προγραμματισμού μπορεί - ανάλογα με τη γλώσσα - να υλοποιηθεί με τους παρακάτω τρόπους: καθώς και με συνδυασμούς τους.

    Αρχιτεκτονική του μεταγλωττιστή

    Η διεργασία της μεταγλώττισης μπορεί να διαχωριστεί στις παρακάτω ξεχωριστές λειτουργίες οι οποίες εκτελούνται σε διαδοχικές φάσεις:

    Λεκτική ανάλυση

    Ο λεκτικός αναλυτής παρέχει τις παρακάτω λειτουργίες: Με τον τρόπο αυτό διαχωρίζονται οι εργασίες της λεκτικής και της συντακτικής ανάλυσης και κάθε μια υλοποιείται με τον πιο αποδοτικό τρόπο.

    Λεκτικές μονάδες

    Χρήση λεκτικών μονάδων

    Η σημασία των σημείων στοίξης

    Η σημασία των σημείων στοίξης

    Ο συντακτικός αναλυτής

    Ο συντακτικός αναλυτής:

    Παράδειγμα

    
        i = 0;
        while ( i < 10) {
            System.out.println(i);
            i = i + 1;
        }
    

    (Το δέντρο μπορεί να κατασκευαστεί και ζωντανά από 17 άτομα.)

    Συντακτικό δένδρο

    Parse graph

    Παραγωγή κώδικα

    Η παραγωγή κώδικα αποτελεί το πιο ενδιαφέρον και σύνθετο στάδιο της μεταγλώττισης. Κατά το στάδιο αυτό μπορούν να υλοποιηθούν τεχνικές βελτιστοποίησης προσανατολισμένες στη συγκεκριμένη γλώσσα ή αρχιτεκτονική και να υλοποιηθούν αλγόριθμοι βέλτιστης χρήσης των στοιχείων της αρχιτεκτονικής. Η παραγωγή του τελικού εκτελέσιμου κώδικα μπορεί να διακριθεί στα παρακάτω στάδια:

    Βελτιστοποίηση του ενδιάμεσου κώδικα

    Η βελτιστοποίηση του κώδικα μετασχηματίζει τον κώδικα σε μια μορφή που παράγει τα ίδια αποτελέσματα με τον αρχικά αλλά βελτιωμένα κάποια κριτήρια απόδοσης. Τέτοια κριτήρια μπορεί να είναι:

    Πλεονεκτήματα βελτιστοποίησης

    Η βελτιστοποίηση μπορεί να απαλλάξει τον προγραμματιστή από αντιπαραγωγικές αλλαγές του κώδικα που έχουν ως στόχο να ικανοποιήσουν τα κριτήρια αυτά και να του επιτρέψει να συγκεντρωθεί σε άλλα ποιοτικά στοιχεία του παραγόμενου κώδικα όπως την ορθότητα, την ασφάλεια, τη διαθεσιμότητα, τη συντηρησιμότητα, και τη μεταφερσιμότητα. Συχνά βελτιστοποιήσεις που γίνονται από τον προγραμματιστή έρχονται σε αντίθεση με τα παραπάνω ποιοτικά στοιχεία.

    Παράδειγμα βελτιστοποίησης

    Απαλοιφή κοινών υποεκφράσεων (common subexpression elimination)
    Εκφράσεις με κοινά στοιχεία υπολογίζονται μόνο μια φορά. Η ακολουθία:
    
    x = b / c;
    y = 42 + b / c;
    
    μετασχηματίζεται στην ακολουθία:
    
    x = b / c;
    y = 42 + x;
    

    Παράδειγμα βελτιστοποίησης

    Μετακίνηση κώδικα βρόχων (loop code motion)
    Εκφράσεις που δεν αλλάζουν μέσα σε ένα βρόχο μετακινούνται έξω από αυτόν. Η ακολουθία:
    
    {
        int a, b, z;
    
        a = 8; b = 4;
        for (i = 0; i < 10; i++) {
            z = a / b;
            System.out.println(z);
        }
    }
    
    μετασχηματίζεται στην ακολουθία:
    
    {
        int a, b, z;
    
        a = 8; b = 4;
        z = a / b;
        for (i = 0; i < 10; i++) {
            System.out.println(z);
        }
    }
    

    Παράδειγμα βελτιστοποίησης

    Απαλοιφή άχρηστου κώδικα (dead code removal)
    Κώδικας που δεν εκτελείται ποτέ απαλείφεται. Η ακολουθία:
    
    {
        int a, q;
    
        q = 48;
        return (q);
        a = q / 2;
    }
    
    μετασχηματίζεται στην ακολουθία:
    
    {
        int a, q;
    
        q = 48;
        return (q);
    }
    

    Παράδειγμα βελτιστοποίησης

    Απαλοιφή κλήσεων σε συναρτήσεις (function inlining)
    Κλήσεις σε συναρτήσεις μετασχηματίζονται σε απευθείας χρήση του αντίστοιχου κώδικα. Η ακολουθία:
    
    static int
    square(int a) {
        return (a * a);
    }
    
    public static void main(String args[]) {
        System.out.println(square(12));
    }
    
    μετασχηματίζεται στην ακολουθία:
    
    public static void main(String args[]) {
        System.out.println(12 * 12);
    }
    

    Παράδειγμα βελτιστοποίησης

    Απαλοιφή αναδρομής από το τέλος συνάρτησης (tail recursion elimination)
    Αναδρομή στο τέλος μιας συνάρτησης μετασχηματίζεται σε βρόχο. Η ακολουθία:
    
    foo() {
        System.out.println("foo");
        foo();
    }
    
    μετασχηματίζεται στην ακολουθία:
    
    foo() {
        for (;;)
            System.out.println("foo");
    }
    

    Βελτιστοποίηση του τελικού κώδικα

    Συχνά ο τελικός κώδικας που παράγεται μπορεί να περιέχει ακολουθίες εντολών οι οποίες να μπορούν να βελτιστοποιηθούν για το συγκεκριμένο επεξεργαστή. Οι ακολουθίες αυτές μπορούν να βρεθούν εξετάζοντας ένα μικρό παράθυρο του τελικού κώδικα, όπως αυτό θα φαίνονταν κοιτάζοντας τον κώδικα από μια κλειδαρότρυπα. Για το λόγο αυτό οι βελτιστοποιήσεις αυτές λέγονται και βελτιστοποιήσεις κλειδαρότρυπας (peephole optimizations).

    Παράδειγμα βελτιστοποίησης τελικού κώδικα

    Η ακολουθία:
    
        mov $12, %rax
        mov %rax, %rbx
        mov $20, %rax
    
    μετασχηματίζεται στην ακολουθία:
    
        mov $12, %rbx
        mov $20, %rax
    
    Επίσης η διάταξη των εντολών μπορεί να βελτιωθεί για να γίνεται καλύτερη χρήση πολλαπλών υπολογιστικών στοιχείων που διαθέτει ο επεξεργαστής. Για παράδειγμα σε ορισμένους επεξεργαστές η εναλλαγή εντολών κινητής υποδιαστολής με εντολές ακεραίων επιτρέπει στις δύο λειτουργικές μονάδες να δουλεύουν παράλληλα.

    Σύνδεση

    Κατά τη σύνδεση τα ανεξάρτητα μεταγλωττισμένα τμήματα του προγράμματος συνδέονται μεταξύ τους και με τις βιβλιοθήκες της γλώσσας για να δημιουργηθεί το τελικό εκτελέσιμο πρόγραμμα. Συχνά οι βιβλιοθήκες που χρησιμοποιούνται είναι κοινές ανάμεσα σε προγράμματα και φορτώνονται δυναμικά κατά το στάδιο εκτέλεσης του προγράμματος (Unix shared libraries, Windows DLLs). Κατά τη φάση της σύνδεσης γίνεται έλεγχος πως όλες οι συναρτήσεις και μεταβλητές που χρησιμοποιούνται έχουν οριστεί και, για ορισμένες γλώσσες όπως η C++, πως οι τύποι των συμβόλων που έχουν οριστεί σε διαφορετικά αρχεία είναι συμβατοί μεταξύ τους. Ορισμένες γλώσσες όπως η Java υλοποιούν μεγάλο μέρος της σύνδεσης κατά τη φόρτωση του προγράμματος στη μνήμη για εκτέλεση.

    Ιδεατές μηχανές

    Μια ιδεατή μηχανή (virtual machine) εμφανίζει στο λογισμικό που τρέχει πάνω σε αυτήν μια διαφορετική διεπαφή από αυτή στην οποία βασίζεται η μηχανή για την υλοποίησή της. Συχνά οι ιδεατές μηχανές υλοποιούνται σε ιεραρχία.

    Πλεονεκτήματα και προβλήματα ιδεατών μηχανών

    Διαχείριση μνήμης

    Κατά τη διάρκεια ζωής του προγράμματος υπάρχουν απαιτήσεις για τη φύλαξη δεδομένων με διαφορετική διάρκεια ζωής. Συγκεκριμένα, πρέπει να υπάρχει υποστήριξη για δεδομένα που διατηρούνται:

    Παράδειγμα διάταξης μνήμης

    Στοίβα (stack)
    ...

    ...
    Σωρός (heap)
    (Δυναμική μνήμη)
    ...
    Στατικά δεδομένα (static data)
    ...
    Μεταγλωττισμένος κώδικας (code (text))

    Τρόποι διαχείρισης μνήμης

    Όταν ο όγκος της κύριας μνήμης του υπολογιστή δεν επαρκεί μπορεί να χρησιμοποιηθεί:

    Τέλος, για οικονομία στο χώρο που απαιτεί ο κώδικας των προγραμμάτων σε δευτερεύουσα αποθήκευση, χρησιμοποιούνται συχνά μοιρασμένες βιβλιοθήκες (shared libraries) (π.χ. .DLL, .so).

    Άσκηση: ορίσματα, εκφράσεις, βρόχοι και αποφάσεις

    Άσκηση 2

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Προγραμματισμός με αντικείμενα

    Αντικείμενα

    Κλάσεις

    Δημιουργία νέων αντικειμένων

    Καθορισμός μνήμης αντικειμένων με new

    Καθορισμός μνήμης αντικειμένων με αναφορά

    Κλήση μεθόδων

    Πρόσβαση σε ιδιότητες

    Ορατότητα

    Παράδειγμα: Point

    
    class Point {
      // Public fields
      public int x, y;
      private boolean visible;
      private int serialNumber;
      // Private method
      private void setpos(int sx, int sy) {
        x = sx;
        y = sy;
      }
      // Public methd
      public void moveToCenter() {
        setpos(0, 0);
      }
    
    }
    

    Παράδειγμα: TestPoint

    
    class TestPoint {
      public static void main(String args[])
      {
        Point a;
    
        a = new Point();
        a.moveToCenter();
        // Use public field
        a.x = 10;
      }
    }
    

    Μέθοδοι κατασκευαστές

    Κλήση κατασκευαστών

    Ιδιότητες και μέθοδοι κλάσης

    Δήλωση μεταβλητών με var

    Παράδειγμα: εύρεση ημέρας

    
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    
    class FindDay {
      /** Return the name of the given numeric week day */
      public static String weekDayName(int weekNumber) {
        return switch (weekNumber) {
          case Calendar.MONDAY -> "Δευτέρα";
          case Calendar.TUESDAY -> "Τρίτη";
          case Calendar.WEDNESDAY -> "Τετάρτη";
          case Calendar.THURSDAY -> "Πέμπτη";
          case Calendar.FRIDAY -> "Παρασκευή";
          case Calendar.SATURDAY -> "Σάββατο";
          case Calendar.SUNDAY -> "Κυριακή";
          default -> throw new IllegalStateException("Unexpected value: " + weekNumber);
        };
      }
    
      public static void main(String args[]) throws Exception {
      // ...
    }
    

    Παράδειγμα: εύρεση ημέρας (main)

    
      public static void main(String[] args) throws Exception {
          // Are appropriate arguments given?
          if (args.length != 3) {
            System.err.println("usage: FindDay year month day");
            System.exit(1);
          }
    
          // Parse year, month, day
          int year = Integer.parseInt(args[0]);
          int month = Integer.parseInt(args[1]) - 1;
          int monthDay = Integer.parseInt(args[2]);
    
          // Set the calendar and calculate the day name
          var d = new GregorianCalendar(year, month, monthDay);
          String dn = weekDayName(d.get(Calendar.DAY_OF_WEEK));
    
          // Print the day name
          System.out.println(dn);
        }
    

    Μέθοδοι όλων των αντικειμένων

    Άσκηση: δημιουργία αντικειμένων και πρόσβαση στις μεθόδους τους

    Άσκηση 3

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Δημιουργία κλάσεων

    Ορισμός κλάσεων

    Ορισμός πεδίων υπόστασης

    Ορισμός μεθόδων υπόστασης

    Πρόσβαση στα μέλη της κλάσης

    Πρόσβαση στα μέλη της κλάσης: παράδειγμα

    Μέθοδοι κατασκευής

    Μέθοδοι κατασκευής: παράδειγμα

    
    class Point {
        /* Fields */
    
        /** Point x coordinate */
        private int x;
        /** Point y coordinate */
        private int y;
    
        /* Methods */
        /** Default constructor */
        Point() { x = y = 0; }
        /** Constructor with coordinates */
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    

    Έλεγχος πρόσβασης

    Κάθε μέθοδος ή πεδίο μπορεί να έχει ως προσδιοριστή
    public
    Το μέλος είναι ορατό σε όλες τις άλλες κλάσεις
    private
    Το μέλος είναι ορατό μόνο στις μεθόδους της δικής μας κλάσης
    (τίποτα)
    Το μέλος είναι ορατό στις κλάσεις του πακέτου μας
    Μια καλοσχεδιασμένη κλάση έχει:

    Ορισμός ιδιοτήτων και μεθόδων κλάσης

    Παράδειγμα ιδιοτήτων και μεθόδων κλάσης

    Μπλοκ αρχικοποίησης

    Σε ανώνυμα μπλοκ { } στο σώμα της κλάσης μπορεί να τοποθετηθεί:

    Μπλοκ αρχικοποίησης: παράδειγμα

    
    import java.util.concurrent.ThreadLocalRandom;
    
    class IdentifiedPoint {
        private double x, y;
        /** Unique point identifier */
        int identifier;
        /** Provide an identifier for each point */
        private static int nextIdentifier;
    
        /** Class initialization block */
        static {
            nextIdentifier = ThreadLocalRandom.current().nextInt();
        }
    
        /** Instance initialization block */
        {
            identifier = nextIdentifier++;
        }
    
        /** Point constructor */
        IdentifiedPoint(int ix, int iy) {
            x = ix;
            y = iy;
        }
        /** Point constructor */
        IdentifiedPoint() {
            x = y = 0;
        }
    
        static public void main(String args[]) {
            var a = new IdentifiedPoint(1, 2);
            var b = new IdentifiedPoint();
            System.out.println(a.identifier);
            System.out.println(b.identifier);
        }
    }
    

    Εσωτερικές κλάσεις

    Μια κλάση μπορεί να οριστεί εσωτερικά:

    Παράδειγμα εσωτερικής κλάσης

    
    class Rectangle {
        private static class Point {
            private int x, y;
    
            /** Point constructor */
            Point(int ix, int iy) {
                x = ix;
                y = iy;
            }
        }
    
        private Point topLeft, bottomRight;
    
        /** Rectangle constructor */
        Rectangle(int x, int y, int height, int width) {
            topLeft = new Point(x, y);
            bottomRight = new Point(x + width, y + height);
        }
    }
    

    Παράδειγμα ανώνυμης κλάσης

    
    class InnerCall {
        public static void main(String args[]) {
            System.out.println(new Object());
            System.out.println(new Object() {
                @Override
                public String toString() {
                    return "I am a woke object";
                }
            });
        }
    }
    

    Απαριθμήσεις

    Παράδειγμα

    
    enum Ingredients {
      TOMATO,
      ONION,
      TZATZIKI,
      POTATO,
      MUSTARD,
      SOUVLAKI,
      GYROS
    }
    

    Χρήση απαριθμήσεων

    Απαρίθμηση ως κλάση

    Η αντίστοιχη κλάση χωρίς τη χρήση απαρίθμησης θα είχε την παρακάτω μορφή.
    
    public class Ingredients {
        // Static array to hold all ingredient constants
        private static final Ingredients[] VALUES = new Ingredients[7];
    
        // Constants with names and ordinal values
        public static final Ingredients TOMATO = new Ingredients("TOMATO", 0);
        public static final Ingredients ONION = new Ingredients("ONION", 1);
        public static final Ingredients TZATZIKI = new Ingredients("TZATZIKI", 2);
        public static final Ingredients POTATO = new Ingredients("POTATO", 3);
        public static final Ingredients MUSTARD = new Ingredients("MUSTARD", 4);
        public static final Ingredients SOUVLAKI = new Ingredients("SOUVLAKI", 5);
        public static final Ingredients GYROS = new Ingredients("GYROS", 6);
    
        private final String name;
        private final int ordinal;
    
        private Ingredients(String name, int ordinal) {
            this.name = name;
            this.ordinal = ordinal;
            VALUES[ordinal] = this;  // Add to the static array
        }
    
        // Getters
        public int ordinal() {
            return ordinal;
        }
    
        public String getName() {
            return name;
        }
    
        public static Ingredients[] values() {
            return VALUES.clone();  // Return a copy of the array
        }
    
        public static Ingredients valueOf(String name) {
            for (Ingredients ingredient : VALUES) {
                if (ingredient.name.equals(name)) {
                    return ingredient;
                }
            }
            throw new IllegalArgumentException("No enum constant " + name);
        }
    
        @Override
        public String toString() {
            return name;
        }
    }
    

    Πολυμορφισμός με ταίριαγμα προτύπων

    Με εντολές switch μπορούμε να γράψουμε κώδικα για συγκεκριμένους τύπους με βάση το ταίριασμα προτύπων (pattern matching).
    
    class PaternMatch {
    
        class RetailCustomer {}
        class BusinessCustomer {}
    
        /** Return the document a given object shall receive */
        private static String documentName(Object o) {
            return switch (o) {
                case RetailCustomer rc -> "receipt";
                case BusinessCustomer bc -> "invoice";
                default -> "unknown document";
            };
        }
    
        public static void main(String[] args) {
            var retailCustomer = new RetailCustomer();
            var businessCustomer = new BusinessCustomer();
            System.out.println("Retail customer gets "
                    + documentName( retailCustomer));
            System.out.println("Business customer gets "
                    + documentName(businessCustomer));
        }
    }
    

    Εγγραφές

    Παράδειγμα

    
    public class RecordDemo {
        record Point(int x, int y) {}
    
        public static void main(String[] args) {
            var a = new Point(5, 12); // Pythagorean triple
            System.out.println("Point " + a + " has magnitude "
                    + Math.sqrt(a.x() * a.x() + a.y() * a.y()));
        }
    }
    

    Εγγραφή ως κλάση

    Η αντίστοιχη κλάση χωρίς τη χρήση εγγραφής θα είχε την παρακάτω μορφή.
    
    public class Point {
        private final int x;
        private final int y;
    
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        // Getters
        public int getX() {
            return x;
        }
    
        public int getY() {
            return y;
        }
    
        // Object methods
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Point point = (Point) o;
            return x == point.x && y == point.y;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(x, y);
        }
    
        @Override
        public String toString() {
            return "Point{" + "x=" + x + ", y=" + y + '}';
        }
    }
    

    Ταίριαγμα προτύπων σε εγγραφές

    Σε εγγραφές μπορούμε να ταιριάξουμε και τα ορίσματά τους.
    
    class PaternMatch {
    
        record Point2D(double x, double y) {}
        record Point3D(double x, double y, double z) {}
    
        /** Output the magnitude of the specified object */
        private static void printMagnitude(Object o) {
            System.out.println("Magnitude of " + o + " is " +
                switch (o) {
                    case Point2D(double x, double y) -> Math.sqrt(x * x + y * y);
                    case Point3D(double x, double y, double z) ->
                        Math.sqrt(x * x + y * y + z * z);
                    default -> throw new IllegalArgumentException("Unexpected type: "
                            + o.getClass().getName());
                }
            );
        }
    
        public static void main(String[] args) {
            printMagnitude(new Point2D(3, 4)); // Pythagorean triple
            printMagnitude(new Point3D(1, 4, 8)); // Pythagorean quadruple
        }
    }
    

    Το σχεδιαστικό πρότυπο singleton

    Παράδειγμα singleton

    Άσκηση: δημιουργία μιας κλάσης

    Άσκηση 4

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Κληρονομικότητα

    Εισαγωγή

    Διάγραμμα κληρονομικότητας

    Κληρονομικότητα σε κλάσεις

    Υπερφόρτωση

    Παράδειγμα: σχήματα

    
    class Shape {
        private int x, y;       // Position
        public void setPosition(int px, int py) {
            x = px;
            y = py;
        }
    
        @Override public String toString() {
            return "Shape(" + x + ", " + y + ")";
        }
    }
    
    class Circle extends Shape {
        private int radius;
        public void setRadius(int r) {
            radius = r;
        }
    
        @Override public String toString() {
            return super.toString() + ": Circle(" + radius + ")";
        }
    }
    
    class Rectangle extends Shape {
        private int height, width;
    
        public void setDimensions(int h, int w) {
            height = h;
            width = w;
        }
    
        @Override public String toString() {
            return super.toString() + ": Rectangle(" + height + " x " + width + ")";
        }
    }
    
    class Test1 {
        static public void main(String args[])
        {
            Circle c = new Circle();
            Rectangle r = new Rectangle();
    
            r.setPosition(1, 2);
            r.setDimensions(50, 50);
            c.setPosition(3, 4);
            c.setRadius(10);
            System.out.println(r);
            System.out.println(c);
        }
    }
    

    Σχήματα: διάγραμμα

    Ο προσδιοριστής protected

    Δυναμική διεκπεραίωση

    Παράδειγμα δυναμικής διεκπεραίωσης

    
    static public void main(String args[])
    {
        Rectangle r = new Rectangle();
        Shape s;
    
        r.setPosition(1, 2);
        r.setDimensions(50, 50);
        s = r;
        s.setPosition(10, 20);
        System.out.println(r);
        System.out.println(s);
        r = (Rectangle)s;
    }
    

    Λειτουργία δυναμικής διεκπεραίωσης

    Πλεονεκτήματα της δυναμικής διεκπεραίωσης

    Σφραγισμένες κλάσεις

    Με τους προσδιοριστές sealed και permits μπορούμε να ορίσουμε ποιες κλάσεις επιτρέπεται να επεκτείνουν τη μητρική κλάση.
    
    public sealed class Shape permits Circle, Rectangle {
    }
    
    class Circle extends Shape {
    }
    
    class Rectangle extends Shape {
    }
    

    Αφηρημένες κλάσεις

    Σχεδιάζοντας με αφηρημένες κλάσεις

    Παράδειγμα: σχήματα

    Σχήματα: ο κώδικας

    
    abstract class Shape {
        private double x, y;        // Position
        protected double getX() { return x; }
        protected double getY() { return y; }
        public void setposition(double px, double py) {
            x = px;
            y = py;
        }
        public abstract double area();
        @Override public String toString() {
            return "Shape(x=" + x + ", y=" + y + ", area=" + area() + ")";
        }
    }
    
    class Circle extends Shape {
        private double radius;
        public void setradius(double r) {
            radius = r;
        }
        @Override public double area() {
            return Math.PI * radius * radius;
        }
        @Override public String toString() {
            return super.toString() + ": Circle(" + radius + ")";
        }
    }
    
    class Rectangle extends Shape {
        private double height, width;
        public void setdimensions(double h, double w) {
            height = h;
            width = w;
        }
        @Override public double area() {
            return height * width;
        }
        @Override public String toString() {
            return super.toString() + ": Rectangle(" + height + " x " + width + ")";
        }
    }
    
    class Test2 {
        static public void main(String args[])
        {
            Circle c = new Circle();
            Rectangle r = new Rectangle();
            Shape s[] = new Shape[2];
    
            s[0] = r;
            r.setposition(1, 2);
            r.setdimensions(50, 50);
    
            s[1] = c;
            c.setposition(3, 4);
            c.setradius(10);
            for (int i = 0; i < s.length; i++)
                System.out.println(s[i]);
        }
    }
    
    Το παραπάνω πρόγραμμα θα τυπώσει:
    Shape(x=1.0, y=2.0, area=2500.0): Rectangle(50.0 x 50.0)
    Shape(x=3.0, y=4.0, area=628.3185307179587): Circle(10.0)
    

    Τελικές μεταβλητές

    Τελικά ορίσματα

    Τελικά πεδία

    Πόσα σχόλια είναι αρκετά;

    Unneeded comments

    Σχόλια για τα σχόλια

    Έλεγχοι

    Τι να αποφεύγετε

    Οδηγίες και παράδειγμα μορφοποίησης κώδικα

    
    /*
     * Όνομα της κλάσης
     *
     * Copyright έτος όνομα/οργανισμός.
     */
    
    
    
    
    package gr.aueb.dmst.Package;
    
    
    
    import java.blah.blough.bligh;
    
    
    
    
    /**
     * Σύνοψη της κλάσης σε μια γραμμή.
     * Αναλυτική περιγραφή της κλάσης.
     *
     * @version     1.82 18 Mar 1999
     * @author      Όνομα Επώνυμο
     */
    
    
    public class SpecialHtmlParser extends FileHtmlParser {
    
    
        /*
         * Εδώ γράφεται το σχόλιο υλοποίησης της κλάσης.
         */
    
    
    
        /** Σύνοψη του πεδίου κλάσης classVar1 */
        public static int classVar1;
    
    
    
        /** Σύνοψη του πεδίου κλάσης classVar2 */
        protected static int classVar2;
    
    
    
        /** Σύνοψη του πεδίου κλάσης classVar3 */
        static int classVar3;
    
    
    
        /** Σύνοψη του πεδίου κλάσης classVar3 */
        private static Object classVar3;
    
    
    
        /**
         * Σύνοψη του πεδίου υπόστασης instanceVar1
         * Εκτενής επεξήγηση του πεδίου instanceVar1 σε πολλαπλές
         * γραμμές
         */
        public int instanceVar1;
    
    
    
        /** Σύνοψη του πεδίου υπόστασης instanceVar2 */
        protected int instanceVar2;
    
    
    
        /** Σύνοψη του πεδίου υπόστασης instanceVar3 */
        static int instanceVar3;
    
    
    
        /** Σύνοψη του πεδίου υπόστασης instanceVar4 */
        private Object instanceVar4;
    
    
    
        /** Construct a parser for the specified HTML dialect. */
        SpecialHtmlParser(string dialect, int maxNesting) {
            // Κώδικας
        }
    
    
    
        /** Construct a default HTML parser. */
        SpecialHtmlParser(string dialect, int maxNesting) {}
    
    
    
        /**
         * Σύνοψη της μεθόδου.
         * Εκτενής επεξήγηση της μεθόδου σε πολλαπλές
         * γραμμές.
         */
        public void doSomething() {
    
    
        int nLines = 0;                // HTML lines in the file
        int nChars = 0                // Number of characters in the file
        int i;
        double averageDensity = 1.;        // Average density of comments in the file
        Car transport;                // Transport to use
    
    
    
            for (;;)
                a++;
    
    
            for (int j = 0; j < 10; j++) {
                a++;
                b++;
            }
    
    
            while (a < 10) {
                a++;
                b += 12;
            }
    
    
            while (a < 10) {
                a++;
                for (int i = 0; i < 10; i++)
                    b += 12;
            }
    
    
            do {
                a++;
                b += 12;
            } while (a < 10);
    
    
            switch (c) {
            case 'a':
                system.out.println("Alpha");
                break;
            case 'b':
                system.out.println("Bravo");
                break;
            case 'c':
                system.out.println("Charlie");
                break;
            default:
                system.out.println("???");
                break;
            }
    
    
            if (a == 3) {
                system.out.println("Threee");
                k = 52;
            }
    
    
            if (a == 3) {
                system.out.println("Three");
                k = 52;
            } else {
                system.out.println("Not three");
                k = 55;
            }
    
    
            if (a == 3)
                system.out.println("Three");
            else
                system.out.println("Not three");
    
    
            if (s.equals("a")
                system.out.println("Alpha");
            else if (s.equals("b")
                system.out.println("Bravo");
            else if (s.equals("c")
                system.out.println("Charlie");
            else
                system.out.println("???");
    
    
            try {
                i = 12;
                o.myMethod();
            } catch (ExceptionClass e) {
                statements;
            } finally {
                statements;
            }
    
    
        if (a && !b) {
            a = 2 * (3 + 8) % 15;
            k = a.myMethod(q, b, c);
        }
        return k;
    
    
       /**
        * Returns an Image object that can then be painted on the screen.
        * The url argument must specify an absolute {@link URL}. The name
        * argument is a specifier that is relative to the url argument.
        * <p>
        * This method always returns immediately, whether or not the
        * image exists. When this applet attempts to draw the image on
        * the screen, the data will be loaded. The graphics primitives
        * that draw the image will incrementally paint on the screen.
        *
        * @param  url  an absolute URL giving the base location of the image
        *         name the location of the image, relative to the url argument
        * @return      the image at the specified URL
        * @see         Image
        */
        public Image getImage(URL url, String name) {
            try {
                return getImage(new URL(url, name));
            } catch (MalformedURLException e) {
                return null;
            }
        }
    
    
         /*
          * A non-javadoc comment with a special keyword
          * (recommended keywords in parenthesis)
          *
          * (XXX, FIXME, TODO): The comment
          */
    
    Σημείωση: οι στηλοθέτες (tab) πρέπει να αντιστοιχούν σε 8 κενά, έστω και αν πάντα η στοίχιση γίνεται σε 4 κενά. Στο διορθωτή vim οι σωστές ρυθμίσεις είναι:
    set shiftwidth=4
    set smarttab
    

    Βιβλιογραφία

    Πρόσθετες πληροφορίες

    Ασκήσεις

    Άσκηση 15

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Γενικεύσεις και νήματα

    Παραμετρικοί τύποι

    Παράδειγμα: ζευγάρι

    
    class Pair <E1, E2> {
        private final E1 element1;
        private final E2 element2;
        public Pair(final E1 e1, final E2 e2) {
            element1 = e1;
            element2 = e2;
        }
        public E1 getFirst() {
            return element1;
        }
        public E2 getSecond() {
            return element2;
        }
        @Override
        public String toString() {
            return "(" + element1.toString() + ", " + element2.toString() + ")";
        }
    }
    
    class Sock {}
    class Man {}
    class Woman {}
    
    class Test {
        public static void main(String args[]) {
            Pair <Sock, Sock> pairOfSocks;
            Pair <Man, Woman> churchMarriedCouple;
            Pair <Man, Man> civilPartners;
        }
    }
    

    Παραμετρικοί τύποι στη Java

    Παραμετρικοί τύποι μπαλαντέρ

    Παράδειγμα γενίκευσης

    
    class LinkedList <E> {
        /** Node's value */
        private E value;
        /** Next node */
        private LinkedList <E> next;
    
        /** Construct a list with a single element v */
        LinkedList(final E v) {
            value = v;
            next = null;
        }
    
        /** Return a list with element n added to it */
        public LinkedList <E> add(final E v) {
            var n = new LinkedList <E>(v);
            n.next = this;
            return n;
        }
    
        /** Return a string representation of the list */
        @Override
        public String toString() {
            final String me = value.toString();
    
            /* Recursive implementation */
            if (next == null)
                return me;
            else
                return me + " -> " + next;
        }
    
        /** Test harness */
        static public void main(String args[]) {
            var ilst = new LinkedList <Integer>(0);
    
            ilst = ilst.add(1);
            ilst = ilst.add(18);
            ilst = ilst.add(45);
    
            for (int i = 0; i < 5; i++)
                ilst = ilst.add(i * 10);
            System.out.println(ilst);
        }
    }
    

    Παράδειγμα υπερφόρτωσης μεθόδων

    
    double
    square(final double x)
    {
      return x * x;
    }
    
    Complex
    square(final Complex x)
    {
      return new Complex(
        square(x.real) + square(x.imaginary),
        2 * x.real + x.imaginary);
    }
    

    Ανακεφαλαίωση πολυμορφισμού

    Έχουμε στο σημείο αυτό εξετάσει όλα τα είδη πολυμορφισμού (polymorphism):

    Χρήση πολυμορφισμού

    Σε συνηθισμένες εφαρμογές σχεδιάζουμε συχνά με κληρονομικότητα διεπαφών, ενώ συναντάμε:

    Διάγραμμα πολυμορφισμού

    polymorpism types

    Νήματα

    Αδιέξοδο

    ="Παράδειγμα"

    Νήματα: προβλήματα

    Όταν υλοποιούμε κώδικα με νήματα δημιουργούνται συχνά προβλήματα συγχρονισμού που πρέπει να αντιμετωπίσουμε. Τα στοιχεία αυτά δεν καλύπτονται στο συγκεκριμένο μάθημα.
  • Νήματα: εναλλακτικές

    Αντί για νήματα μπορούμε συχνά να χρησιμοποιήσουμε

    Ορισμός νήματος στη Java

    Χρήση νήματος στη Java

    Παράδειγμα χρήσης νημάτων

    
    public class CocktailGuest implements Runnable {
        /** What the guest will say */
        private final String mumble;
        /** How many seconds will he/she pause before speaking */
        private final int pause;
        /** How long the guest will stay */
        private final int stay;
        /** How long the guest has stayed */
        private int hereFor;
    
        /** Constructor */
        public CocktailGuest(String mumble, int pause, int stay) {
            this.mumble = mumble;
            this.pause = pause;
            this.stay = stay;
            hereFor = 0;
        }
    
        /** Execution method */
        @Override
        public void run() {
            try {
                while (hereFor < stay) {
                    Thread.sleep(pause * 1000);
                    hereFor += pause;
                    System.out.println(mumble);
                }
            } catch (InterruptedException e) {
                System.out.println("Something has come up; got to go.");
                return;
            } finally {
                System.out.println("Good bye.");
            }
        }
    
        public static void main(String args[]) {
            final int NGUEST = 5;
            var guest = new CocktailGuest[NGUEST];
            var thread = new Thread[NGUEST];
    
            int i = 0;
            guest[i++] = new CocktailGuest("Can I have another drink?", 8, 30);
            guest[i++] = new CocktailGuest("Nice food!", 7, 120);
            guest[i++] = new CocktailGuest("Ha ha ha...", 3, 100);
            guest[i++] = new CocktailGuest("Hi, I am Maria.", 5, 60);
            guest[i++] = new CocktailGuest("Hello, I am Petros.", 15, 60);
    
            // Create the threads
            for (i = 0; i < NGUEST; i++)
                thread[i] = new Thread(guest[i]);
            // Start the threads
            for (i = 0; i < NGUEST; i++)
                thread[i].start();
        }
    }
    

    Άσκηση: χρήση παραμετρικών τύπων και νήματα

    Άσκηση 12

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Δημιουργία γραφικών εφαρμογών

    Στοιχεία της εφαρμογής

    Οι εφαρμογές μπορούν διαχωριστούν ανάλογα με την μέθοδο διεπαφής με τον χρήστη σε

    Συστατικά εισαγωγής δεδομένων

    Συστατικά εμφάνισης δεδομένων

    Επίδειξη συστατικών

    Κατεβάστε και τρέξτε το πρόγραμμα SwingSet2.jar.

    Προγραμματιστική διεπαφή συστατικών

    Παράθυρο (javax.swing.JFrame, Κλάση)

    Παράδειγμα: ένα κενό παράθυρο

    Το παρακάτω παράδειγμα δημιουργεί ένα κενό παράθυρο, θέτει ως τίτλο το αλφαριθμητικό "Hello, World!" και το εμφανίζει.

    
    import javax.swing.JFrame;
    
    public class Window {
        public static void main(String[] args) {
            JFrame jf = new JFrame("Hello, World!");
            
            jf.setBounds(0, 0, 800, 600);
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    }
    

    Προσαρμογή στο τοπικό περιβάλλον

    Μπορούμε να δώσουμε στην εφαρμογή την αίσθηση εφαρμογής φτιαγμένης ειδικά για το λειτουργικό περιβάλλον στο οποίο εκτελείται με τον παρακάτω κώδικα.
    
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }
    

    Προγραμματιστική διεπαφή συμβάντων

    Κουμπιά (javax.swing.JButton)

    Διαχειριστές διάταξης

    Οι διαχειριστές διάταξης (layout managers) είναι αόρατα συστατικά που καθορίζουν δυναμικά την τοποθέτηση των ορατών συστατικών (πχ κουμπιά, πίνακες) στην εφαρμογή. Οι κύριοι διαχειριστές διάταξης είναι:

    Προγραμματιστική διεπαφή διάταξης FlowLayout

    FlowLayout (java.awt.FlowLayout)

    Παράδειγμα διάταξης FlowLayout

    java.awt.FlowLayout
    
    import javax.swing.JFrame;
    import javax.swing.JButton;
    
    import java.awt.FlowLayout;
    
    public class FlowLayoutDemo {
        public static void main(String[] args) {
            JFrame jf = new JFrame("Hello, World!");
            
            jf.setBounds(0, 0, 800, 600);
            
            jf.setLayout(new FlowLayout());
            jf.add(new JButton("button 1"));
            jf.add(new JButton("button 2"));
            jf.add(new JButton("button 3"));
            
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    }
    

    Αποτέλεσμα διάταξης FlowLayout

    Προγραμματιστική διεπαφή διάταξης BorderLayout

    BorderLayout (java.awt.BorderLayout)

    Παράδειγμα διάταξης BorderLayout

    java.awt.BorderLayout
    
    import javax.swing.JFrame;
    import javax.swing.JButton;
    
    import java.awt.BorderLayout;
    
    public class BorderLayoutDemo {
        public static void main(String[] args) {
            JFrame jf = new JFrame("Hello, World!");
            
            jf.setBounds(0, 0, 800, 600);
            
            jf.setLayout(new BorderLayout());
            jf.add(new JButton("north"), BorderLayout.NORTH);
            jf.add(new JButton("south"), BorderLayout.SOUTH);
            jf.add(new JButton("center"), BorderLayout.CENTER);
            jf.add(new JButton("west"), BorderLayout.WEST);
            jf.add(new JButton("east"), BorderLayout.EAST);
            
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    }
    

    Αποτέλεσμα διάταξης BorderLayout

    Προγραμματιστική διεπαφή διάταξης GridLayout

    GridLayout (java.awt.GridLayout)

    Παράδειγμα διάταξης GridLayout

    java.awt.GridLayout
    
    import javax.swing.JFrame;
    import javax.swing.JButton;
    
    import java.awt.GridLayout;
    
    public class GridLayoutDemo {
        public static void main(String[] args) {
            JFrame jf = new JFrame("Hello, World!");
            
            jf.setBounds(0, 0, 800, 600);
            
            jf.setLayout(new GridLayout(3, 2));
            jf.add(new JButton("(1, 1)"));
            jf.add(new JButton("(1, 2)"));
            jf.add(new JButton("(2, 1)"));
            jf.add(new JButton("(2, 2)"));
            jf.add(new JButton("(3, 1)"));
            jf.add(new JButton("(3, 2)"));
            
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    }
    

    Αποτέλεσμα διάταξης GridLayout

    Προγραμματισμός με συμβάντα

    Η διαδραστικότητα στις εφαρμογές καθορίζεται από προκαθορισμένα συμβάντα. Η νοοτροπία τους είναι πολύ απλή:
    1. Επιλέγεται ένα γεγονός στο οποίο θέλουμε να επέμβουμε (πάτημα ένος πλήκτρου κτλ)
    2. Υλοποιόντας την κατάλληλη διεπαφή, γράφουμε το κομμάτι κώδικα που θέλουμε να εκτελεστεί για το συγκεκριμένο γεγονός
    3. Συσχετίζουμε το κομμάτι αυτό κώδικα με τη λίστα γεγονότων του συστατικού
    Τα γεγονότα είναι προκαθορισμένα και αφορούν είσοδο από το πληκτρολόγιο ή το ποντίκι, μετακινήσεις ή διαφοροποίηση του μεγέθους παραθύρων κτλ. Συνήθως οι κλάσεις που τα υλοποιούν βρίσκονται στο πακέτο java.awt.event.*.

    Παράδειγμα προγραμματισμού με συμβάντα

    
    import javax.swing.JFrame;
    import javax.swing.JButton;
    import javax.swing.JOptionPane;
    
    import java.awt.BorderLayout;
    
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class EventDemo {
        class AlertAction implements ActionListener {
            private JFrame parent;
    
            AlertAction(JFrame parent) {
                this.parent = parent;
            }
    
            @Override public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(parent, "information", "Button Pressed!!", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    
        public EventDemo() {
            JFrame jf = new JFrame("Hello, World!");
            JButton jb = new JButton("Click Me!");
    
            jf.setBounds(0, 0, 800, 600);
    
            jf.setLayout(new BorderLayout());
            jf.add(jb, BorderLayout.CENTER);
    
            jb.addActionListener(new AlertAction(jf));
    
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    
        public static void main(String[] args) {
            new EventDemo();
        }
    }
    

    Αποτέλεσμα προγραμματισμού με συμβάντα

    Συντεταγμένες γραφικών

    Συντεταγμένες γραφικών (διάγραμμα)

    Κλάση προγραμματιστικής διεπαφής χαμηλού επιπέδου

    java.awt.Graphics

    Μέθοδοι χαμηλού επιπέδου

    Παράδειγμα: Σχεδίαση κειμένου

    Όλες οι συναρτήσεις χαμηλού επιπέδου υλοποιούνται στην κλάση java.awt.Graphics. Η κλάση java.awt.Font διαθέτει κατασκευαστή που δέχεται 3 παραμέτρους:

    Κώδικας: Σχεδίαση κειμένου

    
    import javax.swing.JFrame;
    import javax.swing.JComponent;
    
    import java.awt.BorderLayout;
    import java.awt.Graphics;
    import java.awt.Font;
    
    public class TextDemo {
        class GraphicPane extends JComponent {
            public GraphicPane() {
                super();
            }
        
            @Override public void paint(Graphics g) {
                g.setFont(new Font(Font.SANS_SERIF, Font.ITALIC, 14));
                g.drawString("Hello, World!", 30, 30);
            }
        }
        
        public TextDemo() {
            JFrame jf = new JFrame("Hello, World!");
            GraphicPane gp = new GraphicPane();
            
            jf.setBounds(0,0, 800, 600);
            jf.setLayout(new BorderLayout());        
            jf.add(gp, BorderLayout.CENTER);
            
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    
        public static void main(String[] args) {
            new TextDemo();
        }
    }
    

    Αποτέλεσμα: Σχεδίαση κειμένου

    Παράδειγμα: Χειρισμός χρωμάτων

    Ο χειρισμός των χρωμάτων γίνεται μέσω της κλάσης java.awt.Color.
    
    import javax.swing.JFrame;
    import javax.swing.JComponent;
    
    import java.awt.BorderLayout;
    import java.awt.Graphics;
    import java.awt.Font;
    import java.awt.Color;
    
    public class ColorDemo {
        class GraphicPane extends JComponent {
            public GraphicPane() {
                super();
            }
        
            @Override public void paint(Graphics g) {
                g.setFont(new Font(Font.SANS_SERIF, Font.ITALIC, 14));
                g.setColor(Color.ORANGE);
                g.drawString("Hello, World! (orange)", 30, 30);
                g.setColor(new Color(250, 100, 120));
                g.drawString("Hello, World! (red ... almost)", 80, 80);
    
            }
        }
        
        public ColorDemo() {
            JFrame jf = new JFrame("Hello, World!");
            GraphicPane gp = new GraphicPane();
            
            jf.setBounds(0,0, 800, 600);
            jf.setLayout(new BorderLayout());        
            jf.add(gp, BorderLayout.CENTER);
            
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    
        public static void main(String[] args) {
            new ColorDemo();
        }
    }
    

    Αποτέλεσμα: Χειρισμός χρωμάτων

    Παράδειγμα: Σχεδίαση σχημάτων

    Κώδικας: Σχεδίαση σχημάτων

    
    import javax.swing.JFrame;
    import javax.swing.JComponent;
    
    import java.awt.BorderLayout;
    import java.awt.Graphics;
    import java.awt.Font;
    import java.awt.Color;
    
    public class ShapeDemo {
        class GraphicPane extends JComponent {
            public GraphicPane() {
                super();
            }
    
            @Override public void paint(Graphics g) {
                //// line
                g.setColor(Color.BLACK);
                // drawLine(int x1, int y1, int x2, int y2)
                g.drawLine(0, 0, 100, 100);
    
                //// ovals
                g.setColor(new Color(250, 100, 120));
                // drawOval(int x, int y, int width, int height)
                g.drawOval(30, 30, 100, 200);
                // same, but it fills the oval with the current color
                g.fillOval(300, 30, 100, 200);
    
                //// Rectangle
                g.setColor(Color.BLUE);
                // drawRect(int x, int y, int width, int height)
                g.drawRect(30, 300, 100, 200);
                // fillRect(int x, int y, int width, int height)
                g.fillRect(300, 300, 100, 200);
            }
        }
    
        public ShapeDemo() {
            JFrame jf = new JFrame("Hello, World!");
            GraphicPane gp = new GraphicPane();
    
            jf.setBounds(0,0, 800, 600);
            jf.setLayout(new BorderLayout());
            jf.add(gp, BorderLayout.CENTER);
    
            // Remember, the method show() is deprecated
            jf.setVisible(true);
        }
    
        public static void main(String[] args) {
            new ShapeDemo();
        }
    }
    

    Αποτέλεσμα: Σχεδίαση σχημάτων

    Παράδειγμα: Αρχεία εικόνων

    Η βιβλιοθήκες που παρέχονται μαζί με το περιβάλλον ανάπτυξης της Java, υποστηρίζουν την επεξεργασία εικόνων μέσω των πακέτων java.awt.image.* και javax.imageio.*.
    
    import javax.swing.JFrame;
    import javax.swing.JComponent;
    
    import javax.imageio.ImageIO;
    
    import java.io.File;
    import java.io.IOException;
    
    import java.awt.BorderLayout;
    import java.awt.Graphics;
    
    import java.awt.image.BufferedImage;
    
    public class ImageDemo {
        class GraphicPane extends JComponent {
            private BufferedImage bi;
            private JFrame parent;
    
            public GraphicPane(JFrame parent) {
                this.parent = parent;
                try {
                    // reads a file
                    this.bi = ImageIO.read(new File("planes.jpg"));
                } catch (IOException ioe) {
                    System.err.println("Could not load image");
                }
            }
    
            @Override public void paint(Graphics g) {
                // drawImage(Image img, int x, int y, ImageObserver observer)
                g.drawImage(bi, 0, 0, parent);
            }
        }
    
        public ImageDemo() {
            JFrame jf = new JFrame("Hello, World!");
            GraphicPane gp = new GraphicPane(jf);
    
            jf.setBounds(0,0, 800, 600);
            jf.setLayout(new BorderLayout());
            jf.add(gp, BorderLayout.CENTER);
    
            jf.setVisible(true);
        }
    
        public static void main(String[] args) {
            new ImageDemo();
        }
    }
    

    Αποτέλεσμα: Αρχεία εικόνων

    Άσκηση: Μία απλή γραφική εφαρμογή

    Άσκηση 9

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Ευχαριστίες

    Ευχαριστίες στο Βασίλη Καρακόιδα για την καθοριστική συνεισφορά του στη συγγραφή της ενότητας αυτής των σημειώσεων.

    Δομές δεδομένων

    Συμβολοσειρές

    Συμβολοσειρές: παράδειγμα

    
    class Book {
        public String toString() { return "Book"; }
        static public void main(String args[]) {
            var b = new Book();
            String k = "*" + b + "*";
            System.out.println(k);
            System.out.println(b);
        }
    }
    

    Συμβολοσειρές πολλαπλών γραμμών

    Μπορούμε να παραστήσουμε συμβολοσειρές πολλαπλών γραμμών με τριπλά εισαγωγικά.
    
    String html = """
        <html>
            <body>
                <h1>Welcome to my page</h1>
                <p>This is a paragraph.</p>
            </body>
        </html>
        """;
    

    String: μέθοδοι κατασκευής

    String()
    Κατασκευάζει μια άδεια συμβολοσειρά.
    String(char[] value)
    Κατασκευάζει μια συμβολοσειρά από τον πίνακα value.
    String(char[] value, int offset, int count)
    Κατασκευάζει μια συμβολοσειρά από count στοιχεία του πίνακα value αρχίζοντας από τη θέση offset.
    String(String original)
    Κατασκευάζει ένα αντίγραφο συμβολοσειράς
    String(StringBuffer buffer)
    Κατασκευάζει μια συμβολοσειρά από ένα αντικείμενο StringBuffer

    String: μέθοδοι επεξεργασίας

    Οι θέσεις σε μια συμβολοσειρά αριθμούνται από το 0.
    h e l l o
    0 1 2 3 4
    Η μη ύπαρξη θέσης συμβολίζεται με το -1.
    String substring(int beginIndex)
    Επιστρέφει το τμήμα που αρχίζει στη θέση beginIndex
    String substring(int beginIndex, int endIndex)
    Επιστρέφει το τμήμα που αρχίζει στη θέση beginIndex και τελειώνει στη θέση endIndex - 1
    char charAt(int index)
    Επιστρέφει το χαρακτήρα στη θέση index
    String concat(String string2)
    Επιστρέφει τη συμβολοσειρά ενωμένη με το string2

    String: μέθοδοι ερωτήσεων

    int length()
    Μήκος
    boolean equals(String string2)
    Σύγκριση
    boolean StartsWith(String string2)
    Σύγκριση αρχής
    boolean endsWith(String string2)
    Σύγκριση τέλους
    int compareTo(String string2)
    Λεξικογραφική σύγκριση (απλή)
    int indexOf(String string2)
    Επιστρέφει τη θέση της συμβολοσειράς string2

    String: μέθοδοι μετατροπής

    static String valueOf(int i)
    Μετατρέπει το όρισμα i σε συμβολοσειρά
    static String valueOf(double d)
    Μετατρέπει το όρισμα d σε συμβολοσειρά
    static String valueOf(boolean b)
    Μετατρέπει το όρισμα b σε συμβολοσειρά
    static String valueOf(long l)
    Μετατρέπει το όρισμα l σε συμβολοσειρά
    static String valueOf(float f)
    Μετατρέπει το όρισμα f σε συμβολοσειρά
    static String valueOf(char c)
    Μετατρέπει το όρισμα c σε συμβολοσειρά

    StringBuffer και StringBuilder

    StringBuffer append(String string2)
    Προσθήκη της συμβολοσειράς string2 στο τέλος
    StringBuffer insert(int offset, String string2)
    Προσθήκη της συμβολοσειράς string2 στη θέση offset
    StringBuffer delete(int start, int end)
    Διαγραφή των χαρακτήρων από τη θέση start μέχρι την end - 1
    StringBuffer replace(int start, int end, String string2)
    Αντικατάσταση των χαρακτήρων από τη θέση start μέχρι την end - 1 με τη συμβολοσειρά string2

    Εσωτερική χρήση της StringBuilder

    Η κλάση StringBuilder παρέχει τις ίδιες δυνατότητες με την StringBuffer, χωρίς όμως να παρέχει ασφάλεια σε πολυνηματική επεξεργασία.

    Η κλάση StringBuilder χρησιμοποιείται και από το μεταγλωττιστή για την υλοποίηση ένωσης συμβολοσειρών. Η ακολουθία

    
    x = "a" + 4 + "c"
    
    μεταγλωττίζεται εσωτερικά σε
    
    x = new StringBuilder().append("a").append(4).append("c").toString()
    

    Πλαίσια συλλογών

    Πλεονεκτήματα

    Τα πλεονεκτήματα της υποστήριξης και του προγραμματισμού με βάση ένα πλαίσιο συλλογών είναι:

    Το πλαίσιο συλλογών της Java

    Το πλαίσιο συλλογών της βιβλιοθήκης της Java περιλαμβάνει:

    Διεπαφές συλλογών

    Υλοποιήσεις συλλογών

    Διαθέσιμες υλοποιήσεις στη Java

    Για τις διεπαφές των συλλογών υπάρχουν οι παρακάτω υλοποιήσεις:

    Set:
    HashSet, TreeSet, LinkedHashSet
    SortedSet:
    TreeSet
    List:
    ArrayList, LinkedList
    Map:
    HashMap, TreeMap, LinkedHashMap
    SortedMap:
    TreeMap

    Πίνακας διεπαφών και υλοποιήσεων

      Υλοποιήσεις
    ΠΚΠίνακας ΙΔΣΛ ΣΛ και ΠΚ
    Διεπαφές SetHashSet   TreeSet   LinkedHashSet
    SortedSet    TreeSet    
    List   ArrayList   LinkedList  
    Map HashMap   TreeMap   LinkedHashMap
    SortedMap     TreeMap    
    (Οι υλοποιήσεις που συνδιάζουν συνδεδεμένη λίστα και πίνακα κατακερματισμού επιτρέπουν την πρόσβαση των στοιχείων με τη σειρά που έγινε η εισαγωγή τους.)

    Διάγραμμα UML

    Η δομή των διεπαφών και κλάσεων που έχουμε εξετάσει μπορεί να παρασταθεί σε μορφή UML ως εξής.
    UML diagram of Java's Collection and Maps
    Σημείωση: στην πράξη η υλοποίηση της Java χρησιμοποιεί και άλλες ενδιάμεσες κλάσεις, όπως AbstractCollection, AbstractSequentialList, AbstractSet.

    Collection: επεξεργασία

    Η γενικευμένη διεπαφή

    
    Collection <E>
    
    ορίζει μεταξύ άλλων τις παρακάτω μεθόδους (κατά περίπτωση επιστρέφουν αληθές αν η συλλογή μεταβλήθηκε):

    void clear()
    Αφαιρεί όλα τα αντικείμενα από τη συλλογή
    boolean add(E o)
    Προσθήκη στοιχείου
    boolean addAll(Collection <? extends E> c)
    Προσθήκη συλλογής
    boolean remove(Object o)
    Αφαίρεση στοιχείου
    boolean removeAll(Collection <?> c)
    Αφαίρεση συλλογής

    Collection: ερωτήσεις

    boolean contains(Object o)
    Επιστρέφει αληθές αν το στοιχείο περιέχεται
    boolean containsAll(Collection <?> c)
    Επιστρέφει αληθές αν τα στοιχεία της συλλογής περιέχονται
    Iterator <E> iterator()
    Επιστρέφει έναν επαναλήπτη για διάσχιση της συλλογής
    boolean isEmpty()
    Επιστρέφει αληθές αν η συλλογή είναι άδεια
    int size()
    Επιστρέφει τον αριθμό των στοιχείων στη συλλογή

    Παράδειγμα της διεπαφής Collection

    
    import java.util.Collection;
    import java.util.LinkedList;
    
    public class CollectionTest <E> {
        static <E> void testContain(Collection <E> c, E o) {
            System.out.print("The collection " + c);
            if (c.contains(o))
                System.out.print(" contains");
            else
                System.out.print(" does not contain");
    
            System.out.println(" the object " + o);
        }
    
        public static void main(String args[]) {
            var list = new LinkedList <String>();
    
            list.add("Petros");
            list.add("Maria");
    
            testContain(list, "Maria");
            testContain(list, "John");
            testContain(list, "Petros");
            System.out.println("Number of elements = " + list.size());
        }
    }
    

    Η διεπαφή Iterator

    Η διεπαφή
    
    Iterator <E>
    
    υποστηρίζει τη διάσχιση και μεταβολή συλλογών. Ορίζει τις παρακάτω μεθόδους:
    boolean hasNext()
    Επιστρέφει αληθές αν υπάρχει επόμενο στοιχείο
    Object next()
    Επιστρέφει το επόμενο στοιχείο
    void remove()
    Διαγράφει το τελευταίο στοιχείο που επιστρέφτηκε

    Η διεπαφή ListIterator

    Η διεπαφή ListIterator επεκτείνει την Iterator με τις παρακάτω μεθόδους:
    boolean hasPrevious()
    Επιστρέφει αληθές αν υπάρχει προηγούμενο στοιχείο
    Object previous()
    Επιστρέφει το προηγούμενο στοιχείο
    void add(Object o)
    Προσθέτει ένα στοιχείο
    void set(Object o)
    Αντικαθιστά το τελευταίο στοιχείο που επιστρέφτηκε

    Παράδειγμα της διεπαφής Iterator

    
    import java.util.*;
    
    public class IteratorTest {
    
        static void fill(Collection <String> c) {
            c.add("Kerkyra");
            c.add("Zakynthos");
            c.add("Kythira");
            c.add("Santorini");
            c.add("Dilos");
            c.add("Samos");
            c.add("Rodos");
            c.add("Kastelorizo");
        }
    
        static void printAll(Collection <?> c) {
            for (var i = c.iterator(); i.hasNext(); )
                System.out.print(i.next() + " ");
        }
    
        public static void main(String args[]) {
            var hash = new HashSet<String> ();
            var list = new LinkedList<String> ();
    
            fill(hash);
            fill(list);
    
            System.out.println("Hash contains:");
            printAll(hash);
            System.out.println("\nList contains:");
            printAll(list);
        }
    }
    

    Διάσχιση δομών με την εντολή foreach

    Παραδείγματα foreach

    Παράδειγμα διάσχισης συλλογής:
    
    static void printAll(Collection <?> c) {
        for (Object o : c)
            System.out.print(o + " ");
    }
    
    Παράδειγμα διάσχισης πίνακα:
    
    class Echo {
        public static void main(String args[]) {
            for (var s : args)
                System.out.print(s + " ");
            System.out.println();
        }
    }
    

    Παράδειγμα: διάσχιση της ακολουθίας Fibonacci

    
    import java.util.Iterator;
    import java.math.BigInteger;
    
    /**
     * An Iterable interface over the Fibonacci sequence.
     * @author Diomidis Spinellis
     */
    class FibonacciSequence implements Iterable<BigInteger> {
    
        /** The iterator over the Fibonacci sequence. */
        private class  FibonacciIterator implements Iterator<BigInteger> {
            /** Integer n-2 of the series. */
            private BigInteger n0 = null;
            /** Integer n-1 of the series. */
            private BigInteger n1 = null;
    
            /**
             * Return true.
             * The FibonacciSequence sequence is infinite.
             */
            public boolean hasNext() { return true; }
    
            /** Return the next FibonacciSequence integer. */
            public BigInteger next() {
                if (n0 == null) {
                    n0 = BigInteger.ZERO;
                    return n0;
                } else if (n1 == null) {
                    n1 = BigInteger.ONE;
                    return n1;
                } else {
                    BigInteger r = n0.add(n1);
                    n0 = n1;
                    n1 = r;
                    return r;
                }
            }
    
            /**
             * Remove an element.
             * Nothing to see here; move on.
             */
            public void remove() {
                throw new UnsupportedOperationException();
            }
        }
    
        /** Return an iterator for the FibonacciSequence series. */
        public Iterator<BigInteger> iterator() {
            return new FibonacciIterator();
        }
    
        /** A simple test harness. */
        public static void main(String argv[]) {
            var fib = new FibonacciSequence();
    
            for (BigInteger i : fib)
                System.out.println(i);
        }
    }
    
    Βλέπε και το βίντεο για την εμφάνιση της ακολουθίας στη φύση (https://www.youtube.com/watch?v=kkGeOWYOFoA).

    Η διεπαφή Map

    Η διεπαφή
    
    Map <K, V>
    
    ορίζει μια απεικόνιση από ένα κλειδί (key) K σε μια τιμή (value) V. Η διεπαφή ορίζει μεταξύ άλλων τις παρακάτω μεθόδους:
    void clear()
    Αφαιρεί όλα τα αντικείμενα από τη συλλογή
    Object put(Object key, Object value)
    Προσθήκη στοιχείου (επιστρέφει την προηγούμενη τιμή ή null)
    void putAll(Map <? extends K, ? extends V> m)
    Προσθήκη στοιχείων
    boolean remove(Object key)
    Αφαίρεση στοιχείου (επιστρέφει την προηγούμενη τιμή ή null)

    Ερωτήσεις διεπαφής Map

    V get(Object key)
    Επιστρέφει την τιμή του στοιχείου με το κλειδί key
    boolean containsKey(Object key)
    Επιστρέφει αληθές αν το στοιχείο με το κλειδί key περιέχεται
    boolean containsValue(Object value)
    Επιστρέφει αληθές αν το στοιχείο με την τιμή value περιέχεται (αργή)
    Set<K> keySet()
    Επιστρέφει το σύνολο των κλειδιών
    Collection<V> values()
    Επιστρέφει μια συλλογή με τις αποθηκευμένες τιμές
    boolean isEmpty()
    Επιστρέφει αληθές αν η συλλογή είναι άδεια
    int size()
    Επιστρέφει τον αριθμό των στοιχείων στη συλλογή

    Παράδειγμα: νομισματικές ισοτιμίες

    
    import java.util.TreeMap;
    
    public class FXConvert {
    
        private static TreeMap<String, Double> FXRate = new TreeMap<String, Double>();
    
        static double FXconvert(String from, String to, double value) {
            double euro = value / FXRate.get(from);
            return euro * FXRate.get(to);
        }
    
        public static void main(String args[]) {
    
            // Euro rates
            FXRate.put("USD", 1.27);
            FXRate.put("JPY", 126.0);
            FXRate.put("GBP", 0.68);
            FXRate.put("CHF", 1.57);
            FXRate.put("CAD", 1.53);
            FXRate.put("SEK", 9.03);
    
            System.out.println("5 SEK = " + FXconvert("SEK", "JPY", 5) + " JPY");
            System.out.println("100 GBP = " + FXconvert("GBP", "CHF", 100) + " CHF");
        }
    }
    

    Η κλάση Stack

    Η κλάση
    
    Stack <E>
    
    υλοποιεί τη δομή δεδομένων που ονομάζεται στοίβα (stack) με το χαρακτηριστικό τύπο πρόσβασης τελευταίο μέσα πρώτο έξω (last in first out) (LIFO). H κλάση Stack υλοποιεί τη διεπαφή Collection και ορίζει τις παρακάτω μεθόδους:
    boolean empty()
    Αληθές αν η στοίβα είναι άδεια
    E push(E item)
    Προσθέτει το αντικείμενο item στην κορυφή της στοίβας
    E pop()
    Αφαιρεί και επιστρέφει το αντικείμενο από την κορυφή της στοίβας
    E peek()
    Επιστρέφει το αντικείμενο από την κορυφή της στοίβας

    οι πύργοι του Ανόι

    Μπορείτε να δοκιμάστε το παιγνίδι εδώ (https://www.mathsisfun.com/games/towerofhanoi.html).

    Παράδειγμα: οι πύργοι του Ανόι

    
    import java.util.Stack;
    import java.util.Iterator;
    import java.util.Collection;
    
    public class Hanoi {
        static Stack<Integer> A, B, C;
    
        /** Display the contents of a collection with a given name */
        static <E> void showCollection(String name, Collection <E> c) {
            System.out.print(name + ": ");
            for (E e : c)
                System.out.print(e + " ");
            System.out.println();
        }
    
        /** Display the hanoi towers */
        static void showConfiguration() {
            showCollection("A", A);
            showCollection("B", B);
            showCollection("C", C);
            System.out.println();
        }
    
        /** Move n blocks from to using tmp */
        static <E> void move(int n, Stack<E> from, Stack<E> to, Stack<E> tmp) {
            if (n == 1) {
                to.push(from.pop());
                showConfiguration();
            } else {
                move(n - 1, from, tmp, to);
                to.push(from.pop());
                showConfiguration();
                move(n - 1, tmp, to, from);
            }
        }
    
        public static void main(String args[]) {
            final int N = 64;
            A = new Stack<Integer>();
            B = new Stack<Integer>();
            C = new Stack<Integer>();
    
            for (int i = N; i > 0; i--)
                A.push(i);
            showConfiguration();
            move(N, A, C, B);
        }
    }
    
    Εδώ (https://upload.wikimedia.org/wikipedia/commons/2/20/Tower_of_Hanoi_recursion_SMIL.svg) ο αλγόριθμος σε δράση.

    Άσκηση: προγραμματισμός με συμβολοσειρές και συλλογές

    Άσκηση 7

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Χειρισμός αρχείων

    Επισκόπηση

    Δευτερεύουσα μνήμη

    Τα προγράμματα συχνά πρέπει να μεταφέρουν τα δεδομένα τους σε δευτερεύουσα μνήμη (μονάδα SSD, μαγνητικό δίσκο, CD/DVD, μνήμη USB, κάρτα μνήμης, ταινία). Οι λόγοι που το επιβάλλουν αυτό είναι οι παρακάτω:

    Η διαδικασία μεταφοράς των δεδομένων μεταξύ του προγράμματος και εξωτερικών συσκευών καλείται είσοδος/έξοδος (input/output) ή Ε/Ε (I/O).

    Παράσταση δεδομένων

    Τα δεδομένα σε ένα αρχείο μπορούμε να τα παραστήσουμε σε δύο μορφές.

    Παραδείγματα παράστασης

    ΤύποςΤιμήΔυαδική παράστασηΠαράσταση κειμένου
    int4200000000 00000000 00000000 0010101000110100 00110010
    short4200000000 0010101000110100 00110010
    chara00000000 0110000101100001
    charα00000011 1011000111001110 10110001
    Το κείμενο παριστάνεται με την κωδικοποίηση UTF-8.

    Παράσταση αριθμών κινητής υποδιαστολής

    ΤύποςΤιμήΔυαδική παράστασηΠαράσταση κειμένου
    double-0.12510111111 11000000 00000000 00000000
    00000000 00000000 00000000 00000000
    00101101
    00110000
    00101110
    00110001
    00110010
    00110101
    double 12.566370614359173 10-7 00111110 10110101 00010101 00110111
    00001111 10011001 11110110 11001011
    00110001
    00110010
    00101110
    00110101
    00110110
    00110110
    00110011
    00110111
    00110000
    00110110
    00110001
    00110100
    00110011
    00110101
    00111001
    00110001
    00110111
    00110011
    01100101
    00101101
    00110111
    (Ο τελευταίος αριθμός παριστάνει τη φυσική σταθερά μ0, τη διαπερατότητα του κενού, 4π 10-7. Το κείμενο παριστάνεται με την κωδικοποίηση UTF-8 και οι αριθμοί κινητής υποδιαστολής σύμφωνα με το πρότυπο IEEE 754-1985.)

    Ομαδοποίηση δεδομένων

    Η ομαδοποίηση στοιχείων μπορεί να γίνει:

    Παράδειγμα: ομαδοποίηση πεδίων σταθερού μήκους

    ΓΓΠΣ/ΑΑΔΕ: Αναλυτική γραμμή πωλήσεων (πελατών)
    ΠΙΝΑΚΑΣ 3. Αναλυτική γραμμή πωλήσεων (στοιχεία πελατών)
    (RECORD τύπου 2)
    ΠΕΡΙΓΡΑΦΗ
    ΠΕΔΙΟΥ
    ΘΕΣΕΙΣ
    ΧΑΡΑΚΤΗΡΙΣΤΙΚΑ ΠΕΔΙΟΥ
    Σημειώσεις
    ΣΤΑΘΕΡΗ
    ΤΙΜΗ
    ΑΠΟ
    ΕΩΣ
    ΜΗΚΟΣ
    ΤΥΠΟΣ
    1
    Τύπος Record (κωδικός)
    1
    1
    1
    Numeric
    KENO
    2
    2
    Α/Α
    2
    6
    5
    Numeric
    KENO
    KENO
    3
    ΑΦΜ πελάτη
    7
    15
    9
    Character
    KENO
    KENO
    4
    Επωνυμία πελάτη
    16
    42
    27
    Character
    KENO
    KENO
    5
    Επαγγελμα πελάτη
    43
    57
    15
    Character
    KENO
    KENO
    61
    Μη υπόχρεοι υποβολής(αγρότες, περιστασιακά απασχολούμενοι κλπ)
    58
    58
    1
    Character
    0 (μηδέν)= υπόχρεος
    1 (ένα) = μη υπόχρεος
    KENO
    7
    Δ/νση / Πόλη πελάτη
    59
    68
    10
    Character
    KENO
    KENO
    8
    Δ/νση / Οδός πελάτη
    69
    84
    16
    Character
    KENO
    KENO
    9
    Δ/νση / Αριθμ πελάτη
    85
    87
    3
    Character
    KENO
    KENO
    10
    Ταχ. Κώδικας πελάτη
    88
    92
    5
    Numeric
    KENO
    KENO
    113
    Αριθμός τιμολογίων (πλήθος)
    93
    99
    7
    Numeric
    KENO
    KENO
    12
    Καθαρή αξία τιμολογίων
    100
    115
    16
    Numeric
    KENO
    KENO
    13
    FILLER
    116
    150
    35
    Character
    KENO
    spaces

    Παράδειγμα: ομαδοποίηση πεδίων με διαχωριστικό

    Αρχείο /etc/passwd στο λειτουργικό σύστημα Unix

    root:*:0:0:Charlie Root:/root:/bin/csh
    dds:*:1000:1000:Diomidis Spinellis:/home/dds:/usr/local/bin/bash
    nutmon:*:1056:1056:NUT UPS monitor unprivileged user:/nonexistent:/usr/sbin/nologin
    sgrig:*:1001:1001:Stavros Grigorakakis:/home/sgrig:/usr/local/bin/bash
    archie:*:1002:1002:Achilleas Anagnostopoulos:/home/archie:/usr/local/bin/bash
    path:*:1003:1003:Stephanos Androutselis:/home/path:/usr/local/bin/bash
    

    Τιμοκατάλογος της Microsoft (CSV)

    Product Description,1st AP Non-Platform,1st AP Platform,2nd AP Non-Platform,2nd AP Platform,3rd AP Non-Platform,3rd AP Platform,Non-Platform,Platform,,,,,,,
    OFFICE FAMILY,,,,,,,,,,
    Office Enterprise Listed Lic/SA Pack MVL,76J-01468,76J-01637, 190.31 , 161.77 , 190.31 , 161.77 , 190.31 , 161.77 ,,
    Office Enterprise Listed SA MVL,76J-01552,76J-01640, 98.96 , 94.02 , 98.96 , 94.02 , 98.96 , 94.02 ,,
    Office Enterprise Listed SA Step Up MVL from Office Pro,76J-01510,76J-00002, 34.51 , 29.33 , 34.51 , 29.33 , 34.51 , 29.33 ,,,,,,,
    Office Professional Plus Listed Lic/SA Pack MVL,269-05924,269-12441, 155.81 , 132.45 , 155.81 , 132.45 , 155.81 , 132.45 ,,,,,,,
    Office Professional Plus Listed SA MVL,269-05925,269-12444, 81.02 , 76.97 , 81.02 , 76.97 , 81.02 , 76.97 ,,,,,,,
    WINDOWS FAMILY,,,,,,,,,,,,,,,
    Windows Vista Business Listed Upg/SA Pack MVL w/VisEnterprise,66J-00588,66J-00579, 48.01 , 40.81 , 48.01 , 40.81 , 48.01 , 40.81 ,,,,,,,
    Windows Vista Business Listed SA MVL w/VisEnterprise,66J-00844,66J-00582, 31.76 , 30.17 , 31.76 , 30.17 , 31.76 , 30.17 ,,,,,,,
    

    Ανάγνωση δυαδικών δεδομένων

    Αυτόματη αποδέσμευση πόρων

    Παράδειγμα: ανάγνωση byte

    
    import java.io.*;
    
    /**
     * Count and display the number of bytes in the specified file
     * @author Diomidis Spinellis
     */
    class ByteCount {
        public static void main(String args[]) {
    	if (args.length != 1) {
    	    System.err.println("Usage: ByteCount file");
    	    System.exit(1);
    	}
    
    	// Try with resources; will auto-close in
    	try (var in = new BufferedInputStream(new FileInputStream(args[0]))) {
    
                // Count bytes
                int count = 0;
    	    int b;
    	    while ((b = in.read()) != -1)
    		count++;
    
                System.out.println(count);
    	} catch (FileNotFoundException e) {
    	    System.err.println("Unable to open file " + args[0] + ": " + e.getMessage());
    	    System.exit(1);
    	} catch (IOException e) {
    	    System.err.println("Error reading byte: " + e.getMessage());
    	    System.exit(1);
    	}
    
        }
    }
    

    Εγγραφή δυαδικών δεδομένων

    Παράδειγμα: εγγραφή εικόνας

    
    import java.io.*;
    
    /**
     * Create a 256*256 24-bit color PNM RGB file containing all combinations
     * of R and G.
     * @author Diomidis Spinellis
     */
    class ColorWrite {
    
        /** Write the specified ASCII string to out as bytes */
        static void writeStringAsBytes(OutputStream out, String s) throws IOException {
            for (int i = 0; i < s.length(); i++)
                    out.write((byte)s.charAt(i));
        }
    
        public static void main(String args[]) {
    	final String fileName = args[0];
    
    	// Open file; try with resources
    	try (var out =
                    new BufferedOutputStream(new FileOutputStream(fileName))) {
                // NetPBM PPM 24-bit color file header
                // https://netpbm.sourceforge.net/doc/ppm.html
                writeStringAsBytes(out, "P6 256 256 255 ");
    	    for (int r = 0; r < 256; r++)
    		for (int g = 0; g < 256; g++) {
    		    out.write(r);
    		    out.write(g);
    		    out.write(0);
    		}
    	} catch (FileNotFoundException e) {
    	    System.err.println("Unable to open file " + fileName
    		+ ": " + e.getMessage());
    	    System.exit(1);
    	} catch (IOException e) {
    	    System.err.println("Error writing byte: " + e.getMessage());
    	    System.exit(1);
    	}
        }
    }
    

    Παράδειγμα: αρχείο PNG

    PNG file format

    Ανάγνωση χαρακτήρων

    Παρένθεση: κωδικοποίηση ελληνικών χαρακτήρων

    Στη Java μπορούμε να επεξεργαστούμε αρχεία με ελληνικούς χαρακτήρες με βάση τα παρακάτω ονόματα κωδικοποίησης της κλάσης Charset.

    Διαθέσιμες κωδικοποιήσεις

    Το παρακάτω πρόγραμμα τυπώνει όλες τις διαθέσιμες κωδικοποιήσεις.
    
    import java.nio.charset.Charset;
    import java.util.SortedMap;
    
    /**
     * List the available character set encodins.
     * @author Diomidis Spinellis
     */
    class ListCharset {
        public static void main(String args[]) {
            SortedMap<String,Charset> ac = Charset.availableCharsets();
    
            for (String k : ac.keySet())
                System.out.println(k);
        }
    }
    

    Παράδειγμα: κατηγοριοποίηση χαρακτήρων

    
    import java.io.*;
    import java.util.*;
    import java.lang.Character.UnicodeBlock;
    
    /**
     * Count and display for the specified input file
     * the number of characters contained in various Unicode blocks .
     * @author Diomidis Spinellis
     */
    class CharCount {
        public static void main(String args[]) {
    	if (args.length != 2) {
    	    System.err.println("Usage: CharCount file encoding");
    	    System.exit(1);
    	}
    
    	// Open file; try-with-resources
    	try (var in = new BufferedReader(new InputStreamReader(
                            new FileInputStream(args[0]), args[1]))) {
    
                // Count characters in blocks
                var count = new HashMap<Character.UnicodeBlock, Integer>();
    	    int c;
    	    while ((c = in.read()) != -1) {
    		var u = Character.UnicodeBlock.of(c);
    		    Integer oldN = count.get(u);
    		    if (oldN == null)
    			count.put(u, 1);
    		    else
    			count.put(u, oldN + 1);
    	    }
    
                // Display results
                for (var s : count.entrySet())
                    System.out.println(s.getKey() + ": " + s.getValue());
    	} catch (FileNotFoundException e) {
    	    System.err.println("Unable to open file " + args[0] + ": " + e.getMessage());
    	    System.exit(1);
    	} catch (UnsupportedEncodingException e) {
    	    System.err.println("Unsupported encoding " + args[1] + ": " + e.getMessage());
    	} catch (IOException e) {
    	    System.err.println("Error reading character: " + e.getMessage());
    	    System.exit(1);
    	}
    
        }
    }
    

    Εγγραφή χαρακτήρων

    E/E συμβολοσειρών, πινάκων· σωληνώσεις

    Είσοδο και έξοδο μπορούμε να πραγματοποιήσουμε επιπλέον μέσω:

    Σειριακοποίηση αντικειμένων

    Δόκιμες λύσεις φύλαξης αντικειμένων

    Για να έχουμε συμβατότητα ανάμεσα σε διαφορετικές εκδόσεις του προγράμματος, καλύτερα είναι όταν έχουμε να αποθηκεύσουμε σύνθετες δομές να χρησιμοποιήσουμε μια εναλλακτική λύση, όπως:

    Ανακεφαλαίωση σειριακής πρόσβασης

    Ανάγνωση Εγγραφή
    byte FileInputStream FileOutputStream
    buffered byte BufferedInputStream BufferedOutputStream
    int/double/… DataInputStream DataOutputStream
    Object ObjectInputStream ObjectOutputStream
    char InputStreamReader OutputStreamWriter
    line(char) BufferedReader BufferedWriter
    PrintWriter

    Αρχεία τυχαίας πρόσβασης

    Η διεπαφή NIO

    H Java προσφέρει την διεπαφή προγραμματισμού (API) ΝΙΟ (New I/O) για πρόσβαση σε αρχεία όταν έχουμε ιδιαίτερα υψηλές απαιτήσεις απόδοσης. Σε σχέση με τη διεπαφή IO αυτή προσφέρει:

    Πρόσβαση στο σύστημα αρχείων

    Η κλάση File παρέχει πρόσβαση στη δομή με μεθόδους όπως τις παρακάτω:
    exists
    Ελέγχει την ύπαρξη ενός αρχείου.
    delete
    Διαγράφει ένα αρχείο.
    lastModified
    Επιστρέφει το χρόνο της τελευταίας αλλαγής στο αρχείο.
    renameTo
    Μετονομάζει ένα αρχείο
    length
    Επιστρέφει το μήκος ενός αρχείου
    list
    Επιστρέφει τα αρχεία που βρίσκονται σε ένα φάκελο.
    mkdir
    Δημιουργεί ένα νέο φάκελο
    getFreeSpace
    Επιστρέφει τον ελεύθερο χώρο στο δίσκο.

    Άσκηση: επεξεργασία αρχείου κειμένου

    Άσκηση 8

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Παράρτημα: Παράσταση ελληνικών χαρακτήρων

    ΧαρακτήραςUnicodeISO 8859-7CP 1253CP 737CP 851Mac GreekCP 423CP 869ISO IR-19ISO IR-27ISO IR-88ISO IR-18ISO IR-150ISO IR-55
    Ά0386b6a2ea86cd7186      
    Έ0388b8b8eb8dce728d      
    Ή0389b9b9ec8fd7738f      
    Ί038ababaed90d87590      
    Ϊ03aadada  ab 91      
    Ό038cbcbcee92d97692      
    Ύ038ebebeef95da7795      
    Ϋ03abdbdb  bd 96      
    Ώ038fbfbff098df7898      
    Α0391c1c180a4b041a461 41614141
    Β0392c2c281a5b542a562 42624242
    Γ0393c3c382a6a143a6672343674344
    Δ0394c4c483a7a244a7644044644445
    Ε0395c5c584a8b645a865 45654546
    Ζ0396c6c685a9b746a97a 467a4649
    Η0397c7c786aab847aa68 4768474a
    Θ0398c8c887aca348ac755c4875484b
    Ι0399c9c988adb949ad69 4969494c
    Κ039acaca89b5ba51b56b 4b6b4a4d
    Λ039bcbcb8ab6a452b66c5e4c6c4b4e
    Μ039ccccc8bb8bb53b76d 4d6d4c4f
    Ν039dcdcd8cb7c154b86e 4e6e4d50
    Ξ039ecece8dbda555bd6a214f6a4e51
    Ο039fcfcf8ebec356be6f 506f4f52
    Π03a0d0d08fc6a657c6703f51705053
    Ρ03a1d1d190c7c458c772 52725155
    Σ03a3d3d391cfaa59cf735f53735356
    Τ03a4d4d492d0c662d074 54745458
    Υ03a5d5d593d1cb63d179 55795559
    Φ03a6d6d694d2bc64d2665d5666565a
    Χ03a7d7d795d3cc65d378 5878575b
    Ψ03a8d8d896d4be66d4633a5963585c
    Ω03a9d9d997d5bf67d5765b5a76595d
    ά03acdcdce19bc0b19b      
    έ03addddde29ddbb29d      
    ή03aededee39edcb39e      
    ί03afdfdfe59fddb59f      
    ϊ03cafafae4a0fbb4a0      
    ΐ0390c0c0 a1fd a1      
    ό03ccfcfce6a2deb6a2      
    ύ03cdfdfde7a3e0b7a3      
    ϋ03cbfbfbe8fbfcb8fb      
    ΰ03b0e0e0 fcfe fc      
    ώ03cefefee9fdf1b9fd      
    α03b1e1e198d6e18ad6  61416161
    β03b2e2e299d7e28bd7  62426262
    γ03b3e3e39ad8e78cd8  63476364
    δ03b4e4e49bdde48ddd  64446465
    ε03b5e5e59cdee58ede  65456566
    ζ03b6e6e69de0fa8fe0  665a6669
    η03b7e7e79ee1e89ae1  6748676a
    θ03b8e8e89fe2f59be2  6855686b
    ι03b9e9e9a0e3e99ce3  6949696c
    κ03baeaeaa1e4eb9de4  6b4b6a6d
    λ03bbebeba2e5ec9ee5  6c4c6b6e
    μ03bcececa3e6ed9fe6  6d4d6c6f
    ν03bdededa4e7eeaae7  6e4e6d70
    ξ03beeeeea5e8eaabe8  6f4a6e71
    ο03bfefefa6e9eface9  704f6f72
    π03c0f0f0a7eaf0adea  71507073
    ρ03c1f1f1a8ebf2aeeb  72527175
    ς03c2f2f2aaedf7afed  77577277
    σ03c3f3f3a9ecf3baec  73537376
    τ03c4f4f4abeef4bbee  74547478
    υ03c5f5f5acf2f9bcf2  75597579
    φ03c6f6f6adf3e6bdf3  7646767a
    χ03c7f7f7aef4f8bef4  7858777b
    ψ03c8f8f8aff6e3bff6  7943787c
    ω03c9f9f9e0faf6dbfa  7a56797d

    Παράρτημα: το πρότυπο ASCII

    Ο παρακάτω πίνακας παρουσιάζει τις τιμές των χαρακτήρων, σύμφωνα με το πρότυπο ASCII (American Standard Code for Information Interchange). Οι πρώτες 32 θέσεις δεσμεύονται για χαρακτήρες διαφυγής (escape character).
    ΧαρακτήραςΔεκαδικήΔεκαεξαδικήΟκταδικήΔυαδική
    nul0000000000 0000
    soh1010010000 0001
    stx2020020000 0010
    etx3030030000 0011
    eot4040040000 0100
    enq5050050000 0101
    ack6060060000 0110
    bel7070070000 0111
    bs8080100000 1000
    ht9090110000 1001
    lf100a0120000 1010
    vt110b0130000 1011
    ff120c0140000 1100
    cr130d0150000 1101
    so140e0160000 1110
    si150f0170000 1111
    dle16100200001 0000
    dc117110210001 0001
    dc218120220001 0010
    dc319130230001 0011
    dc420140240001 0100
    nak21150250001 0101
    syn22160260001 0110
    etb23170270001 0111
    can24180300001 1000
    em25190310001 1001
    sub261a0320001 1010
    esc271b0330001 1011
    fs281c0340001 1100
    gs291d0350001 1101
    rs301e0360001 1110
    us311f0370001 1111
    sp32200400010 0000
    !33210410010 0001
    "34220420010 0010
    #35230430010 0011
    $36240440010 0100
    %37250450010 0101
    &38260460010 0110
    '39270470010 0111
    (40280500010 1000
    )41290510010 1001
    *422a0520010 1010
    +432b0530010 1011
    ,442c0540010 1100
    -452d0550010 1101
    .462e0560010 1110
    /472f0570010 1111
    048300600011 0000
    149310610011 0001
    250320620011 0010
    351330630011 0011
    452340640011 0100
    553350650011 0101
    654360660011 0110
    755370670011 0111
    856380700011 1000
    957390710011 1001
    :583a0720011 1010
    ;593b0730011 1011
    <603c0740011 1100
    =613d0750011 1101
    >623e0760011 1110
    ?633f0770011 1111
    @64401000100 0000
    A65411010100 0001
    B66421020100 0010
    C67431030100 0011
    D68441040100 0100
    E69451050100 0101
    F70461060100 0110
    G71471070100 0111
    H72481100100 1000
    I73491110100 1001
    J744a1120100 1010
    K754b1130100 1011
    L764c1140100 1100
    M774d1150100 1101
    N784e1160100 1110
    O794f1170100 1111
    P80501200101 0000
    Q81511210101 0001
    R82521220101 0010
    S83531230101 0011
    T84541240101 0100
    U85551250101 0101
    V86561260101 0110
    W87571270101 0111
    X88581300101 1000
    Y89591310101 1001
    Z905a1320101 1010
    [915b1330101 1011
    \925c1340101 1100
    ]935d1350101 1101
    ^945e1360101 1110
    _955f1370101 1111
    `96601400110 0000
    a97611410110 0001
    b98621420110 0010
    c99631430110 0011
    d100641440110 0100
    e101651450110 0101
    f102661460110 0110
    g103671470110 0111
    h104681500110 1000
    i105691510110 1001
    j1066a1520110 1010
    k1076b1530110 1011
    l1086c1540110 1100
    m1096d1550110 1101
    n1106e1560110 1110
    o1116f1570110 1111
    p112701600111 0000
    q113711610111 0001
    r114721620111 0010
    s115731630111 0011
    t116741640111 0100
    u117751650111 0101
    v118761660111 0110
    w119771670111 0111
    x120781700111 1000
    y121791710111 1001
    z1227a1720111 1010
    {1237b1730111 1011
    |1247c1740111 1100
    }1257d1750111 1101
    ~1267e1760111 1110
    del1277f1770111 1111

    Παράσταση δεδομένων με XML, JSON και κανονικές εκφράσεις

    Σύνταξη κανονικών εκφράσεων

    Σύμβολα με ειδικό νόημα

    Πρόσθετα σύμβολα με ειδικό νόημα

    Χαρακτήρες διαφυγής

    Πρόσθετοι χαρακτήρες διαφυγής

    Χρήση κανονικών εκφράσεων

    Παράδειγμα: Εύρεση κανονικών εκφράσεων σε αρχείο

    
    /*
     * Globally match regular expression and print
     * Modelled after the Unix command with the same name
     * D. Spinellis, January 2004-2024
     */
    
    import java.util.regex.*;
    import java.io.*;
    
    class Grep {
        public static void main(String args[]) {
            if (args.length != 2) {
                System.err.println("Usage: Grep pattern file");
                System.exit(1);
            }
    
            try (var in = new BufferedReader(new InputStreamReader(
                            new FileInputStream(args[1])))) {
                Pattern compiledRe = Pattern.compile(args[0]);
                String s;
                while ((s = in.readLine()) != null) {
                    Matcher m = compiledRe.matcher(s);
                    if (m.find())
                        System.out.println(s);
                }
            } catch (FileNotFoundException e) {
                System.err.println("Unable to open file " + args[1] + ": " + e.getMessage());
                System.exit(2);
            } catch (PatternSyntaxException e) {
                System.err.println("Invalid RE syntax: " + e.getDescription());
                System.exit(3);
            } catch (IOException e) {
                System.err.println("Error reading line: " + e.getMessage());
                System.exit(4);
            }
        }
    }
    

    Αποτέλεσμα αναζήτησης κανονικών εκφράσεων

    java Grep "abo" /usr/dict/words
    ...
    sabotage
    seaboard
    taboo
    thereabouts
    turnabout
    vagabond
    whereabout
    ...
    
    java Grep "^abo" /usr/dict/words
    aboard
    abode
    abolish
    abolition
    abominable
    abominate
    aboriginal
    
    java Grep bent /usr/dict/words
    absorbent
    bent
    benthic
    debenture
    incumbent
    recumbent
    
    java Grep "bent$" /usr/dict/words
    absorbent
    bent
    incumbent
    recumbent
    
    java Grep "[^AEIOUYaeiouy]{5,}" /usr/dict/words
    angstrom
    Armstrong
    birthplace
    bremsstrahlung
    corkscrew
    Dijkstra
    downstream
    hardscrabble
    jockstrap
    Knightsbridge
    lengthly
    Nietzsche
    nightclub
    offspring
    postscript
    Rothschild
    ...
    
    java Grep "(.)(.)(.)\3\2\1" /usr/dict/words
    braggart
    Brenner
    collocation
    diffident
    dissident
    glossolalia
    grammar
    grammarian
    installation
    staccato
    suffuse
    

    Διαίρεση συμβολοσειρών με πρότυπο

    Διαίρεση συμβολοσειρών με κανονική έκφραση

    Όταν τα τμήματα μιας συμβολοσειράς χωρίζονται από ίδια στοιχεία διαχωρισμού (π.χ. :, κενό, tab) τότε μπορούμε να τα διαχωρίσουμε με τη μέθοδο του αντικειμένου Pattern.
    
    import java.io.*;
    import java.util.regex.*;
    
    public class SplitWords {
        public static void main(String[] args) {
            if (args.length != 1) {
                System.err.println("Usage: SplitWords file");
                System.exit(1);
            }
    
            // Split on non-word characters
            Pattern splitPattern = Pattern.compile("[^a-zA-Z]+");
    
            try (var in = new BufferedReader(new InputStreamReader(
                            new FileInputStream(args[0])))) {
                String line;
                while ((line = in.readLine()) != null) {
                    String[] words = splitPattern.split(line);
                    for (String word : words) {
                        System.out.println(word);
                    }
                }
            } catch (FileNotFoundException e) {
                System.err.println("Unable to open file " + args[0] + ": " + e.getMessage());
                System.exit(2);
            } catch (IOException e) {
                System.err.println("Error reading line: " + e.getMessage());
                System.exit(3);
            }
        }
    }
    

    Παράδειγμα: επεξεργασία αρχείων καταγραφής πρόσβασης σε ιστοσελίδες

    
    /*
     * Collect and print Web statistics
     * D. Spinellis, 2004-2024
     */
    
    import java.util.*;
    import java.util.regex.*;
    import java.io.*;
    
    class WebStats {
    
        /**
         * Increment the integer value of map's member by 1
         * The member is obtained by using the matcher to extract
         * the specified group from the string s
         */
        static void increment(Map<String, Integer> map, String s, Matcher m, int group) {
    	String member = s.substring(m.start(group), m.end(group));
    	Integer i = map.get(member);
            map.put(member, i == null ? 1 : i + 1);
        }
    
        /** List the contents of the given map */
        static void list(String title, Map<String, Integer> map) {
    	System.out.println("\n" + title);
    	for (Map.Entry e : map.entrySet())
    	    System.out.println(e.getValue() + " " + e.getKey());
        }
    
        /** List the contents of the given map ordered by their values.
         * (You are not expected to undestand this).
         */
        static void sortedList(String title, Map<String, Integer> map) {
    	System.out.println("\n" + title);
    	var valueOrder = new TreeSet<Map.Entry<String, Integer>>(new
    	    Comparator<Map.Entry<String, Integer>>() {
    		public int compare(Map.Entry<String, Integer> a,
    			Map.Entry<String, Integer> b) {
    		    return (-a.getValue().compareTo(b.getValue()));
    		}
    	    }
    	);
    	valueOrder.addAll(map.entrySet());
    	for (Map.Entry e : valueOrder)
    	    System.out.println(e.getValue() + " " + e.getKey());
        }
    
    
    
        public static void main(String args[]) {
    	if (args.length != 1) {
    	    System.err.println("Usage: WebStats file");
    	    System.exit(1);
    	}
    
    	Pattern cre = null;	// Compiled RE
    	try {
    	    // A standard log line is a line like:
    	    // 192.168.136.16 - - [26/Jan/2004:19:45:48 +0200] "GET /c136.html HTTP/1.1" 200 1674 "http://office/c120.html" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.5) Gecko/20031007"
    	    String patternString = """
                    ([-\\w.]+)\\s+      # 1. Host
                    ([-\\w]+)\\s+       # 2. Logname
                    ([-\\w]+)\\s+       # 3. User
                    \\[(\\d+)/          # 4. Date
                    (\\w+)/             # 5. Month
                    (\\d+):             # 6. Year
                    (\\d+):             # 7. Hour
                    (\\d+)              # 8. Minute
                    ([^]]+?)\\]\\s+     # 9. Rest of time
                    \"([-\\w]+)\\s*     # 10. Request verb
                    ([^\\s]*)           # 11. Request URL
                    ([^\"]*?)\"\\s+     # 12. Request protocol etc.
                    (\\d+)\\s+          # 13. Status
                    ([-\\d]+)\\s+       # 14. Bytes
                    \"([^\"]*)\"\\s+    # 15. Referrer URL
                    \"([^\"]*)\"        # 16. Client
    	    """;
    	    cre = Pattern.compile(patternString, Pattern.COMMENTS);
    	} catch (PatternSyntaxException e) {
    	    System.err.println("Invalid RE syntax: " + e.getDescription());
    	    System.exit(1);
    	}
    
    	BufferedReader in = null;
    	try {
    	    in = new BufferedReader(new InputStreamReader(new FileInputStream(args[0])));
    	} catch (FileNotFoundException e) {
    	    System.err.println("Unable to open file " + args[1] + ": " + e.getMessage());
    	    System.exit(1);
    	}
    
    	var host = new HashMap<String, Integer>();
    	var hour = new HashMap<String, Integer>();
    	var request = new HashMap<String, Integer>();
    	var referrer = new HashMap<String, Integer>();
    	try {
    	    String s;
    	    while ((s = in.readLine()) != null) {
    		Matcher m = cre.matcher(s);
    		if (!m.matches())
    		    System.out.println("Invalid line: " + s);
    		else {
    		    increment(host, s, m, 1);
    		    increment(hour, s, m, 7);
    		    increment(request, s, m, 11);
    		    increment(referrer, s, m, 15);
    		}
    	    }
    	} catch (Exception e) {
    	    System.err.println("Error reading line: " + e.getMessage());
    	    System.exit(1);
    	}
    	sortedList("Host Access Counts", host);
    	sortedList("Hourly Access Counts", hour);
    	sortedList("Request URL Access Counts", request);
    	sortedList("Referrer URL Access Counts", referrer);
        }
    }
    

    Υλοποίηση αναγνώρισης κανονικών εκφράσεων

    Μηχανή μετάπτωσης καταστάσεων για αναγνώριση της κανονικής έκφρασης (ΔΕΤ!+)|(ΔΕΟΣ) State machine example (Υλοποιείται από 9 άτομα.)

    Επιλογή ανάμεσα σε JSON και XML

    O μορφότυπος JSON

    Σύνταξη JSON

    
    {
        "name": "John",
        "age": 30,
        "isStudent": false,
        "courses": ["Math", "Science"],
        "address": {
            "city": "Athens",
            "country": "Greece"
        }
    }
    

    Βασικοί τύποι δεδομένων σε JSON

    Ενσωμάτωση JSON στη Java

    Ανάγνωση και δημιουργία δεδομένων JSON

    
    package gr.aueb.dmst.dds.example;
    
    import com.google.gson.Gson;
    
    record Person(String name, int age) {}
    
    public class JsonIO {
        public static void main(String[] args) {
            Gson gson = new Gson();
    
    	// Read a JSON object
            String json = "{\"name\":\"Anna\", \"age\":25}";
            Person person = gson.fromJson(json, Person.class);
            System.out.println("Read Person: " + person);
    
    	// Serialize a Java object into JSON
            String serializedJson = gson.toJson(person);
            System.out.println("Serialized JSON: " + serializedJson);
        }
    }
    

    Βέλτιστες πρακτικές

    Βάσεις της XML

    Έγγραφα XML

    Παραδείγματα XML

    Παράδειγμα: ένα στοιχείο με κείμενο

    
    <city>Larisa</city>
    

    Παράδειγμα: στοιχείο με περιεχόμενο άλλα στοιχεία

    
     <?xml version="1.0" encoding="US-ASCII" ?>
     <city_info>
        <name>Larisa</name>
        <area_code>241</area_code>
        <latitude>39.38</latitude>
        <longitude>-22.25</longitude>
        <country>Greece</country>
     </city_info>
    

    Παράδειγμα: κενό στοιχείο

    
    <alumnus />
    
    Ηλεκτρονικό τιμολόγιο (https://docs.oasis-open.org/ubl/os-UBL-2.1/xml/UBL-Invoice-2.1-Example.xml)

    Προσδιορισμοί

    Παράδειγμα:
    
    <city country="el" id="HER">
    <name>Hrakleio</name>
    </city>
    

    Οντότητες και σχόλια

    Οι παρακάτω οντότητες (entities) μπορούν να οριστούν περιφραστικά:
    ΟντότηταΣύνταξη XML
    <&lt;
    &&amp;
    >&gt;
    "&quot;
    '&apos;

    Σχόλια μέσα σε ένα έγγραφο XML γράφονται ως
    <!-- περιεχόμενο -->

    Διάκριση μεταξύ οντοτήτων, στοιχείων και προσδιορισμών

    Παράδειγμα: ΚΑΔ XML

    Τα παρακάτω αρχείο χρησιμοποιείται από τους φορολογούμενους για να δηλώσουν στη ΑΑΔΕ τον κωδικό αριθμό δραστηριότητάς (ΚΑΔ) τους.
    
    <?xml version="1.0" encoding="UTF-8"?>
    <ekad xmlns="http://www.gsis.gr/ekad"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      afm="046523469">
        <branch aa="0">
            <kad typeOfKad="1">
                <value>71121908</value>
            </kad>
        </branch>
    </ekad>
    

    Ορισμός σχήματος εγγράφων με τη χρήση XSD

    Σχήμα για απλά στοιχεία

    Στοιχεία XML που περιέχουν απλά δεδομένα όπως το παρακάτω
    
    <?xml version="1.0" ?>
    <studentID>802345</studentID>
    
    μπορούν να δηλωθούν με το στοιχείο element και τον προσδιορισμό του τύπου.
    
    <?xml version="1.0" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="studentID" type="xsd:integer" />
    </xsd:schema>
    

    Διαθέσιμοι τύποι

    Μερικοί διαθέσιμοι τύποι είναι οι παρακάτω:

    Περιορισμοί σε απλά στοιχεία

    Αν θέλουμε να περιορίσουμε το περιεχόμενο του στοιχείου, μπορούμε να χρησιμοποιήσουμε τα στοιχεία simpleType και restriction μαζί με διάφορους περιορισμούς (restrictions) (στο παράδειγμα pattern).
    
    <?xml version="1.0" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="studentID" >
            <xsd:simpleType>
                <xsd:restriction base="xsd:integer">
                    <xsd:pattern value="80\d{4}" />
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:element>
    </xsd:schema>
    

    Είδη περιορισμών

    Μερικοί υποστηριζόμενοι περιορισμοί είναι οι παρακάτω: Όλοι παίρνουν μια παράμετρο value, που ορίζει την τιμή τους.

    Παραδείγματα περιορισμών

    Παράδειγμα σχήματος για βαθμό:
    
    <?xml version="1.0" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <xsd:element name="grade" >
                    <xsd:simpleType>
                      <xsd:restriction base="xsd:float">
                        <xsd:pattern value="\d+\.[05]"/>
                        <xsd:minInclusive value="0"/>
                        <xsd:maxInclusive value="10"/>
                      </xsd:restriction>
                    </xsd:simpleType>
            </xsd:element>
    </xsd:schema>
    
    
    Παράδειγμα περιορισμού για επιλογή μιας πόλης:
    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
        <xsd:enumeration value="Athens"/>
        <xsd:enumeration value="Thessaloniki"/>
        <xsd:enumeration value="Argostoli"/>
        <xsd:enumeration value="Volos"/>
        <!-- ... -->
      </xsd:restriction>
    </xsd:simpleType>
    

    Σύνθετοι τύποι

    Ορισμοί προσδιορισμών

    Απλό περιεχόμενο

    Παράδειγμα απλού περιεχομένου

    Παράδειγμα σχήματος:
    
    <?xml version="1.0" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="country">
      <xsd:complexType>
        <xsd:simpleContent >
            <xsd:extension base="xsd:string" >
                <xsd:attribute name="code" type="xsd:string" use="required" />
            </xsd:extension>
        </xsd:simpleContent >
      </xsd:complexType>
    </xsd:element>
    </xsd:schema>
    
    Παράδειγμα εγγράφου:
    
    <?xml version="1.0" ?>
    <country code="el">Greece</country>
    

    Ομάδες

    Σε ένα στοιχείο complexType μπορούμε να ορίσουμε και τα παρακάτω στοιχεία

    Παράδειγμα ομάδων

    Παράδειγμα σχήματος:
    
    <?xml version="1.0" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="javaProgram">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="package" type="xsd:string" />
                    <xsd:element name="import" type="xsd:string" maxOccurs="unbounded" />
                    <xsd:element name="class">
                        <xsd:complexType>
                            <xsd:sequence>
                                <xsd:element name="name" type="xsd:string" />
                                <xsd:choice maxOccurs="unbounded">
                                    <xsd:element name="field" type="xsd:string" />
                                    <xsd:element name="ctor" type="xsd:string" />
                                    <xsd:element name="method" type="xsd:string" />
                                </xsd:choice>
                            </xsd:sequence>
                            <xsd:attribute name="extends" type="xsd:string" use="optional" />
                        </xsd:complexType>
                    </xsd:element>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
    
    Παράδειγμα εγγράφου:
    
    <?xml version="1.0" ?>
    <javaProgram>
            <package>gr.aueb.dds.bio</package>
            <import>java.util.Date</import>
            <import>java.math.BigDecimal</import>
            <class extends="Object">
                    <name>Point</name>
                    <field>int x</field>
                    <field>int y</field>
                    <ctor>Point(int x, int y)</ctor>
                    <field>static int numPoints</field>
            </class>
    </javaProgram>
    

    Αριθμητικοί περιορισμοί

    Παράδειγμα: Μια τάξη μπορεί να έχει 10-150 φοιτητές.
    
    <?xml version="1.0" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="class" >
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="student" type="xsd:string"
                     minOccurs="10" maxOccurs="150" />
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
    

    Ανακεφαλαίωση

    Η επιτρεπόμενη δομή ενός εγγράφου XSD εμφανίζεται στο παρακάτω σχήμα.
    the content models in an XML Schema
    (Αναδημοσιεύεται με την άδεια του συγγραφέα Rahul Srivastava).

    Παράδειγμα: ΚΑΔ XSD

    Τα παρακάτω σχήμα ορίζει τη μορφή του αρχείου που χρησιμοποιείται από τους φορολογούμενους για να δηλώσουν στη ΑΑΔΕ τον κωδικό αριθμό δραστηριότητάς (ΚΑΔ) τους.
    
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns="http://www.gsis.gr/ekad" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.gsis.gr/ekad" elementFormDefault="qualified" attributeFormDefault="unqualified">
      <xs:element name="ekad">
        <xs:annotation>
          <xs:documentation>root element</xs:documentation>
        </xs:annotation>
        <xs:complexType>
          <xs:sequence>
            <xs:element name="branch" nillable="false" maxOccurs="unbounded">
              <xs:annotation>
                <xs:documentation>Εγκατάσταση</xs:documentation>
              </xs:annotation>
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="kad" maxOccurs="unbounded">
                    <xs:complexType>
                      <xs:sequence>
                        <xs:element name="value" nillable="false">
                          <xs:annotation>
                            <xs:documentation>Η τιμή του ΚΑΔ</xs:documentation>
                          </xs:annotation>
                          <xs:simpleType>
                            <xs:restriction base="xs:integer">
                              <xs:totalDigits value="15"/>
                            </xs:restriction>
                          </xs:simpleType>
                        </xs:element>
                      </xs:sequence>
                      <xs:attribute name="typeOfKad" use="required">
                        <xs:annotation>
                          <xs:documentation>Είδος ΚΑΔ (δραστηριότητας). 1=Κύρια, 2=Δευτερεύουσα, 3=Λοιπή, 4=Βοηθητική</xs:documentation>
                        </xs:annotation>
                        <xs:simpleType>
                          <xs:restriction base="xs:int">
                            <xs:enumeration value="1"/>
                            <xs:enumeration value="2"/>
                            <xs:enumeration value="3"/>
                            <xs:enumeration value="4"/>
                          </xs:restriction>
                        </xs:simpleType>
                      </xs:attribute>
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
                <xs:attribute name="aa" use="required">
                  <xs:annotation>
                    <xs:documentation>ΑΑ εγκατάστασης. Η έδρα δηλώνεται σαν υποκατάστημα με ΑΑ=0. Εάν υπάρχει μητρική εταιρεία στο εξωτερικό, ο ΚΑΔ της δηλώνεται ως υποκατάστημα με ΑΑ=9999</xs:documentation>
                  </xs:annotation>
                  <xs:simpleType>
                    <xs:restriction base="xs:int">
                      <xs:minInclusive value="0"/>
                    </xs:restriction>
                  </xs:simpleType>
                </xs:attribute>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
          <xs:attribute name="afm" use="required">
            <xs:annotation>
              <xs:documentation>ΑΦΜ υπόχρεου</xs:documentation>
            </xs:annotation>
            <xs:simpleType>
              <xs:restriction base="xs:string">
                <xs:minLength value="9"/>
                <xs:maxLength value="9"/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    Μετασχηματισμοί με τη χρήση XSLT

    Στοιχεία της XSLT

    Παράδειγμα μετασχηματισμού: σχήμα

    
    <?xml version="1.0" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="project">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="shortname" type="xsd:string" />
                    <xsd:element name="projtitle" type="xsd:string" />
                    <xsd:element name="startdate" type="xsd:date" minOccurs="0" />
                    <xsd:element name="enddate" type="xsd:date" />
                    <xsd:element name="web_site" type="xsd:string" minOccurs="0" />
                    <xsd:element name="our_budget" type="xsd:integer" minOccurs="0" />
                    <xsd:element name="total_budget" type="xsd:integer" minOccurs="0" />
                    <xsd:element name="funding_agency" type="xsd:string" minOccurs="0" />
                    <xsd:element name="funding_programme" type="xsd:string" minOccurs="0" />
                    <xsd:element name="project_code" type="xsd:string" minOccurs="0" />
                    <xsd:element name="partner" minOccurs="0" maxOccurs="unbounded">
                        <xsd:complexType>
                            <xsd:sequence>
                                <xsd:element name="shortname" type="xsd:string" />
                                <xsd:element name="country" type="xsd:string" />
                                <xsd:element name="web_site" type="xsd:string" minOccurs="0" />
                            </xsd:sequence>
                        </xsd:complexType>
                    </xsd:element>
                    <xsd:element name="logo" type="xsd:string" minOccurs="0" />
                    <xsd:element name="description" type="xsd:string" />
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
    

    Παράδειγμα μετασχηματισμού: έγγραφο

    
    <?xml version="1.0"?>
    <project>
            <shortname>mExpress</shortname>
            <projtitle>mobile in-EXhibition PRovision of Electronic Support Services</projtitle>
            <startdate>2002-03-05</startdate>
            <enddate>2004-04-01</enddate>
            <web_site>http://mexpress.intranet.gr/</web_site>
            <our_budget>328</our_budget>
            <total_budget>3493</total_budget>
            <funding_agency>European Commission</funding_agency>
            <funding_programme>IST</funding_programme>
            <project_code>IST-2001-33432</project_code>
            <partner>
                    <shortname>Intracom</shortname>
                    <country>EL</country>
                    <web_site>http://www.intracom.gr</web_site>
            </partner>
            <partner>
                    <shortname>Ericsson</shortname>
                    <country>DK</country>
                    <web_site>http://www.ericsson.com/</web_site>
            </partner>
            <partner>
                    <shortname>ELISA</shortname>
                    <country>FIN</country>
                    <web_site>http://www.elisa.com</web_site>
            </partner>
            <partner>
                    <shortname>POULIADIS</shortname>
                    <country>EL</country>
                    <web_site>http://www.pouliadis.gr</web_site>
            </partner>
            <partner>
                    <shortname>SSF</shortname>
                    <country>FIN</country>
                    <web_site>http://www.ssf.fi/</web_site>
            </partner>
            <partner>
                    <shortname>HUT</shortname>
                    <country>FIN</country>
                    <web_site>http://www.hut.fi</web_site>
            </partner>
            <partner>
                    <shortname>FFC</shortname>
                    <country>FIN</country>
            </partner>
            <partner>
                    <shortname>ROTA</shortname>
                    <country>EL</country>
                    <web_site>http://www.rota.gr</web_site>
            </partner>
            <logo>../images/p_mexpress.gif</logo>
            <description>
    mEXPRESS aims to exploit the technological opportunities arising from
    evolution in the areas of wireless networks and positioning mechanisms in
    order to support and facilitate the professional exhibition industry in
    a context-aware manner. It will contribute to the economic development of
    the Community by providing means for efficient operation and interaction
    in information-rich environments such as exhibitions, and significantly
    enhancing promotional activities and business communications. The mEXPRESS
    project will provide an integrated mediation platform (mEXPRESS Service
    Provider) oriented to exhibition shows and events.
            </description>
    </project>
    

    Παράδειγμα μετασχηματισμού: XSLT

    
    <?xml version="1.0"?>
    <!-- Apply using
    xml tr project.xslt mexpress.xml
    -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:template match="project">
                    <h1>
                    <xsl:value-of select="shortname" />
                    -
                    <xsl:value-of select="projtitle" />
                    </h1>
                    <!-- Show Logo -->
                    <xsl:element name="img">
                            <xsl:attribute name="src"><xsl:value-of select="logo" /></xsl:attribute>
                    </xsl:element>
                    <br /> <br />
                    <!-- Project Summary information -->
                    <xsl:if test="count(project_code) != 0">
                            Project Code:
                            <xsl:value-of select="project_code" />
                            <xsl:if test="@international = 'yes'">
                                    (International)
                            </xsl:if>
                            <br/>
                    </xsl:if>
                    <xsl:if test="count(funding_programme) != 0">
                            Funding programme: <xsl:value-of select="funding_programme" />
                            <br />
                    </xsl:if>
                    <xsl:if test="count(funding_agency) != 0">
                            Funding Agency: <xsl:value-of select="funding_agency" />
                            <br />
                    </xsl:if>
                    <xsl:if test="@type != ''">
                            Project type:
                            <xsl:choose>
                                    <xsl:when test="@type = 'rtd'">RTD</xsl:when>
                                    <xsl:when test="@type = 'consulting'">Consulting</xsl:when>
                                    <xsl:when test="@type = 'training'">Training</xsl:when>
                                    <xsl:when test="@type = 'dissemination'">Dissemination</xsl:when>
                            </xsl:choose>
                            <br />
                    </xsl:if>
                    <xsl:if test="count(web_site) != 0">
                            Web site:
                            <xsl:element name="a">
                                    <xsl:attribute name="href"><xsl:value-of select="web_site"/></xsl:attribute>
                                    <xsl:value-of select="web_site" />
                            </xsl:element>
                            <br />
                            <br />
                    </xsl:if>
                    <xsl:if test="count(our_budget) != 0">
                            ELTRUN budget: <xsl:value-of select="our_budget" /> EUR
                            <br />
                    </xsl:if>
                    <xsl:if test="count(total_budget) != 0">
                            Total budget: <xsl:value-of select="total_budget" /> EUR
                            <br />
                    </xsl:if>
                    <br />
            </xsl:template>
    </xsl:stylesheet>
    

    Παράδειγμα μετασχηματισμού: αποτέλεσμα

    mExpress - mobile in-EXhibition PRovision of Electronic Support Services



    Project Code: IST-2001-33432 (International)
    Funding programme: IST
    Funding Agency: European Commission
    Project type: RTD
    Web site: http://mexpress.intranet.gr/ (http://mexpress.intranet.gr/)

    ELTRUN budget: 328 EUR
    Total budget: 3493 EUR

    Το μοντέλο αντικειμένων εγγράφων

    Μέθοδοι της NodeList

    Η υλοποίηση του μοντέλου αντικειμένων εγγράφων στη Java

    Κλήσεις μέσω της διεπαφής Document

    Παράδειγμα: υπολογισμός μέσου όρου

    
    import javax.xml.parsers.*;
    import java.io.*;
    import org.w3c.dom.*;
    
    class Average {
        public static void main(String args[]) {
    
            if (args.length != 2) {
                System.err.println("Usage: Average element file");
                System.exit(1);
            }
    
            Document doc = null;
            try {
                // Create the DocumentBuilderFactory
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                // Create the document builder
                DocumentBuilder db = dbf.newDocumentBuilder();
                // Create DOM document from the file
                doc = db.parse(new File(args[1]));
            } catch (Exception e) {
                System.err.println("Parsing failed: " + e);
                System.exit(1);
            }
    
            NodeList nodes = doc.getElementsByTagName(args[0]);
            double sum = 0.0;
            for (int i = 0; i < nodes.getLength(); i++) {
                String grade = nodes.item(i).getFirstChild().getNodeValue();
                sum += (Integer.valueOf(grade)).doubleValue();
            }
            System.out.println(sum / nodes.getLength());
        }
    }
    

    Αποτέλεσμα υπολογισμού

    Η εκτέλεση στο αρχείο
    
    <result_list>
        <result>
            <id>809678</id>
            <grade>9</grade>
        </result>
        <result>
            <id>809630</id>
            <grade>8</grade>
        </result>
        <result>
            <id>809679</id>
            <grade>10</grade>
        </result>
        <result>
            <id>809673</id>
            <grade>6</grade>
        </result>
    </result_list>
    
    γίνεται ως εξής.
    java Average grade grade.xml
    8.25
    

    Άσκηση: Περιγραφή δεδομένων με XML και κανονικές εκφράσεις

    Άσκηση 10

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Παράρτημα: Ορισμός τύπου εγγράφων με τη χρήση DTD

    Υποστηρίζονται οι παρακάτω ορισμοί:
    Απλοί χαρακτήρες (parsed character data)
    
    <!ELEMENT name (#PCDATA)>
    
    Ένα στοιχείο
    
    <!ELEMENT student (person_data)>
    
    Ακολουθία στοιχείων
    
    <!ELEMENT person_data (name, surname)>
    
    Κανένα ή ένα στοιχείο
    
    <!ELEMENT person_name (given_name, initial?, last_name)>
    
    Μηδέν ή περισσότερα στοιχεία
    
    <!ELEMENT owned_cars (car*)>
    
    Ένα ή περισσότερα στοιχεία
    
    <!ELEMENT course_lecturer (person_data+)>
    
    Επιλογή στοιχείων
    
    <!ELEMENT engine (two_stroke | four_stroke | wankel | rotary)>
    
    Χρήση παρενθέσεων
    
    <!ELEMENT person_details (name, surname, (vat_number | id_number))>
    
    Κενό περιεχόμενο
    
    <!ELEMENT alumnus EMPTY>
    
    Τυχαίο περιεχόμενο
    
    <!ELEMENT text ANY>
    

    Παράδειγμα - DTD

    
    <!--
     -
     - Document Type Description for the projects
     -
     - $Id: project.dtd,v 1.2 2004/01/24 20:20:04 bkarak Exp $
     -
    -->
    <!ELEMENT project (
        shortname, 
        projtitle, 
        startdate?, 
        enddate, 
        web_site?, 
        our_budget?, 
        total_budget?, 
        funding_agency?, 
        funding_programme?, 
        project_code?, 
        partner*, 
        logo?, 
        description
    )>
    
    <!ELEMENT projtitle (#PCDATA)>
    <!ELEMENT our_budget (#PCDATA)>
    <!ELEMENT total_budget (#PCDATA)>
    <!ELEMENT funding_agency (#PCDATA)>
    <!ELEMENT funding_programme (#PCDATA)>
    <!ELEMENT project_code (#PCDATA)>
    <!ELEMENT web_site (#PCDATA)>
    <!ELEMENT startdate (#PCDATA)>
    <!ELEMENT enddate (#PCDATA)>
    <!ELEMENT shortname (#PCDATA)>
    <!ELEMENT logo (#PCDATA)>
    <!ELEMENT description (#PCDATA)>
    
    <!ELEMENT partner (shortname, country, web_site?)>
    <!ELEMENT shortname (#PCDATA)>
    <!ELEMENT country (#PCDATA)>
    

    Παράδειγμα - αντίστοιχη XML

    
    <?xml version="1.0"?>
    <project>
        <shortname>mExpress</shortname>
        <projtitle>mobile in-EXhibition PRovision of Electronic Support Services</projtitle>
        <startdate>20020305</startdate>
        <enddate>20040401</enddate>
        <web_site>http://mexpress.intranet.gr/</web_site>
        <our_budget>328 EUR</our_budget>
        <total_budget>3,493 EUR</total_budget>
        <funding_agency>European Commission</funding_agency>
        <funding_programme>IST</funding_programme>
        <project_code>IST-2001-33432</project_code>
        <partner>
            <shortname>Intracom</shortname>
            <country>EL</country>
            <web_site>http://www.intracom.gr</web_site>
        </partner>
        <partner>
            <shortname>Ericsson</shortname>
            <country>DK</country>
            <web_site>http://www.ericsson.com/</web_site>
        </partner>
        <partner>
            <shortname>ELISA</shortname>
            <country>FIN</country>
            <web_site>http://www.elisa.com</web_site>
        </partner>
        <partner>
            <shortname>POULIADIS</shortname>
            <country>EL</country>
            <web_site>http://www.pouliadis.gr</web_site>
        </partner>
        <partner>
            <shortname>SSF</shortname>
            <country>FIN</country>
            <web_site>http://www.ssf.fi/</web_site>
        </partner>
        <partner>
            <shortname>HUT</shortname>
            <country>FIN</country>
            <web_site>http://www.hut.fi</web_site>
        </partner>
        <partner>
            <shortname>FFC</shortname>
            <country>FIN</country>
        </partner>
        <partner>
            <shortname>ROTA</shortname>
            <country>EL</country>
            <web_site>http://www.rota.gr</web_site>
        </partner>
        <logo>../images/p_mexpress.gif</logo>
        <description>
    mEXPRESS aims to exploit the technological opportunities arising from
    evolution in the areas of wireless networks and positioning mechanisms in
    order to support and facilitate the professional exhibition industry in
    a context-aware manner. It will contribute to the economic development of
    the Community by providing means for efficient operation and interaction
    in information-rich environments such as exhibitions, and significantly
    enhancing promotional activities and business communications. The mEXPRESS
    project will provide an integrated mediation platform (mEXPRESS Service
    Provider) oriented to exhibition shows and events.
        </description>
    </project>
    

    Παράρτημα: Ορισμός τύπων προσδιορισμών με τη χρήση DTD

    Οι προδιορισμοί που επιτρέπονται σε ένα στοιχείο ορίζονται με στοιχεία της μορφής
    
    <!ATTLIST όνομα_στοιχείου
        όνομα_προσδιορισμού τύπος_προσδιορισμού περιορισμός
        ...
    >
    
    Υποστηρίζονται μεταξύ άλλων οι παρακάτω τύποι προσδιορισμού
    Χαρακτήρες
    CDATA
    Απαρίθμηση
    (επιλογή1 | επιλογή2 | ...)
    Κλειδί
    ID
    Αναφορά σε κλειδί
    IDREF
    Αναφορά σε κλειδιά
    IDREFS
    Οι πιο χρήσιμοι περιορισμοί προσδιορισμών είναι:
    #IMPLIED
    Προαιρετικός προσδιορισμός
    #REQUIRED
    Υποχρεωτικός προσδιορισμός

    Παράδειγμα - DTD

    
    <!ATTLIST project
        id ID #REQUIRED
        contact CDATA #IMPLIED
        scientific_coordinator CDATA #IMPLIED
        project_manager CDATA #IMPLIED
        group CDATA #REQUIRED
        international (yes | no) #REQUIRED
        type (consulting | rtd | training | dissemination) #REQUIRED
    >
    

    Παράδειγμα - XML

    
    <?xml version="1.0"?>
    <project
        id="p_mexpress"
        group="g_sense g_wrc"
        scientific_coordinator="m_dds"
        contact="m_pateli"
        international="yes"
        type="rtd"
        project_manager="m_pateli"
    >
    <!-- ... -->
    </project>
    

    Εκτενές παράδειγμα

    Γιορτινή κάρτα

    Ολοκληρωμένο παράδειγμα

    Διάγραμμα των κλάσεων

    XMas card class diagram

    HolidayCard

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import java.awt.Rectangle;
    
    /**
     * The Holiday Card program main class.
     *
     * @author Giorgos Gousios, Diomidis Spinellis
     * @depend - - - gr.aueb.card.DrawPanel
     * @depend - <instantiate> - gr.aueb.card.MidiPlayer
     * @depend - - - gr.aueb.card.Tree
     * @depend - - - gr.aueb.card.PointSnowFlake
     * @depend - - - gr.aueb.card.SlashSnowFlake
     */
    public class HolidayCard {
    
        /** Number of trees */
        private static final int NUM_TREES = 30;
        /** Number of snowflakes */
        private static final int NUM_SNOWFLAKES = 1500;
        /** Minimum tree width. */
        private static final int TREE_WIDTH = 30;
        /** Minimum tree height. */
        private static final int TREE_HEIGHT = 100;
        /** Additional variation to tree height and width */
        private static final int TREE_WOBBLE = 100;
        /** Song to play. */
        private static String musicFile = "/Jingle_Bells_full_Ab.mid";
    
        public static void main(String[] args) {
    
            // Create a window and the canvas to draw onto.
            DrawPanel d = DrawPanel.getInstance();
    
            // Create randomly-positioned trees.
            for (int i = 0; i < NUM_TREES; i++) {
                Rectangle treeBox = new Rectangle(
    		(int)(Math.random() * DrawPanel.WIDTH),
                    (int)(Math.random() * DrawPanel.HEIGHT),
                    TREE_WIDTH + (int)(Math.random() * TREE_WOBBLE),
                    TREE_HEIGHT + (int)(Math.random() * TREE_WOBBLE));
    
                Tree t = new Tree(d.getCanvas(), treeBox);
                d.addDrawObject(t);
            }
    
    	// Start playing music
    	MidiPlayer m = new MidiPlayer(musicFile);
    
            // Create the snowflakes.
            for (int i = 0; i < NUM_SNOWFLAKES; i++) {
    	    switch (i % 6) {
    	    case 0, 1:
                    d.addDrawObject(new PointSnowFlake(d.getCanvas(), '.', 15));
    		break;
    	    case 2:
                    d.addDrawObject(new PointSnowFlake(d.getCanvas(), 'o', 10));
    		break;
    	    case 3:
                    d.addDrawObject(new PointSnowFlake(d.getCanvas(), '*', 5));
    		break;
    	    case 4, 5:
                    d.addDrawObject(new SlashSnowFlake(d.getCanvas()));
    		break;
    	    }
    	    try {
    		// Allow existing snowflakes to fall a bit, before adding more
    		Thread.sleep(100);
    	    } catch (InterruptedException e) {
    	    }
            }
        }
    }
    

    DrawPanel

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.Vector;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    /**
     * The program's main window.
     * Extends JFrame to display the window where the
     * trees and snow are drawn. Implements the {@link java.lang.Runnable Runnable}
     * interface so as to create a thread that repeatedly calls the
     * {@link gr.aueb.card.Drawable#draw() draw}method.
     *
     * @author Giorgos Gousios, Diomidis Spinellis
     * @opt nodefillcolor lightblue
     * @assoc 1 drawablePanel 1 DrawablePanel
     */
    public class DrawPanel extends JFrame implements Runnable {
    
        /** The window's width. */
        public static final int WIDTH = 1024;
        /** The window's height. */
        public static final int HEIGHT = 768;
    
        /** The window's background color (blue). */
        public static final Color BACKGROUND_COLOR = new Color(0, 153, 204);
    
        /* A table that holds the objects to be drawn */
        private Vector<Drawable> drawObjects = null;
    
        /* The drawing thread (not serializable) */
        private transient Thread thread;
    
        /* The canvas to draw onto */
        private DrawablePanel drawablePanel = null;
    
        /** Serial number of persistant  data.
         * Required, because JFrame implements serializable.
         */
        static final long serialVersionUID = 1L;
    
        /**
         * Constructor to initialize an object with the minimal required state.
         * The constructor is private, as the full initialization is done
         * in the getInstance method.
         */
        private DrawPanel() {
            super("Holiday Card");
        }
    
        /**
         * Field initialization based on a constructed instance
         */
        private void initialize() {
            drawObjects = new Vector<Drawable>();
            initializeGraphics();
            initializeThread();
        }
    
        /**
         * Initialize, display the window, and start the animation.
         * The code here is separate from the constructor in order to
         * avoid the resulting "this escape".
         */
        public static DrawPanel getInstance() {
            DrawPanel instance = new DrawPanel();
            instance.initialize();
            return instance;
        }
    
        /** Initialize the main window. */
        private void initializeGraphics() {
            // Make our window look nice
            JFrame.setDefaultLookAndFeelDecorated(true);
    
            // Create our drawing canvas
            drawablePanel = new DrawablePanel(this);
            drawablePanel.setBackground(BACKGROUND_COLOR);
            drawablePanel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
            setContentPane(drawablePanel);
    
            // Handle termination
            setDefaultCloseOperation(
                    javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    
            // Exit when the window is closed
            addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
    
            // Our size
            setSize(WIDTH, HEIGHT);
    
            // Force the parent window to expand the canvas to all available space
            pack();
    
            //Display the window
            setVisible(true);
        }
    
        /** Start the execution of the drawing thread. */
        private void initializeThread() {
            if (thread == null) {
                thread = new Thread(this);
                thread.setPriority(Thread.MIN_PRIORITY);
                thread.start();
            }
        }
    
        /** Add a component to be drawn. */
        public void addDrawObject(Drawable drawObject) {
            drawObjects.add(drawObject);
        }
    
        /** Return a copy of the component list to be drawn */
        public Vector<Drawable> getDrawables() {
            return new Vector<Drawable>(drawObjects);
        }
    
        /**
         * The method to be executed by the running thread. Executes the
         * {@link DrawablePanel#repaint()}method periodically.
         */
        public void run() {
            Thread me = Thread.currentThread();
    
            // Allow termination by setting thread to null
            while (thread == me) {
                // tell drawablePanel to repaint its contents
                drawablePanel.repaint();
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e) {
                }
            }
            thread = null;
        }
    
        /**
         * Get the canvas's drawing panel
         *
         * @return javax.swing.JPanel
         */
        public JPanel getCanvas(){
            return drawablePanel;
        }
    }
    

    Drawable

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import javax.swing.JPanel;
    
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    
    /**
     * An abstract representation of a self-drawable object.
     *
     * @author Giorgos Gousios, Diomidis Spinellis
     */
    public abstract class Drawable {
    
        /**
         * The canvas to draw the object onto
         */
        protected Graphics2D canvas;
    
        /**
         * The canvas's bounds
         */
        protected Rectangle bounds;
    
        /**
         * Create drawable item
         *
         * @param panel The panel to draw the object onto
         */
        public Drawable(JPanel panel) {
            bounds = panel.getBounds();
            canvas = (Graphics2D)panel.getGraphics();
        }
    
        /**
         * Draws the object onto the canvas
         *
         */
        public abstract void draw(Graphics g);
    }
    

    DrawablePanel

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.util.Vector;
    
    import javax.swing.JPanel;
    
    
    /**
     * The Holiday Card program main class.
     *
     * @author Georgios Zouganelis
     * Draw components from this object to reduce flickering.
     */
    public class DrawablePanel extends JPanel {
    
        /** The DrawPanel this DrawablePanel is attached to **/
        private DrawPanel controller = null;
    
        /** Serial number of persistent  data.
         * Required, because JPanel implements serializable.
         */
        private static final long serialVersionUID = 1L;
    
        /**
         * Constructor to initialize the DrawablePanel with it's controller
         *
         */
        public DrawablePanel(DrawPanel panel) {
            controller = panel;
        }
    
        /**
         * Perform all drawing operations
         * By overriding the JPanel method and initiating all the drawing
         * from this place we take advantage of JPanel's double-buffering
         * capability.
         */
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            setBackground(DrawPanel.BACKGROUND_COLOR);
    
            // Ask our controller for a copy of items to draw
            Vector<Drawable> toPaint = controller.getDrawables();
            for (Drawable d : toPaint)
                d.draw(g);
        }
    }
    

    Tree

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Polygon;
    import java.awt.Rectangle;
    import javax.swing.JPanel;
    
    /**
     * A self-drawable tree. Uses a box to specify the tree's bounds (the dimensions
     * constructor parameter). The trunk is placed in the middle of the bottom side
     * of the box, having a width equal to the 8% of the total width of the tree and
     * a height equal to the 20% of the total height of the bounding box. The main
     * body is represented as an isosceles triangle with a height of 80% of the
     * height of the bounding box.
     *
     * @author Giorgos Gousios, Diomidis Spinellis
     * @opt nodefillcolor green
     */
    public class Tree extends Drawable {
    
        /** Tree trunk width as % of the bounding rectangle width */
        private final double TRUNK_WIDTH_FACTOR = 0.08;
        /** Tree trunk height as % of the bounding rectangle height */
        private final double TRUNK_HEIGHT_FACTOR = 0.2;
        /** Tree body height as % of the bounding rectangle height */
        private final double BODY_HEIGHT_FACTOR = 0.8;
        /** Trunk's color (RGB) */
        private final Color BROWN = new Color(204, 102, 0);
        /** Body's color (RGB) */
        private final Color GREEN = new Color(0, 254, 0);
        /** Tree balls' color (RGB) */
        private final Color RED = new Color(250, 0, 0);
    
        /** The tree's bounding rectangle */
        private Rectangle dimensions;
    
        /**
         * Creates a tree from the specified bounding box
         *
         * @param panel The panel to draw the object onto
         * @param dimensions The bounding box dimensions.
         */
        public Tree(JPanel panel, Rectangle dimensions) {
        super(panel);
    	this.dimensions = dimensions;
        }
    
        /**
         * Draws the tree.
         *
         * @param g The Graphics object on which we will paint
         */
        @Override
        public void draw(Graphics g) {
    	drawTrunk(g);
    	drawBody(g);
        }
    
        /**
         * Draws the trunk. For details on how the lengths are calculated
         *
         * @param g The Graphics object on which we will paint
         * @see gr.aueb.Tree the class description.
         */
        private void drawTrunk(Graphics g) {
    	/* Calculate the trunk rectangle first */
    	Rectangle r = new Rectangle();
    
    	r.x = (int) (dimensions.x + (dimensions.width
                        - dimensions.width * TRUNK_WIDTH_FACTOR) / 2);
    	r.y = (int) (dimensions.y + dimensions.height * BODY_HEIGHT_FACTOR);
    	r.width = (int) (dimensions.width * TRUNK_WIDTH_FACTOR);
    	r.height = (int) (dimensions.height * TRUNK_HEIGHT_FACTOR);
    
    	/* Draw it! */
    	g.drawRect(r.x, r.y, r.width, r.height);
    
    	/* Fill it with brown color */
    	Color c = g.getColor();
    	g.setColor(BROWN);
    	g.fillRect(r.x, r.y, r.width, r.height);
    	g.setColor(c); //Revert paint color to default
        }
    
        /**
         * Draws the body. For details on how the lengths are calculated
         *
         * @param g The Graphics object on which we will paint
         * @see gr.aueb.Tree the class description.
         */
        private void drawBody(Graphics g) {
            /* Create the polygon (triangle) to draw */
            Polygon p = new Polygon();
            p.addPoint(dimensions.x + dimensions.width / 2, dimensions.y);
            p.addPoint(dimensions.x,
                    (int) (dimensions.y + dimensions.height * BODY_HEIGHT_FACTOR));
            p.addPoint(dimensions.x + dimensions.width,
                    (int) (dimensions.y + dimensions.height * BODY_HEIGHT_FACTOR));
            /* Draw the body */
            g.drawPolygon(p);
    
            /* Fill it with green color */
            Color c = g.getColor();
            g.setColor(GREEN);
            g.fillPolygon(p);
            g.setColor(c); // Revert paint color to default
    
            /* Set Ornaments to the body. */
            drawTreeOrnaments(g);
        }
    
        /**
         * Draws the ornaments of the tree.
         * @param g The Graphics object on which we will paint
         * @param x The Abscissa of the part of the body to draw the ornament
         * @param y The Ordinate of the part of the body to draw the ornament
         */
        private void addTreeOrnament(Graphics g, int x, int y) {
            /* Draw Tree Ornament. */
            g.drawOval(x, y, 10, 10);
            /* Set color to Red. */
            g.setColor(RED);
            /* Fill Tree Ornament with color. */
            g.fillOval(x, y, 10, 10);
        }
    
        /**
         * Calls addTreeOrnament for specific locations on
         * the tree body.
         * @param g The Graphics object on which we will paint
         */
        private void drawTreeOrnaments(Graphics g) {
            /* yAxis of the body. */
            int yAxis = (int) (dimensions.y + dimensions.height * BODY_HEIGHT_FACTOR);
            /* Add ornament to down left. */
            addTreeOrnament(g, dimensions.x - 2, yAxis - 2);
            /* Add ornament to down right. */
            addTreeOrnament(g, dimensions.x + dimensions.width - 1, yAxis - 1);
            /* Add ornament to up left. */
            addTreeOrnament(g, dimensions.x + dimensions.width / 2 - 5 - 20, yAxis - 25);
            /* Add ornament to up right. */
            addTreeOrnament(g, dimensions.x + dimensions.width / 2 - 5 + 20,  yAxis - 25);
            /* Add ornament to middle. */
            addTreeOrnament(g,dimensions.x + dimensions.width / 2 - 5, yAxis - 65);
        }
    }
    

    SnowFlake

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import java.awt.Color;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import javax.swing.JPanel;
    
    /**
     * A self-drawable 'snowflake' represented by a character. The move pattern and
     * character to be displayed is determined by subclasses.
     *
     * @author Giorgos Gousios, Diomidis Spinellis
     * @opt nodefillcolor white
     */
    public abstract class SnowFlake extends Drawable {
    
        /** The snowflake's background color. */
        private static final Color WHITE = new Color(255, 255, 255);
    
        /**
         * The 'x' current coordinate of the snowflake.
         */
        protected int coordX;
    
        /**
         * The 'y' current coordinate of the snowflake.
         */
        protected int coordY;
    
        /**
         * The character to be displayed as a snowflake
         */
        protected char displayChar;
    
        /**
         * Create a snowflake represented by a point-like character.
         *
         * @param panel The panel to draw the object onto
         */
        public SnowFlake(JPanel panel) {
            super(panel);
            coordX = (int) (bounds.width * Math.random()) + bounds.x;
            coordY = 0;
        }
    
        /**
         * Draw the snowflake and wrap around.
         *
         * @param g The Graphics object on which we will paint
         */
        @Override
        public void draw(Graphics g) {
            // Go back to the top when hitting the bottom
            if (coordY >= bounds.height + bounds.y)
                coordY = 0;
    
            // Draw the character in white
            g.setColor(WHITE);
            g.drawString((Character.valueOf(displayChar)).toString(),
            coordX, coordY);
        }
    }
    

    SlashSnowFlake

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import java.awt.Graphics;
    import javax.swing.JPanel;
    
    /**
     * A class that animates a slash on a canvas.
     *
     * @author Giorgos Gousios, Diomidis Spinellis
     * @opt nodefillcolor white
     */
    public class SlashSnowFlake extends SnowFlake {
    
        /**
         * Create a snowflake represented by a slash.
         *
         * @param panel The panel to draw the object onto
         */
        public SlashSnowFlake(JPanel panel) {
            super(panel);
            displayChar = '/';
        }
    
        /**
         * Display the slash on the drawing canvas. The slash alternates between
         * forward slash and backslash depending on the current 'y' coordinate.
         *
         * @param g The Graphics object on which we will paint
         */
        @Override
        public void draw(Graphics g) {
    
            /* / on even lines, \ on odd lines */
            displayChar = ((coordY % 2) == 0) ? '/' : '\\';
    
            /* Move by 0 to 10 pixels down*/
            coordY += (int) (Math.random() * 10);
    
            // Draw it through the superclass
            super.draw(g);
        }
    }
    

    PointSnowFlake

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import java.awt.Graphics;
    import javax.swing.JPanel;
    
    /**
     * A class that animates a point-like character on a canvas.
     * The character can be e.g. a . or a * or an o.
     *
     * @author Giorgos Gousios, Diomidis Spinellis
     * @opt nodefillcolor white
     */
    public class PointSnowFlake extends SnowFlake {
    
        /** The wieght of the snowflake. */
        int weight;
    
        /**
         * Create a snowflake represented by a point-like character.
         *
         * @param panel The panel to draw the object onto
         * @param c The character to draw
         * @param w The snowflake's weight
         */
        public PointSnowFlake(JPanel panel, char c, int w) {
            super(panel);
            displayChar = c;
            weight = w;
        }
    
        /**
         * Display the star onto the canvas. The star changes its 'x' coordinate,
         * depending on the 'y' coordinate.
         *
         * @param g The Graphics object on which we will paint
         */
        @Override
        public void draw(Graphics g) {
    
            // Move the snowflake left and right
            switch (coordY % 3) {
            case 1:
                coordX = coordX - 5;
                break;
            case 2:
                coordX = coordX + 5;
                break;
            default:
                break;
            }
    
            // Move down, based on the weight
            coordY += (int)(Math.random() * weight);
    
            // Draw it through the superclass
            super.draw(g);
        }
    }
    

    MidiPlayer

    
    /*-
     * Copyright 2005-2018 Diomidis Spinellis
     *
     *   Licensed under the Apache License, Version 2.0 (the "License");
     *   you may not use this file except in compliance with the License.
     *   You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *   Unless required by applicable law or agreed to in writing, software
     *   distributed under the License is distributed on an "AS IS" BASIS,
     *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *   See the License for the specific language governing permissions and
     *   limitations under the License.
     */
    
    package gr.aueb.card;
    
    import javax.sound.midi.*;
    import java.io.InputStream;
    import java.io.IOException;
    
    /**
     * Play the specified MIDI file
     * Note:
     * For this to work you must ensure that the computer's mixer
     * is configured to play the software synhtesizer output.
     *
     * @author Diomidis Spinellis
     */
    public class MidiPlayer {
        /** The sequencer we are using to play the MIDI data. */
        static Sequencer sequencer = null;
    
        /** Constructor for playing the specified file. */
        MidiPlayer(String file) {
    	playFile(file);
        }
    
        /** Play the specified file. */
        public void playFile(String file) {
            InputStream midiFile = getClass().getResourceAsStream(file);
            try {
    	    if (sequencer == null)
    		sequencer = MidiSystem.getSequencer();
    	    else
    		end();
    	    sequencer.setSequence(MidiSystem.getSequence(midiFile));
                sequencer.open();
                sequencer.start();
            } catch(MidiUnavailableException e) {
                System.err.println("Midi device unavailable:" + e);
            } catch(InvalidMidiDataException e) {
                System.err.println("Invalid MIDI data:" + e);
            } catch(IOException e) {
                System.err.println("I/O error:" + e);
            }
        }
    
        /** Return true if the music is still playing. */
        public boolean isPlaying() {
    	return sequencer.isRunning();
        }
    
        /* Stop playing. */
        public void end() {
                sequencer.stop();
                sequencer.close();
    	    sequencer = null;
        }
    }
    

    Τεκμηρίωση

    Τα σχόλια μέσα στον κώδικα επιτρέπουν την αυτόματη δημιουργία της τεκμηρίωσης, με τη χρήση του προγράμματος javadoc.
    Τεκμηρίωση σε μορφή XML

    Προαιρετική άσκηση

    Με βάση τον κώδικα της κάρτας υλοποιήστε ένα παιγνίδι (π.χ. απόφυγε το χιόνι, ή μάζεψε τις μπάλες, ή πιάσε τον τάρανδο, κ.λπ.).

    Πληροφορίες για την άσκηση

    Συναρτήσεις και ροές

    Συναρτησιακός προγραμματισμός

    Εκφράσεις λάμδα

    
    (a) -> a * a;
    (a, b) -> a + b;
    () -> true;
    

    Διαθέσιμοι τύποι

    Το πακέτο java.util.function ορίζει μια σειρά από διεπαφές FunctionalInterface:

    Οι παραπάνω μπορούν κατά περίπτωση να εξειδικευτούν παραπάνω με ένα από τα προθέματα: Bi (δέχεται δύο ορίσματα)· Int, Long, Double (τύπος ορίσματος)· Το (τύπος επιστροφής).

    Μέθοδοι σε συναρτήσεις

    Οι παρακάτω μέθοδοι είναι διαθέσιμες ανάλογα με το αντικείμενο.

    Παράδειγμα λάμδα

    
    import java.util.function.Function;
    
    class Lambda {
        public static void main(String args[]) {
            // Assign lambda to variable
            Function<Integer, Integer> square = (a) -> a * a;
            // Apply function to value
            System.out.println(square.apply(2));
    
            // Pass function to method and obtain function result
            Function<Integer, Integer> fourthPower = square.compose(square);
            System.out.println(fourthPower.apply(2));
        }
    }
    

    Μέθοδοι ως συναρτήσεις

    Μέθοδοι που ικανοποιούν μια διεπαφή Functional μπορούν να χρησιμοποιηθούν ως τέτοιες με τη χρήση του συμβόλου ::.
    
    import java.util.function.UnaryOperator;
    import java.math.BigInteger;
    
    // Methods compatible with a functional interface
    class FunctionalFactorial {
        public static BigInteger factorial(BigInteger i) {
            if (i.equals(BigInteger.ZERO))
                return BigInteger.ONE;
            else
                return i.multiply(factorial(i.subtract(BigInteger.ONE)));
        }
    
        public BigInteger instanceFactorial(BigInteger n) {
            return factorial(n);
        }
    
        // Prints 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
        public static void main(String args[]) {
            UnaryOperator<BigInteger> f;
    
            f = FunctionalFactorial::factorial;
            System.out.println(f.apply(new BigInteger("100")));
    
            f = new FunctionalFactorial()::instanceFactorial;
            System.out.println(f.apply(new BigInteger("100")));
        }
    }
    

    Παράδειγμα σύνθεσης μεθόδων

    
    import java.util.function.DoubleUnaryOperator;
    import java.util.function.Function;
    import static java.lang.Math.abs;
    import static java.lang.Math.PI;
    
    class Inverse {
        // Return true if a almost equals b.
        static boolean almostEquals(double a, double b) {
            final double EPSILON = 1e-15;
            return abs(a - b) < EPSILON;
        }
    
        public static void main(String args[]) {
            Function<DoubleUnaryOperator, DoubleUnaryOperator> inverse =
                (f) -> ( (x) -> 1. / f.applyAsDouble(x) );
    
            DoubleUnaryOperator cot = inverse.apply(Math::tan);
            DoubleUnaryOperator sec = inverse.apply(Math::cos);
            DoubleUnaryOperator csc = inverse.apply(Math::sin);
    
    	// Verify value for key arguments.
            assert almostEquals(sec.applyAsDouble(0), 1);
            assert almostEquals(csc.applyAsDouble(PI / 2), 1);
            assert almostEquals(cot.applyAsDouble(PI / 4), 1);
        }
    }
    

    Ορισμός τύπων συναρτήσεων

    
    @FunctionalInterface
    interface TripletChooser <T> {
        T choose(T a, T b, T c);
    }
    
    class TripletChooserExample {
        public static void main(String args[]) {
            TripletChooser<String> getFirst = (a, b, c) -> a;
            System.out.println(getFirst.choose(args[0], args[1], args[2]));
        }
    }
    

    Παράδειγμα χρήσης τύπου συνάρτησης

    
    @FunctionalInterface
    interface Combiner {
        int combine(int a, char operator, int b);
    }
    
    public class CombinerExample {
        public static void main(String[] args) {
            Combiner arithmeticCombiner = (a, operator, b) -> {
                switch (operator) {
                    case '+': return a + b;
                    case '*': return a * b;
                    default: throw new IllegalArgumentException("Invalid operator for arithmetic: " + operator);
                }
            };
    
            Combiner bitwiseCombiner = (a, operator, b) -> {
                switch (operator) {
                    case '+': return a | b;
                    case '*': return a & b;
                    default: throw new IllegalArgumentException("Invalid operator for bitwise: " + operator);
                }
            };
    
            // Verify Arithmetic Combiner
            assert arithmeticCombiner.combine(5, '+', 3) == 8;
            assert arithmeticCombiner.combine(5, '*', 3) == 15;
    
            // Verify Bitwise Combiner
            assert bitwiseCombiner.combine(5, '+', 3) == 7;
            assert bitwiseCombiner.combine(5, '*', 3) == 1;
        }
    }
    

    Ροές

    Μια ροή (stream) είναι μια επεξεργάσιμη ακολουθία ενός απροσδιόριστου αριθμού στοιχείων. Σε σχέση με μια συλλογή η ακολουθία έχει τις παρακάτω ιδιότητες.

    Τύποι ροών

    Ο τύπος Optional

    Η παραμετρική κλάση java.util.Optional περιέχει μια τιμή τύπου T που μπορεί και να απουσιάζει.

    Χρήσιμες μέθοδοι

    Πηγές ροών

    Ενδιάμεση επεξεργασία ροών

    Τελική επεξεργασία ροών

    Λέξεις κειμένου: Knuth vs McIlroy

    Donald Knuth Douglas McIlroy

    Σχετικά είναι αυτή η εργασία (https://dl.acm.org/doi/pdf/10.1145/5948.315654), αυτό το κόμικ (https://comic.browserling.com/97) και αυτό το βίντεο (https://www.youtube.com/watch?v=kQKrmDLvijo).

    Παράδειγμα: Λέξεις κειμένου

    
    /*
     * Output ordered list of a file's unique words
     */
    
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.stream.Stream;
    import java.io.IOException;
    
    class UniqueWords {
        public static void main(String args[]) {
            if (args.length != 1) {
                System.err.println("Usage: UniqueWords file");
                System.exit(1);
            }
    
            try {
                Files
                    .lines(Paths.get(args[0]))
                    .flatMap(line -> Stream.of(line.split("\\W+")))
                    .sorted()
                    .distinct()
                    .filter((x) -> x.length() > 0)
                    .forEach(System.out::println);
            } catch (IOException e) {
                System.err.println("Error reading line: " + e.getMessage());
                System.exit(1);
            }
        }
    }
    

    Παράδειγμα: εκτίμηση πληθάριθμου

    
    /**
     * Estimate the number of distinct elements in a data stream
     * (F0 estimation problem) based on the algorithm published in the
     * Proceedings of 30th Annual European Symposium on Algorithms (ESA 2022)
     * https://doi.org/10.48550/arXiv.2301.10191
     */
    
    import java.util.HashSet;
    import java.util.Random;
    import java.util.Set;
    import java.util.function.Function;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class F0Estimator {
    
        // Probability to add an element
        private double p = 1.0;
    
        /**
         * Estimate number of unique elements in the passed stream
         * @param storageSize The storage to use
         */
        public <T> long uniqueElements(Stream<T> stream, int storageSize) {
            final float LOAD_FACTOR = 0.5f;
    
            Set<T> X = new HashSet<>(storageSize , LOAD_FACTOR);
            Random random = new Random();
    
            stream.forEach(element -> {
                // Ensure element is in the set with probability p
                if (random.nextDouble() < p)
                    X.add(element);
                else
                    X.remove(element);
    
                if (X.size() >= storageSize) {
                    // Randomly keep each element in X with probability 1/2
                    X.removeIf(e -> random.nextDouble() < 0.5);
                    p /= 2;
                    if (X.size() >= storageSize) {
                        throw new IllegalStateException("Threshold exceeded after sampling");
                    }
                }
            });
    
            return (long) (X.size() / p);
        }
    
        public static void main(String[] args) {
            // Create a Random instance
            Random random = new Random();
    
            // Create a stream of many random integers
            Stream<Integer> stream = IntStream
                .generate(random::nextInt).limit(1_000_000_000)
                .map(i -> i & 0xffff)
                .boxed();
    
            final int STORAGE_SIZE = 1000;
    
            var estimator = new F0Estimator();
    
            long uniqueCount = estimator.uniqueElements(stream, STORAGE_SIZE);
            System.out.println("Estimated number of unique elements: " + uniqueCount);
        }
    }
    

    Η μέθοδος Newton-Raphson

    Η προσεγγιστική μέθοδος Newton-Raphson μας επιτρέπει να βρούμε τη ρίζα οποιασδήποτε πραγματικής συνάρτησης. x n+1 = x n - f ( x n ) f ′ ( x n )

    Τετραγωνική ρίζα με Newton-Raphson

    Παράδειγμα: Υλοποίηση √2 με NR

    Το παρακάτω παράδειγμα υπολογίζει τη √2 δημιουργώντας μια άπειρου μήκους ακολουθία με διαδοχικά καλύτερες προσεγγίσεις.

    
    import java.util.Optional;
    import java.util.function.Predicate;
    import java.util.function.DoubleFunction;
    import java.util.stream.Stream;
    
    
    /** Find a square root using the Newton-Raphson approximation */
    class SquareRoot {
    
        /** Obtain successive approximations of a function's root using the
         * Newton-Raphson method. */
        static class NewtonRaphson {
            /** f(x) and f'(x) */
            DoubleFunction fx, fdx;
    
            NewtonRaphson(DoubleFunction fx, DoubleFunction fdx) {
                this.fx = fx;
                this.fdx = fdx;
            }
    
            /** Return next approximation, given the previous one */
            Double nextApproximation(double previous) {
                // xₙ₊₁ = xₙ - f(xₙ) / f′(xₙ)
                return previous - (double)fx.apply(previous) / (double)fdx.apply(previous);
            }
        }
    
        /** Test whether successive parts of a series differ more than a value */
        static class NotWithin implements Predicate<Double> {
            /** Previous value in series */
            Optional<Double> previous = Optional.empty();
            /** Difference value above which the test method returns true */
            Double epsilon;
    
            NotWithin(double d) {
                epsilon = d;
            }
    
            /**
             * Return true if successive parts of the series do not differ by
             * less than the specified epsilon.
             */
            @Override
            public boolean test(Double d) {
                boolean r;
    
                if (previous.isPresent())
                    r = (Math.abs(previous.get() - d) > epsilon);
                else
                    r = true;
                previous = Optional.of(d);
                return r;
            }
        }
    
        public static void main(String args[]) {
            final double SQRT_TO_FIND = 2;
            DoubleFunction fx = (x -> x * x - SQRT_TO_FIND); // f(x) = x² - α
            DoubleFunction fdx = (x -> 2 * x); // f'(x) = 2x
            var rootTwo = new NewtonRaphson(fx, fdx);
            var greaterThanEpsilon = new NotWithin(1e-15);
    
    	// SQRT_TO_FIND is also our first approximation
            System.out.println(Stream.iterate(SQRT_TO_FIND, rootTwo::nextApproximation)
                .dropWhile(greaterThanEpsilon)
                .findFirst()
                .get());
        }
    }
    

    Άσκηση: συναρτήσεις και ροές

    Άσκηση 17

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

    Ανάπτυξη διαδικτυακών εφαρμογών

    Περιεχόμενα

    Το μοντέλο αναφοράς OSI

    Φυσικό επίπεδο

    Επίπεδο σύνδεσης

    Επίπεδο δικτύου

    Πρωτόκολλα διαδικτύου: IPv4, IPv6, IPsec, ICMP

    IPv4

        0                   1                   2                   3   
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |Version|  IHL  |Type of Service|          Total Length         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |         Identification        |Flags|      Fragment Offset    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Time to Live |    Protocol   |         Header Checksum       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                       Source Address                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Destination Address                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Options                    |    Padding    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    

    Επίπεδο μεταφοράς

    Πρωτόκολλα διαδικτύου: TCP, UDP, …

    TCP

        0                   1                   2                   3   
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          Source Port          |       Destination Port        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                        Sequence Number                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Acknowledgment Number                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Data |           |U|A|P|R|S|F|                               |
       | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
       |       |           |G|K|H|T|N|N|                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Checksum            |         Urgent Pointer        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Options                    |    Padding    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                             data                              |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    

    Επίπεδο συνόδου

    Πρωτόκολλα διαδικτύου: Sockets API

    Επίπεδο παρουσίασης

    (Σε παρένθεση σχετικά πρωτόκολλα του διαδικτύου)

    Επίπεδο εφαρμογής

    (Σε παρένθεση σχετικά πρωτόκολλα του διαδικτύου)

    Αρχιτεκτονική του παγκόσμιου ιστού

    Προσδιορισμός στοιχείων με URI

    URI = scheme ":" ["//" authority] path ["?" query] ["#" fragment]
    
    index.html
    https://www.dmst.aueb.gr/dds/
    https://www.google.com/search?q=AUEB
    https://www.aueb.gr/Hmerologio.pdf#page=3
    

    Το πρωτόκολλο HTTP

    Το πρωτόκολλο HTTP υποστηρίζει τις παρακάτω μεθόδους επικοινωνίας:

    Παράδειγμα HTTP

    Αίτηση

    GET /dds/ HTTP/1.1
    Host: www2.dmst.aueb.gr
    User-Agent: curl/7.71.1
    Accept: */*
    

    Απάντηση

    HTTP/1.1 200 OK
    Date: Sun, 08 Jan 2023 10:00:32 GMT
    Server: Apache/1.3.33 (Linux/RHEL)
    Content-Location: index.en.html
    Vary: negotiate,accept-language,accept-charset
    TCN: choice
    Last-Modified: Fri, 30 Dec 2022 21:03:52 GMT
    Accept-Ranges: bytes
    Content-Length: 22599
    Content-Type: text/html
    Content-Language: en
    

    Αίτημα HTTP στη Java

    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.MalformedURLException;
    
    public class UrlRetriever {
        public static void main(String[] args) {
    	if (args.length != 1) {
    	    System.err.println("Usage: UrlRetriever URL");
    	    System.exit(1);
    	}
    
            URL url = null;
            try {
                // Make a request to the specified URL
                url = new URL(args[0]);
            } catch (MalformedURLException e) {
                    System.err.println("Invalid URL: " + e);
                    System.exit(1);
            }
    
            HttpURLConnection connection = null;
            try {
                connection = (HttpURLConnection)url.openConnection();
            } catch (ClassCastException e) {
                System.err.println("Specified protocol is not HTTP");
                System.exit(1);
            } catch (IOException e) {
                System.err.println("Connection error: " + e);
                System.exit(1);
            }
    
            try {
                connection.setRequestMethod("GET");
    
                // Get the response from the server
                int status = connection.getResponseCode();
                BufferedReader in = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
                int c;
                StringBuilder content = new StringBuilder();
                while ((c = in.read()) != -1) {
                    content.append((char)c);
                }
                in.close();
    
                // Print the response
                System.out.println(content.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    Χαρακτηριστικά της αρχιτεκτονικής REST

    Παραδείγματα αιτήσεων REST

    
    java UrlRetriever https://www.gutenberg.org/cache/epub/1342/pg1342.txt
    
    curl 'https://aviationweather.gov/api/data/metar?ids=LGAV&hours=48'
    curl -v -k "https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&titles=Moon&sites=enwiki" |  jq .
    curl -A "Mozilla/5.0" 'http://telematics.oasa.gr/api/?act=getBusLocation&p1=1822'
    curl -LH "Accept: application/vnd.crossref.unixref+xml;q=1, application/rdf+json;q=0.5" https://doi.org/10.1126/science.169.3946.635
    
    curl --request POST -H "Authorization: Bearer $ROBBIE_API_KEY" --url http://robbie.dmst.aueb.gr:50135/completion --header "Content-Type: application/json" --data '{ "prompt": "You are a helpful Assistant responding to User queries. User: Which city is the capital of Germany?\nAssistant: Berlin\nWhich city is the capital of Greece?"}'
    
    curl https://api.openai.com/v1/engines/davinci/completions \
      -X POST \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer $OPENAI_API_KEY" \
      -d '{
        "prompt": "I can convert a String into an int in Java program by ",
        "max_tokens": 50
      }'
    

    Εξυπηρετητής ώρας HTTP στη Java

    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.InetSocketAddress;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    
    import com.sun.net.httpserver.HttpExchange;
    import com.sun.net.httpserver.HttpHandler;
    import com.sun.net.httpserver.HttpServer;
    
    public class TimeServer {
        static class GetHandler implements HttpHandler {
            @Override
            public void handle(HttpExchange exchange) throws IOException {
    
                var calendar = Calendar.getInstance();
                var dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss\n");
                byte[] response = dateFormat.format(calendar.getTime()).getBytes();
    
                // Set the response header and status code
                exchange.sendResponseHeaders(200, response.length);
    
                // Get the response body output stream
                OutputStream responseBody = exchange.getResponseBody();
    
                System.out.print(exchange.getRemoteAddress());
                responseBody.write(response);
                responseBody.close();
            }
        }
    
        public static void main(String[] args) throws Exception {
            // Create a server on port 8000
            HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
    
            server.createContext("/", new GetHandler()); // "GET /" handler
    
            server.start(); // Start serving requests
        }
    }
    

    Διαδικτυακές εφαρμογές στην πράξη

    Άσκηση: Επικοινωνία Πελάτη-Εξυπηρετητή

    Άσκηση 18

    Μπορείτε να κατεβάσετε το αντίστοιχο αρχείο και να στείλετε τους βαθμούς σας από τους δεσμούς που βρίσκονται στη σελίδα των ασκήσεων.

    Βιβλιογραφία

  • Rogers Candenhead. Πλήρες Εγχειρίδιο της Java 12. 8η Έκδοση. Εκδόσεις X. Γκιούρδα, 2023. Κεφ. 17, 20.
  • Ατομικές ασκήσεις και συμμετοχή

    Αρχείο των ασκήσεων και ηλεκτρονική παράδοση

    Οδηγίες

    Οδηγίες για την εκτέλεση, βαθμολογία και παράδοση των ασκήσεων υπάρχουν στην εισαγωγή του μαθήματος.

    Προθεσμίες παράδοσης

    Η ώρα παράδοσης είναι πάντα τοπική ώρα Ελλάδος.

    Άσκηση Ημερομηνία και ώρα παράδοσης
    1 Sun Oct 11 23:59:59 2026
    2 Sun Oct 18 23:59:59 2026

    Συχνές ερωτήσεις και απαντήσεις (FAQ)

    Περιεχόμενα

    Που θα βρω τεκμηρίωση για τις κλάσεις που υποστηρίζει η Java;

    Στον αντίστοιχο ιστότοπο της Oracle (https://docs.oracle.com/en/java/javase/index.html).

    Πως θα ρυθμίσω το Visal Studio Code για να παραδώσω τον τρόπο επίλυσης των ασκήσεων

    Διαβάστε την τεκμηρίωση που παραπέμπεται στη σχετική σελίδα των σημειώσεων.

    Για κάποιο πολύ σοβαρό λόγο δεν μπόρεσα να παραδώσω την άσκηση στην ώρα της. Μπορώ να πάρω μια παράταση;

    Η προθεσμία παράδοσης της κάθε άσκησης είναι η τελευταία ημερομηνία στην οποία μπορείτε να παραδώσετε την άσκηση χωρίς επιπτώσεις στο βαθμό της. Καλό είναι να την παραδίδετε πριν το επόμενο μάθημα έτσι ώστε
    1. να μπορέσετε να ασχοληθείτε με την καινούρια όταν αυτή ανακοινωθεί
    2. να έχετε ένα περιθώριο χρόνου για να καλύψετε προσωπικά ή τεχνικά προβλήματα που μπορεί να εμφανιστούν
    Σε περίπτωση που δεν μπορέσατε να παραδώσετε την άσκηση μέσα στην προθεσμία, θα πρέπει να την παραδώσετε το συντομότερο δυνατό για να έχετε τη μικρότερη δυνατή επιβάρυνση στο βαθμό. Για λόγους διαφάνειας και αποτελεσματικότητας στη βαθμολόγηση αυτή γίνεται αυτόματα χωρίς να υπάρχει πρόβλεψη για εξαιρέσεις. Ο αριθμός όμως των ασκήσεων σας επιτρέπει να καλύψετε τη διαφορά στις επόμενες ασκήσεις.

    Πότε πρέπει να κατεβάζω ενημερωμένη έκδοση του αρχείου Jarpeb.jar;

    Στη σελίδα αυτή εμφανίζεται η τρέχουσα έκδοση και η ημερομηνία τελευταίας αλλαγής της κάθε άσκησης. Αν έχετε κατεβάσει το αρχείο πριν από την ημερομηνία τελευταίας αλλαγής της άσκησης που σας ενδιαφέρει ή αν η έκδοση της άσκησης στον υπολογιστή σας είναι προγενέστερη αυτής που περιέχει το αρχείο τότε θα πρέπει να κατεβάσετε νεώτερη έκδοση του αρχείου. Για να μπορέσετε να δείτε την έκδοση της άσκησης που έχετε στον υπολογιστή σας μπορείτε να τρέξετε την εντολή
    java -jar Exercise.jar -v <κωδικός μαθήματος> <κωδικός άσκησης> <ΑΜ φοιτητή>
    

    Μπορώ να ασχοληθώ με ασκήσεις που δεν έχουν ανακοινωθεί ακόμα;

    Ναι, αλλά με δική σας ευθύνη. Ασκήσεις που δεν έχουν ανακοινωθεί επίσημα στο μάθημα και για τις οποίες δεν έχει δωθεί ημερομηνία παράδοσης μπορεί να μην έχουν ελεγχθεί πλήρως, να βρίσκονται ακόμα υπό ανάπτυξη και να περιέχουν λάθη στην εκφώνηση και στη βαθμολόγηση. Ο βαθμός που θα καταχωρήσετε ισχύει, αλλά είναι πιθανό κατά την επίλυση να συναντήσετε προβλήματα που θα έχουν διορθωθεί μέχρι την επίσημη ανακοίνωση της άσκησης. Επίσης, σε ασκήσεις που δεν έχουν ανακοινωθεί, μπορεί οι βοηθοί του μαθήματος και οι επιβλέποντες στα εργαστήρια να μην μπορούν να σας βοηθήσουν.

    Γίνεται να υπολογιστούν στο μάθημα οι βαθμοί των ασκήσεων που είχα λάβει την περασμένη χρονιά;

    Δυστυχώς όχι, αυτό δε γίνεται. Κάθε χρόνο οι εκφωνήσεις των ασκήσεων και οι κωδικοί ελέγχου αλλάζουν. Η βαθμολογία των ασκήσεων ισχύει μόνο για την εξεταστική περίοδο του χειμερινού εξαμήνου και την πρόσθετη εξεταστική περίοδο του Σεπτεμβρίου του ίδιου έτους με αυτό στο οποίο έγιναν οι ασκήσεις.

    Ποιες είναι οι ημερομηνίες παράδοσης των ασκήσεων;

    Οι ημερομηνίες παράδοσης εμφανίζονται στη σελίδα αυτή. Για ασκήσεις που δεν έχουν ανακοινωθεί ακόμα σε μάθημα η ημερομηνία παράδοσης είναι ανοιχτή και συνεπώς δεν εμφανίζεται.

    Τι ρόλο παίζει το πεδίο "σχόλια" στη σελίδα παράδοσης της βαθμολογίας; Δεν έχω λάβει απάντηση σε κάποιο σχόλιο που είχα κάνει.

    Τα σχόλια απλώς καταγράφονται στη βάση δεδομένων της βαθμολογίας. Στην καλύτερη περίπτωση μπορεί να τα διαβάσει ο διδάσκων κατά τον υπολογισμό των βαθμών. Αν θέλετε απάντηση σε κάποιο σχόλιο να στείλετε κατευθείαν email στο διδάσκοντα μια και στη σελίδα παράδοσης δεν έχετε τη δυνατότητα να καταχωρήσετε τη διεύθυνσή σας για να μπορέσετε να λάβετε απάντηση.

    Πως ελέγχεται το ποιος υλοποιεί και ποιος καταχωρεί την άσκηση;

    Το πρόγραμμα Jarpeb καταχωρίζει στοιχεία που έχουν σχέση με την άσκηση, τον ΑΜ του φοιτητή ή της φοιτήτριας, τον τρόπο επίλυσης (όπως καταγράφεται από το Visual Studio Code) και το βαθμό. Επιπλέον κατά την καταχώρηση ο βαθμός και ο ΑΜ του φοιτητή συνδέονται με τη διεύθυνση IP του μηχανήματος που έκανε την καταχώρηση. Με τη χρήση στοιχείων ελέγχου οι διευθύνσεις IP αντιστοιχούνται σε συγκεκριμένους φοιτητές. Όπου διαπιστωθούν στοιχεία που δημιουργούν την εντύπωση πως μπορεί στην υλοποίηση να έχει αναμιχθεί τρίτος ή να έχει χρησιμοποιηθεί λογισμικό παραγωγικής τεχνητής νοημοσύνης, ο αντίστοιχος φοιτητής ή φοιτήτρια μπορεί να κληθεί για συμπληρωματική εξέταση.

    Επιτρέπεται η υλοποίηση και καταχώρηση ασκήσεων σε υπολογιστές εκτός του εργαστηρίου;

    Ναι, αλλά η υλοποίηση πρέπει να γίνεται από τον ίδιο το φοιτητή — απαγορεύεται αυστηρά η κάθε συνεργασία. Σε περιπτώσεις που έχουν βρεθεί στοιχεία που δείχνουν πως έχει υπάρξει συνεργασία, έχει ζητηθεί απο τους φοιτητές να επαναλάβουν την άσκηση στο εργαστήριο. Σε περίπτωση υποτροπής όλες οι αντίστοιχες ασκήσεις μηδενίζονται στο τέλος του χρόνου. Επίσης, δε μπορεί να σας παρασχεθεί βοήθεια σχετικά με την εγκατάσταση και διαμόρφωση του περιβάλλοντος εργασίας της Java στον υπολογιστή σας - ειδικά για το θέμα της εμφάνισης των ελληνικών χαρακτήρων στην οθόνη σας.

    Έχω καταχωρήσει το βαθμό μου αλλά δε βλέπω ούτε το βαθμό ούτε την καταχώρηση στις αντίστοιχες σελίδες. Γιατί;

    Ο έλεγχος των καταχωρήσεων και η ενημέρωση των βαθμών γίνονται σε περιοδικά διαστήματα. Κοιτάξτε την ημερομηνία τελευταίας ενημέρωσης που εμφανίζεται στο κάτω μέρος της σελίδας. Αν είναι μικρότερη από την ημερομηνία που καταχωρήσατε την άσκηση, τότε σωστά δεν εμφανίζονται τα στοιχεία της καταχώρησής σας.

    Έχω καταχωρήσει το βαθμό μου παρατηρώ πως η εκφώνηση της άσκησης έχει αλλάξει. Τι πρέπει να κάνω;

    Οι ασκήσεις που καταχωρούνται με επιτυχία κατοχυρώνονται. Δε χρειάζεται να κάνετε απολύτως τίποτα, εκτός αν θέλετε να ξανακάνετε την άσκηση με τη νέα εκφώνηση για να την καταλάβετε καλύτερα ή για να πάρετε υψηλότερο βαθμό.

    Γιατί σε υπολογιστή με λειτουργικό σύστημα Windows η εκφώνηση εμφανίζεται με περίεργους χαρακτήρες;

    Δοκιμάστε να δώσετε την εντολή
    
    chcp 737
    
    πριν την εκτέλεση του Exercise.jar.

    Δοκιμάστε να αλλάξετε τη γραμματοσειρά του παραθύρου σε Lucida Console (κάντε κλικ πάνω αριστερά - Properties - Font).

    Αν ο υπολογιστής σας τρέχει Windows 7–10 με αγγλικές ρυθμίσεις, θα πρέπει να τις ρυθμίσετε στα ελληνικά, με την παρακάτω διαδικασία:
    Control Panel - Region (and Language) - Administrative - Change System Locale και από εκεί επιλέγουμε "Greek (Greece)".

    Σε υπολογιστή με λειτουργικό σύστημα Windows και Internet Explorer το αρχείο Exercise.jar σώζεται ως Exercise.zip. Τι να κάνω;

    Το πρόβλημα οφείλεται σε δυσλειτουργία (bug) του Internet Explorer. Κατά τη διαδικασία της φύλαξης επιλέξτε από την επιλογή "Save as type" το "All Files" και βεβαιωθείτε πως στην επιλογή "File name" γράφει "Exercise.jar". Εναλλακτικά, χρησιμοποιείστε έναν άλλο φυλλομετρητή όπως τον Firefox (http://www.mozilla.com/en-US/firefox/).

    Γιατί σε υπολογιστή με λειτουργικό σύστημα Linux η εκφώνηση εμφανίζεται με περίεργους χαρακτήρες;

    Καταρχήν, μπράβο που πειραματίζεστε με διαφορετικά λειτουργικά συστήματα! Δοκιμάστε να δώσετε την εντολή
    
    export LANG=el_GR
    
    πριν την εκτέλεση του Exercise.jar.

    Τι να κάνω αν μου εμφανιστεί το μήνυμα «Δεν βρέθηκε εγκαταστημένος μεταγλωττιστής»;

    Φροντίστε να θέσετε σωστά τις μεταβλητές περιβάλλοντος, όπως αναφέρεται στον οδηγό των ασκήσεων (https://docs.google.com/document/d/1-7XbmxX5ZhTrxFEAcoQcxQdqi2cnGeun/view).

    Τι να κάνω αν μου εμφανιστεί το μήνυμα «Can not find an installed compiler»;

    Φροντίστε να θέσετε σωστά τις μεταβλητές περιβάλλοντος, όπως αναφέρεται στον οδηγό των ασκήσεων (https://docs.google.com/document/d/1-7XbmxX5ZhTrxFEAcoQcxQdqi2cnGeun/view).

    Γιατί ο κωδικός που καταχώρισα δεν έγινε δεκτός από το σύστημα;

    1. Βεβαιωθείτε πως τρέχετε την έκδοση 1.7 της Java ή νεώτερη (βλ. προηγούμενη απάντηση).
    2. Βεβαιωθείτε πως τρέχετε τη φετινή έκδοση του συστήματος Jarpeb. Οι κωδικοί ασκήσεων του προηγούμενου χρόνου δεν ισχύουν.

      Μπορείτε να εκτελέσετε την εντολή

      
      java -jar Exercise.jar -version
      
      για να δείτε την έκδοση του συστήματος που έχετε στα χέρια σας. Η ημερομηνία της έκδοσης δεν πρέπει να είναι παλαιότερη από το Σεπτέμβριο του αντίστοιχου ακαδημαϊκού έτους.

    Σωστά καταχωρημένες ασκήσεις

    Χρονοσφραγίδα ΑΜ Άσκηση Βαθμός Διεύθυνση IP Αναγνωριστικό
    2026-10-11T19:00:19 8250106 1 10 [...].217.168.[...] 00C745ADA926485AA00F01F03654EB19
    2026-10-11T21:43:43 8250085 1 10 [...].84.212.[...] 05AB6296B3C24594BDC1A28EB85EA827
    2026-10-13T14:08:05 8250023 2 10 [...].210.231.[...] 06A93E190A114D9194967032AA85A685
    2026-10-07T13:51:50 8250164 1 10 [...].140.93.[...] 07D4F7B2FCC447B28B54456635D13FEB
    2026-10-11T11:47:15 8250299 1 10 [...].74.212.[...] 0875787EC85B474AAAF9C3019D0FE5C9
    2026-10-10T22:51:10 8250150 1 10 [...].55.78.[...] 08FA99BFB3F7462FB70740144E3FE978
    2026-10-11T16:13:21 8250275 1 10 [...].87.150.[...] 09C12264E72F4C2DB75B66B24E234D04
    2026-10-08T10:23:39 8250025 1 10 [...].203.213.[...] 0A1ADD9C6A2B4823A6CD803D28F02D06
    2026-10-11T14:47:04 8240316 1 10 [...].102.3.[...] 0A39B7396649493F8D660E950DEAABF3
    2026-10-12T20:05:24 8250289 2 10 [...].74.59.[...] 0A7AF0DA4DB94DC98F20A0B013FC874B
    2026-10-10T17:34:21 8250128 3 10 [...].140.93.[...] 0BDFF91F6A95431CA17A397AFB248997
    2026-10-07T23:11:42 8250026 1 10 [...].178.148.[...] 0C2E6F26A5584955AFB5E8B1A9F5F110
    2026-10-08T16:32:36 8250067 1 8 [...].59.189.[...] 0CD1D5067D0E4D4688C869679ACE1124
    2026-10-09T19:22:02 8250131 1 10 [...].84.194.[...] 0D2C3F8CEEF84D82A33ACC2A0C1C0B34
    2026-10-06T18:44:14 8240226 1 10 [...].55.107.[...] 0D5FBC9145394141A8C980FD3576B173
    2026-10-06T16:52:16 999 1 5 [...].86.153.[...] 0DFC58588C544F71B46DDCAF34563FAF
    2026-10-07T20:13:55 8250128 1 10 [...].242.231.[...] 0E6F5F45CE224E06854AD06D982288EB
    2026-10-11T21:29:17 8250049 1 10 [...].203.235.[...] 10BFC07474CF44E090D72015440BF6AB
    2026-10-10T14:39:30 8250019 1 8 [...].214.209.[...] 111C1BDB79E749C792343B58FD68BC9A
    2026-10-13T17:55:44 8220060 8 10 [...].217.178.[...] 132905948A0F40C49BD8B4D0B5DFE284
    2026-10-09T13:35:00 8250238 1 10 [...].207.159.[...] 142CE525E93A43638C8F7470C29D32E0
    2026-10-13T10:52:13 8250111 2 10 [...].86.153.[...] 146E6CB32F264EDE8AC4220A30DDACE9
    2026-10-07T20:35:21 8250158 1 10 [...].177.227.[...] 147457BFA2D94AB68CCC3E75DCE331FD
    2026-10-13T18:56:07 8250164 2 10 [...].242.230.[...] 17377279B4A04F15ACE11A5B5890A1C2
    2026-10-09T19:56:24 8250293 1 9 [...].203.84.[...] 18624C38B47E40D681179F6C00453510
    2026-10-11T21:29:28 8240235 1 10 [...].49.68.[...] 189FC4006E5549198532639F2CB196D8
    2026-10-05T23:47:34 8240154 1 10 [...].228.61.[...] 1A59FA6BA2A24F4DBE2ECAACD759DDA0
    2026-10-09T13:10:08 8250040 1 10 [...].70.74.[...] 1B3745D6464E497091FE921F52E10C50
    2026-10-09T12:08:07 8250090 1 10 [...].65.3.[...] 1B7F3A0CEA7F486FB3E2ADB13BFBA059
    2026-10-05T21:45:00 8250088 1 10 [...].86.26.[...] 1BEE0D1505CD4055BFBE372AFAE3BA2B
    2026-10-13T23:02:04 8250091 2 10 [...].74.220.[...] 1CABFD67DC9A444E9569FB202EB6CCFB
    2026-10-05T14:05:58 0 1 8 [...].168.10.[...] 1E1343EFAD81481C9252BE39D115C63A
    2026-10-10T17:22:13 8250082 1 9 [...].242.94.[...] 1F211B6939A7474CBD9F8100953EB6CB
    2026-10-12T22:15:30 8250140 2 10 [...].140.16.[...] 211774B9911D4ABA9F7574B5465873CA
    2026-10-06T17:09:09 8250130 1 10 [...].129.228.[...] 21D3BC1BCE544F9FBC58E089F01AAF3F
    2026-10-07T13:08:01 8250065 1 10 [...].69.6.[...] 22174ADAB89445758BCE3630FE798676
    2026-10-09T15:59:08 8250055 1 10 [...].86.62.[...] 2252940073E1496F92319790192CF145
    2026-10-09T21:37:56 8250229 1 10 [...].86.155.[...] 22B1A93318B54CE3A3381EAA86BA11B0
    2026-10-12T01:22:44 8210093 2 10 [...].55.23.[...] 22C7BE1EF18848BB858CC5098519771F
    2026-10-09T00:23:34 8250028 3 10 [...].84.206.[...] 24624F080CC04641AAF54852B2CE7E3C
    2026-10-06T18:13:12 8250023 1 10 [...].74.17.[...] 249E7EF557014355A352ADDD5D9DF23E
    2026-10-11T20:51:54 8250309 17 10 [...].65.157.[...] 24BC486CA4CE4387897E928D027FD7F3
    2026-10-13T21:16:22 8250309 7 10 [...].65.157.[...] 2636E8D28C2E4435BC1F15E8EFE00BE8
    2026-10-13T20:54:18 8250049 2 10 [...].74.20.[...] 2706A456DD2345C786517F0D0DCD6AB4
    2026-10-11T13:17:05 8250290 1 10 [...].86.44.[...] 28A5515D9BFE4EECB8A989FD930E32B6
    2026-10-08T01:03:16 8240266 1 10 [...].130.77.[...] 295E94D3382C4200B180FF87DF470B76
    2026-10-09T19:45:14 8250010 1 10 [...].74.220.[...] 29FD03755EA74455A15B51999D620853
    2026-10-08T00:44:34 8250058 1 10 [...].66.41.[...] 2B4088F8647744658B49116336D046CF
    2026-10-09T17:05:31 8250054 1 10 [...].242.90.[...] 2BE6784A7D8D489482C4DB2364F4F643
    2026-10-09T13:37:05 8250110 1 8 [...].86.136.[...] 2C48CD4D733D4A90856FFADC32F16589
    2026-10-13T12:06:42 8220060 4 10 [...].217.178.[...] 2DC94B1273F3407F99B896DEC756B312
    2026-10-11T22:04:14 8250076 2 10 [...].107.29.[...] 2E0FB0042C0D407DB1CA3604A1B47868
    2026-10-13T15:33:20 8250309 6 10 [...].203.174.[...] 2F221390283C41778E5B7766C00C8692
    2026-10-06T21:23:28 8250117 1 8 [...].74.80.[...] 308762448E004EE69B3CA1D516EE0C29
    2026-10-11T16:41:56 8230141 1 10 [...].86.220.[...] 3136D9A1594446B1987FDBFC4C111817
    2026-10-13T01:47:19 8250160 2 9 [...].140.52.[...] 31B490E8F0E64E9A9193A0CF10CDF258
    2026-10-09T22:14:55 8240236 1 8 [...].84.131.[...] 32247183805A48E197F1573182AD837C
    2026-10-13T11:52:55 8250309 3 10 [...].203.174.[...] 3288C2074501474C8704C76B0B945B99
    2026-10-09T14:45:37 8250029 1 10 [...].65.88.[...] 347EF92019A245C48F04362CD5FF1CDB
    2026-10-14T00:33:00 8250309 9 10 [...].65.157.[...] 349626B57827416ABD0C74350A41BD6B
    2026-10-07T14:43:03 8210105 1 10 [...].26.33.[...] 358148ABD6BA4F8EAA211C909CEC75F6
    2026-10-06T20:50:43 8250241 1 8 [...].74.35.[...] 3708DA51716841FE8841E5EBBA4F447D
    2026-10-09T14:33:54 8250048 1 10 [...].242.92.[...] 371AC2C22C42471C87AF48011D46DD65
    2026-10-06T21:03:22 8250117 1 10 [...].74.80.[...] 372B6EBE633F487B9705DB2494865C15
    2026-10-12T11:26:42 8250309 2 10 [...].65.157.[...] 37A4028919FD4D088A8436D3DD390BB0
    2026-10-13T15:48:22 8250001 2 10 [...].74.57.[...] 393137CCB7754D54A5CB7D6D30D34E69
    2026-10-09T17:40:52 8250142 1 10 [...].127.218.[...] 39610757B6784A9E9255E4DA115F92E9
    2026-10-08T16:42:57 8250092 1 10 [...].242.136.[...] 3BB2B6998798403FAB93E788C8009F32
    2026-10-10T21:11:10 8250247 1 10 [...].246.244.[...] 3CBB699F6A874FB894118BAAB65C7B38
    2026-10-07T18:55:46 8250261 1 10 [...].203.247.[...] 3D55A60751F1493CB5D7267AEF4C92E8
    2026-10-10T18:57:24 8250127 1 10 [...].86.54.[...] 3D81F3D81A9A4BA5934C3CD1D7AC0E39
    2026-10-07T21:35:40 8250065 1 10 [...].69.6.[...] 3E87A8F7238E4AF8A562BD841B8806A7
    2026-10-09T12:53:24 8250135 1 10 [...].86.153.[...] 3F62DCB3D11047169566528477E77FA8
    2026-10-09T21:03:50 8240062 1 10 [...].73.29.[...] 3FA22546961C497BADF86C9304C51C9E
    2026-10-11T18:05:53 8250289 1 10 [...].130.204.[...] 3FC6FDDF133644DDB2A00FC22418FCE5
    2026-10-06T20:52:50 8250069 1 10 [...].228.61.[...] 408E37DA9C064622BDA79E8D3EFEF13C
    2026-10-12T21:05:05 8250282 2 10 [...].6.195.[...] 42219DC710E84233BC6E89D0E145E3B1
    2026-10-09T14:30:37 8250007 1 10 [...].86.229.[...] 42806C5ADAC1428483EBC4AE4830D7AF
    2026-10-09T22:12:00 8250016 1 10 [...].69.45.[...] 43A593C675C947ED868F1E6277E9260F
    2026-10-09T11:45:50 8250125 1 10 [...].107.133.[...] 449AB5CEC2214F0C967AFBA158CD2F57
    2026-10-10T13:58:31 8220060 1 8 [...].217.178.[...] 46B74661865848D98CB6FC529E0C8ABF
    2026-10-11T18:46:11 8250073 1 10 [...].92.180.[...] 46E38F7C5C844FAA8E6B5C17C48C4D29
    2026-10-10T19:29:49 8250033 1 10 [...].74.47.[...] 46F605ED5F694944972076872A12ED36
    2026-10-11T14:24:57 8250036 1 10 [...].86.155.[...] 474BC1CC49B0486599279CD2E58B2420
    2026-10-08T19:13:17 8250257 1 10 [...].84.45.[...] 47C823C214B74D6E98F06343343D4DB5
    2026-10-05T19:58:55 8230241 1 10 [...].242.88.[...] 48442F820C314F258B66DF1642819A49
    2026-10-13T13:10:27 8220060 5 10 [...].217.178.[...] 4AB94F3A3E7E4FF29389D4ABBA66E332
    2026-10-08T23:12:41 8250147 1 10 [...].6.210.[...] 4C60B44712524EB3B7672B862F48DDF7
    2026-10-09T15:17:21 8240054 1 10 [...].38.108.[...] 4C878E665A5A4167B468A4A88440847A
    2026-10-11T22:14:53 8250154 1 10 [...].65.46.[...] 4CBBBE5371C34F92910FB88FBC7624C5
    2026-10-11T16:45:11 8250292 1 4 [...].66.117.[...] 4E69C01B9AF14906A1AC3302FDA223A2
    2026-10-06T18:57:33 8250032 1 10 [...].74.32.[...] 4E934D5BB0BE4E759F13D1896D2A9F7A
    2026-10-09T00:52:48 8250076 1 10 [...].107.29.[...] 4FAA10CF073644DE9517540E178AC0E2
    2026-10-09T18:51:40 8250009 1 10 [...].242.95.[...] 50C92526CDF9437EB67D134631605D81
    2026-10-12T19:22:57 8250103 1 8 [...].1.100.[...] 51C0DEABFCF54E238B7118E56A9106FD
    2026-10-09T12:35:45 8250245 1 10 [...].138.195.[...] 5210B72D66344FEFA1F6886ADF613DBF
    2026-10-13T15:20:12 8240150 2 10 [...].74.16.[...] 530C6A74DC064A21BEF363EBC63723DD
    2026-10-11T20:03:39 8100069 1 10 [...].247.46.[...] 538A7FC0D09C4BEE82FE610BB0C2A007
    2026-10-09T22:40:16 8250002 1 10 [...].217.170.[...] 53C1E7B7850A43F2A5BBC1737F1A865B
    2026-10-13T22:56:51 8250071 2 10 [...].73.239.[...] 54DF1DAA3B7543CEB022D0F432EA3574
    2026-10-11T19:03:01 8250151 1 8 [...].73.39.[...] 554EDABB324844C5A74185711139640C
    2026-10-11T15:37:11 8230150 1 10 [...].66.41.[...] 56A06E6D11A8468286AC37ADC0CDE38C
    2026-10-10T15:24:33 8240236 1 10 [...].84.131.[...] 579E01F0D83A4A1C9FB18A80948B0AFC
    2026-10-06T15:11:16 8250129 1 10 [...].86.113.[...] 57EAE76B32AE4CCF82BE24C2FC8577C6
    2026-10-09T11:37:08 8250042 1 10 [...].65.159.[...] 580C54AE6C82476EA586D537E55111EF
    2026-10-10T19:55:28 8250072 1 10 [...].67.74.[...] 5845ACAD4D054EDA82340F20FE2B67CA
    2026-10-06T15:53:33 999 1 10 [...].86.153.[...] 5880620BBB7A404098B8D74309D35716
    2026-10-13T12:17:45 8250066 2 10 [...].65.157.[...] 5B2DD85241004DBDBB0FD1B30E9F0447
    2026-10-11T15:57:04 8230223 1 10 [...].4.85.[...] 5BAFCE84040B41758308E5FF9C5FFB83
    2026-10-11T13:06:10 8250138 1 10 [...].59.18.[...] 5BF24B28E0A0437281B7ACD19409A68D
    2026-10-13T21:39:12 8250157 2 10 [...].84.148.[...] 5CA303864AE54299A8A97C45A0E2EA7F
    2026-10-13T12:17:49 8250309 4 10 [...].203.174.[...] 5DD6279B761D424EA0CF6279AC6D8DB6
    2026-10-11T11:51:45 8250087 1 10 [...].242.90.[...] 5E3D0E50655C465187C8C59D18EE1485
    2026-10-10T19:15:42 8250301 1 10 [...].84.0.[...] 5F1B6BEF2CFE4A0BA854B9628E61D929
    2026-10-05T20:23:20 8250277 1 10 [...].217.170.[...] 60245B20DB66454D8BB545364E7961B2
    2026-10-08T20:40:44 8250027 1 10 [...].67.74.[...] 6074C96C62184C879E378D204B6B9607
    2026-10-13T01:52:36 8250160 2 10 [...].140.52.[...] 6114811700BB47788F3D121CE56B1BEF
    2026-10-12T18:44:40 8250052 1 10 [...].74.60.[...] 61AEE02330A344FFA6F8BDE318DD02CD
    2026-10-08T20:23:08 8250061 1 10 [...].242.186.[...] 61DCC5F357C143C9AFCCE753D5A39049
    2026-10-12T07:34:03 8250309 9 10 [...].65.157.[...] 652E1AD5A8C2431D9EA2ED33A5645AA8
    2026-10-11T17:55:50 8250053 1 10 [...].168.1.[...] 654FAF7B687940A8B0B89618A0FAE4CE
    2026-10-12T23:09:09 8220040 2 10 [...].202.40.[...] 65CC2E440DDC4A8892A1D53E8AD77871
    2026-10-10T21:24:22 8250083 1 10 [...].84.8.[...] 663C8DD5D18E4A70A166ED9379B14157
    2026-10-12T23:30:13 8250167 2 10 [...].74.47.[...] 668F8DE4B0E148E9898981D8FD1B3D76
    2026-10-10T15:55:03 8250077 1 10 [...].87.196.[...] 66A0699A2DEC453B9AFFDBCBFABE57FF
    2026-10-11T18:32:18 8250123 1 10 [...].65.88.[...] 66D1D18C4F6A4D7DA88B18A6AEA65DC5
    2026-10-07T20:08:58 8250101 1 10 [...].26.5.[...] 67544A56F5F24B148F9FF11CE8A90674
    2026-10-08T19:57:25 8250148 2 10 [...].87.16.[...] 679D8C1317A74398A762D7078C4B6996
    2026-10-10T16:44:49 8250167 1 8 [...].74.9.[...] 68321E8CDD0344EE966DD44FB3C6D7BC
    2026-10-11T14:54:33 8250242 1 9 [...].73.239.[...] 69E3FC6EBB7F4527B485FB7252BECFD8
    2026-10-06T22:14:33 8250013 1 10 [...].130.149.[...] 6E0B8182BCD5443593B1E062380C37F6
    2026-10-11T17:51:28 8250059 1 8 [...].72.122.[...] 6ED7031AA02B4A71973DE7458066B46B
    2026-10-08T23:03:22 8250231 1 10 [...].55.78.[...] 7289DE46A8DD40E4B31CD7E60B3D4B4E
    2026-10-11T15:48:08 8250047 1 10 [...].140.28.[...] 7373F0D50EFB44719C3A648759258CDB
    2026-10-13T19:50:56 8250007 2 10 [...].86.229.[...] 7440A3D5F87D4878AFC00BA0660BF8F5
    2026-10-10T17:52:35 8250096 1 10 [...].131.162.[...] 74A4CB5E6FD249EBA9F3BA9CAE9A667E
    2026-10-07T11:32:09 8240148 1 10 [...].26.9.[...] 756E317E73B54916AC3444A83E96F594
    2026-10-11T18:35:26 8250274 1 10 [...].70.120.[...] 757E8158452845488927610F2923341E
    2026-10-13T14:03:54 8250013 2 10 [...].66.136.[...] 763290B8EC5D4464AE7B19FEAF6858B2
    2026-10-13T01:36:29 8250084 1 10 [...].107.20.[...] 7633748D4BB94C79B8C735752E63ACE9
    2026-10-11T15:35:54 8250302 1 10 [...].210.243.[...] 7645F4FAE38746248313799EB3012529
    2026-10-06T00:29:13 8250075 1 10 [...].86.131.[...] 77235DB1AC1C4869AF5AB1BEDAC00DF7
    2026-10-13T23:29:00 8230241 2 10 [...].242.93.[...] 7795CDA060884BC7A7E39DDC08B43185
    2026-10-12T20:54:10 8250140 2 10 [...].140.16.[...] 79A7E8C1794A4A8AB0AABF74E5169AC0
    2026-10-11T21:48:30 8250076 2 10 [...].107.29.[...] 7B5FB1DEF7B54120B170F5254DFB7C2E
    2026-10-06T13:19:04 8250081 1 10 [...].64.197.[...] 7D335B23051243A1A6D156E752115FD7
    2026-10-12T23:50:19 8250156 2 10 [...].167.147.[...] 7D55DF8A47EE4DE5B4B46D74119CE462
    2026-10-13T20:05:57 8250138 2 10 [...].59.18.[...] 7DFE9C08F8EF47A1BC371ADC7103D8AF
    2026-10-06T23:27:08 8250027 1 10 [...].67.74.[...] 7FDF54CF61944BAD9B66E45F978073B9
    2026-10-11T16:32:11 8230062 1 10 [...].168.2.[...] 800BB09A60714E3E8D7841B05701AED3
    2026-10-10T12:02:05 8220018 1 10 [...].167.124.[...] 800EAA5744964B908953F82125AB107E
    2026-10-07T21:52:21 8250068 1 10 [...].86.205.[...] 836597C9AFDD436DBD94C82EDC3587F3
    2026-10-13T14:34:15 8250043 2 10 [...].74.212.[...] 838A076506704CCBB5CC2935EC258CEA
    2026-10-11T13:23:19 8250006 1 10 [...].75.188.[...] 83D8B29E9E77413B91B276809598B88B
    2026-10-07T15:19:54 8250063 1 10 [...].168.2.[...] 848CDBF06CCC438697C08D564218C582
    2026-10-12T20:58:26 8250265 2 10 [...].217.171.[...] 8508AFA403954538978C66EADEDC05F7
    2026-10-10T15:41:50 8250122 1 10 [...].217.169.[...] 865CA724AC704B76AD72F37DAB3F11DF
    2026-10-12T23:44:23 8250296 2 10 [...].242.187.[...] 86F38670E61948A5B7870322C13AFE5C
    2026-10-13T20:28:24 8250129 4 10 [...].86.113.[...] 890184E6DB3D4AD7A1A37CFB4563BFF4
    2026-10-09T12:38:18 8250236 1 10 [...].138.195.[...] 89A1D158F3F94320950D28EB70A54738
    2026-10-14T01:31:09 8250063 2 10 [...].168.2.[...] 8A666750A2D44190890A58836E0A09E4
    2026-10-06T20:37:37 8250126 1 10 [...].217.169.[...] 8B09E5D66E054E6291389EF7F3B97250
    2026-10-09T14:25:27 8230242 1 10 [...].1.235.[...] 8BA1CD805DA34C47AE7A6EE7BDBC3769
    2026-10-10T12:32:00 8240074 1 10 [...].73.198.[...] 8C90ABF2D3654D0297D5821631657184
    2026-10-07T15:05:00 8250028 1 10 [...].26.22.[...] 8CC636DB6C1B4BD6997FE37FC32DE2DE
    2026-10-11T20:15:52 8250062 1 9 [...].168.1.[...] 8E82D4E80BBD4C8492945A27998A82E0
    2026-10-09T18:27:35 8250117 1 10 [...].55.151.[...] 8F76774FDB334CE6BFF95CC4159DC3B6
    2026-10-11T18:43:23 8250279 1 10 [...].129.228.[...] 8FD2A65A22E54EDFA0B5DB1FD10ADC35
    2026-10-10T13:41:44 250093 1 10 [...].58.136.[...] 91C7D49E29774BF1BC8EE5C3D5025E8C
    2026-10-09T20:13:52 8240266 1 8 [...].130.77.[...] 91C99028CAAE4E38BEA202AB72B53729
    2026-10-13T10:11:49 8220060 2 10 [...].217.178.[...] 924DCF13D30545F88029B1011FB818D8
    2026-10-10T18:04:15 8250128 4 10 [...].140.93.[...] 928C6F98A08B40D792C62AD258FF231F
    2026-10-13T11:00:03 8240236 2 10 [...].26.8.[...] 947A95F23C844FCC9ACB30D876A998CB
    2026-10-11T18:00:56 8240061 1 10 [...].84.49.[...] 974C70A3DEAF45BA9EF3CE602708CFB3
    2026-10-07T20:32:09 8250066 1 10 [...].65.157.[...] 98194307030C4B5D91277ECFB2955BD9
    2026-10-12T21:34:57 8250282 3 9 [...].6.195.[...] 984B671F5C2D4EF1BEDC5AAF301ECCA8
    2026-10-09T11:50:51 8240030 1 10 [...].203.182.[...] 995E0AC9427C4E988633288B1F1ED57D
    2026-10-08T12:58:07 8250149 1 10 [...].74.58.[...] 997158E4D01A4C0286FA16C8ECC0DA9B
    2026-10-07T11:40:44 8250111 1 10 [...].86.153.[...] 9987DA44F9FC4D41A1DDE98D2409C42C
    2026-10-14T00:19:43 8250309 8 10 [...].65.157.[...] 9A1DE1C8584B491693ED7AEB04EBF7B6
    2026-10-11T20:59:28 8250037 1 10 [...].66.231.[...] 9A2D133619AD43538CC00E641F6CA980
    2026-10-11T21:53:29 8250091 1 10 [...].74.220.[...] 9A5478778AC243E0BC325DBD6A919E0D
    2026-10-11T17:23:50 8250263 1 10 [...].178.178.[...] 9A63A3B9A1EF49BB92D0DA2C94EA6050
    2026-10-08T16:46:29 8250067 1 10 [...].59.189.[...] 9B07E96976904D8EB4A2DE199CD3535A
    2026-10-07T20:07:13 8250064 1 10 [...].26.6.[...] 9B1B50948E0940D390241D29084DFE2F
    2026-10-12T13:14:29 8250079 1 10 [...].86.155.[...] 9B45D976297F40DFB55607BBF3D661CC
    2026-10-10T18:18:50 8250266 1 8 [...].49.185.[...] 9CCD1693213A4D1FBD95362D529F6722
    2026-10-07T22:44:55 8250097 1 10 [...].66.62.[...] 9D05086B06D6472EB80A5E648927D476
    2026-10-08T18:03:35 8250143 1 8 [...].251.255.[...] 9D5599A26DDC4C31A5FD30CA41CCC872
    2026-10-07T21:58:31 8250001 1 10 [...].74.14.[...] 9D8517F7D2C048F9B9C838C006B589A2
    2026-10-08T21:47:42 8230046 1 10 [...].197.66.[...] 9DB2944014B84C9F996BA684EA27EC84
    2026-10-11T15:31:43 8250011 1 10 [...].74.92.[...] 9E80E73B303F4BD891909D14BDA4FE5D
    2026-10-09T00:41:33 8250005 1 10 [...].237.212.[...] 9F4F43691A6B4A8998C33738876B9517
    2026-10-13T01:44:56 8250160 2 9 [...].140.52.[...] 9FB7E1FAFCF84A16BD7B1F5F5CCEA659
    2026-10-09T23:18:44 8250309 16 10 [...].65.157.[...] A07EA8F8A2884FB3BF4AFE1EEE0AC5A1
    2026-10-12T21:45:51 8250170 2 10 [...].66.178.[...] A0BD9422688D4854A5F9FE6000B3FCA8
    2026-10-12T16:50:32 8240226 2 10 [...].55.107.[...] A21BE7BB5DBC4407A10B4E474410836A
    2026-10-10T21:43:44 8250038 1 10 [...].217.161.[...] A3309AD61DCF4E0BA0DCC10AC8DAFCBB
    2026-10-11T00:20:59 8250146 1 10 [...].87.82.[...] A36D845CCFD14E7A806AF84093717C56
    2026-10-10T21:19:14 8250283 1 10 [...].242.90.[...] A4ADF30D4E374CA08801D382F9402545
    2026-10-08T21:34:39 8250156 1 10 [...].167.147.[...] A678191214304FCC9F18018AF9458D57
    2026-10-11T13:13:23 8250267 1 10 [...].38.153.[...] A6DD3E828E4F449F856E2EEC7A6ACE73
    2026-10-13T15:17:53 8250309 5 10 [...].203.174.[...] A7970A8A3485448DA18C03850C8C40E8
    2026-10-11T20:36:49 8250003 1 10 [...].55.111.[...] A7F5F49090B542A6A951AE63CD541306
    2026-10-11T21:42:40 8250140 1 10 [...].140.16.[...] A889C8AF60314CEF8EBE06E4299EC72E
    2026-10-09T17:30:43 8250157 1 10 [...].84.148.[...] A88D6C0624ED4567972C3C889333C790
    2026-10-13T12:17:33 8250103 2 10 [...].1.100.[...] A8D68175ED854595AB95E0894C3D56DE
    2026-10-10T17:28:52 8250082 1 10 [...].242.94.[...] AA0BF88DDF0747D4A5C866F2CCACEE4E
    2026-10-11T18:30:33 8190239 1 10 [...].6.96.[...] AA0D1A250CA14F49AB7C09902AC1BF65
    2026-10-10T16:19:10 8250070 1 10 [...].86.208.[...] AD253C5C2CDF47BFA36EA73318374BCC
    2026-10-05T21:04:31 8250160 1 10 [...].140.58.[...] AD2CE4E8F90748FB918CB76B81DFC11E
    2026-10-12T19:58:10 8250048 2 10 [...].254.28.[...] ADDA3021C5A145C18E5E3E0B95CA7AF2
    2026-10-07T11:48:13 8240093 1 10 [...].168.2.[...] ADFD537EC9C042778DB06F7FBC119D54
    2026-10-10T18:48:14 8250153 1 10 [...].65.23.[...] AE437A53A3C64794A353072E1929DDF5
    2026-10-06T21:07:24 8250144 1 10 [...].133.195.[...] AE900C674A5C4788A2FD6E74EADE2F9E
    2026-10-13T12:21:12 8250088 2 10 [...].86.26.[...] AEA6173E69614377AEABF13BD9A1BAF3
    2026-10-11T01:38:21 8210093 1 10 [...].6.124.[...] B142FBE2C94649BDB15BA145509D3CC5
    2026-10-08T21:57:32 8250105 1 10 [...].74.45.[...] B1DCA5D76F2A41C598B6389F26FD644D
    2026-10-11T18:16:14 8250171 1 10 [...].84.142.[...] B338F3756127443FA9554DF5BC2F176C
    2026-10-07T22:37:00 8250166 1 10 [...].103.97.[...] B365286C13A94C71BC5AF11625E520CE
    2026-10-13T20:26:10 8250137 2 10 [...].86.154.[...] B45C7F575D84469AA71562E8CE3F23FE
    2026-10-10T13:21:11 8250089 1 10 [...].66.41.[...] B69A6234A4E844BA999D605960C8CC31
    2026-10-05T21:19:38 8250113 1 10 [...].140.58.[...] B7451FAD69B448DF9DA9FD6616E5CB2A
    2026-10-09T13:39:56 8250168 1 10 [...].1.128.[...] B7CD05131C0A4A19B5E8A8DCDBCE4D8F
    2026-10-08T02:14:23 8250071 1 10 [...].73.239.[...] B8585CFFD8BE434E96132FF70F6DD134
    2026-10-13T17:08:14 8220060 7 10 [...].217.178.[...] B9FB22255A0B416EB443DD7008F39053
    2026-10-11T13:18:56 8250249 1 10 [...].71.237.[...] BA08956759E34364AB541E14C27661B1
    2026-10-09T15:07:57 8250309 1 10 [...].203.251.[...] BBB2E7B6832743849D271A4439644A1D
    2026-10-13T20:19:26 8240270 2 10 [...].86.31.[...] BD609C2DFB344DBF86E13E428D003C1D
    2026-10-05T22:34:35 8250265 1 10 [...].217.171.[...] BDFBAA81E7E1491A9DE748B490C7DCBB
    2026-10-11T16:24:27 8250304 1 10 [...].217.161.[...] BE6A365DA64A4F43B6856855D9298E9A
    2026-10-12T19:03:13 8250129 2 10 [...].86.113.[...] BEBF0A49E10E4480B5BA483CB7E4F29B
    2026-10-10T18:36:55 8250018 1 10 [...].140.109.[...] BF42BD3F012D444DB2492B0F78E42366
    2026-10-09T22:01:01 8250094 1 10 [...].55.102.[...] BFCF235C77DB4F2B8E41D34E11C5FBFA
    2026-10-13T19:23:07 8250135 2 10 [...].86.153.[...] C14A967B7E5E41D5884ACC292E615296
    2026-10-10T01:39:28 8220040 1 10 [...].202.40.[...] C153F57F368A49758094C315E1557A19
    2026-10-06T20:31:06 8250303 1 10 [...].129.228.[...] C20AC2420A89408A8738C78DA159F471
    2026-10-11T23:19:37 8250309 9 7 [...].65.157.[...] C2E1F9EC6E794808B08DF1A464607132
    2026-10-08T17:29:30 8250025 2 10 [...].92.14.[...] C6CEF6A23B0D4B73936B4B2572F4F7EF
    2026-10-08T19:23:50 8250148 1 10 [...].87.16.[...] C7BC692986BE4BE8895804185977ADBA
    2026-10-06T01:43:36 8240150 1 9 [...].255.26.[...] C7C73E1227B243D1B13E898D4145F85E
    2026-10-06T15:46:20 8250137 1 10 [...].86.154.[...] CCADEAF4F72941B6A1530E28AD557B3C
    2026-10-06T22:47:14 8250043 1 10 [...].74.212.[...] CCE56BD95FBA46E39191DE85566A57E8
    2026-10-11T19:29:46 8250057 1 5 [...].86.152.[...] CDCFEC70943C4D0CA92AC6E91C309470
    2026-10-05T23:12:43 0 1 3 [...].86.79.[...] CEEDF73C7CBA46168E7EA9AD99E8A3AB
    2026-10-08T21:32:10 8190306 1 8 [...].255.21.[...] CFD5D83D0B07401482DE8148FD3A33C4
    2026-10-13T11:22:04 8220060 3 10 [...].217.178.[...] CFDFC40614F040C1BB92D34FA215ABDD
    2026-10-11T13:10:04 8250267 1 10 [...].38.153.[...] D06BCBC27BF449D995DB71298F7540B5
    2026-10-07T20:38:54 8250244 1 10 [...].86.98.[...] D3FF283DD7C441BB833E8AA3E697B4D2
    2026-10-11T16:31:13 8230141 1 10 [...].86.220.[...] D4ADBD7BD9FF442C862FE6ADC9232CD9
    2026-10-12T00:03:38 819318 1 7 [...].66.118.[...] D5C3DECE7F7440B7A70AC20787399582
    2026-10-12T18:19:02 8250160 1 4 [...].140.52.[...] D5F85A8FD3AC497695A5DA0EF7447277
    2026-10-09T12:57:15 8250239 1 10 [...].138.195.[...] D63771BBC8EC49D78604A0D1D647CFB6
    2026-10-09T20:32:56 8240270 1 10 [...].86.31.[...] D78B2DAC08A64ADCAE7ADDFCAB7930DC
    2026-10-06T18:35:39 8250235 1 9 [...].140.73.[...] D792B6F467BA4BD6A0028108B33DC770
    2026-10-08T21:15:08 8250028 2 10 [...].84.206.[...] D7B9A90322684B2097FB50C0B6DD1C74
    2026-10-07T11:55:49 8250261 1 10 [...].203.149.[...] D7FE433441D84CD7A4CBBF7D89274D27
    2026-10-08T11:49:34 8250282 1 10 [...].6.195.[...] D85D2BB127B744008558B504747570DE
    2026-10-13T17:15:45 8250129 3 10 [...].86.113.[...] D89C744ABF2F4FE08471374025DEABB5
    2026-10-09T15:04:11 8250017 1 10 [...].65.46.[...] D8AC1DF0805A40059AEC52474D3A4814
    2026-10-09T22:52:10 8250102 1 10 [...].74.107.[...] D9F91D9562854CD1807B8CBD72C5063E
    2026-10-13T15:13:47 8220060 6 10 [...].217.178.[...] DB89FACD960742DBBED6B8A909874133
    2026-10-10T19:22:31 8250104 1 10 [...].66.41.[...] DC272F2824C44991BA67499DC09427BE
    2026-10-11T18:14:43 8250028 4 10 [...].84.206.[...] DD69E304E8164AD8BE83BED3A3984BA4
    2026-10-11T20:23:57 8250264 1 10 [...].203.84.[...] DDA0650FF2D943EE95DFE5C6FCA133F6
    2026-10-13T10:55:55 8240236 2 10 [...].26.8.[...] DE594CB7513040BEBC0FBB335DF11D8F
    2026-10-12T21:16:55 8250044 2 10 [...].154.44.[...] DF70E98AEBBF4FDF844D838F630CF573
    2026-10-08T18:36:21 8250159 1 10 [...].107.34.[...] E0641EABF0084E698C47EE36961CF7F7
    2026-10-13T20:08:09 8250128 5 10 [...].140.28.[...] E1C4D355ED524CD7ADEDB31545D398BC
    2026-10-13T16:20:26 8250126 2 10 [...].217.169.[...] E2253581A8F84E8782148EBB30EA53DB
    2026-10-09T18:53:53 8250162 1 10 [...].228.61.[...] E30ACDD2D8C247F8B3642EE08E6ACA19
    2026-10-11T20:03:22 8240045 1 10 [...].55.140.[...] E319BC47D96F42C987E3F5F36260063D
    2026-10-11T14:14:11 8250230 1 5 [...].166.21.[...] E3E9A3298C704094BC63B931F0CDF9B9
    2026-10-13T19:50:39 8250147 2 10 [...].58.141.[...] E4CEF5B010C24ECDA658CC6805E0148C
    2026-10-13T21:08:38 8250082 2 10 [...].242.94.[...] E6D2FA695DCF4291B11A114C8CF14098
    2026-10-13T20:27:28 8250261 2 9 [...].203.142.[...] E6F435FAE06E440CB71F8E9E72BFB136
    2026-10-09T12:42:16 8250128 2 10 [...].242.231.[...] E6FFEAF569A04EF1B94B7C66F065D717
    2026-10-10T17:14:23 8250133 1 10 [...].49.133.[...] E7647175F77140688E4D252BBF4009BF
    2026-10-06T19:10:08 8250120 2 10 [...].219.254.[...] E7CEB6BCB7504C7596C047DDF71250BE
    2026-10-09T15:55:12 8250155 1 10 [...].4.202.[...] EAD54B0E560348689B8C17694CEC0B00
    2026-10-13T14:25:42 8250026 2 10 [...].49.75.[...] EB184CA3519F458BB78382AACAB5CE18
    2026-10-07T20:59:04 8250044 1 10 [...].154.45.[...] EBFD6EC8C6944101A4C9253406D377A4
    2026-10-11T15:35:21 8250242 1 8 [...].73.239.[...] EBFFE9AE5AB84810A086176AADDF0C12
    2026-10-10T17:10:05 8230222 1 10 [...].86.11.[...] EC4C6C93CA0741E5ACDC92B4DA126926
    2026-10-09T10:52:59 8240064 1 5 [...].251.16.[...] F07A0C5D0C6F49238748898D7D2EF62B
    2026-10-11T13:30:27 8250296 1 10 [...].242.187.[...] F1664C02ACA8403BBA157983532D7306
    2026-10-11T18:05:36 8250243 1 10 [...].66.170.[...] F2A3B19243AB4FA0B40623D5B9CDBD5E
    2026-10-06T00:12:52 8250120 1 10 [...].210.109.[...] F6DF24AAFBBE4EAD98ACDB15F0772230
    2026-10-08T21:54:33 8250165 1 10 [...].166.113.[...] F861E6FB2B35475681E22EA0EE3FA3AC
    2026-10-13T16:28:32 8250303 2 10 [...].129.228.[...] F86EE1B03CD3411CBC2F842B85046462
    2026-10-09T17:13:03 8250098 1 10 [...].217.161.[...] F92DE6851FAF4F10895D7D4A69C28C35
    2026-10-13T18:11:20 8220060 9 8 [...].217.178.[...] F95780A170AC42D9A201543FDAB42D94
    2026-10-06T16:08:12 999 2 8 [...].86.153.[...] FB725EFF54B34BDEB91DCE48F0FF8C9B
    2026-10-12T18:33:12 8250113 2 10 [...].140.52.[...] FBD1948C9C934FC29A72A4CBD605A01F
    2026-10-08T11:04:35 8250066 1 10 [...].65.157.[...] FCFA1204FAFC45B79407D2B545DE7B77
    2026-10-11T22:16:04 8250060 1 10 [...].16.216.[...] FDA3FF467862425DBEBEF7A1EFB8F4C4
    2026-10-10T19:39:48 8250107 1 10 [...].217.174.[...] FDF2482792544BCE931B7A23E40ADEF9
    2026-10-08T20:33:40 8250170 1 10 [...].66.178.[...] FF6E51563E3442FB96E292730D377E6B

    Βαθμοί ασκήσεων ανά Α.Μ.

    Α.Μ. Βαθμοί ατομικής άσκησης Μ.Ο. ατομικών ασκήσεων που έχουν παραδοθεί Μ.Ο. απαιτούμενων ατομικών ασκήσεων (2) Ομαδικές ασκήσεις
    250093Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8100069Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8190239Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8190306Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    819318Α1=7 7.03.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8210093Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8210105Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8220018Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8220040Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8220060Α1=8 Α2=10 Α3=10 Α4=10 Α5=10 Α6=10 Α7=10 Α8=10 Α9=8 9.610.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230046Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230062Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230141Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230150Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230222Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230223Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230241Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8230242Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240030Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240045Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240054Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240061Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240062Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240064Α1=5 5.02.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240074Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240093Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240148Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240150Α1=9 Α2=10 9.59.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240154Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240226Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240235Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240236Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240266Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240270Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8240316Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250001Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250002Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250003Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250005Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250006Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250007Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250009Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250010Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250011Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250013Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250016Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250017Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250018Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250019Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250023Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250025Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250026Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250027Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250028Α1=10 Α2=10 Α3=10 Α4=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250029Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250032Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250033Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250036Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250037Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250038Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250040Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250042Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250043Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250044Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250047Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250048Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250049Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250052Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250053Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250054Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250055Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250057Α1=5 5.02.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250058Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250059Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250060Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250061Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250062Α1=9 9.04.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250063Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250064Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250065Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250066Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250067Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250068Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250069Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250070Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250071Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250072Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250073Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250075Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250076Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250077Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250079Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250081Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250082Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250083Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250084Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250085Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250087Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250088Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250089Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250090Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250091Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250092Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250094Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250096Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250097Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250098Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250101Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250102Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250103Α1=8 Α2=10 9.09.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250104Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250105Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250106Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250107Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250110Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250111Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250113Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250117Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250120Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250122Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250123Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250125Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250126Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250127Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250128Α1=10 Α2=10 Α3=10 Α4=10 Α5=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250129Α1=10 Α2=10 Α3=10 Α4=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250130Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250131Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250133Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250135Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250137Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250138Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250140Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250142Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250143Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250144Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250146Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250147Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250148Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250149Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250150Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250151Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250153Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250154Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250155Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250156Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250157Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250158Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250159Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250160Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250162Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250164Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250165Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250166Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250167Α1=8 Α2=10 9.09.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250168Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250170Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250171Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250229Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250230Α1=5 5.02.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250231Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250235Α1=9 9.04.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250236Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250238Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250239Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250241Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250242Α1=9 9.04.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250243Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250244Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250245Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250247Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250249Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250257Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250261Α1=10 Α2=9 9.59.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250263Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250264Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250265Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250266Α1=8 8.04.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250267Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250274Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250275Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250277Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250279Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250282Α1=10 Α2=10 Α3=9 9.710.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250283Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250289Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250290Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250292Α1=4 4.02.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250293Α1=9 9.04.5 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250296Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250299Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250301Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250302Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250303Α1=10 Α2=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250304Α1=10 10.05.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    8250309Α1=10 Α2=10 Α3=10 Α4=10 Α5=10 Α6=10 Α7=10 Α8=10 Α9=10 Α16=10 Α17=10 10.010.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0
    999Α1=10 Α2=8 9.09.0 Ομ.1=0 Ομ.2=0 Αρχηγός=0

    Φοιτητές που παραδίδουν ασκήσεις: 197
    Μέσος όρος ατομικής άσκησης για φοιτητές που παραδίδουν ασκήσεις: 9.8
    Ατομικές ασκήσεις με προθεσμία παράδοσης: 2
    Μέσος όρος 2 ατομικών ασκήσεων για φοιτητές που παραδίδουν ασκήσεις: 6.2

    Λάθη στον έλεγχο του βαθμού

    Χρονοσφραγίδα ΑΜ Άσκηση Βαθμός Διεύθυνση IP Αναγνωριστικό
    2026-10-13T21:39:44 8200100 1 10 [...].217.174.[...] 12799DD26F4943A7A99F513CADDCCC29
    2026-10-13T22:44:59 8200100 2 10 [...].217.174.[...] 42C9775513634C3B94B0641588F93349

    Ενδιαφέρουσα βιβλιογραφία

    Θέματα εξετάσεων

    Πιλοτικά θέματα εξετάσεων

    Τα πιλοτικά θέματα σε μορφή PDF (έκδοση 1.1 - 2004.02.13).

    Για να βρείτε τις σωστές απαντήσεις αρκεί να μεταγλωττίσετε το πρόγραμμα με μερικές εντολές println στο τέλος.

    Εξεταστική περίοδος Φεβρουαρίου 2004

    Μια διατύπωση των θεμάτων σε μορφή PDF.

    Για να βρείτε τις σωστές απαντήσεις αρκεί να μεταγλωττίσετε το πρόγραμμα με μερικές εντολές println στο τέλος.

    Παράδειγμα προγράμματος

    
    class Exam {
        public static void main(String args[]) {
            int gargoyle = 5;
            int i = 2;
            int dobby = 5;
            while (i < 11) {
                i = i + 4;
                gargoyle = gargoyle + 2;
            }
            for (i = 2; i < 11; i = i + 4)
                dobby = dobby + 2;
            int dockhead = 6;
            try {
                dockhead = 11;
                if (dockhead == 11)
                    throw new Exception();
                dockhead = 21;
            } catch (Exception e) {
                dockhead = 16;
            }
            Ingluvial y = new Ingluvial(2);
            Ingluvial z = new Ingluvial();
            Ingluvial w = y;
            Aneurism x = new Aneurism();
            Ingluvial u = y; Aneurism v = x;
            int toeplate = 11;
            int tubeful = z.m() + 2 * x.m() + 3 * x.t();
            int fenrir = y.naumk;
            toeplate = 20;
            if (w.naumk != y.naumk)
                toeplate += 1;
            else
                toeplate += 10;
            String s = "footful" + "hexameron";
            int unparty = s.substring(1, 13).length();
            int umbelwort = Aneurism.count;
            int arusa = 23;
            Ingluvial r = new Aneurism();
            arusa = r.m();
            int smethe = 25;
            boolean array[] = new boolean[16];
            try {
                if (array[24])
                    smethe = 54;
                else
                    smethe = 44;
            } catch (ArrayIndexOutOfBoundsException e) {
                smethe = 31;
            }
        }
    }
    class Ingluvial {
        public int naumk;
        private char kahan;
        Ingluvial() {naumk = 11; }
        Ingluvial(int v0) { naumk = v0; }
        public int t() { return 1; }
        public int m() { return 37; }
    }
    class Aneurism extends Ingluvial {
        public static int count = 6;
        Aneurism() { count += 6; }
        public int n() { return naumk; }
        public int m() { return 15; }
    }
    

    Μεταβλητές

    Προσοχή

    Τα παραπάνω θέματα μοιάζουν αρκετά με τα πιλοτικά θέματα. Αυτό είναι απίθανο να συμβεί σε επόμενες εξεταστικές περιόδους.

    Εξεταστική περίοδος Σεπτεμβρίου 2005

    Μια διατύπωση των θεμάτων σε μορφή PDF.

    Για να βρείτε τις σωστές απαντήσεις αρκεί να μεταγλωττίσετε το πρόγραμμα με μερικές εντολές println στο τέλος.

    Παράδειγμα προγράμματος

    
    class Exam {
        static boolean ba[] = new boolean[6];
        public static void main(String args[]) {
            int lunula = 12;
            for (int i = 3; i < 11; i += 1)
                if (i % 3 == 1)
                    lunula = lunula + 2;
            int upglean = upslant(4, 9);
            String s = "alfet";
            s += "ceras" + "alfet";
            int chinaware = (s.substring(1, 8) + s).length();
            int bedstock = 6;
            try {
                bedstock = 10;
                if (bedstock == 10)
                    throw new Exception();
                bedstock = 20;
            } catch (Exception e) {
                bedstock = 15;
            }
            Bitted y = new Bitted(2);
            Bitted z = new Bitted();
            Bitted w = y;
            Samantha x = new Samantha();
            Bitted u = y; Samantha v = x;
            int megachile = 11;
            int powerless = z.m(16) - 2 * x.m(18) - 3 * x.t();
            int peccable = y.kangaroo;
            megachile = 23;
            if (w.kangaroo != y.kangaroo)
                megachile += 2;
            else
                megachile += 12;
            int archwise = Samantha.count;
            int drumming = 26;
            int ai = 0;
            ba[ai++] = false; ba[ai++] = true; ba[ai++] = true;
            ba[ai++] = true; ba[ai++] = true; ba[ai++] = true;
            for (int i = 0; i < ba.length - 1; i++) {
                if (!ba[i]) drumming += 11;
                if (ba[i] || ba[i + 1]) drumming += 9;
                if (ba[i] && ba[i + 1]) drumming -= 3;
            }
            int unhumble = 25;
            Bitted r = new Samantha();
            unhumble = r.m(17);
        }
        private static int upslant(int a, int b) {
            int loc1 = a;
            int loc2 = b;
            return (3 * loc1 + 2 * loc2 * loc2);
        }
    }
    class Bitted {
        public int kangaroo;
        Bitted() {kangaroo = 11; }
        Bitted(int v0) { kangaroo = v0 + 1; }
        public int t() { return 2 * 2; }
        public int m(int v) { return 31 - v; }
    }
    class Samantha extends Bitted {
        public static int count = 5;
        Samantha() { count += 7; }
        public int m(int v) { return v - 13 * 2; }
    }
    

    Μεταβλητές

    Περιεχόμενα