Τμήμα Μαθηματικών

Πληροφορική Ι

Εβδομάδα 3 · Λογικοί Τελεστές και η Εντολή If

(Οδηγίες χρήσης του διαδραστικού κώδικα: δείτε την αρχική σελίδα.)

1 Λογικοί Τελεστές και η Εντολή If

1.1 Λογικές εκφράσεις

Οι λογικές (Boolean) εκφράσεις σχηματίζονται με σχεσιακούς τελεστές, που ελέγχουν κάποια σχέση ανάμεσα σε δύο τιμές:

Μαθηματικά Python
\(=\) ==
\(<\) <
\(\le\) <=
\(>\) >
\(\ge\) >=
\(\neq\) !=

Το αποτέλεσμα μιας σύγκρισης είναι τύπου bool, με τιμές True ή False:

Οι λογικές εκφράσεις συνδυάζονται με τους λογικούς τελεστές and (σύζευξη), or (διάζευξη) και not (άρνηση):

Οι and/or λειτουργούν με short-circuit: αν το αποτέλεσμα μπορεί να προσδιοριστεί από την πρώτη λογική έκφραση, η δεύτερη δεν υπολογίζεται καν (π.χ. αν το πρώτο μέλος ενός and είναι False, το αποτέλεσμα είναι σίγουρα False).

Ένα συνηθισμένο λάθος. Για να ελέγξουμε ότι το x δεν ισούται ούτε με 2 ούτε με 3: το x != 2 or x != 3 είναι πάντα True (λάθος!) — το σωστό είναι x != 2 and x != 3.

Τέλος, η Python επιτρέπει αλυσιδωτές συγκρίσεις: το \(0 \le x < 1\) γράφεται απευθείας 0 <= x < 1, χωρίς and:

Οι τιμές True και False

Οι δύο λογικές τιμές είναι στην πραγματικότητα ειδικοί ακέραιοι: το True “είναι” 1 και το False “είναι” 0.

Έτσι μπορούν να μπουν και σε αριθμητικές πράξεις, κάτι απρόσμενα χρήσιμο όταν θέλουμε να μετρήσουμε πόσες συνθήκες ισχύουν:

Κάθε τιμή είναι “αληθής” ή “ψευδής”

Δεν είναι μόνο ο τύπος bool που μπορεί να παίξει ρόλο συνθήκης — κάθε τιμή της Python έχει μια λογική ερμηνεία:

  • θεωρούνται ψευδείς (False) το 0, το 0.0, η κενή συμβολοσειρά '' και το None
  • οτιδήποτε άλλο θεωρείται αληθές (True)

Το βλέπουμε ρητά με τη συνάρτηση bool(...):

Οι and / or επιστρέφουν τιμή, όχι μόνο True/False

Ένα λιγότερο γνωστό στοιχείο: οι and και or επιστρέφουν ένα από τα δύο ορίσματά τους — αυτό που καθόρισε το αποτέλεσμα — και όχι απαραίτητα ένα καθαρό True/False:

Αυτό, μαζί με το short-circuit, μας προστατεύει και από σφάλματα: αν το αριστερό μέλος ενός and είναι ψευδές, το δεξί δεν αποτιμάται καθόλου.

1.2 Η εντολή if

Η if επιτρέπει σε ένα πρόγραμμα να ακολουθήσει διαφορετική διαδρομή ανάλογα με μια συνθήκη:

if συνθήκη:
    εντολές               # εκτελείται μόνο αν η συνθήκη είναι True
elif άλλη_συνθήκη:
    εντολές               # εκτελείται αν η προηγούμενη ήταν False και αυτή True
else:
    εντολές               # εκτελείται αν όλες οι παραπάνω συνθήκες είναι False

Το elif και το else είναι προαιρετικά, και μπορούν να υπάρχουν όσα elif χρειάζονται.

Στην Python, τα όρια ενός μπλοκ κώδικα δεν δηλώνονται με άγκιστρα, αλλά με τη στοίχιση (indentation): η ίδια στήλη έναρξης σηματοδοτεί το ίδιο μπλοκ.

Αφού μια συνθήκη αποτιμάται ήδη σε True/False, μια μεταβλητή τύπου bool μπορεί να χρησιμοποιηθεί απευθείας ως συνθήκη, χωρίς ρητή σύγκριση.

Δηλαδή:

  • το if test: είναι ισοδύναμο με το if test == True:
  • το if not test: είναι ισοδύναμο με το if test == False:

Η σκέτη μορφή είναι και η προτιμώμενη — το == True είναι περιττό.

