Μεταβλητές: ένα όνομα για κάθε τιμή

Ένα σουβλατζίδικο θέλει να τυπώνει τις τιμές του. Η πίτα γύρος κάνει 4 ευρώ, με πατάτες μισό ευρώ παραπάνω. Ο πρώτος τιμοκατάλογος που θα έγραφε οποιοσδήποτε μοιάζει κάπως έτσι:
python
print("Πίτα γύρος:", 4)
print("Πίτα γύρος με πατάτες:", 4 + 0.5)
print("Δύο πίτες γύρος:", 4 + 4)
Μετά η τιμή ανεβαίνει στα 4.5 ευρώ και πρέπει να αλλάξεις το 4 σε τέσσερα σημεία. Αν ξεχάσεις ένα, το πρόγραμμα δε θα σου πει τίποτα: θα τυπώσει ήσυχα μια λάθος τιμή για τις δύο πίτες και θα το ανακαλύψει ο πελάτης στο ταμείο.
Το πρόβλημα είναι ότι το ίδιο γεγονός, «η πίτα γύρος κοστίζει τόσο», είναι γραμμένο σε τέσσερα σημεία. Το λύνεις γράφοντάς το σε ένα:
python
gyros_price = 4

print("Πίτα γύρος:", gyros_price)
print("Πίτα γύρος με πατάτες:", gyros_price + 0.5)
print("Δύο πίτες γύρος:", gyros_price + gyros_price)
Η πρώτη γραμμή λέει στην Python: «κράτα την τιμή 4 και δώσ' της το όνομα gyros_price». Από εκεί και πέρα, όπου γράφεις gyros_price, η Python βάζει το 4.
Το gyros_price είναι μια μεταβλητή: ένα όνομα που δίνεις σε μια τιμή, ώστε να τη χρησιμοποιείς όσες φορές θέλεις χωρίς να την ξαναγράφεις. Το πρόγραμμα κρατάει την τιμή στη μνήμη του και, όταν συναντήσει το όνομα, βάζει στη θέση του την τιμή.
Άλλαξε την τιμή σε 4.5 στην πρώτη γραμμή και τρέξε ξανά. Αλλάζεις ένα σημείο και διορθώνεται όλος ο τιμοκατάλογος.
python
Με 4.5 το πρόγραμμα τυπώνει 4.5, 5.0 και 9.0. Το .0 εμφανίζεται, επειδή ένας δεκαδικός αριθμός μέσα σε πράξη δίνει πάντα δεκαδικό αποτέλεσμα, ακόμα κι όταν βγαίνει στρογγυλό. Το 5.0 και το 5 έχουν την ίδια τιμή.

Πώς να φανταστείς μια μεταβλητή

Φαντάσου μια μεταβλητή σαν κουτί με ταμπέλα. Η ταμπέλα είναι το όνομα και μέσα στο κουτί είναι η τιμή. Το κουτί χωράει μία τιμή τη φορά. Για ό,τι κάνεις εδώ η εικόνα αυτή αρκεί, αν και αργότερα θα χρειαστεί να γίνει πιο ακριβής.
Τρεις μεταβλητές στη μνήμη του προγράμματος Μέσα στη μνήμη του προγράμματος τρία κουτιά με ταμπέλα. Το gyros_price κρατάει 4, το customer κρατάει το κείμενο Νίκος, το yesterday κρατάει 4. Το όνομα είναι απ' έξω, η τιμή μέσα. ΜΝΗΜΗ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ gyros_price 4 customer "Νίκος" yesterday 4 Το όνομα απ' έξω, η τιμή μέσα.
Στο κουτί μπορείς να βάλεις αριθμό ή κείμενο. Το customer = "Νίκος" φτιάχνει μια μεταβλητή που κρατάει ένα string και το print(customer) τυπώνει Νίκος, χωρίς εισαγωγικά.

Το = δεν είναι το ίσον των μαθηματικών

Στα μαθηματικά, x = x + 5 είναι αδύνατη εξίσωση. Κανένας αριθμός δεν ισούται με τον εαυτό του συν πέντε. Στον προγραμματισμό είναι από τις πιο συνηθισμένες γραμμές που θα γράψεις.
Το = εδώ δε ρωτάει αν δύο πράγματα είναι ίσα. Είναι εντολή. Η Python την εκτελεί σε δύο βήματα, πάντα με την ίδια σειρά: πρώτα υπολογίζει ό,τι είναι δεξιά, με τις τιμές που υπάρχουν εκείνη τη στιγμή, και μετά βάζει το αποτέλεσμα στο κουτί που λέει το όνομα αριστερά. Η παλιά τιμή του κουτιού πετιέται. Αυτή η εντολή λέγεται ανάθεση.
Το καρτοκινητό σου έχει υπόλοιπο 10 ευρώ. Κάνεις ανανέωση 5 ευρώ και μετά αγοράζεις ένα πακέτο data των 3 ευρώ. Με τον ίδιο τρόπο παρακολουθείς και το χαρτζιλίκι της εβδομάδας: ξεκινάς με 20 ευρώ και κάθε έξοδο το αφαιρείς από το ίδιο όνομα. Προχώρα γραμμή γραμμή και κοίτα τι κρατάει το balance σε κάθε βήμα.
Βήμα προς βήμα
Βήμα 1 από 4
balance = 10
balance = balance + 5
balance = balance - 3
print(balance)
Μεταβλητές

