Προχωρημένο Μάθημα Ανάπτυξης σε Python
Κεφάλαιο
>
Επίπεδο
Μονάδες σειριοποίησης
Μονάδα Δομών
Στόχος
Ρυθμίστε την τελική ανάλυση δεδομένων για τη νέα εκμετάλλευση χρησιμοποιώντας το module struct.
Στο τέλος του δρόμου υπάρχει ένα πρατήριο εξυπηρέτησης που διαχειρίζεται τη νέα εκμετάλλευση, η οποία έχει ήδη κατασκευαστεί και έχουν φυτευθεί οι καλλιέργειες. Εδώ θα εξετάσουμε και θα επεξεργαστούμε τα δεδομένα για τις ήδη φυτευμένες καλλιέργειες και το προβλεπόμενο αποτέλεσμα της εκμετάλλευσης. Όπως και με τα άλλα επίπεδα σε αυτό το κεφάλαιο, θα εργαστούμε με τη σειριοποίηση και την αποσειριοποίηση δεδομένων, εισάγοντας ένα τελευταίο module με όνομα struct module.
Το module struct εισάγει μια σειρά από συναρτήσεις σειριοποίησης που πακετάρουν δεδομένα σε δυαδική μορφή, σε αντίθεση με τα άλλα modules με τα οποία έχουμε εργαστεί, καθώς σας δίνει μεγαλύτερο έλεγχο για το πώς μπορείτε να δομήσετε τα δεδομένα τόσο κατά τη σειριοποίησή τους όσο και κατά την αποσειριοποίησή τους, καθιστώντας το πιο ευέλικτο από τα υπόλοιπα modules. Χρησιμοποιήστε import struct για να έχετε πρόσβαση στις παρακάτω συναρτήσεις που θα χρησιμοποιήσουμε για την επεξεργασία των δεδομένων:
struct.calcsize(): Καθορίζει πόσα bytes καταλαμβάνει το πακεταρισμένο δεδομένο σε μια δοθείσα σειρά μορφής. Δέχεται ένα (1) όρισμα, το οποίο είναι η μορφή που θέλετε να επαληθεύσετε το μέγεθος σε bytes. Οι μορφές που θα χρησιμοποιήσουμε είναι:- integer: αναπαριστάται ως
'i'και είναι η μορφή για δεδομένα που αναπαρίστανται ως ακέραιοι αριθμοί - float: αναπαριστάται ως
'f'και είναι η μορφή για δεδομένα που αναπαρίστανται ως δεκαδικοί αριθμοί - double: αναπαριστάται ως
'd'και είναι η μορφή για δεδομένα που αναπαρίστανται ως πιο σύνθετοι δεκαδικοί αριθμοί όταν η μορφή float δεν είναι επαρκής.
- integer: αναπαριστάται ως
struct.pack(): Εφαρμόζει σειριοποίηση των δεδομένων σε δυαδική μορφή, πακεταρίζοντάς τα σύμφωνα με μια μορφή της επιλογής σας. Μπορεί να πάρει δύο (2) ή περισσότερα ορίσματα, δηλαδή τη μορφή που επιθυμείτε να χρησιμοποιήσετε και τις τιμές που θέλετε να σειριοποιήσετε. Οι μορφές είναι αυτές που περιγράφηκαν προηγουμένως και πρέπει να τις προσθέσετε ανάλογα με τον αριθμό των ορισμάτων που θα δώσετε.struct.unpack(): Αποσειριοποιεί τα πακεταρισμένα δυαδικά δεδομένα, δέχεται δύο (2) ορίσματα: τη μορφή στην οποία πρέπει να αντιστοιχεί (ώστε να είναι συγκρίσιμη με αυτή που σειριοποιήθηκαν) και το σειριοποιημένο δεδομένο.struct.iter_unpack(): Αποσειριοποιεί τα πακεταρισμένα δυαδικά δεδομένα, λειτουργεί με τον ίδιο τρόπο όπως ηstruct.unpack(), αλλά επαναλαμβάνει κάθε μπλοκ δεδομένων ξεχωριστά μέσω ενός βρόχου.struct.pack_into(): Μια προηγμένη έκδοση τηςstruct.pack(), δέχεται τέσσερα (4) ορίσματα: τη μορφή που θέλετε να χρησιμοποιήσετε, το buffer δεδομένων στο οποίο θέλετε να εισάγετε τα δεδομένα, τη θέση στο buffer που θέλετε να καταλάβουν τα δεδομένα, και τέλος τα δεδομένα που πακετάρετε.struct.unpack_from(): Μια προηγμένη έκδοση τηςstruct.unpack(), δέχεται τρία (3) ορίσματα: τη μορφή που θέλετε να χρησιμοποιήσετε, το buffer δεδομένων από το οποίο θέλετε να αποσειριοποιήσετε, και τέλος τη θέση στο buffer από την οποία θέλετε να αποσειριοποιήσετε. Αυτό σας επιτρέπει να αποσειριοποιήσετε συγκεκριμένα τμήματα των δεδομένων.
Περπατήστε μέχρι το σημάδι X του φωτός στο πρατήριο εξυπηρέτησης και στρέψτε προς το γραφείο, δημιουργώντας τρεις (3) μεταβλητές με ονόματα: integer, float και double. Θα τις χρησιμοποιήσουμε για να επαληθεύσουμε το μέγεθος σε bytes κάθε μορφής, χρησιμοποιώντας τη συνάρτηση struct.calcsize(). Για τη μεταβλητή integer χρησιμοποιήστε τη συνάρτηση με το 'i' ως όρισμα, για τη μεταβλητή float χρησιμοποιήστε τη συνάρτηση με το 'f' ως όρισμα και τέλος για τη μεταβλητή double χρησιμοποιήστε τη συνάρτηση με το 'd' ως όρισμα. Για παράδειγμα: integer = struct.calcsize('i'). Προσθέστε τις τρεις (3) μεταβλητές στην προ-γραμμένη συνάρτηση write().
Περπατήστε μέχρι το χρυσό σημάδι X και χρησιμοποιήστε τη συνάρτηση read() για να συλλέξετε δεδομένα για τη νέα εκμετάλλευση, σημειώνοντας τα σημεία δεδομένων και τη μορφή τους για μελλοντική χρήση, συγκεκριμένα: Resources, Size και Estimate. Μόλις κάνετε τις απαραίτητες σημειώσεις, περπατήστε μέχρι το σημάδι X του φωτός πάνω από το μπλε χαλί και δημιουργήστε μια μεταβλητή με όνομα blue_data.
Με τη μεταβλητή blue_data αποθηκεύστε την τιμή της συνάρτησης struct.pack(), θέτοντας ως ορίσματα τη μορφή και τις τιμές που σημειώσατε προηγουμένως. Κατά τη σύνθεση της μορφής, πρέπει να "πακετάρετε" τους τύπους μορφής σε μια ενιαία μονάδα. Για παράδειγμα, η μορφή για ακέραιο είναι 'i', όπως έχει ήδη περιγραφεί. Εάν προσθέτετε τρεις ακέραιους, θα τους αντιπροσωπεύσετε ως 'iii'. Με τον ίδιο τρόπο, εάν προσθέτετε έναν ακέραιο, έναν float και έναν double, αυτό θα γραφεί ως 'ifd'. Κατά την προσθήκη των δεδομένων, τα τοποθετείτε ξεχωριστά ως ορίσματα. Δείτε το παρακάτω συνολικό παράδειγμα:
data_1 = 8 # is an integer data_2 = 2.25 # is a float data_3 = 900.702938103 # is a double blue_data = struct.pack('ifd', data_1, data_2, data_3)
Η συνάρτηση struct.pack() επιτρέπει μεγάλη ευελιξία, καθώς σας δίνει τη δυνατότητα να ορίσετε πώς θα μορφοποιήσετε τα δεδομένα και να σειριοποιήσετε πολλαπλά σημεία δεδομένων ταυτόχρονα, κατά την κρίση σας. Προσθέστε τα δεδομένα που διαβάσατε προηγουμένως, χρησιμοποιώντας το παραπάνω παράδειγμα ως βάση. Χρησιμοποιήστε τη συνάρτηση display() με το blue_data ως όρισμα για να εμφανίσετε τα πακεταρισμένα δεδομένα.
Περπατήστε μέχρι το σκοτεινό σημάδι X πάνω από το μπλε χαλί και στρέψτε προς τον τερματικό, δημιουργήστε μια μεταβλητή με όνομα blue_unpack και αποθηκεύστε την τιμή της συνάρτησης struct.unpack(), προσθέτοντας τη ίδια μορφή που χρησιμοποιήθηκε για την πακετοποίηση των δεδομένων και τη μεταβλητή blue_data ως ορίσματα. Η μορφή γράφεται με τον ίδιο τρόπο όπως και στη συνάρτηση struct.pack(), ώστε να μπορείτε να αποσειριοποιήσετε τα δεδομένα με τον ίδιο τρόπο που τα σειριοποιήσατε αρχικά. Χρησιμοποιήστε τη συνάρτηση write() με το blue_unpack ως όρισμα για να επαληθεύσετε τα δεδομένα που πακετάρατε προηγουμένως.
Στην ίδια τοποθεσία θα χρησιμοποιήσουμε επίσης τη συνάρτηση struct.iter_unpack(), η οποία δέχεται τα ίδια ακριβώς ορίσματα όπως η struct.unpack(), όμως τώρα είναι δομημένη ως βρόχος for, επιτρέποντάς μας να επαναλάβουμε τα δεδομένα αντί απλώς να τα εμφανίσουμε όλα μαζί. Η συνάρτηση κωδικοποιείται ως εξής:
for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)
Θα χρησιμοποιήσουμε τη συνάρτηση speak() για να εμφανίσουμε τις τιμές. Για τα ελλείποντα ορίσματα στη συνάρτηση struct.iter_unpack(), προσθέστε τα ίδια που χρησιμοποιήθηκαν προηγουμένως με τη struct.unpack(), καθώς είναι παραλλαγές της ίδιας συνάρτησης όσον αφορά τη χρήση.
Περπατήστε μέχρι το χρυσό σημάδι X πάνω από το κόκκινο χαλί και στρέψτε προς το γραφείο, χρησιμοποιήστε τη συνάρτηση read() για να εξετάσετε τις ποσότητες των καλλιεργειών. Κάντε σημειώσεις για όλες τις ποσότητες και τη μορφή κάθε καλλιέργειας. Στη συνέχεια, περπατήστε μέχρι το σημάδι X του φωτός πάνω από το κόκκινο χαλί και δημιουργήστε ένα αντικείμενο με όνομα buffer, το οποίο θα έχει την τιμή bytearray(16). Πρόκειται για μια συλλογή bytes που μπορούμε να διευθετήσουμε πριν τη γεμίσουμε, λειτουργώντας σαν μια τράπεζα δεδομένων όπου μπορείτε να αποθηκεύσετε τα δεδομένα χειροκίνητα. Ο αριθμός 16 ως όρισμα καθορίζει πόσα bytes μπορείτε να αποθηκεύσετε στο αντικείμενο buffer.
Χρησιμοποιήστε τη συνάρτηση struct.pack_into() για να γεμίσετε το αντικείμενο buffer που δημιουργήσατε. Δεν είναι απαραίτητο να δημιουργήσετε μια μεταβλητή για να αποθηκεύσετε την τιμή της συνάρτησης, καθώς η ίδια θα εισάγει τις τιμές απευθείας στο αντικείμενο buffer. Θα χρησιμοποιήσουμε τη συνάρτηση για κάθε μία από τις τιμές που σημειώσαμε προηγουμένως, τοποθετώντας τα αντίστοιχα ορίσματα.
Για παράδειγμα, για την πρώτη τιμή καλλιέργειας που δίνεται, θα σας δοθεί η μορφή της, η θέση των bytes και η ποσότητά της. Προσθέστε τη μορφή ως πρώτο όρισμα, την τοποθεσία στην οποία θέλετε να σειριοποιηθούν τα bytes, η οποία σε αυτή την περίπτωση είναι το buffer. Για το τρίτο όρισμα, ορίστε τη θέση στην οποία θέλετε να προσθέσετε την τιμή μέσα στο buffer – η μορφή καθορίζει τα bytes που καταλαμβάνονται, οπότε προσέξτε να μην πακετάρετε δεδομένα σε θέσεις που έχουν ήδη χρησιμοποιηθεί. Τέλος, προσθέστε την τιμή που θέλετε να σειριοποιήσετε και να πακετάρετε στο αντικείμενο buffer.
struct.pack_into('i', buffer, 0, 82)
Το αντικείμενο buffer έχει 16 bytes, όπως αναφέρθηκε προηγουμένως. Στον παραπάνω κώδικα, η μορφή για ακέραιο καταλαμβάνει 4 bytes και εισάγεται στη θέση 0. Αυτό σημαίνει ότι μόλις εισαχθούν τα δεδομένα στο buffer, απομένουν μόνο 12 bytes ελεύθερα, με τις θέσεις 0-3 να είναι κατειλημμένες από την τιμή που δόθηκε, σε αυτή την περίπτωση το 82. Εφαρμόστε αυτή τη διαδικασία για όλα τα σημεία δεδομένων των καλλιεργειών που διαβάσατε και σημειώσατε, συνολικά υπάρχουν τρία (3). Χρησιμοποιήστε τη συνάρτηση display() και προσθέστε το buffer για να εμφανίσετε τα σειριοποιημένα δεδομένα.
Περπατήστε μέχρι το σκοτεινό σημάδι X πάνω από το κόκκινο χαλί και στρέψτε προς τον τερματικό. Εδώ θα αποσειριοποιήσουμε τα δεδομένα για να επαληθεύσουμε το περιεχόμενο και να βεβαιωθούμε ότι αποθηκεύτηκαν σωστά. Δημιουργήστε τρεις μεταβλητές με ονόματα: lettuce, carrots και melons. Θα αποσειριοποιήσουμε τα δεδομένα κάθε σημείου ξεχωριστά. Για κάθε μεταβλητή, αποθηκεύστε την τιμή της συνάρτησης struct.unpack_from() και ορίστε ως ορίσματα τα ίδια δεδομένα που χρησιμοποιήσατε για την πακετοποίηση. Για το πρώτο όρισμα, ορίστε τη μορφή, για το δεύτερο προσθέστε το αντικείμενο buffer από το οποίο θα αποσειριοποιήσετε και τέλος ορίστε τη θέση στο buffer από την οποία θέλετε να αποσειριοποιήσετε. Για παράδειγμα:
lettuce = struct.unpack_from('i', buffer, 0)
Αυτά τα δεδομένα αντιστοιχούν στο προηγούμενο παράδειγμα πακετοποίησης που αποσειριοποιείται. Κάντε το ίδιο για τις δύο άλλες μεταβλητές και εισάγετε τις lettuce, carrots και melons στην προ-γραμμένη συνάρτηση write() για να ολοκληρώσετε το επίπεδο.