Οι συμβολοσειρές (Εβδομάδα 2) συγκρίνονται με τους ίδιους σχεσιακούς τελεστές. Το ==/!= ελέγχει ταύτιση· το <, <=, >, >= συγκρίνει λεξικογραφικά — χαρακτήρα προς χαρακτήρα, με βάση τον κωδικό ASCII/Unicode, μέχρι την πρώτη διαφορά (ή μέχρι το τέλος της κοντύτερης, αν η μία είναι πρόθεμα της άλλης):

Το τελευταίο παράδειγμα είναι μια συνηθισμένη “παγίδα”: στον πίνακα ASCII/Unicode, όλα τα κεφαλαία γράμματα (A-Z) έχουν μικρότερο κωδικό από όλα τα πεζά (a-z).

Άρα η λεξικογραφική σύγκριση δεν συμπίπτει πάντα με την αλφαβητική σειρά που θα περιμέναμε, όταν τα δύο strings δεν έχουν το ίδιο “κεφαλαίο/πεζό” προφίλ.

1.3 Χαρακτηριστικό της Python: δεσμευμένη έκφραση if (conditional expression)

Όταν το μόνο που θέλουμε είναι να επιλέξουμε μία από δύο τιμές ανάλογα με μια συνθήκη, η πλήρης if/else με τα μπλοκ της είναι μερικές φορές υπερβολική. Η Python προσφέρει μια συνοπτική δεσμευμένη έκφραση if (γνωστή και ως ternary expression), που επιστρέφει μία τιμή ή την άλλη μέσα σε μία μόνο γραμμή:

τιμή_αν_αληθές if συνθήκη else τιμή_αν_ψευδές

Ένα συγγενικό ιδίωμα χρησιμοποιεί τον τελεστή or για να δώσει μια προεπιλεγμένη τιμή όταν μια μεταβλητή είναι “κενή” (π.χ. κενή συμβολοσειρά, 0, ή None — τιμές που η Python θεωρεί False όταν χρησιμοποιούνται ως συνθήκη):

Και οι δύο εκδοχές είναι πιο συνοπτικές από μια πλήρη if, αλλά χρησιμοποιήστε τις με μέτρο: για πολύπλοκη λογική, μια κανονική if/elif/else παραμένει πιο ευανάγνωστη.

1.4 Επίλυση δευτεροβάθμιας εξίσωσης

Θέλουμε να υπολογίσουμε τις (πραγματικές) ρίζες μιας δευτεροβάθμιας εξίσωσης

\[ a x^2 + b x + c = 0, \qquad a \neq 0, \]

χρησιμοποιώντας τον γνωστό τύπο

\[ x_{1,2} = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}. \]

Η διακρίνουσα \(\Delta = b^2 - 4ac\) καθορίζει πόσες πραγματικές ρίζες υπάρχουν:

  • δύο, αν \(\Delta > 0\)·
  • μία (διπλή), αν \(\Delta = 0\)·
  • καμία, αν \(\Delta < 0\) — η τετραγωνική ρίζα αρνητικού δεν ορίζεται στους πραγματικούς.

Τώρα που έχουμε την if, μπορούμε επιτέλους να χειριστούμε σωστά και τις τρεις περιπτώσεις, αντί να υποθέτουμε ότι \(\Delta \ge 0\). (Δεν έχουμε δει ακόμα συναρτήσεις, οπότε δοκιμάζουμε τρεις τριάδες a, b, c γράφοντας τον ίδιο κώδικα τρεις φορές στο ίδιο κελί.)

Δοκιμάστε τους δικούς σας συντελεστές a, b, c παραπάνω. Σε αντίθεση με πριν, ο κώδικας δεν σκάει ποτέ με σφάλμα: για κάθε δυνατή είσοδο, η if/elif/else εξασφαλίζει ότι εκτελείται ακριβώς η σωστή διαδρομή.

2 Σύνοψη

Σε αυτή την εβδομάδα είδαμε:

  • Σχεσιακούς και λογικούς τελεστές (==, <, and, or, not), short-circuit αποτίμηση, και αλυσιδωτές συγκρίσεις.
  • Ότι True/False είναι ειδικοί ακέραιοι, και ότι κάθε τιμή είναι truthy ή falsy (bool(...)).
  • Την εντολή if/elif/else, και τη λεξικογραφική σύγκριση συμβολοσειρών.
  • Τη δεσμευμένη έκφραση if (x if συνθήκη else y) και το ιδίωμα or για προεπιλεγμένες τιμές.

⤺ Πίσω στην αρχική σελίδα / πρόγραμμα μαθήματος  ·  Διαφάνειες αυτής της εβδομάδας