Πρακτικά εργαστήρια: ροές, ZIP, API, UTF-8 και HTTP — DedSec Project
Πρακτικά εργαστήρια: ροές, ZIP, API, UTF-8 και HTTP 14. Επεξεργασία δεδομένων σε παρτίδες Μοντέλο κατανάλωσης Ένας iterable στην Python μπορεί να παράγει δεδομένα σταδιακά. Το…
14. Επεξεργασία δεδομένων σε παρτίδες
Μοντέλο κατανάλωσης
Ένας iterable στην Python μπορεί να παράγει δεδομένα σταδιακά. Το 14_batched_generator.py χρησιμοποιεί islice για να ζητά μόνο τα επόμενα size στοιχεία και τα επιστρέφει ως tuple. Αυτό βοηθά όταν η είσοδος προέρχεται από μεγάλη ροή αντί από ήδη υπάρχουσα λίστα.
from itertools import islice
def batches(iterable, size):
if size < 1:
raise ValueError("size must be positive")
it = iter(iterable)
while True:
batch = tuple(islice(it, size))
if not batch:
break
yield batch
Το list(batches(range(5), 2)) αναμένεται να είναι [(0, 1), (2, 3), (4,)]. Η τελευταία παρτίδα μπορεί να είναι μικρότερη. Η memory use δεν είναι O(1) απόλυτα: μία παρτίδα κρατά έως size στοιχεία και ο ίδιος ο iterable μπορεί να έχει δικούς του buffers.
Lazy iteration και λάθος υπόθεση
Η κλήση gen = batches(range(5), 2) κατασκευάζει generator, δεν έχει ακόμη παράγει παρτίδες. Με next(gen) ζητάς το πρώτο tuple. Με εξάντληση και νέο next(gen) προκύπτει StopIteration. Μη χρησιμοποιείς τον ίδιο εξαντλημένο generator σαν να ξεκινά εκ νέου: δημιούργησε νέο generator από την αρχική πηγή μόνο αν η πηγή μπορεί να ξαναδιαβαστεί.
Ασφαλής αλλαγή πολιτικής
Δοκίμασε size=0 και size=-1: η συνάρτηση οφείλει να απορρίπτει την τιμή πριν προχωρήσει στο loop. Προσπάθησε επίσης size=2.5 και σύγκρινε το σφάλμα με την πολιτική σου για input types. Αν επιθυμείς αυστηρό integer, πρόσθεσε isinstance(size,int) με προσοχή γιατί bool είναι υποκλάση της int.
Τι συμβαίνει αν ο παραγωγός αποτύχει
Ένας iterable μπορεί να υψώσει exception στη μέση παρτίδας. Η islice δεν μετατρέπει το σφάλμα σε έγκυρο partial result. Σε pipeline προς βάση δεδομένων, σχεδίασε explicit transaction policy πριν επιτρέψεις να αποθηκευτούν τα πρώτα chunks και να χαθούν τα επόμενα. Η χρήση generator δεν σου δίνει αυτόματα exactly-once processing.
Άσκηση αξιολόγησης
Μέτρησε πόσα στοιχεία ζητήθηκαν από έναν δικό σου iterator με side effect καταγραφής. Σύγκρινε χρήση μνήμης όταν περνάς range(1000000) απέναντι σε list(range(1000000)), χωρίς να ισχυριστείς ότι είναι ισοδύναμες πηγές. Παράδωσε tests για κενή ροή, υπόλοιπο μικρότερης παρτίδας, μη έγκυρο size, και exception από upstream generator. Γράψε τις πραγματικές παρατηρήσεις σε Python 3 και κράτησε τα tests αναπαραγώγιμα.
15. Συγχώνευση ταξινομημένων ροών
Στόχος
Το heapq.merge απαιτεί ήδη ταξινομημένες εισόδους· δεν ταξινομεί μόνο του.
Αρχείο κώδικα
15_merge_sorted.py
Βήματα
- Διάβασε τη συνάρτηση και πρόβλεψε το αποτέλεσμα.
- Τρέξε το αρχείο μόνο μέσα σε φάκελο εξάσκησης:
python 15_merge_sorted.py. - Άλλαξε ένα δεδομένο και πρόσθεσε δική σου δοκιμή
assert. - Δοκίμασε λανθασμένη είσοδο και σημείωσε τη συμπεριφορά.
- Σκέψου τι απαιτείται πριν το βάλεις σε πραγματικό πρόγραμμα.
Λύση / βάση αναφοράς
Το αρχείο 15_merge_sorted.py περιέχει την πλήρη υλοποίηση και τις αρχικές δοκιμές.
16. Τοπικός κατάλογος ελέγχου αρχείων
Στόχος
Τα checksums δείχνουν αλλαγές· απόφυγε συμβολικούς συνδέσμους και ιδιωτικά αρχεία σε δημόσια πακέτα.
Αρχείο κώδικα
16_backup_manifest.py
Βήματα
- Διάβασε τη συνάρτηση και πρόβλεψε το αποτέλεσμα.
- Τρέξε το αρχείο μόνο μέσα σε φάκελο εξάσκησης:
python 16_backup_manifest.py. - Άλλαξε ένα δεδομένο και πρόσθεσε δική σου δοκιμή
assert. - Δοκίμασε λανθασμένη είσοδο και σημείωσε τη συμπεριφορά.
- Σκέψου τι απαιτείται πριν το βάλεις σε πραγματικό πρόγραμμα.
Λύση / βάση αναφοράς
Το αρχείο 16_backup_manifest.py περιέχει την πλήρη υλοποίηση και τις αρχικές δοκιμές.
17. Έλεγχος ZIP χωρίς αποσυμπίεση
Στόχος
Η προεπισκόπηση ZIP δεν αποσυμπιέζει. Ένας πραγματικός extractor χρειάζεται επίσης ελέγχους symlinks και ορίων πόρων.
Αρχείο κώδικα
17_zip_preview.py
Βήματα
- Διάβασε τη συνάρτηση και πρόβλεψε το αποτέλεσμα.
- Τρέξε το αρχείο μόνο μέσα σε φάκελο εξάσκησης:
python 17_zip_preview.py. - Άλλαξε ένα δεδομένο και πρόσθεσε δική σου δοκιμή
assert. - Δοκίμασε λανθασμένη είσοδο και σημείωσε τη συμπεριφορά.
- Σκέψου τι απαιτείται πριν το βάλεις σε πραγματικό πρόγραμμα.
Λύση / βάση αναφοράς
Το αρχείο 17_zip_preview.py περιέχει την πλήρη υλοποίηση και τις αρχικές δοκιμές.
19. Σχεδίαση δομημένων σφαλμάτων API
Τι θα μάθεις
Ένα API error response πρέπει να έχει σταθερό machine-readable code και χωριστό ανθρώπινο message. Ο client μπορεί να αλλάξει τη γλώσσα του μηνύματος αλλά δεν πρέπει να βασίζεται σε ελεύθερο κείμενο για να καταλάβει τι συνέβη. Το συνοδευτικό script είναι το 19_api_errors.py.
import json
def error_response(code: str, message: str, field: str | None = None) -> str:
if not code or not message:
raise ValueError("code and message required")
return json.dumps(
{"error": {"code": code, "message": message, "field": field}},
ensure_ascii=False
)
Η ensure_ascii=False διατηρεί αναγνώσιμους μη ASCII χαρακτήρες στην παραγωγή JSON, όχι όμως κάποια ειδική εγγύηση ασφάλειας κατά την εμφάνιση HTML. Ο client πρέπει να διαβάσει το JSON και να εμφανίσει το message με ασφαλή text renderer.
Συμβόλαιο έναντι HTTP status
Η συνάρτηση φτιάχνει μόνο σώμα JSON και δεν ορίζει HTTP status code. Σχεδίασε mapping όπως validation error προς 400, unauthenticated request προς 401, forbidden operation προς 403 και missing resource προς 404. Η επιλογή έχει επιχειρησιακές συνέπειες: 401 και 403 δεν είναι ταυτόσημα, και ενδέχεται να μη θέλεις να αποκαλύπτεις την ύπαρξη προστατευμένου αντικειμένου. Το error.code παραμένει σταθερό ανεξάρτητα από μετάφραση του message.
Σκόπιμες αποτυχίες
Κάλεσε error_response("", "Missing age", "age") και βεβαιώσου ότι προκύπτει ValueError. Έπειτα δοκίμασε None αντί field και δες ότι το JSON παράγει null. Αν η εφαρμογή δεν επιτρέπει field=null, αυτό είναι αλλαγή στο συμβόλαιο, όχι bug του json.dumps.
Ασφάλεια πληροφορίας
Μην επιστρέφεις stack traces, query strings με μυστικά ή εσωτερικές διαδρομές αρχείων στο δημόσιο error.message. Κράτησε εσωτερική τεχνική περιγραφή στα server logs, με ελεγχόμενη καταγραφή χωρίς credentials, και επέστρεψε σύντομο σφάλμα στον client. Ένα correlation ID μπορεί να συνδέει τις δύο όψεις χωρίς έκθεση μυστικών.
Παραδοτέα
Επέκτεινε το ίδιο script με τρία pytest ή unittest cases για κανονική είσοδο, κενό code, και Unicode message. Παράδωσε συγκεκριμένο παραγόμενο JSON, status-to-code table και ένα παράδειγμα του γιατί ένας client που συγκρίνει το αγγλικό μήνυμα θα σπάσει όταν μεταφραστεί στα ελληνικά. Ο κώδικας παρέχεται ως εργαστήριο, όχι ως δήλωση ότι εκτελέστηκε στον έλεγχο.
21. Κωδικοποίηση και αποκωδικοποίηση UTF-8
Στόχος
Η ρητή κωδικοποίηση UTF-8 διατηρεί σωστό το δίγλωσσο κείμενο.
Αρχείο κώδικα
21_utf8_roundtrip.py
Βήματα
- Διάβασε τη συνάρτηση και πρόβλεψε το αποτέλεσμα.
- Τρέξε το αρχείο μόνο μέσα σε φάκελο εξάσκησης:
python 21_utf8_roundtrip.py. - Άλλαξε ένα δεδομένο και πρόσθεσε δική σου δοκιμή
assert. - Δοκίμασε λανθασμένη είσοδο και σημείωσε τη συμπεριφορά.
- Σκέψου τι απαιτείται πριν το βάλεις σε πραγματικό πρόγραμμα.
Λύση / βάση αναφοράς
Το αρχείο 21_utf8_roundtrip.py περιέχει την πλήρη υλοποίηση και τις αρχικές δοκιμές.
22. Κινούμενο παράθυρο με deque
Στόχος
Η μονότονη deque βρίσκει μέγιστα παραθύρων σε συνολικό χρόνο O(n).
Αρχείο κώδικα
22_sliding_window.py
Βήματα
- Διάβασε τη συνάρτηση και πρόβλεψε το αποτέλεσμα.
- Τρέξε το αρχείο μόνο μέσα σε φάκελο εξάσκησης:
python 22_sliding_window.py. - Άλλαξε ένα δεδομένο και πρόσθεσε δική σου δοκιμή
assert. - Δοκίμασε λανθασμένη είσοδο και σημείωσε τη συμπεριφορά.
- Σκέψου τι απαιτείται πριν το βάλεις σε πραγματικό πρόγραμμα.
Λύση / βάση αναφοράς
Το αρχείο 22_sliding_window.py περιέχει την πλήρη υλοποίηση και τις αρχικές δοκιμές.
24. Ασφαλής ανάλυση γραμμής HTTP status
Στόχος
Απόρριψε αλλαγές γραμμής σε πεδία πρωτοκόλλου. Το παράδειγμα δεν αντικαθιστά πλήρη HTTP parser.
Αρχείο κώδικα
24_simple_http_parse.py
Βήματα
- Διάβασε τη συνάρτηση και πρόβλεψε το αποτέλεσμα.
- Τρέξε το αρχείο μόνο μέσα σε φάκελο εξάσκησης:
python 24_simple_http_parse.py. - Άλλαξε ένα δεδομένο και πρόσθεσε δική σου δοκιμή
assert. - Δοκίμασε λανθασμένη είσοδο και σημείωσε τη συμπεριφορά.
- Σκέψου τι απαιτείται πριν το βάλεις σε πραγματικό πρόγραμμα.
Λύση / βάση αναφοράς
Το αρχείο 24_simple_http_parse.py περιέχει την πλήρη υλοποίηση και τις αρχικές δοκιμές.