Έχοντας δει στα προηγούμενα μαθήματα κάποιες βασικές εντολές, έχουμε σχηματίσει πλέον μια εικόνα για το πώς εκτελείται ένα πρόγραμμα στην Python. Στην πραγματικότητα όμως, στον προγραμματισμό σπανίως τρέχουν οι εντολές γραμμικά η μία μετά την άλλη. Ανάλογα με το αποτέλεσμα διάφορων εκφράσεων, το πρόγραμμα συχνά θα αποφασίσει να ακολουθήσει διαφορετική ροή.
Προτάσεις συνεργασίας
Τα νέα άρθρα του PCsteps
Γίνε VIP μέλος στο PCSteps
Για να δείτε όλα τα μαθήματα Python από την αρχή τους, αλλά και τα επόμενα, αρκεί να κάνετε κλικ εδώ.
Με τις λεγόμενες δηλώσεις ελέγχου ροής μπορούμε να καθορίσουμε ποιες εντολές της Python θα εκτελεστούν και υπό ποιες συνθήκες.
Προτού πάμε εκεί όμως, θα πρέπει να δούμε κάποιες νέες κατηγορίες δεδομένων και τελεστών, τις οποίες χρησιμοποιούμε για τον έλεγχο ροής του προγράμματος.
Τιμές Boolean
Οι τύποι δεδομένων που έχουμε δει μέχρι τώρα, όπως οι integers (ακέραιοι) και τα strings, μπορούν να λάβουν άπειρες πιθανές τιμές. Αντίθετα, η κατηγορία δεδομένων που λέγεται Boolean (ονομάστηκε έτσι από τον George Boole) έχει μόνο δύο δυνατές τιμές: True και False.
Οι τιμές True και False γράφονται ακριβώς έτσι, χωρίς τα συνήθη εισαγωγικά που βάζουμε γύρω από strings, και με το πρώτο γράμμα κεφαλαίο. Όπως οποιαδήποτε άλλη τιμή, έτσι και οι Boolean χρησιμοποιούνται σε εκφράσεις και μπορούν να αποθηκευτούν σε μεταβλητές.
Αν ξεχάσουμε να βάλουμε το πρώτο γράμμα κεφαλαίο…
…ή προσπαθήσουμε να χρησιμοποιήσουμε τις συγκεκριμένες λέξεις ως ονόματα μεταβλητών…
…η Python θα μας δώσει το αντίστοιχο μήνυμα σφάλματος.
Τελεστές σύγκρισης και λογικοί τελεστές
Στα προηγούμενα μαθήματα ασχοληθήκαμε ως επί το πλείστον με μαθηματικούς τελεστές. Ωστόσο, στις εκφράσεις χρησιμοποιούνται κατά κόρον τόσο οι λογικοί, όσο και οι τελεστές σύγκρισης.
Τελεστές σύγκρισης
Οι τελεστές αυτοί συγκρίνουν δύο τιμές και υπολογίζουν το τελικό αποτέλεσμα σε μια Boolean τιμή, True ή False. Στον παρακάτω πίνακα φαίνονται οι τελεστές σύγκρισης της Python με μια σύντομη περιγραφή.
Μπορούμε να τους δοκιμάσουμε άμεσα στο κέλυφος:
Όπως μαντεύει κανείς, το “==” (ίσον με) δίνει ως αποτέλεσμα True όταν οι τιμές και από τις δυο μεριές είναι ίδιες, ενώ το “!=” (διάφορο του) όταν είναι διαφορετικές. Οι δύο αυτοί τελεστές μπορούν να δουλέψουν με κάθε είδους δεδομένα.
Ας σημειωθεί ότι ένας integer ή float θα είναι πάντοτε διάφορος ενός string. Για την Python, το ‘14’ είναι διαφορετικό από το 14. Έτσι, 14 == ‘14’ δίνει False.
Αντίθετα, τα <, >, <=, >= δουλεύουν σωστά μόνο με αριθμούς.
Μπορούμε βέβαια να τα χρησιμοποιήσουμε και για σύγκριση string. Στην περίπτωση αυτή, η Python θα συγκρίνει αλφαβητικά τα δύο string, χαρακτήρα – χαρακτήρα, όπως θα συγκρίναμε και εμείς δυο λέξεις για να τις βάλουμε σε αλφαβητική σειρά.
Τα string, όμως, περιέχουν εκτός από μικρά και κεφαλαία γράμματα, και σημεία στίξης, παύλες κλπ. Υπάρχουν, επομένως, κανόνες και για την προτεραιότητα των υπόλοιπων χαρακτήρων (που δεν μας ενδιαφέρουν άμεσα).
‘==' ή ‘=' ?
Βλέπουμε ότι το μέχρι τώρα σύμβολο της ισότητας που είχαμε γνωρίσει από τα μαθηματικά, σημαίνει κάτι άλλο στην Python. Πιο συγκεκριμένα, πρόκειται για τον τελεστή ανάθεσης, για να δώσουμε μια τιμή σε μια μεταβλητή.
Αντίθετα ο τελεστής της ισότητας είναι το διπλό ίσον. Αυτή η μικρή διαφορά προκαλεί μια σύγχυση και γίνεται συχνά αιτία λαθών μέχρι να εξοικειωθούμε με τα σύμβολα, οπότε καλό είναι να την έχουμε κατά νου όταν ερχόμαστε αντιμέτωποι με κάποιο error.
Λογικοί τελεστές (Boolean)
Υπάρχουν τρεις τελεστές Boolean: οι and, or, και not, οι οποίοι χρησιμοποιούνται για να συγκρίνουν τιμές Boolean. Κατ’ αντιστοιχία με τους τελεστές σύγκρισης, εκτιμούν τις εκφράσεις σε ένα τελικό Boolean αποτέλεσμα.
And
Το and πάντοτε παίρνει δύο τιμές ή εκφράσεις Boolean και επιτρέφει True μόνον αν είναι και οι δύο αληθείς.
Or
Το or από την άλλη θα μας δώσει True, αρκεί μία τουλάχιστον από τις δύο τιμές να είναι αληθής.
Not
To not, τέλος, είναι το μόνο που λειτουργεί με μία τιμή ή έκφραση Boolean, δίνοντας απλώς την αντίθετή της τιμή. Όπως και στον ανθρώπινο λόγο μπορούμε να εκφράσουμε διπλή άρνηση, έτσι και στην Python μπορούμε να κάνουμε χρήση εμφωλευμένων not.
Μπορούμε εύκολα λοιπόν, να κάνουμε έναν πίνακα αληθείας για τα and, or, και not. Έναν πίνακα δηλαδή που περιέχει κάθε δυνατό αποτέλεσμα των τελεστών.
Μίξη λογικών και σύγκρισης
Εφόσον οι τελεστές σύγκρισης μας δίνουν ως αποτέλεσμα τιμές Boolean, μπορούμε να τους χρησιμοποιούμε σε εκφράσεις μαζί με λογικούς τελεστές.
Ο υπολογιστής θα υπολογίσει πρώτα την αριστερή έκφραση, έπειτα τη δεξιά, και τελικά τη συνολική έκφραση.
Στην Python υπάρχουν κανόνες για την προτεραιότητα κατά τον υπολογισμό των εκφράσεων, όπως και με τους μαθηματικούς τελεστές: πρώτα εκτιμώνται τα not, κατόπιν τα and, και τελευταία τα or.
Εξυπακούεται ότι, αν θέλουμε, βάζουμε στην ίδια έκφραση μαζί με τους τελεστές σύγκρισης και περισσότερους από έναν Boolean.
Εκτέλεση προγράμματος
Στο πρόγραμμα του περασμένου μαθήματος, η Python εκτελούσε τις εντολές κατεβαίνοντας από την αρχή του προγράμματος μέχρι την τελευταία γραμμή. Με τον όρο εκτέλεση προγράμματος, αναφερόμαστε στην τρέχουσα εντολή η οποία εκτελείται.
Χρησιμοποιώντας, τώρα, στοιχεία ελέγχου της ροής του προγράμματος, μπορούμε να μεταφέρουμε την εκτέλεση σε άλλη εντολή (και όχι στην επόμενη), να επαναλάβουμε εντολές, ή να τις αποφεύγουμε εντελώς.
Έλεγχος ροής
Μια δήλωση ελέγχου ροής περιέχει συνήθως μια συνθήκη, η οποία ακολουθείται από κάποιο block κώδικα.
Συνθήκη
Οι εκφράσεις Boolean που έχουμε δει μέχρι τώρα θα μπορούσαν να αποτελέσουν συνθήκες. Είναι το ίδιο πράγμα με τις εκφράσεις, απλά χρησιμοποιούνται σε δηλώσεις ελέγχου ροής.
Οι συνθήκες επίσης υπολογίζονται σε μια τελική τιμή True ή False, και βάσει αυτής της τιμής ο μηχανισμός ελέγχου ροής θα αποφασίσει πώς θα ενεργήσει στο πρόγραμμα.
Block κώδικα
Οι γραμμές ενός κώδικα Python μπορούν να ομαδοποιηθούν σε block, τα οποία ξεχωρίζουν από την αριστερή τους στοίχιση.
Τα block:
- αρχίζουν εκεί που η αριστερή εσοχή αυξάνεται προς τα μέσα
- δύνανται να περιέχουν άλλα block
- τελειώνουν εκεί που η εσοχή επιστρέφει στην αρχική στοίχιση ή στη στοίχιση του block στο οποίο περιέχονται
Για να καταλάβουμε τι θεωρείται block, μπορούμε να δούμε τον παρακάτω κώδικα:
name = 'John' password = '135' if name == 'John': print('Hi John') if password == '135': print('Access granted.') else: print('Wrong password.')
Το πρώτο block ξεκινάει από την\ γραμμή με το:
print('Hi John')
και περιέχει όλες τις επόμενες γραμμές.
Εντός αυτού του block βρίσκεται ένα άλλο με μία μόνο γραμμή, το:
print('Access granted')
Τέλος, υπάρχει ένα τρίτο block, επίσης μίας μόνο γραμμής, το:
print('Wrong password.')
If
Ο πιο κοινός τύπος ελέγχου ροής είναι η δήλωση if. Αν ισχύει η συνθήκη της, θα εκτελεστεί μια ομάδα εντολών. Ειδάλλως, το πρόγραμμα θα συνεχιστεί χωρίς την εκτέλεσή τους. Θα μπορούσαμε να διαβάσουμε: “Αν (if) ισχύει η συνθήκη, τότε εκτέλεσε αυτόν τον κώδικα.”
Σύνταξη:
- η λέξη – κλειδί if
- μία συνθήκη
- άνω κάτω τελεία
- στην επόμενη γραμμή και σε δεξιότερη στοίχιση ένα block κώδικα
Έστω, για παράδειγμα, ότι θέλουμε να ελέγξουμε αν μια μεταβλητή ισούται με 10, προκειμένου να εκτυπώσουμε το ανάλογο μήνυμα. Θα γράψουμε:
if var == 10: print('The variable equals 10.')
Else
Προαιρετικά, ένα if μπορεί να ακολουθείται από μια δήλωση else, η οποία εκτελείται αν η συνθήκη του if είναι ψευδής. Θα την διαβάζαμε κάπως έτσι: “Αν (if) ισχύει η συνθήκη, τότε εκτέλεσε αυτόν τον κώδικα. Αλλιώς (else) εκτέλεσε αυτόν τον κώδικα”
Σύνταξη:
- η λέξη – κλειδί else
- άνω κάτω τελεία
- στην επόμενη γραμμή και σε δεξιότερη στοίχιση ένα block κώδικα
if var == 10: print('The variable equals 10.'’) else: print('The variable does not equal 10')
Elif
Αν θέλουμε να ελέγξουμε πάνω από μία συνθήκες, θα καταφύγουμε σε μια δήλωση elif.
Σύνταξη:
- η λέξη – κλειδί elif
- άνω κάτω τελεία
- στην επόμενη γραμμή και σε δεξιότερη στοίχιση ένα block κώδικα
if var == 10: print('The variable equals 10.') elif var == 20: print('The variable equals 20.')
Mπορούμε επίσης να εξαλείψουμε την πιθανότητα να χάσουμε κάποιο αποτέλεσμα, χρησιμοποιώντας στο τέλος των elif δηλώσεων και μία else, για κάθε άλλη περίπτωση που δεν συμπεριλάβαμε.
While
Για να κάνουμε ένα block κώδικα να εκτελείται πάνω από μία φορές, μπορούμε να χρησιμοποιήσουμε μία δήλωση while (τον λεγόμενο βρόχο του while). Ο κώδικας που περιλαμβάνει το while θα εκτελείται όσο η συνθήκη του είναι αληθής.
Σύνταξη:
- η λέξη – κλειδί while
- μία συνθήκη
- άνω κάτω τελεία
- στην επόμενη γραμμή και σε δεξιότερη στοίχιση ένα block κώδικα
Το while θυμίζει αρκετά ένα if, με τη διαφορά ότι στο if το πρόγραμμα θα συνεχίσει την εκτέλεσή του με την επόμενη εντολή, ενώ στο while θα επιστρέψει στην αρχική εντολή του block. Γι’ αυτόν τον λόγο, χρησιμοποιούμε και μια μεταβλητή i, την οποία αυξάνουμε μέχρι η συνθήκη του while να πάψει να είναι αληθής για να βγούμε από τον βρόχο.
i = 0 while i < 3: print ('Hello') i = i +1
Break
Υπάρχει η περίπτωση να επιθυμούμε να σταματήσει η εκτέλεση του βρόχου, αν επαληθευτεί κάποιο κριτήριο πέρα από την αρχική συνθήκη. Για τον σκοπό αυτόν υπάρχει η δήλωση break, η οποία απευθείας βγάζει την εκτέλεση του προγράμματος από τον βρόχο.
Ας πάρουμε για παράδειγμα το παρακάτω while:
while True: print('Give the password.') password = input() if password == 's.a.g.a.p.o.': break print('password accepted')
Με την πρώτη γραμμή δημιουργείται ένας ατέρμων βρόχος: ένα while loop με συνθήκη μονίμως αληθή. Αν δεν υπήρχε το break που σταματάει την εκτέλεση μόλις δοθεί ο ορθός κωδικός, το block αυτό θα εκτελούνταν για άπειρες επαναλήψεις.
Σημείωση: Αν βρεθούμε ποτέ από λάθος μας σε έναν ατέρμονα βρόχο, μπορούμε να τον σταματήσουμε πατώντας CTRL + C. Αυτό θα στείλει ένα KeyboardInterrupt error στο πρόγραμμά μας και θα το κάνει να σταματήσει.
Εναλλακτικά στον IDLE, μπορούμε να επιλέξουμε Shell > Restart Shell από το μενού.
Continue
Όπως και το break, το continue χρησιμοποιείται μέσα σε βρόχους. Μόλις η εκτέλεση του προγράμματος βρει ένα continue, μεταφέρεται κατευθείαν στην αρχή του βρόχου και υπολογίζει ξανά τη συνθήκη του βρόχου. Όπως δηλαδή θα συνέβαινε αν έφτανε στο τέλος του βρόχου.
while True: print('Who are you?') name = input() if name != 'Marika': continue print('Hello, Marika. Give the password') password = input() if password == '135': break print('Access granted.')
Αν ο χρήστης εισάγει οποιοδήποτε άλλο όνομα εκτός από το Marika, το continue προκαλεί τη μεταφορά της εκτέλεσης του προγράμματος στην αρχή του while. Εκεί γίνεται ξανά εκτίμηση της συνθήκης, η οποία είναι πάντα True, οπότε η εκτέλεση θα εισέρχεται πάντα στον βρόχο μέχρι να δοθεί το σωστό όνομα.
Έπειτα ζητείται ο κωδικός. Αν είναι λανθασμένος, οδηγούμαστε στο τέλος του βρόχου, και από εκεί ξανά στην αρχή του για άλλη μία επανάληψη. Αν είναι σωστός, θα πάμε στο break και άρα θα εξέλθουμε από τον βρόχο, στο print(‘Access granted’).
Σημείωση: Υπάρχουν και άλλες τιμές, οι οποίες όταν χρησιμοποιηθούν εντός μιας συνθήκης θεωρούνται ισοδύναμες των True και False: Το 0, το 0.0, και το ‘ ‘(κενό string) θεωρούνται False, ενώ όλες οι άλλες τιμές (πχ το 1) θεωρούνται True.
For και range()
Ο βρόχος του while εκτελείται όσο η συνθήκη είναι αληθής. Αν θέλουμε όμως ένα block κώδικα να εκτελεστεί για έναν ορισμένο αριθμό επαναλήψεων, θα το κάνουμε με έναν βρόχο for και την συνάρτηση range().
Σύνταξη:
- η λέξη – κλειδί for
- μία μεταβλητή
- η λέξη – κλειδί in
- κλήση της συνάρτησης range() με έως και τρεις ακεραίους για ορίσματα
- άνω κάτω τελεία
- στην επόμενη γραμμή και σε δεξιότερη στοίχιση, ένα block κώδικα
Ας δούμε ένα παράδειγμα με το πρόγραμμα sum.py, που υπολογίζει το άθροισμα όλων των ακεραίων από το 1 έως το 100:
sum= 0 for i in range(101): sum = sum + i print(i, sum) #prints to check “i” and “sum” in each iteration print('Final sum is', sum)
Την πρώτη φορά που τρέχει ο βρόχος, η μεταβλητή i λαμβάνει την τιμή 0 και το print θα τυπώσει ένα 0. Στη συνέχεια θα λάβει διαδοχικά τις τιμές 1, 2, 3, …, 100.
Βλέπουμε λοιπόν ότι η range() δίνει στη σειρά εκατό τιμές στην i, όσες καθορίζει ο ακέραιος που της έχουμε περάσει ως όρισμα, ξεκινώντας όμως από το 0 και φτάνοντας μέχρι τον αμέσως προηγούμενο ακέραιο.(0-100)
Μπορούμε να καλέσουμε τη συνάρτηση range() με παραπάνω από ένα ορίσματα, χωρίζοντάς τα με κόμμα. Αυτό μας επιτρέπει να ρυθμίσουμε την αλληλουχία των ακεραίων που θα ακολουθήσει η range().
Βάζοντας δύο ορίσματα, θα ξεκινήσει από όποιον αριθμό θέλουμε, αντί του 0 που είναι από προεπιλογή. Για παράδειγμα ο παρακάτω κώδικας:
for i in range(15, 20): print(i)
θα τυπώσει:
Με τρία ορίσματα, καθορίζουμε τόσο από πού ξεκινάει και πού καταλήγει (με τους δύο πρώτους αριθμού), όσο και το βήμα, δηλαδή πόσο θα αυξάνεται η μεταβλητή σε κάθε επανάληψη. Έτσι ο παρακάτω κώδικας…
for i in range(10, 0, -2): print(i)
…θα περάσει από το 10 μέχρι το 0 (χωρίς να το συμπεριλάβει), μειούμενο κατά 2:
Εισαγωγή Modules
Σε κάθε πρόγραμμα μπορούμε να καλέσουμε κάποιες βασικές συναρτήσεις που μας δίνει η Python έτοιμες. Μια τέτοια είναι και η print(), που έχουμε ήδη δει. Ωστόσο, υπάρχουν αμέτρητες ακόμα τέτοιες συναρτήσεις, τις οποίες μας παρέχει η Python πακεταρισμένες σε διάφορα modules.
Τα modules (αρθρώματα) συλλέγουν συναρτήσεις, συναφείς μεταξύ τους, και μας τις δίνουν έτοιμες για χρήση.
Τυπικά παραδείγματα αποτελούν το module math, που περιέχει μαθηματικές συναρτήσεις, και το random που έχει συναρτήσεις σχετικές με τυχαίους αριθμούς. Περί συναρτήσεων θα μιλήσουμε πιο αναλυτικά σε επόμενο μάθημα.
Για να χρησιμοποιήσουμε λοιπόν μια τέτοια έτοιμη συνάρτηση ενός module, θα πρέπει πρώτα να εισάγουμε το συγκεκριμένο module στον κώδικά μας, κάτι που γίνεται με μια δήλωση import. Η δήλωση συνίσταται στο “import”, ακολουθούμενο από το όνομα ενός module ή περισσότερων, χωριζόμενων με κόμμα.
Μπορούμε κατόπιν, να χρησιμοποιήσουμε τη συνάρτηση του module της αρεσκείας μας. Για παράδειγμα:
import random for i in range(5): print(random.randint(1,10))
Με τη συνάρτηση randint() του module random εκτυπώσαμε πέντε τυχαίους αριθμούς, επιλέγοντας από τους 1 έως και 10.
Παράδειγμα Προγράμματος
Την περασμένη εβδομάδα είχαμε πει ότι θα δούμε μια προσομοίωση ρίψεων ζαριού.
Έχοντας κατά νου τις έννοιες που είδαμε σήμερα, το πρόγραμμα αποδεικνύεται ιδιαίτερα απλό.
Αρχικά εισάγουμε το module “random”, που θα μας επιτρέψει να κάνουμε κατόπιν χρήση της συνάρτησης randint(). Η repeat θα λειτουργήσει ως η συνθήκη ελέγχου του βρόχου, και αρχικοποιείται με True για να ξεκινήσουν οι επαναλήψεις.
Το πρώτο print() τυπώνει ένα μήνυμα, και μαζί τον τυχαίο αριθμό που παρήγαγε η randint() μεταξύ 1 και 6 (όσοι και οι αριθμοί ενός ζαριού).
Με το δεύτερο print() ο χρήστης καλείται να πληκτρολογήσει “Y” ή “Ν” και η επιλογή του περνάει μέσω της input().
Τώρα, αν το ‘Υ’ υπάρχει στα όσα πληκτρολόγησε ο χρήστης, τότε η repeat αξιολογεί την έκφραση ως True και στέλνει την εκτέλεση του προγράμματος στην αρχή του βρόχου.
Αλλιώς, η repeat γίνεται False και το πρόγραμμα τελειώνει.
Θα μπορούσαμε ίσως να βελτιώσουμε τον κώδικά μας με κάποιον τρόπο?
Μετά από μερικές δοκιμές διαπιστώνουμε ότι, αν ο χρήστης πατήσει μικρό “y”, το πρόγραμμα θα σταματήσει την εκτέλεσή του. Αυτό συμβαίνει γιατί το repeat συγκρίνει το input() του χρήστη μόνον με τον χαρακτήρα “Y”.
Μπορούμε λοιπόν, αν και δεν είναι απαραίτητο, να συμπεριλάβουμε με ένα “or” και την λέξη “yes”, καθώς και να χρησιμοποιήσουμε άλλη μια συνάρτηση μαζί με την input(), την upper(). Tο συντακτικό της είναι:
word = input("Please Enter a word:").upper() # or lower()
Εκείνο που κάνει είναι να μετατρέπει οποιοδήποτε input του χρήστη άμεσα σε κεφαλαία.
Έτσι, είτε περάσει μικρό είτε κεφαλαίο “y” ο χρήστης, αυτό θα καταλήξει ως κεφαλαίο στον έλεγχο που πραγματοποιεί το repeat.
Βλέπουμε μάλιστα ότι το πρόγραμμα καταλαβαίνει ως “Y” οτιδήποτε εισάγει ο χρήστης και περιέχει τον χαρακτήρα “y”, όπως πχ το “yeah”.
Γράφοντας το πρόγραμμα όμως, θεωρούμε εύλογο ο χρήστης που δεν επιθυμεί άλλη ζαριά να επιλέξει γράμμα ή λέξη που δεν περιέχει το “y”. Η Python σε κάθε περίπτωση θα κάνει ακριβώς αυτό που έχουμε γράψει στην εντολή.
Στο επόμενο μάθημα για τον προγραμματισμό Python
Θα δούμε λίγο πιο αναλυτικά τις συναρτήσεις, μια έννοια που αναφέραμε συχνά στα μαθήματά μας μέχρι τώρα, και θα φτιάξουμε ακόμα ένα, λίγο πιο διαδραστικό πρόγραμμα προσομοίωσης ενός παιχνιδιού.
Σας άρεσε το σημερινό μάθημα για τον προγραμματισμό Python?
Το μάθημα σήμερα είχε αρκετή θεωρία, κάτι που δεν μπορούμε να αποφύγουμε πριν δούμε τις εντολές που μας ενδιαφέρουν στην πράξη. Αν σας γεννήθηκε οποιαδήποτε απορία ή αντιμετωπίσατε κάποιο πρόβλημα, γράψτε μας στα σχόλια.
Για να δείτε όλα τα μαθήματα Python από την αρχή τους, αλλά και τα επόμενα, αρκεί να κάνετε κλικ εδώ.