Η Ελπίδα Τσαγκάρη κρατάει το απόθεμα ενός βιβλιοπωλείου στα Ιωάννινα: 12.400 τίτλοι στα ράφια και ένα αρχείο τιμών από τον προμηθευτή με 41.000 γραμμές. Το πρώτο πρόγραμμα που έγραψε για να τα αντιστοιχίσει διάβαζε έναν τίτλο και ύστερα ξαναδιάβαζε ολόκληρο το αρχείο από την αρχή. Είναι 508.400.000 συγκρίσεις για μια ερώτηση περί τιμών, και κράτησε έντεκα λεπτά.
Η διόρθωση δεν ήταν γλώσσα. Ήταν μία παρατήρηση: μια αναζήτηση σε λεξικό κοστίζει το ίδιο στα δέκα και στα δέκα εκατομμύρια στοιχεία, ενώ ένα πέρασμα λίστας κοστίζει όσο η λίστα. Η πρόταση ίσχυε πριν υπάρξει η Python και θα ισχύει και μετά, και γι' αυτό κάθεται εδώ και όχι στις Γλώσσες προγραμματισμού.
price = {}for row in supplier:price[row.isbn] = row.valuefor book in shelf:print(book.title, price.get(book.isbn))
41.000 καταχωρίσεις και ύστερα 12.400 αναζητήσεις, δηλαδή 53.400 βήματα στη θέση των 508.400.000 συγκρίσεων. Ίδιο αρχείο, ίδια γλώσσα, ίδια μηχανή.
Τα οκτώ υποθέματα είναι μία ερώτηση σε οκτώ μεγέθη
Κάθε ιδέα που μπαίνει εδώ απαντάει σε κάποια εκδοχή του τι κοστίζει κάτι όταν γίνει περισσότερο. Μια δομή δεδομένων είναι στοίχημα για το ποια πράξη θα γίνει τις περισσότερες φορές. Ένας αλγόριθμος είναι ένας φθηνότερος δρόμος που κάποιος βρήκε πρώτος και του έδωσε όνομα. Ακόμη και οι συνήθειες στον Καθαρό κώδικα είναι ισχυρισμός για τιμή: την τιμή του δεύτερου αναγνώστη, που συνήθως είστε εσείς σε οκτώ μήνες.
Γι' αυτό τα οκτώ κάθονται μαζί, και γι' αυτό αυτό το θέμα είναι το κομμάτι του Προγραμματισμού υπολογιστών που κρατάει την αξία του όταν αλλάξει η γλώσσα. Κανένα από τα οκτώ δεν είναι το πρώτο. Η Ελπίδα δεν χρειαζόταν τη λέξη «πίνακας κατακερματισμού». Χρειαζόταν να ξέρει ότι το σχήμα που διάλεξε είχε τιμή, και ότι ένα άλλο σχήμα είχε άλλη. Ο ίδιος λογαριασμός ξαναβγαίνει μια οθόνη πιο κάτω, στις Βάσεις δεδομένων, όπου ένας πίνακας χωρίς ευρετήριο είναι η ίδια λίστα που περπατιέται.
Τρεις τιμές, πριν από οποιοδήποτε υπόθεμα
Η πρώτη διόρθωσε το αρχείο των Ιωαννίνων. Μια λίστα περπατιέται ώσπου να βρεθεί το ζητούμενο, άρα η δουλειά μεγαλώνει μαζί με τη λίστα. Ένα λεξικό διευθυνσιοδοτείται: το κλειδί γίνεται θέση, και η θέση κοιτιέται μία φορά. Οι Δομές δεδομένων είναι το υπόθεμα όπου αυτή η επιλογή αποκτάει όνομα.
Η δεύτερη είναι αυτό που έγραψε η Ελπίδα την πρώτη φορά. Δύο εμφωλευμένοι βρόχοι πάνω σε δύο λίστες κοστίζουν το γινόμενο των μηκών τους, και ο αριθμός ξεφεύγει πιο γρήγορα απ' όσο αντέχει η διαίσθηση. Η χρήσιμη συνήθεια δεν είναι ο ακριβής υπολογισμός. Είναι να προσέχετε τον δεύτερο βρόχο κάτω από τον πρώτο, και να ρωτάτε πόσο μεγάλο θα είναι το αρχείο του χρόνου.
Η τρίτη δεν έχει σχέση με ταχύτητα και βγάζει τα πιο παράξενα σφάλματα. Όταν η Ελπίδα κράτησε ένα αντίγραφο του καταλόγου για να σημειώνει τα εξαντλημένα, έγραψε checked = shelf, και ύστερα είδε ότι η αφαίρεση ενός τίτλου από το ένα τον έσβηνε και από το άλλο. Η ίδια λίστα δοσμένη σε δύο ονόματα είναι μία λίστα με δύο ονόματα. Το όνομα είναι ετικέτα πάνω σε ένα αντικείμενο, όχι κουτί που κρατάει αντίγραφο, και checked = list(shelf) είναι η γραμμή που κάνει τη δεύτερη λίστα να υπάρξει στ' αλήθεια.
Η αλφαβητική σειρά στα ελληνικά δεν βγαίνει από μόνη της
Ο κατάλογος πελατών του βιβλιοπωλείου έχει τέσσερα ονόματα, και η sorted() τα βάζει σε σειρά που κανένας Έλληνας δεν θα αναγνώριζε: Άννα Ζέρβα, Όλγα Ρίζου, Αλέξης Βαρδής, Βασίλης Θεοχάρης. Η προεπιλεγμένη ταξινόμηση συγκρίνει κωδικοσημεία, όχι γράμματα. Και το Ά είναι U+0386 ενώ το Α είναι U+0391, οπότε κάθε τονισμένο κεφαλαίο προηγείται ολόκληρου του αλφαβήτου, και κάθε πεζό ακολουθεί μετά από όλα τα κεφαλαία.
Η επιδιόρθωση είναι ένα κλειδί ταξινόμησης που βγάζει τον τόνο πριν από τη σύγκριση, και χωράει σε τρεις γραμμές:
import unicodedataflat = lambda s: unicodedata.normalize('NFD', s.casefold())sorted(names, key=lambda s: ''.join(c for c in flat(s) if not unicodedata.combining(c)))
Τώρα η σειρά είναι Αλέξης Βαρδής, Άννα Ζέρβα, Βασίλης Θεοχάρης, Όλγα Ρίζου, που είναι η σειρά ενός τηλεφωνικού καταλόγου. Δεν πρόκειται για ελληνική ιδιοτροπία. Είναι η ίδια τιμή με πριν, πληρωμένη σε άλλο νόμισμα: μια σύγκριση είναι φθηνή επειδή δεν ξέρει τίποτα, και ό,τι θέλετε να ξέρει το βάζετε εσείς στο κλειδί.
Η σειρά
Κάθε σκαλί είναι αυτό που δίνει νόημα στο επόμενο
Η σκάλα ανεβαίνεται ανάποδα σχεδόν από όλους, επειδή ένα μάθημα γλώσσας ξεκινάει από το δεύτερο σκαλί και δεν αναφέρει ποτέ το πρώτο.
- 01Εκπλαγείτε από έναν αριθμό μία φοράΔείτε κάτι να κρατάει έντεκα λεπτά ενώ έπρεπε να κρατήσει ένα δευτερόλεπτο. Χωρίς αυτό, τίποτα από πάνω δεν κάθεται.
- 02Μάθετε τι κοστίζει το κάθε σχήμαΗ λίστα περπατιέται, το λεξικό διευθυνσιοδοτείται. Τα ονόματα περιμένουν, οι τιμές όχι.
- 03Συναντήστε ένα πρόβλημα δεύτερη φοράΈνα πρότυπο διαβασμένο πριν από τη δεύτερη φορά είναι λύση χωρίς βλάβη από πίσω της.
- 04Γράψτε για τον δεύτερο αναγνώστηΟι συνήθειες βγάζουν νόημα μόλις ανοίξετε το δικό σας αρχείο μετά από οκτώ μήνες.
Δεν λέει πόσο κρατάει ένα σκαλί. Το πρώτο γίνεται σε ένα απόγευμα και τακτικά δεν γίνεται για δύο χρόνια, που είναι όλο το επιχείρημα για να το ψάξει κανείς επίτηδες.
Όταν σταματήσει, το χρήσιμο πλαίσιο είναι το δικό σας
Ένα πρόγραμμα που σταματάει τυπώνει την αλυσίδα των κλήσεων που ήταν ανοιχτές τη στιγμή που σταμάτησε. Ένα πλαίσιο στη στοίβα είναι μια συνάρτηση σε αναμονή, που περιμένει να γυρίσει εκείνη την οποία κάλεσε, και η σειρά τους είναι η διαδρομή που ακολούθησε το πρόγραμμα. Το χρήσιμο πλαίσιο είναι σχεδόν πάντα το χαμηλότερο που ονομάζει αρχείο γραμμένο από την Ελπίδα, και όχι αρχείο μέσα σε βιβλιοθήκη που εγκατέστησε.
Το διάβασμα αυτής της αλυσίδας είναι η διαφορά ανάμεσα στη διόρθωση και στο μάντεμα, και είναι η είσοδος στην Αποσφαλμάτωση. Ακριβώς από κάτω, το Πώς εκτελείται ο κώδικας εξηγεί γιατί η αλυσίδα έχει αυτό το σχήμα.
Η σειρά που δουλεύει, και τι κοστίζει η ανάποδη
Το ελληνικό πρόγραμμα σπουδών διδάσκει τα ονόματα πριν από τις τιμές, και εξετάζει τα ονόματα. Ένας φοιτητής τρίτου έτους στην Πάτρα γράφει τον ορισμό της πολυπλοκότητας για δεκαοκτώ μονάδες, και δεν έχει δει ποτέ βρόχο να κρατάει έντεκα λεπτά πάνω σε αρχείο που δεν του το έδωσε καθηγητής. Δεν είναι αδυναμία στον προγραμματισμό. Είναι η ανάποδη σειρά, και είναι η σειρά που βαθμολογείται, οπότε κανείς δεν την ονομάζει λάθος.
Υπάρχει και ένα δεύτερο ελληνικό μισό, μικρότερο και πιο ενοχλητικό. Η ορολογία είναι διπλή: το λεξικό λέγεται και dictionary, ο πίνακας κατακερματισμού λέγεται και hash map, ο βρόχος λέγεται και loop. Η εξέταση ζητάει το ελληνικό, το μήνυμα λάθους δίνει το αγγλικό, και μια αναζήτηση επιστρέφει μόνο ό,τι πληκτρολογήθηκε. Γράψτε και τα δύο, από την πρώτη φορά, και το μισό πρόβλημα φεύγει.
Η άλλη σειρά που σπάει είναι τα Πρότυπα σχεδίασης διαβασμένα πριν συναντηθούν τα προβλήματα. Ένα πρότυπο που μαθεύτηκε νωρίς είναι λύση που ψάχνει βλάβη, και βγάζει προγράμματα με έξι αρχεία εκεί που έφτανε ένα. Το ίδιο ισχύει και προς την αντίθετη κατεύθυνση: όσα βρίσκονται στο Από τον κώδικα στην παραγωγή ανοίγουν πολύ νωρίτερα απ' όσο φαίνεται λογικό, επειδή μαθαίνονται πιο εύκολα πάνω σε πέντε γραμμές παρά πάνω σε τέσσερις χιλιάδες.
Τι ανοίγετε το 2026, και τι κοστίζει
Η μονάδα timeit είναι μέσα στην τυπική βιβλιοθήκη της Python και λύνει μια διαφωνία για δύο εκδοχές ενός βρόχου σε δέκα δευτερόλεπτα. Αντικατέστησε τη συνήθεια να μπαίνει ρολόι γύρω από ολόκληρο το πρόγραμμα, που χρονομετράει και την εκκίνηση του διερμηνευτή μαζί.
Για τη στιγμή που κάτι σταματάει, το pdb έρχεται μαζί με τη γλώσσα και παίρνει τη θέση της εντολής εκτύπωσης που προστίθεται και ύστερα τρέχει το αρχείο ξανά. Η γραμμή python3 -m pdb -c continue script.py σας αφήνει στο πλαίσιο όπου έσπασε, με κάθε τιμή ακόμη στη μνήμη, που είναι ακριβώς αυτό που δεν επιστρέφει μια εκτύπωση.
Για τα ελληνικά, η μονάδα unicodedata είναι επίσης μέσα στη γλώσσα και αντικατέστησε τους χειρόγραφους πίνακες αντιστοίχισης ελληνικών χαρακτήρων που κυκλοφορούσαν σε φόρουμ ως το 2010 περίπου. Καμία από τις τρεις δεν εγκαθίσταται και καμία δεν πληρώνεται. Αυτό το θέμα δεν έχει λογαριασμό σε ευρώ, πράγμα σπάνιο σε αυτόν τον χάρτη, και ο λογαριασμός του πληρώνεται σε απογεύματα.
Ένας βοηθός κώδικα γράφει την εκδοχή με το λεξικό αμέσως και σωστά, επειδή είναι σχήμα που έχει δει χιλιάδες φορές. Το κλειδί ταξινόμησης για τα ελληνικά ονόματα το γράφει επίσης, και εκεί έχει άδικο αρκετά συχνά ώστε να αξίζει να το δοκιμάσετε με τέσσερα ονόματα πριν το εμπιστευτείτε με τέσσερις χιλιάδες.
Η ερώτηση που μένει δεν είναι ποιο σχήμα είναι το γρηγορότερο. Είναι ποιο σχήμα διαλέγεται όταν το πρόβλημα δεν είναι αναζήτηση, και απαντιέται στους Αλγορίθμους.