balance = 10

Η μεταβλητή balance δεν υπήρχε. Τώρα υπάρχει και κρατάει 10.

Αν απλώσεις τις ίδιες τέσσερις γραμμές σε μια γραμμή χρόνου, βλέπεις ότι ένα όνομα κρατάει διαφορετική τιμή σε κάθε σημείο του προγράμματος:
Η τιμή μιας μεταβλητής γραμμή προς γραμμή Χρονολόγιο τεσσάρων γραμμών. Γραμμή 1: balance = 10, η τιμή είναι 10. Γραμμή 2: balance = balance + 5, η τιμή γίνεται 15. Γραμμή 3: balance = balance - 3, η τιμή γίνεται 12. Γραμμή 4: print(balance), η τιμή μένει 12 γιατί το print μόνο διαβάζει. ΤΙΜΗ ΤΟΥ balance 10 γραμμή 1 balance = 10 15 γραμμή 2 balance = balance + 5 12 γραμμή 3 balance = balance - 3 12 γραμμή 4 print(balance) Κάθε νέα ανάθεση πετάει την προηγούμενη τιμή. Το print μόνο διαβάζει.
Γι' αυτό η ερώτηση «πόσο είναι το balance;» δεν έχει απάντηση χωρίς το «σε ποια γραμμή;». Σε κάθε σημείο του προγράμματος η μεταβλητή κρατάει την τελευταία τιμή που της έδωσες.

Μια μεταβλητή που αντιγράφει μια άλλη

Μια μεταβλητή μπορεί να πάρει την τιμή της από μια άλλη. Το ερώτημα είναι τι γίνεται όταν η πρώτη αλλάξει αργότερα.
Πρόβλεψε
price = 4
yesterday = price
price = 5
print(yesterday)

Τι τυπώνει η τελευταία γραμμή;

Διάλεξε μία

Η αντιμετάθεση: πρώτα η λάθος εκδοχή

Έχεις δύο μεταβλητές και θέλεις να ανταλλάξουν τιμές. Το first κρατάει "καφές" και το second κρατάει "τσάι". Στο τέλος πρέπει το first να έχει τσάι και το second καφέ. Πρόσθεσε γραμμές ανάμεσα στις δύο αναθέσεις και στα δύο print, χωρίς να ξαναγράψεις τις λέξεις καφές και τσάι.
python
Η πρώτη ιδέα σχεδόν όλων είναι αυτή και είναι λάθος:
python
first = second
second = first
Τυπώνει τσάι δύο φορές. Ακολούθησε τις γραμμές με τη σειρά: η πρώτη βάζει τσάι στο first και ο καφές πετιέται. Όταν τρέξει η δεύτερη, το first έχει ήδη τσάι, οπότε το second παίρνει τσάι. Ο καφές χάθηκε στην πρώτη γραμμή και δεν υπάρχει τρόπος να γυρίσει.
Αυτό που λείπει είναι ένα τρίτο κουτί για να κρατήσει τον καφέ πριν χαθεί:
python
saved = first
first = second
second = saved
Η πρώτη εκδοχή είναι έγκυρος κώδικας, αλλά χάνει μια τιμή. Για τέτοια λάθη η Python δε βγάζει μήνυμα σφάλματος.

Ονόματα που διαβάζονται

