Μια λογική έκφραση είναι μια παράσταση, η τιμή της οποίας είναι είτε αληθής/true είτε ψευδής/false. Τα επόμενα παραδείγματα χρησιμοποιούν τον τελεστή ==
, ο οποίος συγκρίνει δύο τελεστέους και επιστρέφει True
αν είναι ίσοι και False
σε διαφορετική περίπτωση:
>>> 5 == 5
True
>>> 5 == 6
False
True
και False
είναι ειδικές τιμές που ανήκουν στην κλάση bool
, δεν είναι συμβολοσειρές:
>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>
Ο τελεστής ==
είναι ένας από τους συγκριτικούς τελεστές, οι υπόλοιποι είναι:
x != y # το x δεν είναι ίσο με το y
x > y # το x είναι μεγαλύτεο του y
x < y # το x είναι μικρότερο του y
x >= y # το x είναι μεγαλύτερο ή ίσο του y
x <= y # το x είναι μικρότερο ή ίσο του y
x is y # το x είναι ίδιο με το y
x is not y # το x δεν είναι ίδιο με το y
Αν και αυτές οι πράξεις σας είναι πιθανώς γνωστές, τα σύμβολα της Python διαφέρουν από τα αντίστοιχα μαθηματικά σύμβολα. Ένα συνηθισμένο λάθος είναι το να χρησιμοποιήσετε ένα μόνο σύμβολο ίσου (=
) αντί για ένα διπλό ίσο (==
). Θυμηθείτε ότι το =
είναι τελεστής εκχώρησης τιμής και το ==
είναι τελεστής σύγκρισης. Δεν έχουν νόημα τα =<
ή =>
.
Υπάρχουν τρεις λογικοί τελεστές: and
, or
και not
. Η σημασιολογία (έννοια) αυτών των τελεστών είναι παρόμοια με τη σημασία τους στα αγγλικά (και, ή και όχι αντίστοιχα). Για παράδειγμα το
x > 0 and x < 10
είναι αληθές μόνο αν το x
είναι μεγαλύτερο του 0 και μικρότερο του 10.
Το n%2 == 0 or n%3 == 0
είναι αληθές αν τουλάχιστον μία από τις συνθήκες είναι αληθής, δηλαδή αν ο αριθμός διαιρείτεαι με το 2 ή το 3.
Τέλος, ο τελεστής not
είναι η άρνηση μιας λογικής έκφρασης, έτσι το not (x > y)
είναι αληθές αν το x > y
είναι ψευδές, δηλαδή αν το x
είναι μικρότερο ή ίσο του y
.
Αυστηρά μιλώντας, οι τελεστέοι των λογικών τελεστών πρέπει να είναι λογικές εκφράσεις, αλλά η Python δεν είναι πολύ αυστηρή. Κάθε μη μηδενικός αριθμός ερμηνεύεται ως “αληθές”.
>>> 17 and True
True
Αυτή η ευελιξία μπορεί να είναι χρήσιμη, αλλά υπάρχουν κάποιες λεπτόμέρειες σε αυτό, που μπορεί να προκαλέσουν σύγχυση. Ίσως θα ήταν καλύτερα να το αποφύγετε μέχρι να είστε σίγουροι ότι ξέρετε τι κάνετε.
Για να γράψουμε χρήσιμα προγράμματα, χρειαζόμαστε σχεδόν πάντα τη δυνατότητα να ελέγξουμε τις συνθήκες και να αλλάξουμε ανάλογα τη συμπεριφορά του προγράμματος. Οι εντολές επιλογής μας δίνουν αυτή τη δυνατότητα. Η πιο απλή μορφή τους είναι η εντολή if
:
if x > 0 :
print('το x είναι θετικό')
Η λογική έκφραση που ακοουθεί την εντολή if
ονομάζεται συνθήκη. Τελειώνουμε την γραμμή της εντολής if
με τον χαρακτήρα άνω κάτω τελεία (:) και στη γραμμή(ές) μετά το if δημιουργούμε εσοχή.
Εάν η λογική συνθήκη είναι αληθής, τότε οι εντολές με εσοχή εκτελούνται. Εάν η λογική συνθήκη είναι ψευδής, οι εντολές με εσοχή παραλείπονται.
Η εντολή if
έχει την ίδια δομή με τους ορισμούς συνάρτησης ή τους βρόχους for
1. Η εντολή αποτελείται από μια γραμμή κεφαλίδας που τελειώνει με τνν άνω και κάτω τελεία (:) ακολουθούμενη από ένα μπλοκ εντολών με εσοχή. Τέτοιες εντολές ονομάζονται σύνθετες εντολές επειδή εκτείνονται σε περισσότερες από μία γραμμές.
Δεν υπάρχει όριο στον αριθμό των εντολών που μπορούν να εμφανιστούν στο μπλοκ των εντολών, αλλά πρέπει να υπάρχει τουλάχιστον μία. Περιστασιακά, είναι χρήσιμο να έχετε ένα μπλοκ χωρίς εντολές (συνήθως ως δέσμευση θέσης για κάποιον κώδικα, που δεν έχετε γράψει ακόμα). Σε αυτή την περίπτωση, μπορείτε να χρησιμοποιήσετε τη εντολή pass
, η οποία δεν κάνει τίποτα.
if x < 0 :
pass # πρέπει να χειριστώ τις αρνητικές τιμές!
Εάν εισαγάγετε μια εντολή if
στον διερμηνέα της Python, η προτροπή θα αλλάξει από >>>
σε τρεις τελείες για να υποδείξει ότι βρίσκεστε στη μέση ενός μπλοκ δηλώσεων, όπως φαίνεται παρακάτω:
>>> x = 3
>>> if x < 10:
... print('Μικρό')
...
Μικρό
>>>
Όταν χρησιμοποιείτε τον διερμηνέα της Python, πρέπει να αφήσετε μια κενή γραμμή στο τέλος του μπλοκ, διαφορετικά η Python θα επιστρέψει σφάλμα:
>>> x = 3
>>> if x < 10:
... print('Μικρό')
... print('Τέλος')
File "<stdin>", line 3
print('Τέλος')
^
SyntaxError: invalid syntax
Η κενή γραμμή στο τέλος ενός μπλοκ δηλώσεων δεν είναι απαραίτητη όταν γράφετε και εκτελείτε σενάριο, μπορεί όμως να βελτιώσει την αναγνωσιμότητα του κώδικα σας.
Η δεύτερη μορφή της εντολής if
είναι η σύνθετη επιλογή, στην οποία υπάρχουν δύο περιπτώσεις και η συνθήκη καθορίζει ποια θα εκτελεστεί. Η σύνταξη μοιάζει με αυτήν:
if x%2 == 0 :
print('το x είναι άρτιος')
else :
print('το x είναι περιττός')
Εάν το υπόλοιπο, όταν το x
διαιρεθεί με το 2 είναι 0, τότε ξέρουμε ότι το x
είναι άρτιος και το πρόγραμμα εμφανίζει σχετικό μήνυμα. Εάν η συνθήκη είναι ψευδής εκτελείτε το δεύτερο μπλοκ εντολών.
Δεδομένου ότι η συνθήκη πρέπει να είναι αληθής ή ψευδής, θα εκτελεστεί ακριβώς μία από τις εναλλακτικές περιπτώσεις. Οι εναλλακτικές περιπτώσεις ονομάζονται κλάδοι, επειδή αποτελούν διακλαδώσεις στη ροή εκτέλεσης.
Μερικές φορές υπάρχουν περισσότερες από δύο δυνατότητες και χρειαζόμαστε περισσότερους από δύο κλάδους. Ένας τρόπος για να εκφράσετε έναν τέτοιο υπολογισμό είναι μια πολλαπλή επιλογή:
if x < y:
print('το x είναι μικρότερο από το y')
elif x > y:
print('το x είναι μεγαλύτερο από το y')
else:
print('τα x και y είναι ίσα')
Το elif
είναι μια συντομογραφία του “else if”. Και πάλι, θα εκτελεστεί ακριβώς ένας κλάδος.
Δεν υπάρχει όριο στον αριθμό των δηλώσεων elif
. Εάν υπάρχει ο όρος else
, πρέπει να είναι στο τέλος, αλλά δεν είναι απαραίτητο να υπάρχει.
if choice == 'a':
print('Μάντεψες Λάθος')
elif choice == 'b':
print('Μάντεψες Σωστά')
elif choice == 'c':
print('Πλησίασες, αλλά όχι σωστό')
Κάθε συνθήκη ελέγχεται με τη σειρά. Εάν η πρώτη είναι ψευδής, ελέγχεται η επόμενη και ούτω καθεξής. Εάν μία από αυτές είναι αληθής, ο αντίστοιχος κλάδος εκτελείται και η εντολή τελειώνει. Ακόμα κι αν περισσότερες από μία συνθήκες είναι αληθείς, εκτελείται μόνο ο πρώτος αληθής κλάδος.
Μια εντολή επιλογής μπορεί να εμφωλευτεί σε άλλη. Θα μπορούσαμε να γράψουμε το παράδειγμα των τριών-κλάδων και έτσι:
if x == y:
print('τα x και y είναι ίσα')
else:
if x < y:
print('το x είναι μικρότερο από το y')
else:
print('το x είναι μεγαλύτερο από το y')
Η εξωτερική επιλογή περιέχει δύο κλάδους. Ο πρώτος κλάδος περιέχει μια απλή εντολή. Ο δεύτερος κλάδος περιέχει άλλη μια εντολή if
, η οποία έχει δύο δικούς της κλάδους. Αυτοί οι δύο κλάδοι περιέχουν και οι δύο απλές εντολές, αν και θα μπορούσαν να ήταν και νέες εντολές επιλογής.
Αν και η χρήση εσοχών καθιστά εμφανή τη δομή, οι εμφωλευμένες επιλογές είναι δύσκολο να διαβαστούν πολύ γρήγορα. Γενικά, είναι καλή ιδέα να τις αποφεύγετε όταν μπορείτε.
Οι λογικοί τελεστές παρέχουν συχνά έναν τρόπο απλοποίησης των εμφωλευμένων επιλογών. Για παράδειγμα, μπορούμε να ξαναγράψουμε τον ακόλουθο κώδικα χρησιμοποιώντας μία μόνο εντολή επιλογής:
if 0 < x:
if x < 10:
print('το x είναι ένας θετικός μονοψήφιος αριθμός.')
Η εντολή print
εκτελείται μόνο αν ικανοποιούνται και οι δύο συνθήκες, οπότε μπορούμε να έχουμε το ίδιο αποτέλεσμα χρησιμοποιώντας τον τελεστή and
:
if 0 < x and x < 10:
print('το x είναι ένας θετικός μονοψήφιος αριθμός.')
Νωρίτερα είδαμε ένα τμήμα κώδικα όπου χρησιμοποιήσαμε τις συναρτήσεις input
και int
για να διαβάσουμε και να αναλύσουμε έναν ακέραιο αριθμό που εισήγαγε ο χρήστης. Είδαμε επίσης πόσο εύκολα μπορεί να οδηγήσει σε σφάλματα:
>>> μήνυμα = "Με τί ταχύτητα πετάει ένα χελιδόνι;\n"
>>> ταχύτητα = input(μήνυμα)
Με τί ταχύτητα πετάει ένα χελιδόνι;
Τί εννοείς, ένα Αφρικανικό ή Ευρωπαϊκό χελιδόνι;
>>> int(ταχύτητα)
ValueError: invalid literal for int() with base 10:
>>>
Όταν εκτελούμε αυτές τις εντολές στον διερμηνέα της Python, λαμβάνουμε ένα νέο μήνυμα από τον διερμηνέα, σκεφτόμαστε “ωχ” και προχωράμε στην επόμενη εντολή μας.
Ωστόσο, εάν γράψετε αυτόν τον κώδικα σε ένα σενάριο Python και παρουσιαστεί αυτό το σφάλμα, το σενάριό σας σταματά αμέσως γιατί εντοπίζει το πρόβλημα με ιχνηλάτηση/traceback. Δεν εκτελεί την ακόλουθη πρόταση.
Ακολουθεί ένα δείγμα προγράμματος για τη μετατροπή θερμοκρασίας Φαρενάιτ σε θερμοκρασία Κελσίου:
inp = input('Εισαγάγετε τη θερμοκρασία Φαρενάιτ: ')
fahr = float(inp)
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)
# Code: http://www.py4e.com/code3/fahren.py
Εάν εκτελέσουμε αυτόν τον κώδικα και του δώσουμε μη έγκυρη είσοδο, απλώς αποτυγχάνει με ένα όχι και τόσο φιλικό μήνυμα σφάλματος:
python fahren.py
Εισαγάγετε τη θερμοκρασία Φαρενάιτ:72
22.22222222222222
python fahren.py
Εισαγάγετε τη θερμοκρασία Φαρενάιτ:fred
Traceback (most recent call last):
File "fahren.py", line 2, in <module>
fahr = float(inp)
ValueError: could not convert string to float: 'fred'
Υπάρχει μια δομή εκτέλεσης υπό όρους ενσωματωμένη στην Python για να χειρίζεται αυτούς τους τύπους αναμενόμενων και/ή απροσδόκητων σφαλμάτων που ονομάζονται “try / except”. Η βάση των try
και except
είναι ότι γνωρίζετε ότι κάποια ακολουθία οδηγιών μπορεί να προκαλέσει πρόβλημα και θέλετε να προσθέσετε ορισμένες προτάσεις που θα εκτελεστούν σε περίπτωση σφάλματος. Αυτές οι πρόσθετες προτάσεις (το μπλοκ except) αγνοούνται εάν δεν προκληθεί σφάλμα.
Μπορείτε να θεωρήσετε τη λειτουργία try
και except
στην Python ως μια «δικλείδα ασφαλείας» για μια ακολουθία εντολών.
Μπορούμε να ξαναγράψουμε τον μετατροπέα θερμοκρασίας μας ως εξής:
inp = input('Εισαγάγετε τη θερμοκρασία Φαρενάιτ:')
try:
fahr = float(inp)
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)
except:
print('Παρακαλώ εισάγετε έναν αριθμό')
# Code: http://www.py4e.com/code3/fahren2.py
Η Python ξεκινά εκτελώντας την ακολουθία εντολών που περιέχονται στο μπλοκ try
. Αν όλα πάνε καλά, παραλείπει το μπλοκ except
και προχωρά. Εάν προκύψει πρόβλημα στο μπλοκ try
, η Python βγαίνει από το μπλοκ try
και εκτελεί την ακολουθία εντολών του μπλοκ except
.
python fahren2.py
Εισαγάγετε τη θερμοκρασία Φαρενάιτ:72
22.22222222222222
python fahren2.py
Εισαγάγετε τη θερμοκρασία Φαρενάιτ:fred
Παρακαλώ εισάγετε έναν αριθμό
Η διαχείριση μιας εξαίρεσης με την εντολή try
ονομάζεται σύλληψη της εξαίρεσης. Σε αυτό το παράδειγμα, ο όρος except
εκτυπώνει ένα φιλικό μήνυμα σφάλματος. Σε γενικές γραμμές, η σύλληψη μιας εξαίρεσης σας δίνει την ευκαιρία να διορθώσετε το πρόβλημα ή να προσπαθήσετε ξανά ή τουλάχιστον να το πρόγραμμα τερματίσει χωρίς μήνυμα σφάλματος.
Όταν η Python επεξεργάζεται μια λογική έκφραση όπως η x >= 2 and (x/y) > 2
, αξιολογεί την έκφραση από αριστερά προς τα δεξιά. Λόγω του ορισμού του and
, αν το x
είναι μικρότερο του 2, η έκφραση x >= 2
είναι False
και έτσι συνολικά η έκφραση είναι False
ανεξάρτητα από το αν το (x/y) > 2
έχει ως αποτέλεσμα True
ή False
.
Όταν η Python διαπιστώσει ότι δεν θα να κερδίσει τίποτα με την αξιολόγηση της υπόλοιπης λογικής έκφρασης, σταματά την αξιολόγησή της και δεν κάνει τους υπολογισμούς στην υπόλοιπη λογική έκφραση. Όταν σταματήσει η αξιολόγηση μιας λογικής έκφρασης επειδή η συνολική τιμή είναι ήδη γνωστή, ονομάζεται short-circuiting/βραχυκύκλωμα της αξιολόγηση.
Ενώ αυτό μπορεί να φαίνεται σαν μια καλή τεχνική, η συμπεριφορά βραχυκυκλώματος οδηγεί σε μια εξυπνότερη τεχνική που ονομάζεται τιμή φρουρός/guardian pattern. Εξετάστε το ακόλουθο τμήμα κώδικα στον διερμηνέα της Python:
>>> x = 6
>>> y = 2
>>> x >= 2 and (x/y) > 2
True
>>> x = 1
>>> y = 0
>>> x >= 2 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and (x/y) > 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
Ο τρίτος υπολογισμός απέτυχε επειδή η Python αξιολόγησε το (x/y)
και το y
ήταν μηδέν, γεγονός που προκάλεσε σφάλμα χρόνου εκτέλεσης. Αλλά το πρώτο και το δεύτερο παράδειγμα δεν απέτυχαν, επειδή στον πρώτο υπολογισμό το y
ήταν μηδέν και στο δεύτερο, το πρώτο μέρος της έκφρασης, το x >= 2
αξιολογήθηκε ως False
οπότε το (x /y)
δεν εκτελέστηκε ποτέ λόγω του κανόνα short-circuiting και δεν προέκυψε σφάλμα.
Μπορούμε να κατασκευάσουμε τη λογική έκφραση με τέτοιο τρόπο ώστε να τοποθετήσουμε στρατηγικά έναν φύλακα αξιολόγηση, ακριβώς πριν από την αξιολόγηση που μπορεί να προκαλέσει σφάλμα ως εξής:
>>> x = 1
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x >= 2 and (x/y) > 2 and y != 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
Στην πρώτη λογική έκφραση, το x >= 2
είναι False
, έτσι η αξιολόγηση σταματά στο and
. Στη δεύτερη λογική έκφραση, το x >= 2
είναι True
αλλά το y != 0
είναι False
οπότε δεν φτάνουμε ποτέ στο (x/y)
.
Στην τρίτη λογική έκφραση, το y != 0
βρίσκεται μετά τον υπολογισμό (x/y)
έτσι η έκφραση αποτυγχάνει με συνέπεια ένα σφάλμα.
Στη δεύτερη έκφραση, λέμε ότι το y != 0
λειτουργεί ως φρουρός για να διασφαλίσει ότι εκτελούμε το (x/y)
μόνο αν το y
είναι μη μηδενικό.
Το traceback της Python εμφανίζεται όταν προκύψει ένα σφάλμα και περιέχει πολλές πληροφορίες, αλλά αυτές μπορεί να είναι υπερβολικές. Τα πιο χρήσιμα μέρη είναι συνήθως τα:
Τι είδους λάθος ήταν και
Πού συνέβη.
Τα σφάλματα σύνταξης είναι συνήθως εύκολο να βρεθούν, αλλά υπάρχουν μερικές παγίδες. Τα σφάλματα στους λευκούς χαρακτήρες μπορεί να είναι δύσκολα επειδή τα κενά και τα tab είναι αόρατα και έχουμε συνηθίσει να τα αγνοούμε.
>>> x = 5
>>> y = 6
File "<stdin>", line 1
y = 6
^
IndentationError: unexpected indent
Σε αυτό το παράδειγμα, το πρόβλημα είναι ότι στη δεύτερη γραμμή έχει δημιουργηθεί εσοχή ενός διαστήματος. Αλλά το μήνυμα σφάλματος δείχνει το y
, το οποίο είναι παραπλανητικό. Σε γενικές γραμμές, τα μηνύματα σφάλματος υποδεικνύουν πού εντοπίστηκε το πρόβλημα, αλλά το πραγματικό σφάλμα μπορεί να είναι νωρίτερα στον κώδικα, μερικές φορές σε προηγούμενη γραμμή.
Σε γενικές γραμμές, τα μηνύματα σφάλματος σας λένε πού ανακαλύφθηκε το πρόβλημα, αλλά συχνά δεν προκλήθηκε εκεί.
True
είτε False
.
and
, or
και not
.
==
, !=
, >
, <
, >=
, and <=
.
Άσκηση 1: Ξαναγράψτε τον υπολογισμό της αμοιβής για να δώσετε στον υπάλληλο 1,5 φορές το ωρομίσθιο για τις ώρες εργασίας πέραν των 40 ωρών.
Δώστε Ώρες: 45
Δώστε Ποσό/Ώρα: 10
Μισθός: 475.0
Άσκηση 2: Ξαναγράψτε το πρόγραμμα πληρωμών χρησιμοποιώντας το try
και except
έτσι ώστε το πρόγραμμά σας να χειρίζεται μη αριθμητικές τιμές εισόδου σωστά, εκτυπώνοντας ένα μήνυμα και τερματίζοντας την εκτέλεση. Παρακάτω φαίνεται το αποτέλεσμα δύο εκτελέσεων του προγράμματος:
Δώστε Ώρες: 20
Δώστε Ποσό/Ώρα: εννιά
Σφάλμα, παρακαλώ δώστε αριθμητική είσοδο
Δώστε Ώρες: σαράντα
Σφάλμα, παρακαλώ δώστε αριθμητική είσοδο
**Άσκηση 3: Γράψτε ένα πρόγραμμα για να ζητήσετε βαθμολογία μεταξύ 0,0 και 1,0. Εάν η βαθμολογία είναι εκτός εμβέλειας, να εκτυπώνετε ένα μήνυμα σφάλματος. Εάν η βαθμολογία είναι μεταξύ 0.0 και 1.0, να εκτυπώνετε μια αξιολόγηση με βάση τον ακόλουθο πίνακα:
Βαθμός Αξιολόγηση
>= 0.9 A
>= 0.8 B
>= 0.7 C
>= 0.6 D
< 0.6 F
Εισάγετε βαθμολογία: 0.95
A
Εισάγετε βαθμολογία: τέλεια
Άκυρη βαθμολογία
Εισάγετε βαθμολογία: 10.0
Άκυρη βαθμολογία
Εισάγετε βαθμολογία: 0.75
C
Εισάγετε βαθμολογία: 0.5
F
Εκτελέστε το πρόγραμμα επανειλημμένα όπως φαίνεται παραπάνω για να το δοκιμάσετε για τις διαφορετικές τιμές εισόδου.
Θα μάθουμε για τις συναρτήσεις στο Κεφάλαιο 4 και τους βρόχους στο Κεφάλαιο 5.↩
Αν εντοπίσετε κάποιο λάθος σε αυτό το βιβλίο μην διστάσετε να μου στείλετε τη διόρθωση στο Github.