(Πηγή: Βιβλίο Μαθητή, Πληροφορική Γ΄ Γυμνασίου, §7.4 Άσκηση, σελ. 90 — τελευταία άσκηση του βιβλίου. Η εκφώνηση είναι αυτούσια από το σχολικό βιβλίο.)
Να δημιουργήσετε τα αντίστοιχα υποπρογράμματα για τα υπολογιστικά μοντέλα της επίλυσης εξισώσεων και της εκθετικής μετάδοσης του ιού. Ποιές παραμέτρους χρειάζεται κάθε υποπρόγραμμα;
Σκέψη / Μεθοδολογία: Πρόκειται να «τυλίξουμε» τα δύο προγράμματα των §7.2 και §7.3 μέσα σε δικά τους υποπρογράμματα (συναρτήσεις), ώστε να μπορούμε να τα ξανακαλέσουμε εύκολα με διαφορετικά δεδομένα, χωρίς να ξαναγράφουμε τον κώδικα. Το ερώτημα «ποιες παραμέτρους χρειάζεται» απαντιέται εντοπίζοντας ποια στοιχεία του κώδικα άλλαζαν από τη μία εκτέλεση/άσκηση στην άλλη μέσα στο κεφάλαιο: στο §7.2 άλλαζε η ίδια η εξίσωση (οι συντελεστές της)· στο §7.3 άλλαζε το πλήθος των ημερών και ο ρυθμός μετάδοσης (2 ή 4 άτομα).
Λύση:
1) Υποπρόγραμμα για την επίλυση εξίσωσης με εξαντλητική αναζήτηση (§7.2)
Το πρόγραμμα του βιβλίου έλεγχε πάντα μία συγκεκριμένη εξίσωση, γραμμένη «μέσα» στον κώδικα (π.χ. 10*x+5==105). Για να γίνει υποπρόγραμμα που να λύνει ΟΠΟΙΑΔΗΠΟΤΕ πολυωνυμική εξίσωση, η ίδια η εξίσωση πρέπει να γίνει παράμετρος. Περνάμε, λοιπόν, τη λίστα με τους συντελεστές του πολυωνύμου (από τον μεγαλύτερο βαθμό στον μικρότερο) και το εύρος αναζήτησης:
def λύση_εξίσωσης(συντελεστές, αρχή, τέλος):
λύσεις = []
for x in range(αρχή, τέλος + 1):
τιμή = 0
βαθμός = len(συντελεστές) - 1
for σ in συντελεστές:
τιμή += σ * (x ** βαθμός)
βαθμός -= 1
if τιμή == 0:
λύσεις.append(x)
return λύσεις
Παράμετροι που χρειάζεται:
Ελέγχοντας το υποπρόγραμμα με τις εξισώσεις του κεφαλαίου (εκτελέστηκε πραγματικά ο κώδικας):
| Κλήση | Αποτέλεσμα | Εξίσωση |
|---|---|---|
λύση_εξίσωσης([10, -100], 1, 1000000) |
[10] |
10x + 5 = 105 |
λύση_εξίσωσης([1, -5, 6], 1, 1000000) |
[2, 3] |
x² − 5x + 6 = 0 |
λύση_εξίσωσης([26, -260], 1, 1000000) |
[10] |
26x − 260 = 0 |
λύση_εξίσωσης([1, -9, 26, -24], 1, 1000000) |
[2, 3, 4] |
x³ − 9x² + 26x − 24 = 0 |
Όλα τα αποτελέσματα συμφωνούν με τις λύσεις που βρέθηκαν στο §7.2.
2) Υποπρόγραμμα για το μοντέλο εκθετικής μετάδοσης (§7.3)
Το πρόγραμμα του βιβλίου υπολόγιζε τα συνολικά κρούσματα για δεδομένο πλήθος ημερών, με σταθερό ρυθμό μετάδοσης 2. Στη νέα μετάλλαξη του κεφαλαίου ο ρυθμός γινόταν 4 — άρα κι αυτός πρέπει να γίνει παράμετρος:
def μοντέλο_μετάδοσης(ημέρες, ρυθμός_μετάδοσης):
ημερήσια_κρούσματα = 1
συνολικά_κρούσματα = 0
for i in range(ημέρες):
συνολικά_κρούσματα += ημερήσια_κρούσματα
ημερήσια_κρούσματα = ρυθμός_μετάδοσης * ημερήσια_κρούσματα
return συνολικά_κρούσματα
Παράμετροι που χρειάζεται:
Ελέγχοντας το υποπρόγραμμα (εκτελέστηκε πραγματικά ο κώδικας):
| Κλήση | Αποτέλεσμα |
|---|---|
μοντέλο_μετάδοσης(3, 2) |
7 |
μοντέλο_μετάδοσης(4, 2) |
15 |
μοντέλο_μετάδοσης(10, 2) |
1.023 |
μοντέλο_μετάδοσης(24, 2) |
16.777.215 |
μοντέλο_μετάδοσης(13, 4) |
22.369.621 |
μοντέλο_μετάδοσης(18, 4) |
22.906.492.245 |
Οι τιμές με ρυθμό 2 ταυτίζονται με τον πίνακα του §7.3, ενώ με ρυθμό 4 τα 10.000.000 κρούσματα ξεπερνιούνται ήδη στη 13η ημέρα (αντί για την 24η) και ο παγκόσμιος πληθυσμός «ξεπερνιέται» στην 18η ημέρα — ίδιοι αριθμοί με όσους συζητήθηκαν στη θεωρία.
Απάντηση: Χρειαζόμαστε δύο υποπρογράμματα: (1) λύση_εξίσωσης(συντελεστές, αρχή, τέλος) — λύνει με εξαντλητική αναζήτηση οποιαδήποτε πολυωνυμική εξίσωση, με παραμέτρους τους συντελεστές της εξίσωσης και το εύρος αναζήτησης· (2) μοντέλο_μετάδοσης(ημέρες, ρυθμός_μετάδοσης) — υπολογίζει τα συνολικά κρούσματα εκθετικής μετάδοσης, με παραμέτρους το πλήθος των ημερών και τον ρυθμό μετάδοσης. Και στα δύο υποπρογράμματα, οι παράμετροι είναι ακριβώς τα στοιχεία που άλλαζαν από τη μία εφαρμογή του μοντέλου στην άλλη μέσα στο κεφάλαιο.
Πρόσεξε:
λύση_εξίσωσης, η αναπαράσταση της εξίσωσης ως λίστα συντελεστών είναι μία δυνατή επιλογή· μια εναλλακτική (πιο προχωρημένη) λύση θα περνούσε ως παράμετρο μια ολόκληρη συνάρτηση που υπολογίζει την τιμή της εξίσωσης.(Με αυτή την άσκηση ολοκληρώνεται το σχολικό βιβλίο Πληροφορικής της Γ΄ Γυμνασίου — και μαζί του ολόκληρη η τριλογία Α΄/Β΄/Γ΄ Γυμνασίου.)