Ένα όνομα μεταβλητής έχει λίγους κανόνες. Φτιάχνεται από γράμματα, αριθμούς και κάτω παύλα _. Δεν έχει κενά και δεν ξεκινάει με αριθμό. Τα κεφαλαία μετράνε, οπότε το balance και το Balance είναι δύο διαφορετικά ονόματα. Όταν το όνομα έχει πολλές λέξεις, τις ενώνεις με κάτω παύλα: gyros_price, όχι gyros price.
Η Python δέχεται και ελληνικά ονόματα. Το τιμή = 4 τρέχει κανονικά. Στη δουλειά όμως θα δεις σχεδόν παντού αγγλικά ονόματα. Υπάρχει κι ένας πολύ πρακτικός λόγος να μην ανακατεύεις πληκτρολόγια. Το παρακάτω πρόγραμμα είναι σκόπιμα χαλασμένο. Στις δύο γραμμές το όνομα total φαίνεται ίδιο, αλλά στη δεύτερη ένα γράμμα έχει γραφτεί με ελληνικό πληκτρολόγιο. Τρέξε το και κοίτα το μήνυμα.
python
Το μήνυμα λέει NameError: name 'tοtal' is not defined. Did you mean: 'total'?. Στη δεύτερη γραμμή το ο είναι ελληνικό όμικρον, ενώ στην πρώτη είναι λατινικό o. Για την Python είναι διαφορετικά γράμματα, άρα διαφορετικά ονόματα. Σβήσε το όνομα και γράψ' το ξανά με αγγλικό πληκτρολόγιο.
Πέρα από τους κανόνες, ένα όνομα πρέπει να λέει τι κρατάει. Το x = 4 τρέχει εξίσου καλά με το gyros_price = 4, αλλά σε δύο μήνες, ή σε κάποιον άλλον που θα διαβάσει τον κώδικα, το x δε λέει τίποτα.
Η σειρά μετράει και στα ονόματα. Αυτό το πρόγραμμα ζητάει το total μία γραμμή πριν το φτιάξει:
python
print(total)
total = 3
Κρασάρει στην πρώτη γραμμή με NameError: name 'total' is not defined, γιατί η Python δεν έχει φτάσει ακόμα στη γραμμή που φτιάχνει τη μεταβλητή.

Το ίδιο σε ψευδοκώδικα

Το καρτοκινητό σε ψευδοκώδικα:
ΓΛΩΣΣΑ
ΠΡΟΓΡΑΜΜΑ ΚΑΡΤΟΚΙΝΗΤΟ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: ΥΠΟΛΟΙΠΟ
ΑΡΧΗ
  ΥΠΟΛΟΙΠΟ ← 10
  ΥΠΟΛΟΙΠΟ ← ΥΠΟΛΟΙΠΟ + 5
  ΥΠΟΛΟΙΠΟ ← ΥΠΟΛΟΙΠΟ - 3
  ΓΡΑΨΕ ΥΠΟΛΟΙΠΟ
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ
Πριν από το ΑΡΧΗ, στο τμήμα ΜΕΤΑΒΛΗΤΕΣ, δηλώνεις κάθε μεταβλητή μαζί με το είδος της τιμής που θα κρατάει, εδώ ακέραιο. Στην Python δε δηλώνεις τίποτα: η μεταβλητή φτιάχνεται την πρώτη φορά που της δίνεις τιμή. Την ανάθεση, που στο σχολικό βιβλίο λέγεται εκχώρηση, τη γράφεις με το βέλος ← αντί για =. Το βέλος δείχνει προς τα πού πάει η τιμή, από το δεξί μέρος στο όνομα. Έτσι το ΥΠΟΛΟΙΠΟ ← ΥΠΟΛΟΙΠΟ + 5 δε μοιάζει με εξίσωση.

Σύνοψη

  • Μια μεταβλητή δίνει όνομα σε μια τιμή. Τη γράφεις μία φορά και τη χρησιμοποιείς όπου τη χρειάζεσαι, οπότε μια αλλαγή γίνεται σε ένα σημείο.
  • Φαντάσου τη σαν κουτί με ταμπέλα: απ' έξω το όνομα, μέσα μία τιμή τη φορά, αριθμός ή κείμενο.
  • Το = είναι ανάθεση, όχι ισότητα. Πρώτα υπολογίζεται το δεξί μέρος, με τις τιμές που έχουν εκείνη τη στιγμή οι μεταβλητές, μετά το αποτέλεσμα μπαίνει στο όνομα αριστερά και η παλιά τιμή πετιέται.
  • Μια μεταβλητή κρατάει την τελευταία τιμή που της έδωσες. Το yesterday = price αντιγράφει την τιμή εκείνης της στιγμής και δε μένει δεμένο με το price.
  • Με λάθος σειρά στις αναθέσεις χάνεις τιμές χωρίς κανένα σφάλμα. Στην αντιμετάθεση χρειάζεσαι τρίτη μεταβλητή.
  • Τα ονόματα έχουν γράμματα, αριθμούς και _, χωρίς κενά. Στα ονόματα τα κεφαλαία μετράνε: το balance και το Balance είναι διαφορετικά. Χρησιμοποίησε αγγλικά ονόματα που λένε τι κρατάνε.
  • Στον ψευδοκώδικα δηλώνεις τις μεταβλητές στο τμήμα ΜΕΤΑΒΛΗΤΕΣ και γράφεις την εκχώρηση με ←: ΥΠΟΛΟΙΠΟ ← ΥΠΟΛΟΙΠΟ + 5.

Θες να συνεχίσεις;

Το course είναι δωρεάν. Κάνε σύνδεση για να κρατάς την πρόοδο και τις σημειώσεις σου.