You are on page 1of 251

Εισαγωγή στον Προγραµµατισµό

Γλώσσα προγραμματισμού Python

Ν. Μαμουλής

Πανεπιστήμιο Ιωαννίνων 2014

Προγραµµατισµός

Προγραµµατισµός
ΔΕΝ ΕΙΝΑΙ απλά γράφω κώδικα…

λύνω πρακτικά
είναι

προβλήµατα
χρησιµοποιώντας τον υπολογιστή
2
Εφαρµογές
Τι είναι η Εφαρµογή (Application);
Η εφαρµογή είναι το λογισµικό που αναπτύσσεται για
να διευκολύνει τους χρήστες να διαικπεραιώσουν
συγκεκριµένες εργασίες.

Εφαρµογή κράτησης θέσεων

Εφαρµοφή ηλεκτρονικής πληρωµής 3

Εφαρµογές

Εφαρµογές Google Maps Google maps πλάνο κτιρίου


(π.χ., προτειν. διαδροµές) http://maps.google.com/help/maps/floorplans/

Τρισδιάστατοι χάρτες στη Google Earth


Google’s Trekker Google street view http://www.youtube.com/watch?v=U8CMtRS6IUw
Project http://www.youtube.com/watch?v=N6Douyfa7l8 4
Εφαρµογές
Εφαρµογές παντού!
Εφαρµογές στο διαδύκτιο
Εφαρµογές ηλεκτρονικού εµπορίου
Ασύρµατες και κινητές εφαρµογές
Εφαρµογές Βάσεων Δεδοµένων
Εφαρµογές Κοινωνικών Δικτύων

Εφαρµογές
Εφαρµογές παντού!
Ηλεκτρονικά Παιχνίδια
Πολυµεσικές εφαρµογές
Υπολογιστική Όραση, Γραφικά
Εφαρµογές Τεχνητής Νοηµοσύνης

6
Προγραµµατισµός Εφαρµογών

Καινοτοµία, δηµιουργικότητα, όραµα

Απόκτηση των θεµελιωδών δεξιοτήτων


προγραµµατισµού και υλοποίηση των
ιδεών σου!

ΙΔΕΑ Δεξιότητες
7

Βασικές Πληροφορίες Μαθήµατος

Σύγγραµµα
•  Beginning Python: From Novice to Professional,
Magnus Lie Hetland, Apress, 2008.
•  To pdf είναι διαθέσιµο για download από τη σελίδα
του ecourse.
•  Άλλα συγγράµµατα:
•  Introduction to Computing Using Python: An
Application Development Focus, L. Perkovic,
Wiley, 2012
•  Εισαγωγή στους Υπολογιστές µε τη γλώσσα
Python, Ν. Αβούρης, Μ. Κουκιάς, Β. Παλιούρας,
Κ. Σγάρµπας, Παν/µιο Πατρών, 2013
9
Βασικές Πληροφορίες Μαθήµατος

Python
•  Κατεβάστε τη γλώσσα Python στον υπολογιστή
σας!
•  www.python.org
•  Ο προγραµµατισµός µαθαίνεται αφιερώνοντας
χρόνο στον υπολογιστή, δεν αρκεί το διάβασµα.

10

Μαθησιακοί Στόχοι
1. [Επίλυση Προβληµάτων] Ανάλυση απαιτήσεων
απλών προβληµάτων, σχεδιασµός και υλοποίηση
προγραµµάτων που τα λύνουν µέσω µιας λογικής ροής
απλών εντολών.
2. [Ανάπτυξη Εφαρµογών] Ανάπτυξη µεγαλύτερων
προγραµµάτων, µέσω κατάλληλων δοµών και
συναρτήσεων.
3. [Εκσφαλµάτωση] Έλεγχος, εντοπισµός και διόρθωση
των σφαλµάτων ενός προγράµµατος.
4. [Έλεγχος Προγράµµατος] Έλεγχος της σωστής
λειτουργίας ενός προγράµµατος µε βάση τις
προδιαγραφές του.
15
Πρόγραµµα Μαθήµατος
1.  Εισαγωγή στον προγραµµατισµό
2.  Εισαγωγή στην Python
3.  Λίστες και πλειάδες
4.  Αλφαριθµητικά
5.  Λεξικά
6.  Έλεγχος ροής προγράµµατος
7.  Διαγράµµατα ροής
8.  Δόµηση προγράµµατος και συναρτήσεις
9.  Αναδροµικές συναρτήσεις
10.  Ταξινόµηση και αναζήτηση
11.  Διαχείρηση αρχείων κειµένου
12.  Το περιβάλλον γραφικών της Python

16

Άλλες Πληροφορίες
n  Το µάθηµα δεν προαπαιτεί γνώσεις προγραµµατισµού.
Προαπαιτεί όµως:
¡  Βασικές γνώσεις χρήσης υπολογιστή (άνοιγµα/σώσιµο
αρχείων, εύρεση/οργάνωση αρχείων στο δίσκο,
πληκτρολόγηση)
¡  Καλό επίπεδο Αγγλικών
n  Οι βασικές αρχές προγραµµατισµού σε Python είναι
χρήσιµες/απαραίτητες για την εκµάθηση άλλων
γλωσσών (Java, C++)
n  Ο προγραµµατισµός µαθαίνεται µε την εξάσκηση
¡  εργαστήρια, ασκήσεις, προσωπική ενασχόληση

17
Ας αρχίσουµε!

Ένας καλός προγραµµατιστής είναι ικανός


να δώσει µια προγραµµατιστική λύση σε
ένα πρόβληµα, χρησιµοποιώντας τους
διαθέσιµους πόρους. Επίσης έχει την
ικανότητα να αναλύει τα δυνατά σηµεία
και τις αδυναµίες της λύσης του.
18

Εισαγωγή στον Προγραµµατισµό


Τι θα µάθουµε;
Υπολογιστής; Πρόγραµµα;
•  Ποια είναι τα βασικά µέρη του υπολογιστή;
•  Πως εκτελείται ένα πρόγραµµα;
Γλώσσες Προγραµµατισµού
Έλεγχος και Εκσφαλµάτωση

Σχεδιασµός Προγράµµατος

Βασικές Έννοιες
«Υπολογιστής» δεν είναι µόνο ο προσωπικός
σας υπολογιστής (PC), µπορεί να είναι:
•  Ο υπολογιστής µέσα στο κινητό σας
•  Ο υπολογιστής µέσα στην ψηφιακή µηχανή σας
•  Ο υπολογιστής µέσα στην κονσόλα
παιχνιδιών σας

iPhone 5 Galaxy S4
Panasonic Lumix GF

Ερώτηση: Ποια είναι τα


κοινά µέρη αυτών των
«υπολογιστών»;
XBOX 360 and Kinect Play station 3 CANNON EOS 600D
3
Υλικό
Τα φυσικά («χειροπιαστά») µέρη τα
οποία συνθέτουν έναν υπολογιστή.

Υλικό
Τα φυσικά («χειροπιαστά») µέρη τα
οποία συνθέτουν έναν υπολογιστή.

1. Κεντρική Μονάδα Επεξεργασίας (ΚΜΕ)


•  Central Processing Unit (CPU)
•  Tο «µυαλό» του υπολογιστή
•  Εκτελεί απλές εργασίες όπως
quad-core i7 CPU
•  Πρόσθεση, αφαίρεση,
πολλαπλασιασµός, Ερώτηση: Ξέρεις πως µετράµε την ταχύτητα ενός
επεξεργαστή;
διαίρεση
•  Μετακίνηση δεδοµένων
από µία θέση µνήµης
στην άλλη

5
Υλικό
Τα φυσικά («χειροπιαστά») µέρη τα
οποία συνθέτουν έναν υπολογιστή.

1. Κεντρική Μονάδα Επεξεργασίας (ΚΜΕ)


•  Central Processing Unit (CPU)
•  Tο «µυαλό» του υπολογιστή
•  Εκτελεί απλές εργασίες όπως
quad-core i7 CPU
•  Πρόσθεση, αφαίρεση,
πολλαπλασιασµός, Ερώτηση: Ξέρεις πως µετράµε την ταχύτητα ενός
επεξεργαστή;
διαίρεση
Απάντηση: Ο ρυθµός-ρολογιού του
•  Μετακίνηση δεδοµένων επεξεργαστή µετράει πόσους κύκλους
από µία θέση µνήµης κάνει το δευτερόλεπτο. Σε ένα κύκλο
στην άλλη µπορεί να κάνει µια βασική πράξη.
100MHz = 100 Million cycles per second,
1GHz = 1 Billion cycles per second. 6

Υλικό
Τα φυσικά («χειροπιαστά») µέρη τα
οποία συνθέτουν έναν υπολογιστή.
2. Κύρια Μνήµη (RAM)
A DDR3 RAM
Main Memory

Μια µακριά λίστα από κελλιά µνήµης Address 1


Address 2
Address 3
Κάθε κελλί έχει µια διεύθυνση (έναν

αριθµό) που προσδιορίζει τη θέση του.


0 0 0 0 0 0 0 1

Κάθε κελλί µνήµης έχει 8


δυαδικά ψηφία (1 byte). Ερώτηση: Ποιο είναι ένα τυπικό
µέγεθος RAM σήµερα;
Προσωρινή – τα δεδοµένα στη
µνήµη χάνονται (σβήνονται) µε
το κλείσιµο του υπολογιστή 7
Υλικό
Τα φυσικά («χειροπιαστά») µέρη τα
οποία συνθέτουν έναν υπολογιστή.
2. Κύρια Μνήµη (RAM)
A DDR3 RAM
Main Memory

Μια µακριά λίστα από κελλιά µνήµης Address 1


Address 2
Address 3
Κάθε κελλί έχει µια διεύθυνση (έναν


αριθµό) που προσδιορίζει τη θέση του.
0 0 0 0 0 0 0 1


Κάθε κελλί µνήµης έχει 8
δυαδικά ψηφία (1 byte). Ερώτηση: Ποιο είναι ένα τυπικό
µέγεθος RAM σήµερα;
Προσωρινή – τα δεδοµένα στη
Απάντηση: 8GB DDR3 RAM,
µνήµη χάνονται (σβήνονται) µε έχοντας 8,589,934,592 κελλιά
το κλείσιµο του υπολογιστή µνήµης! 8

Υλικό
Τα φυσικά («χειροπιαστά») µέρη τα
οποία συνθέτουν έναν υπολογιστή.

3. Δευτερεύουσα Μνήµη
Μόνιµη – η πληροφορία δεν χάνεται µε
το κλείσιµο του υπολογιστή.
Για µόνιµη αποθήκευση πληροφορίας σε
αρχεία. A 3.5” Hard Disk

Π.χ., σκληρός δίσκος, DVD/CD, flash memory

Flash hard drive External Hard Disk DVD/CD ROMs USB flash drive 9
Υλικό
Τα φυσικά («χειροπιαστά») µέρη τα
οποία συνθέτουν έναν υπολογιστή.

4. Περιφερειακά
Συσκευές επικοινωνίας µεταξύ χρήστη και
υπολογιστή.

Συσκευές εισόδου

Συσκευές εξόδου

10

Υλικό
Επεξεργαστής
(CPU) Συσκευές
εισόδου

γρήγορα

Συσκευές
Κύρια Μνήµη εξόδου

αργά

Δευτερεύουσα Ερώτηση: Πέραν του προσωπικού υπολογιστή, µπορείς να


Μνήµη ξεχωρήσεις αυτά τα µέρη σε ένα κινητό ή tablet ή κονσόλα;
11
Υλικό
Επεξεργαστής Xbox360 Kinect Ipad 4 iPhone5
(CPU) Συσκευές
εισόδου 3.2 GHz PowerPC 1.4 GHz dual-
Processor A6 Dual core
Tri-Core Xenon core Apple A6X

γρήγορα Main memory 512 MB 1024 MB 1GB

Secondary 16, 32, or 64,


Συσκευές memory Up to 320 GB 128 GB 16, 32 or 64 GB
Κύρια Μνήµη εξόδου
Controller /
Input device(s) Kinect (motion Touch screen, Touch screen,
sensing) …etc camera, mic… camera, mic…
etc etc

Output Video output, 9.7 inches retina 4 inches retina


device(s) Audio output, display, touch display, touch
αργά Controller screen screen

Δευτερεύουσα Ερώτηση: Πέραν του προσωπικού υπολογιστή, µπορείς να


Μνήµη ξεχωρήσεις αυτά τα µέρη σε ένα κινητό ή tablet ή κονσόλα;
12

Πρόγραµµα
Τι είναι ένα πρόγραµµα
Επεξεργαστής
(CPU) Συσκευές Μία ακολουθία εντολών που
εισόδου
σκοπό έχουν την εκτέλεση µιας
γρήγορα
συγκεκριµένης εργασίας στον
υπολογιστή.
Συσκευές
Κύρια Μνήµη εξόδου

αργά

Δευτερεύουσα Compute
Μνήµη 2+3=?
13
Πρόγραµµα
Όταν ένα πρόγραµµα εκτελείται
Επεξεργαστής
(CPU) Συσκευές 1) Το πρόγραµµα φορτώνεται
εισόδου στην κύρια µνήµη.
γρήγορα

Συσκευές
Κύρια Μνήµη εξόδου
Compute
2+3=?

αργά

Δευτερεύουσα Compute
Μνήµη 2+3=?
14

Πρόγραµµα
Όταν ένα πρόγραµµα εκτελείται
Επεξεργαστής
(CPU) Συσκευές 1) Το πρόγραµµα φορτώνεται
Compute
εισόδου στην κύρια µνήµη.
2+3=5

γρήγορα
2) Ο επεξεργαστής διαβάζει και
εκτελεί τις εντολές, καθώς και τα
Συσκευές
δεδοµένα από τη µνήµη.
Κύρια Μνήµη εξόδου
Compute
2+3=?

αργά

Δευτερεύουσα Compute
Μνήµη 2+3=?
15
Πρόγραµµα
Όταν ένα πρόγραµµα εκτελείται
Επεξεργαστής
(CPU) Συσκευές 1) Το πρόγραµµα φορτώνεται
Compute
εισόδου στην κύρια µνήµη.
2+3=5

γρήγορα
2) Ο επεξεργαστής διαβάζει και
εκτελεί τις εντολές, καθώς και τα
Συσκευές
δεδοµένα από τη µνήµη.
Κύρια Μνήµη εξόδου 3) Η έξοδος του προγράµµατος
Compute
2+3=? µπορεί να γραφτεί στην κύρια
µνήµη, στη δευτερεύουσα µνήµη
ή σε συσκευή εξόδου.
αργά

Δευτερεύουσα Compute
Μνήµη 2+3=?
16

Πρόγραµµα
Μία κοντινή µατιά στον επεξεργαστή
Επεξεργαστής
Επεξεργαστής
(CPU)
(CPU)
Μονάδα Ελέγχου (ΜΕ) – Εξάγει τις εντολές
Συσκευές
]\ από τη µνήµη, τις αποκωδικοποιεί και τις
εισόδου
ΜΕ
εκτελέι.
γρήγορα

Συσκευές
Κύρια Μνήµη εξόδου

αργά

Δευτερεύουσα
Μνήµη
17
Πρόγραµµα
Καταχωρητές Μία κοντινή µατιά στον επεξεργαστή
Επεξεργαστής
Processer CPU
(CPU)
Μονάδα Ελέγχου (ΜΕ) – Εξάγει τις εντολές
Συσκευές
ΜΕ από τη µνήµη, τις αποκωδικοποιεί και τις
εισόδου
εκτελεί.
γρήγορα Καταχωρητές (Registers) – Αποθηκεύουν
τις εντολές/δεδοµένα που εξάχθηκαν από
Συσκευές
τη µνήµη για γρήγορη επεξεργασία.
Κύρια Μνήµη εξόδου

αργά

Δευτερεύουσα
Μνήµη
18

Πρόγραµµα
Καταχωρητές
ΑΛΜ
Μία κοντινή µατιά στον επεξεργαστή
Επεξεργαστής
Processer CPU
(CPU)
Μονάδα Ελέγχου (ΜΕ) – Εξάγει τις εντολές
Συσκευές
ΜΕ από τη µνήµη, τις αποκωδικοποιεί και τις
εισόδου
εκτελεί.
γρήγορα Καταχωρητές (Registers) – Αποθηκεύουν
τις εντολές/δεδοµένα που εξάχθηκαν από
Συσκευές
τη µνήµη για γρήγορη επεξεργασία.
Κύριαmemory
Main Μνήµη εξόδου
Compute Αριθµητική Λογική Μονάδα (ΑΛΜ) – Εκτελεί
2+3=?
απλές αριθµητικές/λογικές πράξεις (AND/OR).
Ερώτηση: Η ΚΜΕ επεξεργάζεται δεδοµένα και εντολές
αργά εκφρασµένες µε «0» και «1». Πώς µπορεί να εκτελέσει
ένα πρόγραµµα από µια γλώσσα προγραµµατισµου;

Δευτερεύουσα
Μνήµη
19
Πρόγραµµα
Καταχωρητές
ΑΛΜ
Μία κοντινή µατιά στον επεξεργαστή
Επεξεργαστής
(CPU)
Μονάδα Ελέγχου (ΜΕ) – Εξάγει τις εντολές
Συσκευές
ΜΕ από τη µνήµη, τις αποκωδικοποιεί και τις
εισόδου
εκτελεί.
γρήγορα Καταχωρητές (Registers) – Αποθηκεύουν
001100100100
100101010110 τις εντολές/δεδοµένα που εξάχθηκαν από
Συσκευές
τη µνήµη για γρήγορη επεξεργασία.
Κύριαmemory
Main Μνήµη εξόδου
Compute Αριθµητική Λογική Μονάδα (ΑΛΜ) – Εκτελεί
2+3=?
απλές αριθµητικές/λογικές πράξεις (AND/OR).
Ερώτηση: Η ΚΜΕ επεξεργάζεται δεδοµένα και εντολές
αργά εκφρασµένες µε «0» και «1», πώς µπορεί να εκτελέσει
ένα πρόγραµµα από µια γλώσσα προγραµµατισµου;

Δευτερεύουσα Απάντηση: Ένα µεταφραστικό εργαλείο


Μνήµη µετατρέπει το πρόγραµµα στη γλώσσα µηχανής 20
(“0” και “1”) της ΚΜΕ.

Γλώσσες Προγραµµατισµού
Γλώσσα Μηχανής
Ο επεξεργαστής καταλαβαίνει µόνο γλώσσα µηχανής.
Συγκεκριµένες εντολές σε γλώσσα µηχανής εκτελούνται
απευθείας στην κεντρική µονάδα επεξεργασίας.

?
Γλώσσα Ανθρώπινη
µηχανής γλώσσα
0111000100001111 Γράψε µου ένα πρόγραµµα
που να υπολογίζει το
1001110110110001
άθροισµα 2 αριθµών.
1110000100111110

21
Γλώσσες Προγραµµατισµού
Γλώσσα Assembly
Γλώσσα χαµηλού επιπέδου ορισµένη από τον
κατασκευαστή του επεξεργαστή.
Είναι διατυπωµένη σε δυαδική γλώσσα µηχανής για να
εκτελεστεί από την ΚΜΕ.

Γλώσσα Γλώσσα Ανθρώπινη


µηχανής Assembly γλώσσα
0111000100001111 LOAD A Γράψε µου ένα πρόγραµµα
που να υπολογίζει το
1001110110110001 ADD B
άθροισµα 2 αριθµών.
1110000100111110 STORE C

22

Γλώσσες Προγραµµατισµού
Γλώσσες προγραµµατισµού υψηλού επιπέδου
C C++ Pytho
n Pascal COBOL
Θυµίζουν ανθρώπινη γλώσσα.
Έχουν πιο περίπλοκες εντολές από αυτές της Assembly.
Προγράµµατα σε αυτές τις γλώσσες πρέπει να
µεταφραστούν σε κώδικα µηχανής για να εκτελεστούν
από την ΚΜΕ.
Γλώσσα Γλώσσα Γλώσσα Ανθρώπινη
µηχανής Assembly Προγραµµατισµού γλώσσα
0111000100001111 LOAD A Γράψε µου ένα πρόγραµµα
# Python code που να υπολογίζει το
1001110110110001 ADD B C = A+B άθροισµα 2 αριθµών.
1110000100111110 STORE C

23
Λογισµικό
Τα προγράµµατα που χρησιµοποιούνται
ευρέως σε ένα υπολογιστικό σύστηµα

Λογισµικό σχετικό µε τον προγραµµατισµό:


Λειτουργικό Σύστηµα
Κέλυφος
Επεξεργαστής κειµένου
Μεταφραστής ή Διερµηνέας
Περιβάλλον Ανάπτυξης Λογισµικού

24

Λειτουργικό Σύστηµα Χρήστης

Δρα ως διαχειριστής. Ελέγχει και δεσµεύει Εφαρµογές


τους υπολογιστικούς πόρους (π.χ.,
διάβασµα δεδοµένων από το δίσκο,
Λειτουργικό
εκτέλεση προγραµµάτων). Σύστηµα
Παρέχει γραφικό περιβάλλον στους χρήστες
για την εύκολη περάτωση εργασιών (π.χ.,
Υλικό
εκτύπωση, δικτύωση, διαχείριση αρχείων)

25
Κέλυφος - Command Prompt
Το κέλυφος (shell) ή το περιβάλλον γραµµής διαταγών
(command prompt) επιτρέπει στους χρήστες να
επικοινωνούν µε το λειτουργικό, εισάγοντας εντολές.
Στα Windows, το command prompt ενεργοποιείται
πληκτρολογώντας “cmd” στη γραµµή εκκίνησης.

26

Επεξεργαστής κειµένου
Χρησιµοποιείται για να γράφουµε και να
αλλάζουµε τον πηγαίο κώδικα ενός
προγράµµατος. Μπορεί να αναγνωρίσει και
να χρωµατίσει τα µέρη του προγράµµατος. Επεξεργαστής
Κειµένου
Δηµοφιλείς επεξεργαστές κειµένου
-  emacs
-  vi width = int(input("Width: "))
length = int(input("Length: "))
-  pico area = width*length
-  UltraEdit print("Area: ", area)

-  Crimson
Πηγαίος κώδικας (area.py)
-  TextWrangler

27
Μεταγλωττιστής
Οι επεξεργαστές καταλαβαίνουν µόνο
προγράµµατα σε γλώσσα χαµηλού επιπέδου
(απλές εντολές), που µπορεί να διαφέρουν
ανάλογα τον υπολογιστή.
Επεξεργαστής
Ο µεταγλωττιστής (compiler) είναι ένα Κειµένου
πρόγραµµα που µεταφράζει αυτόµατα
πηγαίο κώδικα υψηλού επιπέδου (π.χ. #include <iostream>
C++) σε γλώσσα µηχανής, ώστε ο …
υπολογιστής να µπορεί να τον εκτελέσει. int main (){
int width = 5;
int height = 10;
int area = width * height;
cout << “Area is “ <<
Δυαδικός Κώδικας area;
(Γλώσσα Μηχανής) Compiler return 0;
}
(π.χ. area.o) Πηγαίος κώδικας (area.cpp) 28

Μεταγλωττιστής
Το αποτέλεσµα της µεταγλώττισης πολλές
φορές δεν είναι το βέλτιστο αφου η διαδικασία
είναι µηχανιστική.
Είναι όµως εντυπωσιακά καλό και Επεξεργαστής
πολλές φορές καλύτερο από τον κώδικα Κειµένου
µηχανής που θα έγραφε ένας
προγραµµατιστής. #include <iostream>

Απευθείας προγραµµατισµός σε γλώσ- int main ( ) {
σα µηχανής είναι εξαιρετικά δύσκολος. int width = 5;
int height = 10;
int area = width * height;
cout << “Area is “ <<
Δυαδικός Κώδικας area;
(Γλώσσα Μηχανής) Compiler return 0;
}
(π.χ. area.o) Πηγαίος κώδικας (area.cpp) 29
Συνδετής
Ένα πρόγραµµα µπορεί να χρησιµοποιεί
κοµµάτια κώδικα (βιβλιοθήκες) που έχουν
γραφτεί από άλλους (π.χ. µαθ. συναρτήσεις)
Ο συνδετής (linker) είναι ένα Επεξεργαστής
πρόγραµµα που συνδέει ένα ή Κειµένου
περισσότερα αρχεία (µεταγλωττισµένου)
µηχανικού κώδικα σε ένα εκτελέσιµο #include <iostream>
πρόγραµµα …
int main ( ) {
Linker Εκτελέσιµο int width = 5;
int height = 10;
(π.χ. area.exe) int area = width * height;
Library
Library cout << “Area is “ <<
Library
Δυαδικός Κώδικας area;
(Γλώσσα Μηχανής) Compiler return 0;
(π.χ. iostream.o) }
(π.χ. area.o) Πηγαίος κώδικας (area.cpp) 30

Διερµηνέας
Κάποιες γλώσσες προγραµµατισµού “π.χ.
Python) δεν έχουν µεταγλωττιστή, αλλά
διερµηνέα (interpreter).
Ο διερµηνέας µεταφράζει και εκτελεί ένα Επεξεργαστής
πρόγραµµα, εντολή προς εντολή Κειµένου

Πλεονέκτηµα: γρηγορότερη παραγωγή


και έλεγχος πηγαίου κώδικα width = int(input("Width: "))
length = int(input("Length: "))
Μειονέκτηµα: το τελικό πρόγραµµα area = width*length
είναι συνήθως πιο αργό print("Area: ", area)
Interpreter
Πηγαίος κώδικας (area.py)
width = int(input("Width: "))

µεταγλώττιση και εκτέλεση


31
Ολοκληρωµένο Περιβάλλον
Ανάπτυξης Λογισµικού
Ένα Ολοκληρωµένο Περιβάλλον
Ανάπτυξης Λογισµικού (Integrated
Development Environment - IDE) ενοποιεί
τα βήµατα ανάπτυξης ενός προγράµ-
µατος (επεξεργασία κειµένου, µετα- IDE Editor
γλώττιση, εκσφαλµάτωση)
Π.χ., IDLE (Python), Eclipse #include <iostream>

int main ( ) {
Linker Εκτελέσιµο int width = 5;
int height = 10;
(π.χ. area.exe) int area = width * height;
Library
Library cout << “Area is “ <<
Library Object code
area;
(Machine Compiler return 0;
(πχ. iostream.o) language ) }
(π.χ. area.o) Πηγαίος κώδικας (area.cpp) 32

Παράδειγµα προγράµµατος Python

! "#$%
& ! 0- 12(+! +
# sample Python program ) 2" % . &3 &/+! +4
# computes the area of a ) . ’ 2) /&0

µ’ () * $+(, / rectangle ! 0- 12(+! +


) - (%
. ’ /µ’ - & ’%! #5&0 ) 3 # (&
" 2, ! (+
width = int(input("Width: "))
) $6 ) 2%7µ+(%
.,
! 0- 12(+! + length = int(input("Length: ")) ! () 7’ 21
’ 8#5&0 ! (+- area = width*length
&7#- +
print("Area: ", area)
area.py
33
Έλεγχος και Εκσφαλµάτωση
n  Το σφάλµα σε ένα πρόγραµµα λέγεται bug (ζωύφιο).
n  Ένα πρόγραµµα που γράφουµε είναι πιο πιθανό
να έχει bugs από το να µην έχει.
n  Η κυριότερη αιτία ενός bug είναι η απροσεξία του
προγραµµατιστή.
n  Ακόµα και ο πιο έµπειρος προγραµµατιστής κάνει
σφάλµατα
¡  Κατ’ αναλογία, ακόµα κι ο πιο έµπειρος συντάκτης κάνει γραµµατικά
και συντακτικά λάθη.

34

Τύποι Σφαλµάτων
n  Συντακτικά λάθη (syntax errors)
n  Λάθη κατά την εκτέλεση (run-time errors)
n  Λογικά σφάλµατα

35
Συντακτικά λάθη
n  Εντοπίζονται από το µεταγλωττιστή/διερµηνέα
ή τον συντακτικό αναλυτή (parser)
n  Διορθώνονται εύκολα

width = int(input("Width: "))


length = int(input("Length: "))
area = width*legth
Interpreter print("Area: ", area)

Traceback (most recent call last):


Πηγαίος κώδικας (area.py)
File "area.py", line 3, in <module>
area = width*legth
NameError: name 'legth' is not defined
36

Λάθη κατά την εκτέλεση


n  Συµβαίνουν κατά την εκτέλεση του
προγράµµατος και όχι πάντα.
n  Τυπικό σφάλµα: διαίρεση µε το 0

area = int(input("Area: "))


Interpreter length = int(input("Length: "))
width = area/length
Area: 10 print("Width: ", width)
Length: 0
Traceback (most recent call last): Πηγαίος κώδικας (area2.py)
File "area2.py", line 3, in <module>
width = area/length
ZeroDivisionError: division by zero
37
Λογικά σφάλµατα
n  Λογικά λάθη στο πρόγραµµα: το πρόγραµµα δεν
κάνει την επιθυµητή λειτουργία ή παράγει λάθος
αποτελέσµατα
n  Ο πονοκέφαλος του προγραµµατιστή: συνήθως
είναι δύσκολο να βρεθούν
width = int(input("Width: "))
length = int(input("Length: "))
area = width+length
Interpreter print("Area: ", area)

Width: 5 Πηγαίος κώδικας (area.py)


Length: 2
Area: 7
38

Ανάπτυξη Προγράµµατος
n  Βήµα 1: Σχεδιασµός
¡  Κατανόηση των απαιτήσεων (τι θέλουµε να κάνουµε;)
¡  Αναγνώριση της εισόδου και της επιθυµητής εξόδου του
προγράµµατος
¡  Σχεδιασµός ενός αλγορίθµου που λύνει το πρόβληµα
n  Βήµα 2: Υλοποίηση
¡  Μετατροπή του αλγορίθµου στη γλώσσα προγραµµατισµού
¡  Μεταγλώττιση/Διερµηνεία για εντοπιστό τυχόν συντακτικών λαθών
¡  Εκτέλεση του προγράµµατος δίνοντας ως είσοδο δεδοµένα µε τα
οποία µπορούµε να ελεγξουµε τυχόν σφάλµατα κατα την εκτέλεση
και λογικά λάθη

39
Παράδειγµα
n  Προδιαγραφές προβλήµατος:
Μία κατασκευαστική εταιρία παρέχει µια υπηρεσία δόµησης σκάλας µε
λίθινες ράβδους για τους πελάτες της. Υποθέστε ότι κάθε ράβδος έχει 30
εκ. ύψος και το κόστος µιας ράβδου είναι 10€. Ζητείται ένα πρόγραµµα
που να υπολογίσει το κόστος κατασκευής µιας σκάλας ύψους χ εκ.

ύψος 30 60 90
κόστος 10€ 20€ 30€
40

Παράδειγµα
n  Προδιαγραφές προβλήµατος:
Μία κατασκευαστική εταιρία παρέχει µια υπηρεσία δόµησης σκάλας µε
λίθινες ράβδους για τους πελάτες της. Υποθέστε ότι κάθε ράβδος έχει 30
εκ. ύψος και το κόστος µιας ράβδου είναι 10€. Ζητείται ένα πρόγραµµα
που να υπολογίσει το κόστος κατασκευής µιας σκάλας ύψους χ εκ.

Ερώτηση:
Ποια είναι η είσοδος και η έξοδος
του προγράµµατος µας;

Απάντηση:
1) Ο χρήστης θα ορίσει το επιθυµητό
ύψος χ της σκάλας
2) Το κόστος κάθε ράβδου είναι 10€
3) Το ύψος κάθε ράβδου είναι 30 εκ. ύψος 30 60 90
4) Ζητούµενο (έξοδος) είναι το κόστος κόστος 10€ 20€ 30€
µιας σκάλας χ εκατοστών.
41
Παράδειγµα
n  Προδιαγραφές προβλήµατος:
Μία κατασκευαστική εταιρία παρέχει µια υπηρεσία δόµησης σκάλας µε
λίθινες ράβδους για τους πελάτες της. Υποθέστε ότι κάθε ράβδος έχει 30
εκ. ύψος και το κόστος µιας ράβδου είναι 10€. Ζητείται ένα πρόγραµµα
που να υπολογίσει το κόστος κατασκευής µιας σκάλας ύψους χ εκ.

Τώρα, σχεδίασε έναν αλγόριθµο


που να λύνει το πρόβληµά µας!

ΙΔΕΑ :
1) Διαιρώ το χ µε 30 για να πάρω το
ύψος υ της σκάλας σε ράβδους
2) Χρειάζοµαι 1+2+...+ υ ράβδους! ύψος 30 60 90
3) Το κόστος είναι (1+2+...+ υ)*10! κόστος 10€ 20€ 30€
42

Παράδειγµα
n  Προδιαγραφές προβλήµατος:
Μία κατασκευαστική εταιρία παρέχει µια υπηρεσία δόµησης σκάλας µε
λίθινες ράβδους για τους πελάτες της. Υποθέστε ότι κάθε ράβδος έχει 30
εκ. ύψος και το κόστος µιας ράβδου είναι 10€. Ζητείται ένα πρόγραµµα
που να υπολογίσει το κόστος κατασκευής µιας σκάλας ύψους χ εκ.

Τώρα, γράψε το πρόγραµµα!

x = int(input("Required height (in cm): "))


import math
u = math.ceil(x/30)
numrods = 0
for i in range(1,u+1): ύψος 30 60 90
numrods = numrods+i
cost = numrods*10 κόστος 10€ 20€ 30€
print("The cost is: ", cost)
43
Παράδειγµα
n  Προδιαγραφές προβλήµατος:
Μία κατασκευαστική εταιρία παρέχει µια υπηρεσία δόµησης σκάλας µε
λίθινες ράβδους για τους πελάτες της. Υποθέστε ότι κάθε ράβδος έχει 30
εκ. ύψος και το κόστος µιας ράβδου είναι 10€. Ζητείται ένα πρόγραµµα
που να υπολογίσει το κόστος κατασκευής µιας σκάλας ύψους χ εκ.

Μπορούµε να κάνουµε το
πρόγραµµα πιο γρήγορο;

x = int(input("Required height (in cm): "))


import math
u = math.ceil(x/30)
numrods = int((u*(u+1))/2)
cost = numrods*10 ύψος 30 60 90
print("The cost is: ", cost)

✔ κόστος 10€ 20€ 30€


44

Ένα καλό πρόγραµµα


n  Είναι οπωσδήποτε σωστό!
n  Είναι γρήγορο

45
Πρότυπα Προγραµµατισµού
n  Διαδικαστικός (Δοµηµένος) Προγραµµατισµός
¡  Πρόγραµµα σε µεταβλητές, δοµές, συναρτήσεις
¡  Pascal, C
n  Αντικειµενοστρεφής Προγραµµατισµός
¡  Πρόγραµµα βασισµένο σε αντικείµενα
¡  C++, Java, Python
n  Συναρτησιακός Προγραµµατισµός
¡  Πρόγραµµα σαν µαθηµατικές συναρτήσεις
¡  Lisp, Haskel, Erlang, Scala
n  Λογικός Προγραµµατισµός
¡  Prolog 46

Φιλοσοφία του Μαθήµατος


n  Εκµάθηση βασικών αρχών και φιλοσοφίας του
προγραµµατισµού µε την Python
n  Έµφαση στα βασικά στοιχεία της Python που είναι
κοινά και σε άλλες γλώσσες (π.χ. C, Java)
n  Οµαλή µετάβαση στο µάθηµα «Τεχνικές
Αντικειµενοστρεφούς Προγραµµατισµού» του
εαρινού εξαµήνου

47
Γιατί Python;
n  Εξαιρετικά δηµοφιλής γλώσσα
n  Εύκολη και γρήγορη ανάπτυξη εφαρµογών
n  Υπάρχει διαθέσιµος µεγάλος όγκος ελεύθερου
λογισµικού (προγράµµατα και βιβλιοθήκες)
n  Χρησιµοποιείται και στην ανάπτυξη εµπορικών
εφαρµογών
n  Μαθαίνοντάς την, µαθαίνουµε στοιχεία διαδικαστικού
και αντικειµενοστρεφούς προγραµµατισµού

48

Εισαγωγή στην Python


Εγκατάσταση
n  Από το www.python.org è Downloads
¡  Υπάρχουν εκτενείς οδηγίες για όλα τα λειτουργικά
(π.χ., Windows, Mac OS X)
n  Δύο βασικές εκδόσεις της Python:
¡  Python 2.X
¡  Python 3.X
n  Οι διαφορές τους (τουλάχιστον στο επίπεδο αυτού
του µαθήµατος) δεν είναι πολύ µεγάλες.
n  Δεν είναι όµως συµβατές µεταξύ τους.
n  Στο µάθηµα θα ακολουθήσουµε την Python 3.X.
2

Ο Διαδραστικός Διερµηνέας
n  Μετά την εγκατάσταση, µπορούµε να «ανοίξουµε»
το διαδραστικό διερµηνέα (interactive interpreter)
¡  Μέσω του κελύφους, πληκτρολογώντας python3
¡  Τρέχοντας το πρόγραµµα IDLE
n  Ο διερµηνέας σας επιτρέπει να εισάγετε εντολές
Python γραµµή-γραµµή, που εκτελούνται άµεσα.
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 00:54:21)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
Visit http://www.python.org/download/mac/tcltk/ for current information.

>>>

3
Εξοικείωση
n  Μια πρώτη εντολή:
>>> print("Hello, world!")
Hello, world!

n  Κάτι άκυρο:


>>> The Spanish Inquisition
SyntaxError: invalid syntax

Αριθµητικές Πράξεις

>>> 2+2
µπορείτε να
4 χρησιµοποιήσετε την
Python σαν αριθµητήριο!
>>> 1/2
0.5
>>> 4/2
2.0

5
int και float
n  Οι πραγµατικοί αριθµοί στις γλώσσες
προγραµµατισµού λέγονται «αριθµοί κινητής
υποδιαστολής» (floating-point numbers)
¡  int (integer, ακέραιος)
¡  float (floating-point number, πραγµατικός)
n  Οι αριθµοί 3 και 5 είναι ακέραιοι.
n  Οι αριθµοί 3.5 και 5.0 είναι αριθµοί κινητής
υποδιαστολής.
n  Οι ακέραιοι µετατρέπονται σε floats κατ’ ανάγκην

int και float


n  Οι ακέραιοι στην Python µπορούν να είναι όσο
µεγάλοι θέλουµε
>>> 2**1024
1797693134862315907729305190789024733617976978942306572734300811577326
7580550096313270847732240753602112011387987139335765878976881441662249
2847430639474124377767893424865485276302219601246094119453082952085005
7688381506823424628814739131105408272371633505106845862982399472459384
79716304835356329624224137216

n  Οι floats περιορίζονται σε 64bits


>>> 2.0**1024
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
2.0**1024 1.79*10308
OverflowError: (34, 'Result too large')
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, … min=2.2250738585072014e-308)
7
Τελεστές Ακέραιας Διαίρεσης

>>> 5/2 διαίρεση πραγµατικών

2.5
>>> 5//2 ακέραια διαίρεση

2
>>> 5%2 υπόλοιπο
ακέραιας διαίρεσης
1

Ύψωση σε δύναµη

>>> 2**3
8
>>> -3**2
-9
>>> (-3)**2
9

9
Μη δεκαδικοί αριθµοί
n  Το AF στο δεκαεξαδικό σύστηµα ισούται µε
10*16+15=175 στο δεκαδικό σύστηµα.
>>>0xAF
175
n  To 10 στο οκταδικό σύστηµα ισούται µε
1*8+0=8 στο δεκαδικό σύστηµα.
>>>0o10 >>> 0b1001000101001
8 4649
10

Απλές Μαθηµατικές Συναρτήσεις

>>> abs(-4)
4
>>> max(2,-5,6)
6
>>> min(2,-5,6)
-5
>>>pow(2,3)
8
>>>round(3.8)
4

11
Modules
n  Επεκτείνουν την Python πέρα από τις βασικές
εντολές/συναρτήσεις της Το math είναι
module
>>> import math µεγαλύτερος
ακέραιος
>>> math.floor(3.5) µικρότερος ή
ισος του 3.5
3 συνάρτηση
>>> math.sqrt(9) τετραγωνικής
ρίζας
3.0

12

Module fraction
n  Χειρισµός κλασµάτων
¡  Αν θέλουµε µεγαλύτερη ακρίβεια από floats
Το κλάσµα
>>> import fractions 3/4
>>> a = fractions.Fraction(3,4)
>>> b = fractions.Fraction(1,2)
>>> c = a+b
>>> c
Fraction(5, 4)

13
Module fraction
n  Χειρισµός κλασµάτων
¡  Αν θέλουµε µεγαλύτερη ακρίβεια από floats
>>> 0.5**1075
0.0
>>> fractions.Fraction(1,2)**1075
Fraction(1,
404804506614621236704990693437834614099113299528284236713
802716054860679135990693783920767402874248990374155728633
623822779617474771586953734026799881477019843034848553132
722728933815484186432682479535356945490137124014966849385
397236206711298319112681620113024717539104666829230461005
064372655017292012526615415482186989568)

14

Δυαδικές Εκφράσεις

>>> 2<3
δεσµευµένες
True λέξεις στην Python
για δυαδικές εκφρασεις
>>> 3<2
False
>>> 5-1>2+1
True

15
Τελεστές Σύγκρισης Αριθµών

>>> 3 == 3
True
>>> 3+5 == 4+4
True
>>> 3 == 5-3
False
>>> 3 <= 4
True
>>> 3 > 5
False
>>> 3 != 5
True
16

Δυαδικοί Τελεστές
>>> 2 < 3 and 4 > 5
False
πίνακες αληθείας
>>> 3 < 5 and True
True
p not p p q p and p p q p or p
>>> 3 < 4 or 4 <3
True T F T T T T T T
>>> 3 < 2 and 2 < 1 F T T F F T F T
False
F T F F T T
>>> not (3 < 4)
False F F F F F F

17
Σχέση τύπων bool, int, float
n  True = 1 και False = 0
n  Μετατροπή τύπων µε bool(), int(), float()
>>> 5+True µετατροπή σε
True/False
6
>>> bool(5-5) όλοι οι αριθµοί εκτός του
0 µετατρέπονται σε True
False
>>> bool(3-2.8)
µετατροπή σε
True πραγµατικό
>>> float(False)
0.0 ακέραιο µέρος του 5.8
>>> int(4.8+True)
5
18

Μεταβλητές
απόδοση τιµής
<µεταβλητή> = <έκφραση>
>>> x=3
>>> x*2
6
>>> print(x*3)
9

19
Προσοχή!

>>> x=1
>>> y=x
>>> x=100
>>> y Η τιµή µιας µεταβλητής µετά
την αρχικοποίησή της είναι
1 ανεξάρτητη από τις άλλες
µεταβλητές!

20

Ποια η διαφορά;
Η έκφραση αυτή δεν θα κάνει
τίποτα σε ένα πρόγραµµα
>>> 2*3 Python
6 Η εντολή αυτή θα τυπώσει 6 σε
ένα πρόγραµµα Python
>>> print(2*3)
6

21
Απόδοση τιµής από το χρήστη

>>> name = input("Please input your name: ")


Please input your name: Nikos
>>> name
'Nikos’
>>> x = input("x: ")
x: 3
To x δεν είναι αριθµός!
>>> x
Η συνάρτηση int() αρχικοποιεί
'3'
έναν ακέραιο παίρνοντας σαν
>>> x = int(input("x: "))
είσοδο ένα αλφαριθµητικό
x: 4
>>> x
4
22

Αλλά...
Η συνάρτηση µετατροπής
περιµένει ακέραιο!
>>> x = int(input("x: "))
x: 4.5
Traceback (most recent call last):
File "<pyshell#64>", line 1, in <module>
x = int(input("x: "))
ValueError: invalid literal for int() with base 10: '4.5’
>>> x = float(input("x: "))
x: 4.5
>>> x
4.5 Αυτόµατη µετατροπή
>>> x = eval(input("x: "))

23
Ονόµατα Μεταβλητών
n  Στα Αγγλικά!
n  Επιτρεπτοί χαρακτήρες:
¡  A..Z, a..z, _, 0..9
¡  Μια µεταβλητή ΔΕΝ µπορεί να αρχίζει µε ψηφίο (0..9)
¡  π.χ. my_list, myList, mylist, _list, αλλά όχι 5list, list-3
n  Διαλέγουµε ονόµατα που βγάζουν νόηµα
¡  π.χ. interestRate, tempVar
¡  θα βοηθήσουν άλλους να κατανοήσουν το πρόγραµµά µας
n  ...και εµάς(!) για να το θυµηθούµε ή να το εκσφαλµατώσουµε
n  ΔΕΝ χρησιµοποιούµε δεσµευµένα ονόµατα
(reserved keywords), π.χ. False, for, class
24

Αλφαριθµητικά
n  Ακολουθίες χαρακτήρων κλεισµένες σε εισαγωγικά
¡  "Hello World" ή 'Hello World', αλλά όχι "Hello World’

>>> "Hello World!"


'Hello World!'
>>> s = "hello"
>>> s
'hello'

25
Προσοχή!
>>> 'Let's go'
SyntaxError: invalid syntax
>>> "Let's go"
"Let's go"
>>> 'Let\'s go'
"Let's go"

26

Σύγκριση αλφαριθµητικών
>>> s = "hello"
>>> s == "hello"
True
>>> t = "world"
>>> s != t
True
>>> s == t
False µε βάση τη λεξικογραφική
σειρά!
>>> s < t
True

27
Πράξεις µε αλφαριθµητικά

>>> s + " " + t


'hello world'
>>> s * t
Traceback (most recent call last):
File "<pyshell#94>", line 1, in <module>
s*t
TypeError: can't multiply sequence by non-int of type 'str’
>>> 3 * "A"
'AAA'
>>> "hello " * 2
'hello hello '

28

Τελεστής in και συνάρτηση len

>>> s = "hello"
>>> 'g' in s
False
>>> 'll' in s
True
>>> len(s)
5

29
Δεικτοδότηση αλφαριθµητικών
n  Οι χαρακτήρες σε ένα αλφαριθµητικό
δεικτοδοτούνται
n  Ο πρώτος χαρακτήρας είναι στη θέση 0, ο
δεύτερος στη θέση 1, κ.ο.κ.
>>> s = "hello"
>>> s[0]
'h'
>>> s[3]
'l'
>>> s[4]
'o'
30

Αρνητική δεικτοδότηση
n  Μπορούµε να προσπελάσουµε τους χαρακτήρες
και από το τέλος
n  Ο τελευταίος χαρακτήρας είναι στη θέση -1, ο
προτελευταίος στη θέση -2, κ.ο.κ.
>>> s = "hello"
>>> s[-1]
'o' θετικοί δείκτες 0 1 2 3 4
>>> s[-4] αρνητικοί δείκτες -5 -4 -3 -2 -1
'e' αλφαριθµητικό h e l l o

31
Μακρά Αλφαριθµητικά
n  Αλφαριθµητικά που χρειάζονται πολλές γραµµές
(π.χ. κείµενα).

>>> print( '''This is a very long string.


It continues here.
And it's not over yet.
"Hello, world!”
Still here.''')

>>> print("Hello, \
World!")
Hello, World!
32

Τιµές, Τύποι, Αντικείµενα


n  Έχουµε δει κάποιους τύπους τιµών
¡  int, float, str
n  Κάθε τιµή στην Python (π.χ. ακέραιος,
αλφαριθµητικό) αποθηκεύεται στη µνήµη ως
αντικείµενο
n  Κάθε αντικείµενο έχει λοιπόν µια τιµή και ένα τύπο

type: int type: float type: str

3 3.0 'Hello World'

33
Οι µεταβλητές δεν έχουν τύπο
n  Οι µεταβλητές είναι απλά ονόµατα για τα
αντικείµενα στα οποία αναφέρονται.
>>> s = "hello"
>>> type(s)
<class 'str'>

n  Η παραπάνω συνάρτηση µας δίνει τον τύπο του


αντικειµένου στο οποίο αναφέρεται η µεταβλητή s

34

Προγράµµατα σε Python
n  Μπορούµε να δηµιουργήσουµε ένα πρόγραµµα
και να το σώσουµε σε ένα αρχείο κειµένου.
n  Μπορούµε να χρησιµοποιήσουµε οποιοδήποτε
επεξεργαστή κειµένου.
n  Επεξεργαστές κειµένου για γλώσσες
προγραµµατισµού µας βοηθάνε στη συγγραφή
και παρέχουν λειτουργίες εκτέλεσης του
προγράµµατος.
n  Ο επεξεργαστής κειµένου που έρχεται µε την
εγκατάσταση της Python ειναι το IDLE.
¡  Εναλλακτικά: UltraEdit, Crimson, emacs 35
Προγράµµατα σε Python
n  Ένα αρχείο προγράµµατος Python πρόγραµµα
µπορεί να εκτελεστεί: εκτέλεσης
αρχείων Python
¡  Μέσω του IDLE
όνοµα
¡  Από το κέλυφος ή τη γραµµή διαταγών αρχείου
Python
width = int(input("Width: ")) Ø  python3 area.py
length = int(input("Length: ")) Width: 3
area = width*legth
print("Area: ", area) Length: 4
Area: 12
Αρχείο (area.py)
Εκτέλεση στο κέλυφος

¡  Μετατρέποντας το αρχείο σε εκτελέσιµο

36

Σχόλια
n  Τα προγράµµατα πρέπει να τεκµηριώνονται
¡  για να µπορεί κάποιος που θα διαβάσει τον κώδικά σας
να τον κατανοήσει
¡  για να θυµάστε εσείς ποιος είναι ο σκοπός ή το νόηµα
ενός µέρους του προγράµµατος
¡  η τεκµηρίωση διευκολύνει την εκσφαλµάτωση
n  Σχόλια: οτιδήποτε ακολουθεί µια δίεση (#)
# this program computes the area of a rectangle
width = int(input("Width: ")) # ask the user to input the width
length = int(input("Length: ")) # ask the user to input the length
area = width*legth # compute the area
print("Area: ", area) # print the area

Αρχείο (area.py)
37
Λίστες και Πλειάδες

Δοµές δεδοµένων
n  Μια δοµή δεδοµένων είναι µια δοµηµένη
(οργανωµένη) συλλογή στοιχείων (π.χ., ψηφίων,
χαρακτήρων, αριθµών, αλφαριθµητικών, κλπ.).
n  Η πιο βασική δοµή στην Python είναι η ακολουθία.
n  Κύριοι τύποι ακολουθιών:
¡  Λίστα (list)
¡  Πλειάδα (tuple)
¡  Αλφαριθµητικό (string)
n  Βασική διαφορά µεταξύ λιστών και άλλων
ακολουθιών είναι ότι οι λίστες µπορούν να
µεταβληθούν 2
Χρήση ακολουθιών
n  Η χρήση ακολουθιών στην Python είναι εκτενής
n  Ορίζουµε και χρησιµοποιούµε ακολουθίες όταν
θέλουµε να διαχειριστούµε συλλογές δεδοµένων
n  Π.χ. χρήση λιστών για τη δηµιουργία µιας βάσης
δεδοµένων µε ονόµατα και ηλικίες προσώπων:
>>>edward=['Edward Gumby', 42]
>>>john=['John Smith', 50]
>>>database=[edward, john]
>>>database
[['Edward Gumby', 42], ['John Smith', 50]]

Λίστες
n  Μια λίστα ορίζεται σαν ακολουθία στοιχείων,
χωρισµένα από κόµµατα, εντός ενός [ και ενός ]
n  Μια λίστα µπορεί να περιέχει στοιχεία διαφορετικών
τύπων

>>>edward=['Edward Gumby', 42]


>>>john=['John Smith', 50] λίστα από λίστες
>>>database=[edward, john]
>>>database
[['Edward Gumby', 42], ['John Smith', 50]]

4
Προσπέλαση στοιχείων
n  Τα στοιχεία µιας λίστας µπορούν να προσπελαστούν
κατ’ αντιστοιχία µε την προσπέλαση χαρακτήρων σε
ένα αλφαριθµητικό
n  Το πρώτο στοιχείο στη θέση 0, το 2ο στη θέση 1,
κλπ.
n  Επίσης: αρνητική δεικτοδότηση
>>> john[0]
'John Smith'
>>> database[-1]
['John Smith', 50]

Άλλες λειτουργίες σε λίστες


µήκος λίστας =
αριθµός στοιχείων στη λίστα
>>> len(database)
2 συνένωση λιστών
>>> john + john
['John Smith', 50, 'John Smith', 50] συνένωση λιστών
µε διαφορετικά στοιχεία
>>> john + database
['John Smith', 50, ['Edward Gumby', 42], ['John Smith', 50]]
επαλήθευση µέλους λίστας
>>> 'John Smith' in john
True
>>> 'John Smith' in database
False γιατί;;
τα µέλη της database είναι ['Edward Gumby', 42] και ['John Smith', 50]

6
Άλλες λειτουργίες σε λίστες
>>> 3 * john
['John Smith', 50, 'John Smith', 50, 'John Smith', 50]

>>> lst = [23.99, 19.99, 34.50, 120.99]


>>> min(lst)
19.99
>>> max(lst)
120.99
>>> sum(lst)
199.46999999999997

Άσκηση
n  Δίνεται µια λίστα µε λέξεις. Βρες τη µικρότερη και
τη µεγαλύτερη λέξη (σε λεξικογραφική σειρά)

>>> words = ['bat', 'ball', 'barn', 'basket', 'badmington']

>>> min(words)
'badmington'
>>> max(words)
'bat'

8
Κατάτµηση λιστών
n  Κατάτµηση (slicing): Ένα τµήµα µιας λίστας
ορίζεται µε ένα διάστηµα θέσεων [x:y] σε αυτή
n  Το x είναι η θέση του πρώτου στοιχείου και το y η
εποµένη της θέσης του τελευταίου που θέλουµε
>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
>>> letters[3:6]
['d', 'e', 'f']
>>> letters[-3:-1]
µη έγκυρο διάστηµα
['h', 'i']
>>> letters[-3:0]
[]
9

Κατάτµηση λιστών
n  To διάστηµα θέσεων [x:y] µπορεί να έχει ένα ή
και κανένα όριο
¡  Π.χ. αν δεν προσδιορίσουµε το πάνω όριο, τότε
εννοείται ότι θέλουµε µεχρι το τελευταίο στοιχείο
>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
>>> letters[-3:]
['h', 'i', 'j']
>>> letters[:5]
['a', 'b', 'c', 'd', 'e']
>>> letters[:]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

10
Άσκηση
n  Δίνεται µια διαδικτυακή διεύθυνση (URL) του
τύπου http://www.something.com
n  Ζητείται να υπολογίσουµε το domain (something)

# Split up a URL of the form http://www.something.com


url = input('Please enter the URL: ')
postfix = url[11:]
domain = postfix[:-4]
print("Domain name: ", domain)

Please enter the URL: http://www.python.org


Domain name: python
11

Βήµα
n  Στo διάστηµα θέσεων [x:y] µπορούµε να
ορίσουµε έναν τρίτο αριθµό (βήµα)
¡  ορίζει για καθε πόσα στοιχεία θα παίρνουµε ένα

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
>>> letters[0:7:2]
['a', 'c', 'e', 'g']
>>> letters[1::2]
['b', 'd', 'f', 'h', 'j']
>>> letters[::3]
['a', 'd', 'g', 'j'] αρνητικό βήµα
>>> letters[8:4:-2]
['i', 'g']
12
Δηµιουργία λίστας από
αλφαριθµητικό
n  Η συνάρτηση list() προσφέρει έναν γρήγορο
τρόπο δηµιουργίας λίστας χαρακτήρων

>>> list('Hello')
['H', 'e', 'l', 'l', 'o']

>>> x=list('Hello')
>>> x
['H', 'e', 'l', 'l', 'o']

13

Αλλαγή στοιχείων λίστας


n  Μπορούµε να προσπελάσουµε και να αλλάξουµε
ένα στοιχείο λίστας µε την χρήση δείκτη
n  Μπορούµε να σβήσουµε ένα στοιχείο λίστας
>>> x=list('Hello')
>>> x
['H', 'e', 'l', 'l', 'o']
>>> x[3]='p'
>>> x
['H', 'e', 'l', 'p', 'o']
>>> del x[4]
>>> x
['H', 'e', 'l', 'p']
14
Αλλά...
>>> x= 'Hello’
>>> x
'Hello'
>>> x[3] = 'p'
Traceback (most recent call last):
File "<pyshell#72>", line 1, in <module>
x[3] = 'p'
TypeError: 'str' object does not support item assignment

n  Στα αλφαριθµητικά (όπως και στις πλειάδες) δεν


µπορούµε να κάνουµε αλλαγές!

15

Αλλαγή τµηµάτων λίστας


n  Μπορούµε να αλλάξουµε ολόκληρα τµήµατα
λιστών µε χρήση slicing
>>> name = list('Perl')
>>> name
['P', 'e', 'r', 'l']
>>> name[2:] = list('ar')
>>> name αλλαγή στοιχείων και
['P', 'e', 'a', 'r'] επέκταση της λίστας
>>> name[1:] = list('ython') ταυτόχρονα
>>> name
['P', 'y', 't', 'h', 'o', 'n']

16
Αλλαγή τµηµάτων λίστας
n  Μπορούµε να αλλάξουµε ολόκληρα τµήµατα
λιστών µε χρήση slicing
εισαγωγή στοιχείων χωρίς
>>> numbers = [1, 5] να διαγράψουµε τα
>>> numbers[1:1] = [2, 3, 4] υπάρχοντα
>>> numbers
[1, 2, 3, 4, 5] διαγραφή στοιχείων µέσα
στο διάστηµα θέσεων
>>> numbers[1:4] = []
>>> numbers
[1, 5]

17

Μέθοδοι λίστών (append)


n  Μπορούµε να προσθέσουµε ένα στοιχείο στο
τέλος της λίστας µε τη µέθοδο append
¡  Μέθοδος: συνάρτηση που καλείται µέσα από ένα αντικείµενο

>>> x = list('Hello') η λίστα είναι αντικείµενο


>>> x η append είναι µέθοδος
['H', 'e', 'l', 'l', 'o'] λιστών
>>> x.append('p')
>>> x
['H', 'e', 'l', 'l', 'o', 'p'] µπορούµε να
>>> x.append('pow') προσθέσουµε
>>> x οποιουδήποτε τύπου
['H', 'e', 'l', 'l', 'o', 'p', 'pow'] στοιχεία σε µια λίστα
18
Μέθοδοι λίστών (count)
n  Μπορούµε να µετρήσουµε το πλήθος των
στοιχείων µιας λίστας που έχουν µια συγκεκριµένη
τιµή µε τη µέθοδο count

>>> x = [[1, 2], 1, 1, [2, 1, [1, 2]]]


>>> x.count(1)
2
>>> x.count([1,2])
1
>>> ['to', 'be', 'or', 'not', 'to', 'be'].count('to')
2

19

Μέθοδοι λίστών (extend)


n  Πολλαπλά στοιχεία προστίθενται σε µια λίστα µε
τη µέθοδο extend

>>> a = [1, 2, 3]
>>> b = a
>>> a.extend(b)
>>> a
[1, 2, 3, 1, 2, 3]

¡  To a.extend(b) είναι ισοδύναµο µε το a[len(a):]=b

20
Μέθοδοι λίστών (pop)
n  Η µέθοδος pop υπολογίζει ένα στοιχείο της λίστας
και ταυτόχρονα το διαγράφει από αυτή
αν δεν προσδιορίσουµε τη
>>> x = [1, 2, 3] θέση του στοιχείου η pop
>>> x.pop() θεωρεί ότι θέλουµε το
τελευταίο στοιχείο από τη
3 λίστα
>>> x
[1, 2]
>>> x.pop(0)
1
>>> x
[2]
21

Μέθοδοι λίστών (index)


n  Μπορούµε να ψάξουµε για την πρώτη εµφάνιση
ενός στοιχείου µε τη µέθοδο index

>>> knights = ['We', 'are', 'the', 'knights', 'who', 'say', 'ni']


>>> knights.index('who')
4
>>> knights.index('herring')
Traceback (most recent call last):
File "<pyshell#123>", line 1, in <module>
knights.index('herring')
ValueError: 'herring' is not in list

22
Μέθοδοι λίστών (reverse)
n  Η µέθοδος reverse αντιστρέφει τη σειρά των
στοιχείων της λίστας
>>> x=[1,2,3]
>>> x.reverse()
>>> x
[3, 2, 1] reversed(x): επιστρέφει τα
στοιχεία της λίστας x σε
>>> x=[1,2,3] αντίστροφη σειρά χωρίς να
>>> y=list(reversed(x)) αντιστρέφει την ίδια τη
>>> y λίστα x
[3, 2, 1]
>>> x
[1, 2, 3]

23

Μέθοδοι λίστών (sort)


n  Η µέθοδος sort ταξινοµεί τη λίστα, βάζοντας τα
στοιχεία της σε αυξουσα σειρα
>>> x = [4, 6, 2, 1, 7, 9]
>>> x.sort()
>>> x
[1, 2, 4, 6, 7, 9]

24
Μέθοδοι λίστών (sort)
n  Άσκηση: Θέλουµε να αρχικοποιήσουµε µια νέα
λίστα µε τα περιεχόµενα της x ταξινοµηµένα, χωρίς
να πειράξουµε τη x

>>> x = [4, 6, 2, 1, 7, 9]
>>> y=x
>>> y.sort() λάθος τρόπος:
>>> y το πρόβληµα είναι ότι το y
αναφέρεται στην ίδια λίστα µε
[1, 2, 4, 6, 7, 9] το x (το y δεν είναι αντιγραφή
>>> x του x)
[1, 2, 4, 6, 7, 9]

25

Μέθοδοι λίστών (sort)


n  Άσκηση: Θέλουµε να αρχικοποιήσουµε µια νέα
λίστα µε τα περιεχόµενα της x ταξινοµηµένα, χωρίς
να πειράξουµε τη x
>>> x = [4, 6, 2, 1, 7, 9] σωστός τρόπος αντιγραφής
>>> y=x[:] λίστας
>>> y.sort()
εναλλακτικά:
>>> y
[1, 2, 4, 6, 7, 9] y = list(x)
y = sorted(x)
y.sort()
>>> x
[4, 6, 2, 1, 7, 9]

26
Αντίστροφη ταξινόµηση
n  Άσκηση: Ταξινόµησε τη λίστα x τοποθετώντας τα
στοιχεία από το µεγαλύτερο στο µικρότερο
>>> x = [4, 6, 2, 1, 7, 9]
>>> x.sort()
>>> x.reverse()
>>> x
[9, 7, 6, 4, 2, 1]

n  Αλλιώς: x.sort(reverse=True)


n  Μεγάλη γκάµα δυνατοτήτων ταξινόµησης στην
Python: http://wiki.python.org/moin/HowTo/Sorting
27

Μεταβλητές (ξανά!)
n  Γενικά µια µεταβλητή αναφέρεται σε ένα
αντικείµενο (αριθµός, αλφαριθµητικό, λίστα, κλπ.)

>>> x = 5 x lst
>>> lst = [1,2,3,4]

5 [1,2,3,4]

28
Μεταβλητές (ξανά!)
n  Υπάρχουν δύο τύποι αντικειµένων:
µεταβαλλόµενα και µη µεταβαλλόµενα
¡  µεταβαλλόµενα: λίστες
¡  µή µεταβαλλόµενα: αριθµοί, αλφαριθµητικά, πλειάδες

>>> x = 5 x lst
>>> lst = [1,2,3,4]

5 [1,2,3,4]

29

Μεταβλητές (ξανά!)
n  Ο µόνος τρόπος να αλλάξουµε ένα
µη µεταβαλλόµενο αντικείµενο είναι να ορίσουµε
ένα νέο αντικείµενο για τη µεταβλητή µας

>>> x = 7 x lst

5 7 [1,2,3,4]

30
Μεταβλητές (ξανά!)
n  Αντίθετα, µπορούµε να αλλάξουµε ένα
µεταβαλλόµενο αντικείµενο, χωρίς να χρειαστεί
να ορίσουµε νέο

>>> lst[2] = 7 lst

[1,2,3,4]
7

31

Μεταβλητές (ξανά!)
n  Αν εξισώσουµε 2 µεταβλητές, αυτές θα
αναφέρονται στο ίδιο αντικείµενο.
¡  Αν το αντικείµενο είναι µεταβαλλόµενο και αλλάξει, οι
τιµές και των δύο µεταβλητών αλλάζουν

>>> lst = [1,2,3,4]


lst lstNew
>>> lstNew = lst
>>> lst[2] = 7
>>> lstNew [1,2,3,4]
[1, 2, 7, 4] 7

32
Μεταβλητές (ξανά!)
n  Αν εξισώσουµε 2 µεταβλητές, αυτές θα
αναφέρονται στο ίδιο αντικείµενο.
¡  Αν το αντικείµενο είναι µη µεταβαλλόµενο και
αλλάξουµε τη µία µεταβλητή, τότε αυτή θα αναφέρεται
σε άλλο αντικείµενο

>>> x = 5 y x
>>> y = x
>>> x = 7 5 7
>>> y
5
33

Μέθοδοι λίστών
n  Οι λίστες είναι η κύρια δοµή δεδοµένων στην
Python.
n  Υποστηρίζονται από µεγάλο αριθµό µεθόδων
>>> help(list)
Help on class list in module builtins:

class list(object)
| list() -> new empty list
| list(iterable) -> new list initialized from iterable's items
|
| Methods defined here:

34
Πλειάδες
n  Οι πλειάδες (tuples) είναι ακολουθίες, όπως οι
λίστες, οι οποίες όµως δεν µπορούν να
αλλαχθούν
¡  Το ίδιο ισχύει και για τα αλφαριθµητικά (strings)
>>> x=1,2,3
>>> x
(1, 2, 3)
>>> x[2]
3
>>> x[2] = 5
Traceback (most recent call last):
File "<pyshell#212>", line 1, in <module>
x[2] = 5
TypeError: 'tuple' object does not support item assignment 35

Πλειάδες - αρχικοποίηση
το κόµµα στο τέλος
>>> x = 1, υπονοεί πλειάδα µε ένα
>>> x στοιχείο
(1,) x = 1 (χωρίς κόµµα) ορίζει
>>> x = tuple([1]) οτί το x είναι ακέραιος
>>> x αριθµός και όχι πλειάδα!
(1,)
>>> tuple([1, 2, 3])
(1, 2, 3)
>>> tuple('abc')
('a', 'b', 'c')
>>> tuple((1, 2, 3))
(1, 2, 3)
>>> z = tuple()
>>> z
()
36
Λειτουργίες σε Πλειάδες
n  Ακριβώς όπως οι λειτουργίες σε λίστες (π.χ. slicing)
n  Διαφορές
¡  Οι πλειάδες δεν µπορούν να αλλαχθούν
¡  Οι πλειάδες δεν έχουν όλες τις µεθοδους λιστών
n  συγκεκριµένα: δεν έχουν τις µεθόδους που αλλάζουν τις λίστες

>>> x=1,2,3 >>> x.sort()


>>> x[:2] Traceback (most recent call last):
(1, 2) File "<pyshell#209>", line 1, in <module>
>>> x.count(2) x.sort()
AttributeError: 'tuple' object has no
1
attribute 'sort'
>>> x.index(3)
2 37

Γιατί πλειάδες;
n  Αφου οι πλειάδες έχουν περιορισµένη
λειτουργικότητα σε σχέση µε τις λίστες, γιατί τις
χρησιµοποιούµε;
¡  Κάποιες λειτουργίες που θα δούµε αργότερα (π.χ.
κλειδιά σε λεξικό) υποστηρίζοντα µε πλειάδες
¡  Κάποιες συναρτήσεις επιστρέφουν το αποτέλεσµά τους
σε µορφή πλειάδων, οπότε πρέπει να ξέρουµε πως να
τις χειριστούµε
n  Στη γενική περίπτωση στα προγράµµατα
χρησιµοποιούµε λίστες αντί για πλειάδες

38
Αλφαριθµητικά

Λειτουργίες σε αλφαριθµητικά
n  Μπορούµε να εφαρµόσουµε όλες τις λειτουργίες
που έχουµε δει για πλειάδες και λίστες (π.χ.
slicing) σε αλφαριθµητικά
n  Προσοχή!
¡  Τα αλφαριθµητικά δεν τροποποιούνται

>>> website = 'http://www.python.org'


>>> website[-3:] = 'com'
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
website[-3:] = 'com'
TypeError: 'str' object does not support item assignment
2
Slicing αλφαριθµητικών
>>> s='Hello World'
>>> s[4]
'o'
>>> s[3:7]
'lo W'
>>> s[-4:-1]
'orl' µη έγκυρο
διάστηµα
>>> s[4:2]
''
>>> s[7:2:-2]
'o l'

Άλλες λειτουργίες
>>> s='Hello World'
>>> min(s)
''
>>> max(s)
'r'
>>> 'Hello' in s
True
>>> len(s)
11
>>> 'Hello'*2+'World'
'HelloHelloWorld'

4
Μέθοδοι Αλφαριθµητικών
>>> s='Hello Hello World' επιστρέφει το αλφαριθµητικό
>>> s.count('Hello') µετά την αντικατάσταση αλλά
2 δεν αλλάζει το αρχικό s
>>> s.replace('Hello','Bye') τα αλφαριθµητικά δεν
'Bye Bye World' τροποποιούνται!
>>> s.split()
['Hello', 'Hello', 'World']
>>> s = 'hello'
>>> s.capitalize()
'Hello'
>>> s.upper()
'HELLO'
5

Μέθοδοι Αλφαριθµητικών
επιστρέφει τη θέση της
>>> s='Hello Hello World'
πρώτης εµφάνισης του
>>> s.find('Hello') ‘Hello’ στο s
0 άρχισε να ψάχνεις από τη
>>> s.find('Hello',1) θέση 1 και µετά
6
δηλώνει ότι το ‘Help’ δεν
>>> s.find('Help') υπάρχει στο s
-1
>>> seq = ['1', '2', '3', '4', '5']
>>> sep = '+' συνένωση των στοιχείων της
λίστας seq σε ένα
>>> sep.join(seq) αλφαριθµητικό
'1+2+3+4+5'

6
Που είναι το λάθος;
ΟΛΑ τα στοιχεία της
>>> seq = ['1', '2', '3', '4', 5] λίστας πρέπει να είναι
>>> sep = '+’ αλφαριθµητικά!
>>> sep.join(seq)
Traceback (most recent call last):
File "<pyshell#106>", line 1, in <module>
sep.join(seq)
TypeError: sequence item 4: expected str instance, int
found

Παράδειγµα της join


>>> dirs = '', 'usr', 'bin', 'env'
>>> '/'.join(dirs)
ο χαρακτήρας ‘\’
'/usr/bin/env'
>>> print('C:' + '\\'.join(dirs))
C:\usr\bin\env

8
string formating
n  Χρησιµοποιείται στον ορισµό η τύπωση
(στοιχισµένων) αλφαριθµητικών µε διαφόρους
τύπους δεδοµένων
δηλώνει µετατροπή σε αλφαριθµητικό
>>> '%s plus %s equals %s' % (1, 1, 2)
'1 plus 1 equals 2'
>>> from math import pi
>>> 'Pi: %f...' % pi δηλώνει µετατροπή σε float
'Pi: 3.141593...' δηλώνει µετατροπή
>>> 'Very inexact estimate of pi: %i' % pi σε int
'Very inexact estimate of pi: 3'

Πλάτος και ακρίβεια


>>> '%10f' % pi # Field width 10
η έξοδος είναι αλφαριθµητικό πλάτους 10
' 3.141593'
>>> '%10.2f' % pi # Field width 10,
precision 2
' 3.14'
>>> '%.2f' % pi # Precision 2
'3.14'
>>> '%.5s' % 'Guido van Rossum'
'Guido' παραµετροποιηµένο πλάτος
>>> '%.*s' % (5, 'Guido van Rossum')
'Guido'
‘0’ αντί για κενά στις θέσεις
>>> '%010.2f' % pi που δεν χρησιµοποιούνται
'0000003.14'
Στοίχηση
στοίχηση στα αριστερά
>>> '%-10.2f' % pi
'3.14 ' θετικός: κενο, αρνητικός: -
>>> print(('% 5d' % 10) + '\n' + ('% 5d' % -10))
10
-10 θετικός: +, αρνητικός: -
>>> print(('%+5d' % 10) + '\n' + ('%+5d' % -10))
+10
-10

Παραδείγµατα
>>> x=1234.5678
>>> print(x)
1234.5678
>>> print('%d' % x)
1234
>>> print('%10d' % x)
1234
>>> print('%s' % x)
1234.5678
>>> print('%10s' % x)
1234.5678

12
Παραδείγµατα
>>> x=1234.5678
>>> print('%9.4f' % x)
1234.5678
>>> print('%10.4f' % x)
1234.5678
>>> print('%10.3f' % x)
1234.568
>>> print('%10.5f' % x)
1234.56780

13

Παράδειγµα: τύπωµα
τιµοκαταλόγου
# Print a formatted price list with a given width
width = int(input('Please enter width: '))
price_width = 10
item_width = width - price_width
header_format = '%-*s%*s'
fformat = '%-*s%*.2f'
print ('=' * width)
print (header_format % (item_width, 'Item', price_width, 'Price'))
print ('-' * width)
print (fformat % (item_width, 'Apples', price_width, 0.4))
print (fformat % (item_width, 'Pears', price_width, 0.5))
print (fformat % (item_width, 'Cantaloupes', price_width, 1.92))
print (fformat % (item_width, 'Dried Apricots (16 oz.)', price_width, 8))
print (fformat % (item_width, 'Prunes (4 lbs.)', price_width, 12))
print ('=' * width)

14
Παράδειγµα: τύπωµα
τιµοκαταλόγου
Please enter width: 40
========================================
Item Price
----------------------------------------
Apples 0.40
Pears 0.50
Cantaloupes 1.92
Dried Apricots (16 oz.) 8.00
Prunes (4 lbs.) 12.00
========================================

15

Αλφαριθµητικές σταθερές
>>> import string χρήση του string module
>>> string.digits
'0123456789'
>>> string.printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGH
IJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\
\]^_`{|}~ \t\n\r\x0b\x0c'
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> '5' in string.digits
True

16
Αλφαριθµητικές σταθερές
n  string.digits A string containing the digits 0–9
n  string.letters A string containing all letters (upper- and
lowercase)
n  string.lowercase A string containing all lowercase letters
n  string.printable A string containing all printable characters
n  string.punctuation A string containing all punctuation
characters
n  string.uppercase A string containing all uppercase letters

17

Λεξικά
Γιατί Λεξικά;
n  Στις ακολουθίες (π.χ. λίστες, αλφαριθµητικά)
µπορούµε να αναφερόµαστε σε ένα στοιχείο µε
τον αριθµητικό δείκτη του (π.χ. database[1], s[4])
n  Κάποιες φορές βολεύει να αναφερόµαστε σε ένα
στοιχείο ή να ψάχνουµε ένα στοιχείο µε το όνοµά
του (π.χ. database['John'])
n  Τα λεξικά µας δίνουν αυτή τη δυνατότητα
¡  Ανάλογο της χρήσης λεξικού στην καθηµερινή µας ζωή

Λεξικά
n  Το λεξικό είναι µια συλλογή ζευγών
n  Κάθε ζεύγος περιέχει ένα κλειδί και µια τιµή
¡  Χρησιµοποιούµε τα κλειδιά για να ψάξουµε ή να
αναφερθούµε στις τιµές
¡  π.χ. κλειδί = όνοµα λέξης, τιµή = ορισµός λέξης
¡  π.χ. κλειδί = όνοµα, τιµή = τηλέφωνο χωρίζει κλειδί από τιµή
>>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
>>> phonebook['Beth'] δεν είµαστε
'9102' υποχρεωµένοι να
εισάγουµε τα κλειδιά σε
λεξικογραφική σειρά

3
Μοναδικότητα κλειδιών
n  Τα κλειδιά είναι µοναδικά σε ένα λεξικό
¡  δεν µπορεί δύο ζεύγη να έχουν τα ίδια κλειδιά
n  Οι τιµές δεν χρειάζεται να είναι µοναδικές
χρήση τελευταίου κλειδιού

>>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Beth': '3258’}


>>> phonebook
{'Beth': '3258', 'Alice': '2341'}
>>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '9102'}
>>> phonebook
{'Cecil': '9102', 'Beth': '9102', 'Alice': '2341'}

Μετατροπή από Λίστα


n  Η συνάρτηση dict δηµιουργεί ένα λεξικό από µια
λίστα πλειάδων
¡  κάθε πλειάδα είναι ένα ζεύγος-στοιχείο του λεξικού

>>> items = [('name', 'Gumby'), ('age', 42)]


>>> d = dict(items) οι τιµές ενός λεξικού
>>> d µπορεί να είναι
{'age': 42, 'name': 'Gumby'} οποιουδήποτε τύπου
>>> d['name']
'Gumby' τα κλειδιά δεν µπορεί να είναι λίστες
>>> d = {23:56, 'a':25, 'b':'c', (4,5):'d', 2:[4,5]}

5
Άλλη χρήση της dict()
n  Η συνάρτηση dict µπορεί να πάρει ως είσοδο και
µια σειρά από στοιχεία τύπου κλειδί=τιµή
>>> d = dict(name='Gumby', age=42)
>>> d
{'age': 42, 'name': 'Gumby'}
για κλειδιά τύπου
αλφαριθµητικού µόνο!

Βασικές λειτουργίες
>>> d = dict(name='Gumby', age=42)
>>> len(d)
2
>>> d['age']
42
>>> d['something']
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
d['something']
KeyError: 'something' True, αν υπάρχει
>>> 'something' in d εγγραφή στο d µε
False κλειδί ‘something’
>>> d['age']=43
>>> del d['age'] εισάγει νέα εγγραφή αν δεν υπάρχει το
>>> d['something']='I don\'t know’ κλειδί, αλλιώς την αλλάζει
7
Ειδικά χαρακτηριστικά
n  Τα κλειδιά πρέπει να είναι µη µεταβαλλόµενου
τύπου (δεν µπορεί να είναι λίστες)
n  Όταν ορίζουµε µια τιµή για ένα κλειδί, το ζευγάρι
(κλειδί, τιµή) εισάγεται στο λεξικό αν δεν υπάρχει
ήδη το κλειδί
¡  δεν γίνεται έτσι µε τις λίστες
>>> lst = ['a','b','c']
>>> lst[3] = 'd'
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
lst[3] = 'd'
IndexError: list assignment index out of range 8

Ειδικά χαρακτηριστικά
n  Η εύρεση (π.χ. τελεστής in) γίνεται µε βάση το
κλειδί
n  Η εύρεση σε µεγάλα λεξικά είναι γρηγορότερη από
την εύρεση σε µεγάλες λίστες
¡  δεικτοδότηση (indexing) µέσω κατακερµατισµού
(hashing)
n  Στα λεξικά, τα στοιχεία κλειδιών-τιµών δεν έχουν
κάποια συγκεκριµένη σειρά
¡  τα λεξικά είναι αταξινόµητα σύνολα, τα στοιχεία των
λιστών/πλειάδων είναι σε συγκεκριµένη σειρά

9
Formatting µε χρήση λεξικού
κλειδί λεξικό
>>> phonebook
{'Beth': '9102', 'Cecil': '3258', 'Alice': '2341'}
>>> "Cecil's phone number is %(Cecil)s." % phonebook
"Cecil's phone number is 3258."
>>> "Cecil's phone number is %s." % phonebook['Cecil']
"Cecil's phone number is 3258."

10

Η µέθοδος clear
n  Καθαρίζει το λεξικό από τα περιεχόµενά του

>>> d = {}
>>> d['name'] = 'Gumby’
>>> d['age'] = 42
>>> d
{'age': 42, 'name': 'Gumby'}
>>> d.clear()
>>> d
{}

11
Γιατί όχι αρχικοποίηση;

>>> x = {} >>> x = {}
>>> y = x >>> y = x
>>> x['key']='value' >>> x['key']='value'
>>> y >>> y
{'key': 'value'} {'key': 'value'}
>>> x = {} >>> x.clear()
>>> y >>> y
{'key': 'value'} {}

12

Η µέθοδος copy
n  Αντιγράφει το λεξικό σε ένα άλλο λεξικό
¡  ρηχή αντιγραφή: τα αντικείµενα δεν αντιγράφονται

>>> x = {'username': 'admin', 'machines': ['zeus','gaia']}


>>> y = x.copy()
>>> y['username']='user1' λίστα
>>> y['machines'].remove('gaia') (µεταβαλλόµενο
αντικείµενο)
>>> y
{'username': 'user1', 'machines': ['zeus']}
>>> x
{'username': 'admin', 'machines': ['zeus']}

13
Η µέθοδος copy
n  Αντιγράφει το λεξικό σε ένα άλλο λεξικό
¡  ρηχή αντιγραφή: τα αντικείµενα δεν αντιγράφονται

x = {'username': 'admin', x y
'machines': ['zeus','gaia']}
'username' 'machines' 'username' 'machines'
y = x.copy()
'admin' ['zeus','gaia'] 'user1'
y['username']='user1'

y['machines'].remove('gaia')

¡  αν αντικαταστήσουµε ένα µη µεταβαλλόµενο αντικείµενο


το πρωτότυπο δε µεταβάλλεται
¡  αν αλλάξουµε ένα µεταβαλλόµενο, το πρωτότυπο αλλάζει14

Η συνάρτηση deepcopy
n  Αντιγράφει το λεξικό σε ένα άλλο λεξικό
¡  πλήρης αντιγραφή: τα αντικείµενα αντιγράφονται

>>> from copy import deepcopy


>>> d = {}
>>> d['names'] = ['Alfred', 'Bertrand']
>>> c = d.copy()
>>> dc = deepcopy(d)
>>> d['names'].append('Clive')
>>> c
{'names': ['Alfred', 'Bertrand', 'Clive']}
>>> dc
{'names': ['Alfred', 'Bertrand']}
15
Αρχικοποίηση µέσω fromkeys
n  Αρχικοποίηση λεξικού µε κλειδιά µόνο
>>> dict.fromkeys(['name', 'age']) ειδική τιµή: σηµαίνει
{'age': None, 'name': None} «τίποτα» µια δική
>>> dict.fromkeys(['name', 'age'], '(unknown)') µας τιµή για
όλα τα
{'age': '(unknown)', 'name': '(unknown)'} κλειδιά

16

Η µέθοδος get
n  Ψάχνει και επιστρέφει µια τιµή µε βάση το κλειδί,
ενώ επιστρέφει «None» αν το κλειδί δεν υπάρχει
>>> d ={'John': '3456'}
>>> d['Paul']
Traceback (most recent call last):
File "<pyshell#145>", line 1, in <module>
d['Paul']
KeyError: 'Paul’
>>> print(d.get('Paul')) ειδική τιµή: σηµαίνει
None «τίποτα»
>>> print(d.get('John'))
3456
17
Η µέθοδος get
n  Ψάχνει και επιστρέφει µια τιµή µε βάση το κλειδί,
ενώ επιστρέφει «None» αν το κλειδί δεν υπάρχει
>>> d ={'John': '3456'} αντικαθιστά το None, σε
>>> print(d.get('Paul','N/A')) περίπτωση που δεν
υπαρχει το κλειδί ‘Paul’
N/A
>>> d = dict.fromkeys(['name', 'age'])
>>> print(d.get('name'))
None
>>> print(d.get('Paul','N/A')) το ‘Paul’ δεν υπάρχει
N/A
>>> print(d.get('name','N/A')) το ‘name’ υπάρχει!
None
18

Η µέθοδος has_key
n  Επιστρέφει True αν το κλειδί που παίρνει για
όρισµα υπάρχει στο λεξικό, αλλίως False
>>> d = {}
>>> d.has_key('name')
False
>>> d['name'] = 'Eric'
>>> d.has_key('name')
True

19
Η µέθοδοi items, keys και
values
n  items: Επιστρέφει όλα τα ζευγάρια του λεξικού σε µια λίστα
(χωρίς κάποια συγκεκριµένη σειρά)
n  keys: Επιστρέφει όλα τα κλειδιά του λεξικού σε µια λίστα
(χωρίς κάποια συγκεκριµένη σειρά)
n  values: Επιστρέφει όλες τις τιµές του λεξικού σε µια λίστα
(χωρίς κάποια συγκεκριµένη σειρά)

>>> d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0}


>>> d.items()
[('url', 'http://www.python.org'), ('spam', 0), ('title', 'Python Web Site')]
>>> list(d.keys())
['url', 'title', 'spam']
>>> list(d.values())
['http://www.python.org', 'Python Web Site', 0]
20

Η µέθοδοι pop και popitem


n  pop: Επιστρέφει την τιµή του κλειδιού που παίρνει
σαν όρισµα, µετά σβήνει το αντίστοιχο ζευγάρι
n  pop: Επιστρέφει οποιοδήποτε ζευγάρι και το
σβήνει από το λεξικό
>>> d = {'x': 1, 'y': 2, 'z': 2}
>>> d.pop('y')
2
>>> d
{'x': 1, 'z': 2}
>>> d.popitem()
('x', 1)
>>> d
{'z': 2}
21
Η µέθοδος setdefault
n  Παρόµοια µε την get. Αν δε βρει το κλειδί, το
εισάγει στο λεξικό µε µια τιµή που δίνουµε εµείς
>>> d ={'John': '3456'}
>>> d.setdefault('Paul', 'unknown') το κλειδί ‘Paul’ δεν
'unknown' υπάρχει: εισάγεται το
'Paul’: ‘unknown’ στο
>>> d λεξικό
{'Paul': 'unknown', 'John': '3456'}
>>> d.setdefault('John', 'unknown') το κλειδί ‘John’ υπάρχει:
'3456' επιστρέφεται η τιµή του και
το λεξικό δεν αλλάζει
>>> d
{'Paul': 'unknown', 'John': '3456'}

22

Η µέθοδος update
n  Εισάγει σε ένα λεξικό τα περιεχόµενα ενός άλλου.
Τυχόν υπάρχουντα κλειδιά, ενηµερώνονται.

>>> d ={'John': '3456', 'Paul': '9123'}


>>> t ={'Paul': '1234', 'Sue': '2014'}
>>> d.update(t)
>>> d η τιµή του ‘Paul’
{'Sue': '2014', 'Paul': '1234', 'John': '3456'} αντικαθίσταται

23
Διάφορες Λειτουργίες

Τύπωµα µε κόµµατα
n  Η συνάρτηση print µπορεί να πάρει µια σειρά
από ορίσµατα χωρισµένα µε κόµµατα
n  Η print αφήνει ένα κενό µεταξύ των τυπωµένων
ορισµάτων
>>> x = 10
>>> print("x =", x) δεν επιτρέπεται πρόσθεση αριθµού σε
x = 10 αλφαριθµητικό
>>> print("x = "+x)
Traceback (most recent call last):
File "<pyshell#232>", line 1, in <module>
print("x = "+x)
TypeError: Can't convert 'int' object to str implicitly 2
Modules, ξανά
n  Η συνάρτηση import επιτρέπει τη χρήση
συναρτήσεων από modules
>>> import math
>>> math.sqrt(4)
2.0
>>> from math import sqrt
>>> sqrt(4) ΟΛΕΣ τις συναρτήσεις και σταθερές
2.0 από τη math
>>> from math import *
>>> sqrt(pi)
1.7724538509055159

Μαζικές αναθέσεις τιµών


n  Μπορούµε να αναθέσουµε τιµές σε πολλές
µεταβλητές ταυτόχρονα
>>> x,y,z = 1,2,3
>>> print(z)
3
>>> print(x,y)
12
>>> values = 1,2,3
>>> values
(1, 2, 3)
>>> z,y,x = values
>>> z
1 4
Αναθέσεις από άλλο
αντικείµενο
n  Μπορούµε να αναθέσουµε τιµές σε πολλές
µεταβλητές ταυτόχρονα
>>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Beth': '3258'}
>>> name, phoneno = phonebook.popitem()
>>> name
'Beth'
>>> phoneno
'3258'

Αλυσιδωτές αναθέσεις
n  Αναθέσεις ίδιων τιµών σε πολλές µεταβλητές σε
µία γραµµή
>>> x = y = max(2,15,4)
>>> x
15
>>> y Το ίδιο µε:
15 y = max(2,15,4)
x=y

6
Ανάθεση µε βάση
προηγούµενη τιµή
n  Οι τελεστές +,*,/,%,κλπ. µπορούν να
χρησιµοποιηθούν σαν +=,*=,κλπ. αν παίρνουµε τις
τιµές από την ίδια µεταβλητή
>>> x=1
>>> x+=1 Το ίδιο µε:
>>> x x = x+1
2
>>> fnord = 'foo'
>>> fnord += 'bar'
>>> fnord *= 2
>>> fnord
'foobarfoobar'
7

Έλεγχος Ροής Προγράµµατος


Ροή προγράµµατος
n  Μέχρι τώρα έχουµε δει προγράµµατα απλής ροής
¡  Οι εντολές εκτελούνται η µία µετά την άλλη σύµφωνα µε
την ακολουθία γραµµών του προγράµµατος
n  Σε τυπικά προγράµµατα η ροή είναι πιο σύνθετη
¡  Χρήση συνθηκών για τον έλεγχο ροής
¡  Χρήση επαναλήψεων

Διαγράµµατα Ροής
n  Τρόπος σχεδιασµού ενός αλγορίθµου
¡  Ο αλγόριθµος είναι το σχέδιο του προγράµµατος
n  Βασικά µέρη ενός διαγράµµατος ροής

no
temp > 30 print(x)

yes

απόφαση εντολή ροή

3
Έλεγχος ροής µε if
n  if δυαδική έκφραση :
µπλοκ εντολών οι εντολές στο
temp = eval(input('Enter the current temperature: ')) µπλοκ είναι
if temp > 25: στοιχισµένες
print('It is hot!') 4 θέσεις δεξιά
print('Be sure to drink liquids.')

temp = eval(input('Enter the current temperature: '))

yes
temp > 25
no print('It is hot!')

print('Be sure to drink liquids.')

Έλεγχος ροής µε if
n  if δυαδική έκφραση :
µπλοκ εντολών
temp = eval(input('Enter the current temperature: '))
if temp > 25: µετά το µπλόκ,
print('It is hot!') εκτελείται
print('Be sure to drink liquids.') ανεξάρτητα από
print('Goodbye!') την έκβαση της if

temp = eval(input('Enter the current temperature: '))

yes
temp > 25
no print('It is hot!')

print('Be sure to drink liquids.')

print('Goodbye!') 5
Έλεγχος ροής µε if/else
n  if δυαδική έκφραση :
µπλοκ εντολών
else :
µπλοκ εντολών

temp = eval(input('Enter the current temperature: '))


if temp > 25:
print('It is hot!')
print('Be sure to drink liquids.')
else:
print('It is not hot.')
print('Bring a jacket.')
print('Goodbye!')

Έλεγχος ροής µε if/else


n  if δυαδική έκφραση :
µπλοκ εντολών
else :
µπλοκ εντολών
temp = eval(input('Enter the current temperature: '))

no yes
temp > 25
print('It is not hot.') print('It is hot!')

print('Bring a jacket.') print('Be sure to drink liquids.')

print('Goodbye!')
7
Έλεγχος ροής µε if/elif/else
n  if δυαδική έκφραση :
µπλοκ εντολών
elif δυαδική έκφραση :
µπλοκ εντολών
else :
µπλοκ εντολών

x = eval(input('Enter a number: '))


if x > 0:
print('The number is positive')
elif x < 0:
print('The number is negative')
else:
print('The number is zero')

Έλεγχος ροής µε if/elif/else


µπορούµε να βάλουµε
n  if δυαδική έκφραση : όσα διαδοχικά elif
µπλοκ εντολών θέλουµε!
elif δυαδική έκφραση : Το elif σηµαίνει ‘else if’
µπλοκ εντολών
else :
µπλοκ εντολών
x = eval(input('Enter a number: '))

x > 0 yes
no print('The number is positive')
yes
x < 0
print('The number is negative') no

print('The number is zero')


9
Φωλιασµένα if
x = eval(input('Enter a number: '))
if x > 0:
if x > 1000:
print('A large positive number')
else :
print('The number is positive')
elif x < 0:
print('The number is negative')
else:
print('The number is zero') x = eval(input('Enter a number: '))

yes yes
x > 0 x > 1000
no no
yes print('A large positive number')
x < 0
print('The number is negative') no print('The number is positive')
print('The number is zero')
10

Συγκρίσεις

>>> a = 3 >>> x = [1,2,3]


>>> 0<a<5 >>> y = [1,2,3]
Για λίστες,
True >>> x == y πλειάδες,
>>> b = 3 True λεξικά, True
>>> a ==b >>> x is y µόνο αν οι
False µεταβλητές
True δείχνουν στο
>>> a is b >>> z = x
ίδιο
True >>> z is x αντικείµενο
>>> s1 = 'hello' True
>>> s2 = 'hello'
>>> s1 is s2
True
11
Τελεστές σύγκρισης
n  x == y το x ισούται µε το y.
n  x<y το x είναι µικρότερο από το y.
n  x>y το x είναι µεγαλύτερο από το y.
n  x >= y το x είναι µεγαλύτερο ή ίσο από το y.
n  x <= y το x είναι µικρότερο ή ίσο από το y.
n  x != y το x είναι διάφορο του y.
n  x is y x και y είναι το ίδιο αντικείµενο.
n  x is not y x και y είναι διαφορετικά αντικείµενα.
n  x in y το x είναι µέλος της ακολουθίας y.
n  x not in y το x δεν είναι µέλος της ακολουθίας y.

12

Λεξικογραφική σειρά

>>> "alpha" < "beta"


True
>>> [1, 2] < [2, 1]
True
>>> [2, [1, 4]] < [2, [1, 5]]
True

13
Παραδείγµατα
name = input('What is your name? ')
if 's' in name:
print('Your name contains the letter "s".')
else:
print('Your name does not contain the letter "s".')

14

Παραδείγµατα
number = int(input('Enter a number between 1 and 10: '))
if number <= 10:
if number >= 1:
print('Great!')
else:
print('Wrong!')
else:
print('Wrong!')

number = int(input('Enter a number between 1 and 10: '))


if 1<=number<=10:
print('Great!')
else:
print('Wrong!')

15
Παραδείγµατα (and, or, not)
number = int(input('Enter a number between 1 and 10: '))
if number>=1 and number<=10:
print('Great!')
else:
print('Wrong!')

number = int(input('Enter a number between 1 and 10: '))


if number<1 or number>10:
print('Wrong!')
else:
print('Great!')

number = int(input('Enter a number between 1 and 10: '))


if number>=1 and not number>10:
print('Great!')
else:
print('Wrong!')
16

Εναλλακτικοί τρόποι χρήσης if


>>> name = input('Please enter your name: ') or '<unknown>'
Please enter your name: επιστρέφει το or
>>> name µόνο αν το input()
'<unknown>' είναι κενό (False)
>>> name = input('Please enter your name: ') or '<unknown>'
Please enter your name: Joe False είναι τα
>>> name ακόλουθα:
'Joe' 0,'', (), {}, [], None

το ίδιο µε:
>>> y=0
if y>1:
>>> x = 5 if y>1 else 0
x=5
>>> x
else:
0
x=0
17
Άσκηση
n  Τί πρόβληµα έχει ο παρακάτω κώδικας;

temp = int(input('Please input the current temperature: '))


if temp > 5:
print('It is cool') δεν θα
elif temp > 25: εκτελεστεί
print('It is hot!') ποτε!
else:
print('It is freezing!')
πρέπει να
προσέχουµε
n  Πώς θα φτιάξουµε το πρόγραµµά µας; τη σειρά µε
...
if temp > 25: την οποία
print('It is hot!') βάζουµε τις
elif temp > 5: συνθήκες!
print('It is cool')
... 18

Άσκηση
n  Είσοδος: ένας αριθµός από το 1 ως το 4
n  Έξοδος: τύπωσε ‘John’ αν είναι 1, ‘Paul’ αν είναι 2,
‘Maria’ αν είναι 3, ‘Sue’ αν είναι 4
c = int(input('Please input a number between 1 and 4: '))
if c == 1:
print('John')
elif c == 2:
print('Paul')
elif c == 3:
print('Maria')
elif c == 4:
print('Sue')

19
Άσκηση
n  Είσοδος: ένας αριθµός από το 1 ως το 4
n  Έξοδος: τύπωσε ‘John’ αν είναι 1, ‘Paul’ αν είναι 2,
‘Maria’ αν είναι 3, ‘Sue’ αν είναι 4
n  Χωρίς να χρησιµοποιήσετε if !
d = {1:'John',2:'Paul',3:'Maria',4:'Sue'}
c = int(input('Please input a number between 1 and 4: '))
print(d[c])

20

Επαναλήψεις (loops)
n  Στα προγράµµατά µας µπορεί να θέλουµε να
τρέξουµε την ίδια σειρά εντολών πολλές φορές
¡  µε πιθανές παραµετροποιηµένες µικροαλλαγές σε κάθε
επανάληψη
¡  είτε γνωρίζοντας πόσες φορές (for) είτε ενόσω µια
συνθήκη είναι αληθής (while)
x=1

no yes
x <= 100
print(x)

x=x+1
21
Ο βρόγχος while
n  Eνόσω η συνθήκη είναι αληθής εκτελείται το
µπλοκ εντολών που είναι στοιχισµένες κάτω της
x =1
while x <= 100:
print(x)
x += 1

κενό αλφαριθµητικό
True, αν το name
name = '' είναι κενό
while not name:
name = input('Please enter your name: ')
print('Hello, %s!' % name)

Αν θέλουµε το διάστηµα ' ' να µην είναι αποδεκτό σαν όνοµα, βάζουµε:
while not name or name.isspace() ή while not name.strip() 22

Ο βρόγχος for
n  Χρησιµοποιείται αν θέλουµε να επαναλάβουµε ένα
µπλοκ κώδικα, για κάθε τιµή ενός συνόλου
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for x in numbers:
print(x)

words = ['this', 'is', 'an', 'ex', 'parrot']


for x in words:
print(x[-1])
ορίζει ένα
for x in range(1,101): διάστηµα τιµών,
print(x) όπως και στο
slicing
23
Άσκηση
n  Γράψτε ένα πρόγραµµα που θα παίρνει ένα
αλφαριθµητικό από το χρήστη και θα τυπώνει τα
φωνήεντα του

s = input('Please input a string: ')


for c in s:
if c in 'aeoiu':
print(c)

24

Άσκηση
n  Τύπωσε τους ζυγούς αριθµούς µέχρι το 10

for x in range(11): range(11)=range(0,11)=


if x % 2 == 0: [0,1,2,3,4,5,6,7,8,9,10]
print(x)

for x in range(0,11,2):
print(x)

25
Άσκηση
n  Δίνεται µια λίστα lst αριθµών. Βρές το γινόµενό
τους
lst = [3,4,6,5]
prod = 1
for x in lst: το ίδιο µε
prod *= x prod = prod*x
print(prod)

26

Επαναλήψεις σε λεξικά
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print(key, 'corresponds to', d[key])
z corresponds to 3
y corresponds to 2
n  Εναλλακτικά: x corresponds to 1
d = {'x': 1, 'y': 2, 'z': 3}
for key, value in d.items():
print(key, 'corresponds to', value)

Υπενθύµηση: στα λεξικά δεν υπάρχει συγκεκριµένη σειρά προσπέλασης


των ζευγαριών

27
Παράλληλες επαναλήψεις
names = ['anne', 'beth', 'george', 'damon']
ages = [12, 45, 32, 102] range(4)=range(0,4)
for i in range(len(names)):
print (names[i], 'is', ages[i], 'years old')

anne is 12 years old


beth is 45 years old
george is 32 years old
damon is 102 years old

28

Παράλληλες επαναλήψεις - zip


names = ['anne', 'beth', 'george', 'damon']
ages = [12, 45, 32, 102]
for name, age in zip(names, ages):
print(name, 'is', age, 'years old')

anne is 12 years old


beth is 45 years old
george is 32 years old
damon is 102 years old

names = ['anne', 'beth', 'george', 'damon', 'paul', 'sue'] Τι θα τυπώσει;


ages = [12, 45, 32, 102]
Το ίδιο! Η zip
for name, age in zip(names, ages):
σταµατά στην
print(name, 'is', age, 'years old')
κοντύτερη σειρά
29
Παράλληλες επαναλήψεις - zip
names = ['anne', 'beth', 'george', 'damon']
ages = [12, 45, 32, 102]
lst = (3,45,66)
d = {'1':3, '2':4}
for n,a,l,di in zip(names, ages, lst, d):
print(n,a,l,d[di])

anne 12 3 4
beth 45 45 3

30

Διακοπή βρόγχου µε break


n  Χρησιµοποιούµε break όταν θέλουµε να
σταµατήσουµε ένα loop
n  Π.χ. βρες το µεγαλύτερο ακέραιο τετράγωνο < 100
from math import sqrt κατέβασµα από το
for n in range(99, 0, -1): 99 στο 1 µε
root = sqrt(n) αρνητικό βήµα (-1)
if root == int(root): Π.χ. προσπαθήστε:
print (n) list(range(0,100,5))
break
είναι το root ακέραιος;

31
While True µε break
n  Όταν θέλουµε να βγούµε από το βρόγχο ακριβώς
µόλις ικανοποιηθεί µια συνθήκη εξόδου, χωρίς να
εκτελέσουµε τις υπόλοιπες εντολές του βρόγχου
πάντα αληθές
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!"
µόνη πιθανή έξοδος

32

While True µε break


while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!"

33
While True µε break
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40 !

34

While True µε break


while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40 ! x == 40

35
While True µε break
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 40


The answer is NOT correct!!

36

While True µε break


while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 40


The answer is NOT correct!!

37
While True µε break
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 40


The answer is NOT correct!!
How many states are in the U.S.? 60!

38

While True µε break


while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 60


The answer is NOT correct!!
How many states are in the U.S.? 60!

39
While True µε break
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 60


The answer is NOT correct!!
How many states are in the U.S.? 60!
The answer is NOT correct!!

40

While True µε break


while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 60


The answer is NOT correct!!
How many states are in the U.S.? 60!
The answer is NOT correct!!

41
While True µε break
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 60


The answer is NOT correct!!
How many states are in the U.S.? 60!
The answer is NOT correct!!
How many states are in the U.S.? 50!

42

While True µε break


while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 50


The answer is NOT correct!!
How many states are in the U.S.? 60!
The answer is NOT correct!!
How many states are in the U.S.? 50!

43
While True µε break
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 50


The answer is NOT correct!!
How many states are in the U.S.? 60!
The answer is NOT correct!!
How many states are in the U.S.? 50!
Correct! There are 50 states in the U.S.!
44

While True µε break


while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!")

How many states are in the U.S.? 40! x == 50


The answer is NOT correct!!
How many states are in the U.S.? 60!
The answer is NOT correct!!
How many states are in the U.S.? 50!
Correct! There are 50 states in the U.S.!
45
Άσκηση
n  Ποια η διαφορά µεταξύ των 2 προγραµµάτων;
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
else:
print("The answer is NOT correct!"

while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
print("The answer is NOT correct!"
46

Άσκηση
n  Γράψε το ίδιο πρόγραµµα χωρίς χρήση break
while True:
x = int(input("How many states are in the U.S.? "))
if x == 50:
print("Correct! There are 50 states in the U.S.")
break;
print("The answer is NOT correct!"

x=0
while x !=50 :
x = int(input("How many states are in the U.S.? "))
if x !=50 :
print("The answer is NOT correct!")
print("Correct! There are 50 states in the U.S.")

47
Άσκηση
n  Δίνεται µια λίστα lst. Γράψε ένα πρόγραµµα που
να ελέγχει αν η λίστα είναι ταξινοµηµένη
lst = [3,4,6,5,7]
βοηθητική
is_sorted = True µεταβλητή
for i in range(0,len(lst)-1): έλεγχος αν
if lst[i] > lst[i+1]: υπαρχει στοιχείο
print('list',lst, 'is not sorted!') µεγαλύτερο από
is_sorted = False
το επόµενο
break
if is_sorted:
print('list' , lst , 'is sorted!')

48

H break σπάει τον


εσωτερικότερο βρόγχο
n  Τι θα τυπώσει το παρακάτω πρόγραµµα;
for i in range(3):
for j in range(3):
print(i,j)
if j==1: break

0 0!
0 1! Δες το στο http://pythontutor.com/visualize.html
1 0!
1 1!
2 0!
2 1!

49
Η εντολή continue
n  Τερµατίζει την τρέχουσα επανάληψη και πάει στην
επόµενη
n  Παράδειγµα: τύπωσε όλους τους χαρακτήρες ενός
αλφαριθµητικού, εκτός από τα φωνήεντα

s = input('Please input a string: ')


for c in s:
if c in 'aeoiu':
continue
print(c) Πήγαινε κατευθείαν στην
επόµενη επανάληψη

50

Χρήση else στη for


n  Εκτελείται µόνο όταν το for-loop δεν έχει «σπάσει»
λόγω break
from math import sqrt
for n in range(99, 90, -1):
root = sqrt(n)
if root == int(root):
print (n)
break
else: Εκτελείται αν το for
print("Didn't find it") τερµατίσει χωρίς break

51
Σύνθεση λίστας µε for/if

>>> [x*x for x in range(10)]


[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10) if x % 3 == 0]
[0, 9, 36, 81]
>>> [(x, y) for x in range(3) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
>>> girls = ['alice', 'bernice', 'clarice']
>>> boys = ['chris', 'arnold', 'bob']
>>> [b+'+'+g for b in boys for g in girls if b[0] == g[0]]
['chris+clarice', 'arnold+alice', 'bob+bernice']

52

Η εντολή pass

n  Χρησιµοποιείται αν δεν θέλουµε να κάνουµε


τίποτα σε ένα block

if name == 'Ralph Auldus Melish':


print 'Welcome!'
elif name == 'Enid':
# Not finished yet...
pass
elif name == 'Bill Gates':
print 'Access Denied'

53
Άσκηση

n  Τι θα κάνουν τα παρακάτω προγράµµατα;

for i in range(10):
if i % 2 == 0:
pass
else:
print(i)

for i in range(10):
pass
else:
print('ok')
54

Η συνάρτηση enumerate
n  Για κάθε στοιχείο µιας ακολουθίας (λίστας,
πλειάδας, κλπ.), επιστρέφει το στοιχείο και ένα
δείκτη στη θέση του.
n  Π.χ. τύπωσε τα διακριτά στοιχεία µιας λίστας

lst = [1,2,4,5,6,3,2,3,6,2,6,3,2]
lst2 = []
for idx,elem in enumerate(lst):
if elem not in lst[0:idx]: Αν δεν εµφανίζεται στα
lst2.append(elem) προηγούµενα
print(lst2)
[1, 2, 4, 5, 6, 3]
55
Σηµαντικό!

n  Εξασκηθείτε στο να «τρέχετε» ένα πρόγραµµα


µόνοι σας και στο να παρακολουθείτε τις τιµές
των µεταβλητών και τη ροή του προγράµµατος
n  Θα σας βοηθήσει και ο Python visualizer:
¡  http://pythontutor.com/visualize.html

56
Εισαγωγή στον Προγραµµατισµό

Σύντοµες Σηµειώσεις

Γιώργος Μανής

Νοέµβριος 2012
Αλγόριθµοι και Λογικά
∆ιαγράµµατα

Αλγόριθµος λέγεται µία πεπερασµένη διαδικασία καλά ορισµένων ϐηµάτων


µου ακολουθείται για τη λύση ενός προβλήµατος, ενώ το λογικό διάγραµµα
(Λ∆) ή αλλιώς διάγραµµα ϱοής προγράµµατος (∆ΡΠ) είναι µία σχηµατική πα-
ϱάσταση του αλγορίθµου. Η έννοια του αλγορίθµου είναι πολύ ϐασική στην
πληροφορική, ενώ το λογικό διάγραµµα ένα πολύ χρήσιµο περιγραφικό ερ-
γαλείο. ΄Ενα λογικό διάγραµµα αποτελείται από σύµβολα και λέξεις οι οποίες
είναι σε ϑέση να περιγράψουν µε λεπτοµέρεια κάθε διαδικασία επίλυσης ο-
ποιουδήποτε προβλήµατος.
Η κατασκευή ενός λογικού διαγράµµατος προηγείται της κωδικοποίησης.
Το λογικό διάγραµµα δίνει τη δυνατότητα να µελετήσουµε καλά ένα πρόβληµα
και να εµβαθύνουµε σε αυτό, επιτρέπει να το σχεδιάσουµε στην ολότητά του
και να το δούµε λυµένο (ή να διαπιστώσουµε αν λύνεται) πριν ακόµα ξεκινή-
σουµε την επίπονη διαδικασία της κωδικοποίησης, αλλά και να συγκρίνουµε
διαφορετικές µεταξύ τους λύσεις και να επιλέξουµε την καλύτερη αρκετά νω-
ϱίς, αφού οι αλλαγές κατά την κωδικοποίηση είναι πολύ πιο ακριβές από ότι
οι αλλαγές κατά τη σχεδίαση ενός συστήµατος.
Τα ϐασικότερα σύµβολα που χρησιµοποιούνται από ένα λογικό διάγραµ-
µα είναι η έλλειψη, το ορθογώνιο και το πλάγιο παραλληλόγραµµο, ο ϱόµβος
και τα ϐέλη (Σχήµα 1). Οι ελλείψεις χρησιµοποιούνται για να συµβολίσουν
την αρχή και το τέλος ενός αλγορίθµου. Τα ορθογώνια παραλληλόγραµµα
συµβολίζουν επεξεργασία. Τα πλάγια παραλληλόγραµµα είσοδο και έξοδο δε-
δοµένων, ενώ οι ϱόµβοι αποτελούν σηµεία στα οποία πρέπει να ληφθεί κάποια
απόφαση. Με τα ϐέλη απεικονίζουµε τη ϱοή του προγράµµατος. Πέρα από
αυτά τα σύµβολα, υπάρχουν µερικά ακόµα, δευτερεύουσας σηµασίας, αλλά

1
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 2

Σχήµα 1: Τα ϐασικότερα σύµβολα που χρησιµοποιούνται στα λογικά διαγράµ-


µατα

επίσης χρήσιµα. Ας µείνουµε τώρα σε αυτά και ας τα δούµε αναλυτικά.


Η έλλειψη χρησιµοποιείται για να σηµειωθεί η αρχή και το τέλος του αλ-
γορίθµου. Το πλάγιο παραλληλόγραµµο περιγράφει διαδικασία εισόδου ή
εξόδου στοιχείων. Στο παράδειγµα της πρόσθεσης είσοδο δεδοµένων έχουµε
στην αρχή του προγράµµατος όπου και πρέπει να δοθούν από το χρήστη στον
υπολογιστή οι δύο αριθµοί που ϑα προστεθούν. Σε εκείνο το σηµείο έχουµε
και έξοδο δεδοµένων, αφού για κάθε έναν από τους δύο αριθµούς που Ϲη-
τούνται προηγείται ένα µήνυµα διευκρινιστικό προς το χρήστη (¨∆ώσε µου τον
πρώτο αριθµό¨ και ¨∆ώσε µου τον δεύτερο αριθµό¨). ΄Εξοδο έχουµε στο τέλος
του προγράµµατος, όπου έχουµε την εµφάνιση του αποτελέσµατος στην οθό-
νη συνοδευόµενο πάλι από το κατάλληλο ϐοηθητικό µήνυµα (¨Το αποτέλεσµα
είναι :¨). Τα µέρη του διαγράµµατος ϱοής προγράµµατος για το πρόβληµα
της πρόσθεσης που αναλογούν στην είσοδο και έξοδο δεδοµένων ϕαίνεται στα
σχήµατα 2(α΄) και 2(ϐ΄) αντίστοιχα.
Ο ϱόµβος χρησιµοποιείται για να συµβολιστούν σηµεία στα οποία πρέπει
να ληφθεί κάποια απόφαση. Σηµεία δηλαδή, στα οποία το πρόγραµµα έχει
περισσότερες από ένα δρόµο να επιλέξει ανάλογα µε το αν ισχύουν ή όχι
κάποιες συνθήκες. Στο πρόγραµµα της πρόσθεσης δεν απαιτείται ϱόµβος,
αλλά ϑα δούµε παρακάτω ένα άλλο πρόβληµα (την λύση του τριωνύµου) στο
οποίο απαιτείται.
Το ορθογώνιο παραλληλόγραµµο χρησιµοποιείται για να περιγραφεί κά-
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 3

(α΄) Εισαγωγή δεδοµένων για το (ϐ΄) ΄Εξοδος δεδοµένων για το πρό-


πρόγραµµα της πρόσθεσης γραµµα της πρόσθεσης

Σχήµα 2: Είσοδος και έξοδος δεδοµένων για την πρόσθεση

ποια διαδικασία. Στο παράδειγµα, ϑα συµβολιστεί µε ορθογώνιο παραλληλό-


γραµµο η πρόσθεση των δύο αριθµών.
Τέλος, τα ϐέλη ϱοής δείχνουν ποιο είναι το επόµενο σχήµα στο λογικό
διάγραµµα στο οποίο ϑα µεταβεί ο έλεγχος του προγράµµατος. Από κάθε
σχήµα µπορεί να µη ξεκινά κανένα ϐέλος (συµβαίνει όταν τερµατίζεται το
πρόγραµµα), µπορεί να ξεκινά ένα ϐέλος το οποίο καταλήγει στο επόµενο
σχήµα στο οποίο ϑα περάσει η εκτέλεση ή περισσότερα ϐέλη όταν έχουµε
ϱόµβο απόφασης. Το διάγραµµα ϱοής προγράµµατος για το πρόβληµα της
πρόσθεσης εικονίζεται στο σχήµα 3.
Πριν όµως προχωρήσουµε στην κωδικοποίηση, ας δούµε και ένα λίγο µε-
γαλύτερο παράδειγµα, ένα πρόγραµµα που δέχεται σαν είσοδο ένα τριώνυµο
και αποφασίζει αν το τριώνυµο έχει και πόσες πραγµατικές ϱίζες. Στην περί-
πτωση που το τριώνυµο έχει πραγµατικές ϱίζες τότε αυτές υπολογίζονται και
τυπώνονται στην οθόνη. Στην περίπτωση που το τριώνυµο δεν έχει πραγµα-
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 4

Σχήµα 3: Ολοκληρωµένο το λογικό διάγραµµα της πρόσθεσης

τικές ϱίζες, τότε τυπώνεται ένα µήνυµα που µας ειδοποιεί ότι δεν υπάρχουν
πραγµατικές ϱίζες.
Είσοδος στοιχείων απαιτείται κατά την εκκίνηση του προγράµµατος όπου
και Ϲητείται το τριώνυµο, οι συντελεστές α, ϐ και γ δηλαδή. ΄Ετσι, στην αρχή
του λογικού διαγράµµατος υπάρχουν τρία πλάγια παραλληλόγραµµα. Για να
είναι το πρόγραµµα ϕιλικό στο χρήστη πριν από κάθε ερώτηση για τις τιµές
των α, ϐ και γ πρέπει να τυπώνεται ένα µήνυµα στην οθόνη που να πληροφορεί
το χρήστη τι ακριβώς πρέπει να κάνει. Συνεπώς, πριν από κάθε πλάγιο πα-
ϱαλληλόγραµµο για την εισαγωγή µίας τιµής πρέπει να υπάρχει και ένα άλλο
πλάγιο παραλληλόγραµµο που να τυπώνει ένα µήνυµα της µορφής : ¨∆ώσε
µου το συντελεστή α :¨, ή ¨∆ώσε µου το συντελεστή ϐ:¨ ή ¨∆ώσε µου το συν-
τελεστή γ:¨, αντίστοιχα. Στο τέλος του προγράµµατος πρέπει να τυπώνεται το
αποτέλεσµα. ΄Ετσι, σε κάποιο σηµείο του λογικού µας διαγράµµατος πρέπει
να υπάρχουν τα κατάλληλα πλάγια παραλληλόγραµµα για τα αποτελέσµατα :
¨Το τριώνυµο δεν έχει πραγµατικές ϱίζες¨ και ¨Το τριώνυµο έχει µία πραγ-
µατική διπλή ϱίζα την :¨ και ¨Το τριώνυµο έχει δύο πραγµατικές ϱίζες τις :¨.
Επίσης, αν διαπιστωθεί ότι η εξίσωση είναι πρωτοβάθµια πρέπει να τυπωθεί το
κατάλληλο µήνυµα ¨Η εξίσωση είναι πρωτοβάθµια¨ (Αν και αυτό µαθηµατικά
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 5

δεν είναι απόλυτα σωστό, αλλά ας κρατήσουµε το πρόγραµµα σχετικά απλό).


Μπορεί κανείς να παρατηρήσει ότι σε ένα τόσο απλό πρόγραµµα και για µια
τόσο απλή διαδικασία απαιτούνται τόσα πολλά πλάγια παραλληλόγραµµα. Το
ίδιο πρόβληµα υπάρχει µε όλα τα σχήµατα του λογικού διαγράµµατος. Για να
µειώσουµε την έκτασή του συνηθίζουµε να οµαδοποιούµε λειτουργίες περισ-
σοτέρων σχηµάτων σε ένα, όταν αυτό δεν αποβαίνει σε ϐάρος της περιγραφής
του αλγορίθµου. Στο συγκεκριµένο παράδειγµα µπορούµε να χρησιµοποιή-
σουµε ένα ή δύο πλάγια παραλληλόγραµµα αντί για έξι στην αρχή του προ-
γράµµατος, ενώ από ένα µπορεί να χρησιµοποιηθεί και για κάθε µία από τις
πιθανές περιπτώσεις αποτελέσµατος.

Σχήµα 4: ∆ιάγραµµα ϱοής για την επίλυση του τριωνύµου

Στο παράδειγµα του τριωνύµου χρησιµοποιείται και ο ϱόµβος. Ο αλγό-


ϱιθµος σε κάποιο σηµείο εξετάζει εάν η διακρίνουσα είναι ϑετική, αρνητική ή
µηδέν και αποφασίζει εάν υπάρχουν και πόσες πραγµατικές ϱίζες. Σε κάθε
µία από τις τρεις περιπτώσεις το πρόγραµµα ακολουθεί διαφορετικό δρόµο
και κάνει διαφορετικούς υπολογισµούς. Είναι ένα χαρακτηριστικό παράδειγ-
µα λογικής απόφασης. Στο ίδιο πρόγραµµα πρέπει να γίνει έλεγχος εάν το
α είναι µηδέν ή όχι, γιατί σε αυτή την περίπτωση η λύση είναι πρωτοβάθµια.
Πάλι δηλαδή έχουµε µία περίπτωση απόφασης µε δύο δρόµους αυτή τη ϕορά,
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 6

έναν που το πρόγραµµα ϑα συνεχίζει κανονικά στην επίλυση του τριωνύµου


και έναν που ϑα τυπώνει το µήνυµα ¨Η επίλυση ανάγεται πρωτοβάθµια¨ και
ϑα τερµατίζεται το πρόγραµµα. Το διάγραµµα ϱοής για το τριώνυµο ϕαίνεται
στο σχήµα 4.

Σχήµα 5: ∆ιάγραµµα ϱοής για την εύρεση του µέγιστου τριών αριθµών

Ας δούµε λίγα ακόµα ενδιαφέροντα διαγράµµατα ϱοής προγράµµατος.


Στο σχήµα 5 ϕαίνεται ένα διάγραµµα ϱοής στο οποίο τρεις αριθµοί συγκρί-
νονται έτσι ώστε να ϐρεθεί ποιος από τους τρείς είναι ο µεγαλύτερος. ∆ε µας
ενδιαφέρει να διαπιστώσουµε ότι για παράδειγµα ο δεύτερος αριθµός είναι ο
µεγαλύτερος, αλλά ποια τιµή έχει ο µεγαλύτερος από τους τρεις αριθµούς.
∆ηλαδή, αν έχουµε σαν είσοδο τους αριθµούς 3,8,5 η απάντηση είναι 8. Το
λογικό διάγραµµα ξεκινάει εισάγωντας τους τρεις αριθµούς, έστω A,B ,C . Στη
συνέχεια εξετάζουµε ποιος από τους δύο πρώτους (A και B ) είναι ο µεγαλύ-
τερος. Αν ο A είναι ο µεγαλύτερος, τότε αποκλείουµε την περίπτωση ο B να
είναι ο µεγαλύτερος από τους τρεις. ΄Ετσι συνεχίζουµε την αναζήτηση ανάµε-
σα στους A και C . ΄Οµοια, αν ο B ήταν ο µεγαλύτερος, τότε ϑα αποκλείαµε
την περίπτωση ο A να ήταν ο µεγαλύτερος από τους τρεις. ΄Ετσι ϑα συνεχί-
Ϲουµε την αναζήτηση ανάµεσα στους B και C . Η δεύτερη σύγκριση ανάµεσα
στους δύο πιθανούς αριθµούς, αφού αποκλείστηκε ο ένας από τους τρεις, µας
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 7

ϕανερώνει το µέγιστο ο οποίος και τυπώνεται. Παρατηρείστε ότι το διάγραµ-


µα ϱοής προγράµµατος επιστρέφει σωστό αποτέλεσµα στην περίπτωση που ο
µεγαλύτερος αριθµός εµφανίζεται σε δύο ή και στις τρεις από τις µεταβλητές
A,B ,C . Ας δούµε γιατί : έστω A = B και A > C και ϕυσικά B > C . Η πρώτη
σύγκριση ϑα µας οδηγήσει στο ϱόµβο B > C και στη συνέχεια ϑα τυπωθεί το
B . ∆ε µας πειράζει ότι το αποτέλεσµα τυπώθηκε από το B . Θα µπορούσε να
είχε τυπωθεί και από το A αν είχαµε σχεδιάσει διαφορετικά το διάγραµµα. Σε
κάθε περίπτωση όµως και ανεξάρτητα από το αν ϑα τυπωθεί το αποτέλεσµα
από το A ή το B ο αριθµός που ϑα τυπωθεί ϑα έχει τη µέγιστη τιµή, την τιµή
δηλαδή που αναζητούσαµε. Σηµειώνουµε πάλι ότι το διαγραµµα ϱοής ϑα ήταν
διαφορετικό αν δε µας έννοιαζε να τυπωθεί η µέγιστη τιµή, αλλά µας ένοιαζε
και από ποια ή ποιες απο τις A,B ,C προήλθε αυτή η µέγιστη τιµή.

Σχήµα 6: ∆ιάγραµµα ϱοής για την εύρεση του παραγοντικού

Στο σχήµα 6 παρουσιάζεται το διάγραµµα ϱοής προγράµµατος για τον


υπολογισµό του παραγοντικού. Για να υπολογίσουµε το παραγοντικό του x
ϑα πρέπει να υπολογίσουµε την παράσταση 1 ∗ 2 ∗ 3 ∗ . . . ∗ x. Χρειαζόµαστε
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 8

δηλαδή µία µεταβλητή που ϑα ξεκινήσει από την τιµή 1, ϑα αυξάνεται σε


κάθε ϐήµα κατά 1 και ϑα καταλήγει να έχει την τιµή x. Ας ονοµάσουµε
τη µεταβλητή αυτή i. Σε κάθε ένα ϐήµα ϑα πρέπει µία άλλη µεταβλητή να
πολλαπλασιάζει την τιµή που είχε στο προηγούµενο ϐήµα µε την τιµή της
i. Ας την ονοµάσουµε f act. ∆είτε στη µέση του σχήµατος 6 την αύξηση των
µεταβλητών i και f act κατά 1 και i ϕορές αντίστοιχα. Παρατηρήστε στην αρχή
του διαγράµµατος την αρχικοποίηση των µεταβλητών αυτών σε 1. Το i είναι
προφανές γιατί πρέπει να αρχικοποιηθεί σε 1, αφού είπαµε ότι ϑέλουµε να
υπολογίσουµε την παράσταση 1 ∗ 2 ∗ 3 ∗ . . . ∗ x. Το f act πρέπει και αυτό
να αρχικοποιηθεί σε 1, και ο λόγος είναι ότι ϑέλουµε να το αρχικοποιήσουµε
στο ουδέτερο στοιχείο του πολλαπλασιασµού. Σκεφτείτε τι ϑα γινόταν αν το
αρχικοποιούσαµε στο 0. Το f act ϑα είχε πάντοτε την τιµή 0, αφού µε ό,τι
και να το πολλαπλασιάζαµε το αποτέλεσµα ϑα ήταν 0. Τώρα, σχεδόν έχουµε
περιγράψει όλο το διάγραµµα εκτός από το ϱόµβο που συγκρίνει το i µε το
x. Μετά την αύξηση της τιµής του f act, το i ελέγχεται για να διαπιστωθεί εάν
έχουν γίνει όλες οι επαναλήψεις που απαιτούνται. Εάν έχουν γίνει, δηλαδή αν
οι δύο µεταβλητές έχουν την ίδια τιµή, τότε ο υπολογισµός του παραγοντικού
έχει τελειώσει και τυπώνουµε το αποτέλεσµα. Εάν όχι, οδηγούµε τον έλεγχο
στο σηµείο που αυξάνεται το i κατά 1 και εκτελούµε ακόµα µία επανάληψη.

Σχήµα 7: ΄Ελεγχος ορθής εισόδου για το ∆ΡΠ του παραγοντικού


ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 9

Το διάγραµµα ϱοής προγράµµατος για τον υπολογισµό του παραγοντικού


ϕαίνεται να λειτουργεί. Για να είµαστε όµως περισσότερο ορθοί ϑα πρέπει
να ελέξουµε ότι η τιµή που δόθηκε από το χρήστη για τη µεταβλητή x είναι
νόµιµη. Το παραγοντικό ορίζεται για αριθµούς µεγαλύτερους ή ίσους από το
0. ΄Ετσι εάν από το χρήστη δοθεί αρνητικός αριθµός ϑα πρέπει να εµφανιστεί
κάποιο κατάλληλο µήνυµα λάθους και να επιστρέψει ο έλεγχος στην εντολή
που Ϲητά να δοθεί τιµή για το x. ΄Ετσι, όσο ο χρήστης δίνει αρνητικές τιµές
για το x ϑα του εµφανίζεται το µήνυµα λάθους και ϑα του Ϲητείται να δώσει
εκ νέου τιµή. Το τµήµα του διαγράµµατος ϱοής που υλοποιεί την παραπάνω
λειτουργία ϕαίνεται στο σχήµα 7.

Σχήµα 8: Μετατροπή δεκαδικού αριθµού σε δυαδικό

΄Ολα τώρα ϕαίνεται να λειτουργούν σωστά. ΄Η µήπως όχι ; Αναφέραµε


προηγουµένως ότι το παραγοντικό ορίζεται για αριθµούς µεγαλύτερους ίσους
από το µηδέν. Εµείς στον συλλογισµό που κάναµε για το λογικό διάγραµµα
δεν εξετάσαµε καθόλου τι γίνεται για x = 0 και µάλιστα αρχικοποιήσαµε την
τιµή του f act σε ένα. Είναι σωστό αυτό που κάναµε ή πρέπει να διορθώουµε
κάτι. Κατ΄ αρχήν ας ϑυµηθούµε ότι το παραγοντικό του 0 είναι ίσο µε 1
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 10

(0!=1). Ας δούµε τι ϑα ϐγάλει το διάγραµµα ϱοής προγράµµατος αν δώσουµε


στο x την τιµή 1. Το f act ϑα αρχικοποιηθεί σε 1, ϑα εκτελεστεί µία ϕορά η
f act = f act ∗ i, χωρις να αλλάξει η τιµή του f act αφού το i ισούται µε 1 και δε
ϑα γίνει άλλη επανάληψη αφού ο ϱόµβος ϑα οδηγήσει την εκτέλεση έξω από
το ϐρόχο (το i ισούται µε x). Τώρα έχουµε ϐεβαιωθεί ότι όλα έχουν πάει καλά
και µπορούµε να ϑεωρήσουµε ότι ολοκληρώθηκε το διάγραµµα ϱοής.

Σχήµα 9: ΄Αθροισµα περιττών αριθµών

Παραθέτουµε ακόµα τρία ακόµα λογικά διαγράµµατα. Στο σχήµα 9 ϕαί-


νεται το άθροισµα των περιττών αριθµών µικρότερων ή ίσων από ένα δεδοµένο
αριθµό. Στο σχήµα 8 ϕαίνεται ο τρόπος µετατροπής ενός δεκαδικού αριθµού
σε δυαδικό, ενώ στο σχήµα 10 ο τρόπος υπολογισµού του µέσου όρου µίας
σειράς αριθµών.
΄Εχοντας µελετήσει τα λογικά διαγράµµατα των προηγούµενων παραδειγ-
µάτων είµαστε σε ϑέση να αρχίσουµε την κωδικοποίηση. Σε ποια γλώσσα
όµως ; Γιατί όχι στη C, αφού είναι ευρέως χρησιµοποιούµενη και αποτελεί τη
ϐάση για πολλές από τις περισσότερο χρησιµοποιούµενες γλώσσες, ενώ αυτή
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΛΟΓΙΚΑ ∆ΙΑΓΡΑΜΜΑΤΑ 11

Σχήµα 10: Μέσος όρος σειράς αριθµών

και όσες γλώσσες έχουν προκύψει από αυτήν Ϲητούνται στην αγορά εργασίας.
΄Ισως είναι λίγο νωρίς να µπούµε από τώρα στα ϐαθιά. Θα αναζητήσουµε τον
κοινό παρονοµαστή όλων των γλωσσών προγραµµατισµού που ανήκουν στην
κατηγορία των γλωσσών του δοµηµένου προγραµµατισµού (όσο αυτό ϐέβαια
είναι δυνατό), και ϑα διδακτούµε αυτό. Σαν ϐάση, λοιπόν, ϑα χρησιµοποι-
ήσουµε τη γλώσσα Python αλλά σκοπός µας δεν είναι να µάθουµε Python
και να εµβαθύνουµε σε αυτή, αλλά να τη χρησιµοποιήσουµε ως µέσο για να
µάθουµε αυτό που καλείται δοµηµένος προγραµµατισµός.
Έλεγχος Ροής - Παραδείγµατα

Δίσεκτο έτος
n  Ένα έτος είναι δίσεκτο αν διαιρείται ακριβώς µε το
400 ή διαιρείται ακριβώς µε το 4 και δεν διαιρείται
ακριβώς µε το 100
n  Υπολογίστε αν ένα δοθέν έτος είναι δίσεκτο

year = int(input('Enter a year: '))


if year%400 == 0:
print(year, 'is a leap year')
elif year%4 == 0 and year%100 != 0:
print(year, 'is a leap year')
else:
print(year, 'is a common year')

2
ln(2) – συγκλίνον άθροισµα
n  Ο φυσικός λογάριθµος του 2 µπορεί να X ∞
(−1)k+1
υπολογιστεί µε την εξίσωση: ln 2 =
k
n  ln(2) = 1/1 – 1/2 + 1/3 – 1/4 =… k=1
from math import log
print('computes ln(2) up to a given accuracy’) log(): φυσικός
error = float(input('allowed error = ')) λογάριθµος
sum=0 log(x,base)=
previous=1000 #a very large integer log(x)/log(base)
sign=-1
i=1
while abs(sum-previous)>error:
previous=sum
sign=sign*(-1)
sum=sum+sign/float(i)
i=i+1
print('%f %f %10.8f’ % (sum, log(2), abs(sum-log(2)))) 3

Προπαίδεια του 7
n  Τύπωσε στοιχισµένα την προπαίδεια του 7

print ('Προπαίδεια του 7')


for i in range (1,11):
print('%2d x 7 = %2d'%(i,i*7))
1 x 7 = 7!
2 x 7 = 14!
3 x 7 = 21!
4 x 7 = 28!
5 x 7 = 35!
6 x 7 = 42!
7 x 7 = 49!
8 x 7 = 56!
9 x 7 = 63!
10 x 7 = 70!
4
Πίνακας προπαίδειας
n  Τύπωσε στοιχισµένα τις προπαίδειες του 1 εώς
του 10
print ('Πίνακας Προπαίδειας') Τυπώνει ένα
for i in range (1,11): κενό στο
τέλος αντί να
for j in range (1,11): αλλάξει
print('%2dx%d=%2d'%(i,j,i*j),end=' ') γραµµή
print()
1x1= 1 1x2= 2 1x3= 3 1x4= 4 1x5= 5 1x6= 6 1x7= 7 1x8= 8 1x9= 9 1x10=10 !
2x1= 2 2x2= 4 2x3= 6 2x4= 8 2x5=10 2x6=12 2x7=14 2x8=16 2x9=18 2x10=20 !
3x1= 3 3x2= 6 3x3= 9 3x4=12 3x5=15 3x6=18 3x7=21 3x8=24 3x9=27 3x10=30 !
4x1= 4 4x2= 8 4x3=12 4x4=16 4x5=20 4x6=24 4x7=28 4x8=32 4x9=36 4x10=40 !
5x1= 5 5x2=10 5x3=15 5x4=20 5x5=25 5x6=30 5x7=35 5x8=40 5x9=45 5x10=50 !
6x1= 6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36 6x7=42 6x8=48 6x9=54 6x10=60 !
7x1= 7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49 7x8=56 7x9=63 7x10=70 !
8x1= 8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64 8x9=72 8x10=80 !
9x1= 9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81 9x10=90 !
10x1=10 10x2=20 10x3=30 10x4=40 10x5=50 10x6=60 10x7=70 10x8=80 10x9=90 10x10=100! 5

Τρίγωνο από αστεράκια


n  Τυπώστε ένα ορθογώνιο τρίγωνο µε βάση και
ύψος x αστεράκια

x = int(input('Input triangle\'s height: ')) *!


for i in range (1,x+1): x = 5 **!
for j in range (1,i+1): ***!
print('*',end='') ****!
print() *****!

x = int(input('Input triangle\'s height: '))


for i in range (1,x+1):
print(i*'*')

6
Δέντρο από αστεράκια
n  Τυπώστε ένα δέντρο από αστεράκια µε ύψος x

x = int(input('Input tree\'s height: ')) *!


for i in range (1,x+1): ***!
x=5
for j in range (1,x-i+1): *****!
print(' ',end='') *******!
for j in range (1,2*i): *********!
print('*',end='')
print()

x = int(input('Input tree\'s height: '))


for i in range (1,x+1):
print(" "*(x-i),end='')
print("*"*(2*i-1))
7

Ύψωση σε δύναµη: xy
x = int(input('Input base: '))
y = int(input('Input power: '))
value = 1
for i in range(0, y):
value *= x
print('%d to the power of %d = %d' % (x, y, value))

x = int(input('Input base: '))


y = int(input('Input power: '))
from math import pow
print('%d to the power of %d = %d' % (x, y, pow(x,y)))

8
Παραγοντικό: x!
n  x! = 1*2*3*…*x
x = int(input('Input a number: '))
f=1
for i in range(1,x+1):
f *= i
print('%d! = %d' % (x,f))

x = int(input('Input a number: '))


from math import factorial
print('%d! = %d' % (x, factorial(x)))

Υπολογισµός αθροίσµατος
ψηφίων ακέραιου αριθµού
n  x = 4579, dsum = 4+5+7+9 = 25
n = int(input('Input a number: '))
dsum = 0
while n>0:
dsum += n%10
n//=10
print('The sum of the number\'s digits is', dsum)

n = int(input('Input a number: '))


dsum = 0
s = str(n)
for i in s:
dsum+=int(i)
print('The sum of the number\'s digits is', dsum)
10
Υπολογισµός µέσης τιµής
N −1
n  a = [4,5,7,9], µ = (4+5+7+9)/4 1
µ=
N
∑ a[i]
i =0

s = input('Input a set of numbers separated by commas: ')


a = [eval(x) for x in s.split(",")]
print('The mean of your numbers is',sum(a)/len(a))

11

Υπολογισµός τυπικής
απόκλισης
1 N −1
n  a = [4,5,7,9], µ = (4+5+7+9)/4, σ = ∑
N i =0
(a[i] − µ ) 2

from math import sqrt


s = input('Input a set of numbers separated by commas: ')
a = [eval(x) for x in s.split(",")]
print('The mean of your numbers is',sum(a)/len(a))
sumdiff = 0.0
for num in a:
sumdiff += (num-sum(a)/len(a))**2
stdev = sqrt(sumdiff/len(a))
print('The standard deviation is',stdev)

12
Άσκηση: άθροισµα ζυγών
n  Δίνεται µια λίστα αριθµών. Βρές το άθροισµα των
ζυγών στη λίστα
s = input('Input a set of numbers separated by commas: ')
a = [int(x) for x in s.split(",")]
esum = 0
for x in a:
if x%2 ==0:
esum = esum + x
print("The sum is: ", esum)

s = input('Input a set of numbers separated by commas: ')


a = [int(x) for x in s.split(",")]
print("The sum is: ", sum([x for x in a if x%2==0]))
13

Άσκηση
n  Δίνονται δύο λίστες αριθµών. Υπολόγισε µια νέα
λίστα που περιέχει το γινόµενο όλων των ζευγών
από τις 2 λίστες
¡  Π.χ. L1 = [3,4,5], L2 = [1,2], L3 = [3,6,4,8,5,10]
s1 = input('Input a set of numbers separated by commas: ')
L1 = [int(x) for x in s1.split(",")]
s2 = input('Input a set of numbers separated by commas: ')
L2 = [int(x) for x in s2.split(",")]
L3 = []
for x in L1:
for y in L2:
L3.append(x*y)
print(L3)
14
Ορισµός και χρήση πινάκων
n  Μπορούµε να χρησιµοποιήσουµε λίστες ως
πίνακες
¡  Μπορούµε να χρησιµοποιήσουµε και πλειάδες
¡  Ποια η διαφορά; µονοδιάστατος πίνακας:
A = [4 5 6 7]
>>> A = [4,5,6,7] προσπέλαση του Αi µε A[i]
>>> A[2] δισδιάστατος πίνακας:
6
 
1 2 3
>>> B = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] B = 4 5 6
>>> B[2][1] 7 8 9
8
προσπέλαση του Bij µε B[i][j]

15

Ορισµός και χρήση πινάκων


n  Η αρχικοποίηση ενός πίνακα συγκεκριµένων
διαστάσεων µπορεί να γίνει µε την εντολή for
>>> A = [0 for i in range(10)]
>>> A
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> M=[[0 for i in range(3)] for i in range(3)]
>>> M
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

16
Πρόσθεση πινάκων
n  Πρόσθεση δύο πικάνων διαστάσεων N x M
N=M=2
A = [[0.0 for j in range(M)] for i in range(N)]   
B = [[0.0 for j in range(M)] for i in range(N)] 1 2 5 6 6 8
C = [[0.0 for j in range(M)] for i in range(N)] + =
for i in range(N):
3 4 7 8 10 12
for j in range(M):
A[i][j] = float(input('A[%d][%d]: ' % (i, j)))
for i in range(N):
for j in range(M):
B[i][j] = float(input('B[%d][%d]: ' % (i, j)))
for i in range(N):
for j in range(M):
C[i][j] = A[i][j] + B[i][j]
for i in range(N):
for j in range(M):
print('C[%d][%d]:%7.2f ' % (i, j, C[i][j]), end = '')
print('')
17

Πολλαπλασιασµός πινάκων
NxN
N=2
A = [[0.0 for j in range(N)] for i in range(N)]
B = [[0.0 for j in range(N)] for i in range(N)]
C = [[0.0 for j in range(N)] for i in range(N)]
for i in range(N):
for j in range(N):
A[i][j] = float(input('A[%d][%d]: ' % (i, j)))
for i in range(N):
for j in range(N):
B[i][j] = float(input('B[%d][%d]: ' % (i, j)))
for i in range(N):   
for j in range(N):
for k in range(N):
1 2 5 6 19 22
× =
C[i][j] += A[i][k]*B[k][j] 3 4 7 8 43 50
for i in range(N):
for j in range(N):
print('C[%d][%d]:%7.2f ' % (i, j, C[i][j]), end = '')
print('')

18
Εύρεση ελάχιστου σε πίνακα
N=M=2 Ερώτηση:
A = [[0.0 for j in range(N)] for i in range(N)] Τι θα
for i in range(N): επιστρέψει
for j in range(M): το min(A);
A[i][j] = float(input('A[%d][%d]: ' % (i, j)))
minelem = A[0][0] Ερώτηση:
for i in range(N): πως θα
for j in range(M): βρούµε το
ελάχιστό
if minelem > A[i][j]: ΚΑΙ τη θέση
minelem = A[i][j] του;
print('The minimum element is ',minelem)

19

Υπολογισµός ανάστροφου
πίνακα
N=2 
M=3 1 2 3
A=
A = [[0.0 for j in range(M)] for i in range(N)] 4 5 6
invA = [[0.0 for j in range(N)] for i in range(M)] 
1 4

for i in range(N): T
A = 2 5
for j in range(M):
3 6
A[i][j] = float(input('A[%d][%d]: ' % (i, j)))
invA[j][i] = A[i][j]
for i in range(M):
for j in range(N):
print('invA[%d][%d]:%7.2f ' % (i, j, invA[i][j]), end = '')
print('')
20
Άσκηση
n  Όρισε ένα άνω τριγωνικό πίνακα, µε τα στοιχεία
από τη διαγώνιο και πάνω =1

M=[[0 for i in range(3)] for j in range(3)]


for i in range(3):
for j in range(3):
if i<=j:
M[i][j]=1
for row in M:
print(row)

21

Συναρτήσεις
Δόµηση προγράµµατος
n  Μέχρι τώρα έχουµε δει πως να χρησιµοποιούµε
έτοιµες συναρτήσεις και µεθόδους στα
προγράµµατά µας (π.χ. len(), max(), print())
n  Μπορούµε να ορίσουµε τις δικές µας συναρτήσεις
για λειτουργίες που επαναλαµβάνονται στο
πρόγραµµά µας
n  Ο ορισµός συναρτήσεων συντελεί στη σωστή
δόµηση του προγράµµατός µας
¡  Το πρόγραµµά µας γίνεται πιο ευανάγνωστο
¡  Αποφεύγονται οι επαναλήψεις κώδικα
¡  Βοηθούν στο σχεδιασµό του προγράµµατός µας
2

Συναρτήσεις
n  Οι συναρτήσεις στις γλώσσες προγραµµατισµού
µοιάζουν µε τις συναρτήσεις στα µαθηµατικά
¡  µπορούν να πάρουν σαν όρισµα κάποιες τιµές
¡  µπορούν να επιστρέψουν µια τιµή
n  Οι συναρτήσεις στις γλώσσες προγραµµατισµού
γενικεύουν τις µαθηµατικές συναρτήσεις
¡  µπορούν να εκτελέσουν κάποια λειτουργία χωρίς
απαραίτητα να παίρνουν ορίσµατα ή να επιστρέφουν
τιµές
¡  µπορούν να παίρνουν µεταβλητό αριθµό ορισµάτων
¡  µπορούν να εκτελούν λειτουργίες ανεξάρτητες από τα
ορίσµατά τους 3
Παραδείγµατα συναρτήσεων
n  Μαθηµατικές συναρτήσεις στην Python:
n  f(x) = x2+1 µπλοκ κώδικα που ορίζει
τη συνάρτηση f
def f(x):
return x**2 + 1
µέρος κώδικα όπου
εκτελείται η f
print(4*f(2))
Τι θα τυπώσει το πρόγραµµα;

n  Γενικά οι συναρτήσεις ορίζονται ως εξής:


¡  def <όνοµα συνάρτησης> (<µεταβλητές>):
<κώδικας συνάρτησης>
4

Παραδείγµατα συναρτήσεων
n  Άσκηση: Ορίστε µια συνάρτηση µε όνοµα average
που θα παίρνει ως ορίσµατα 2 µεταβλητές και θα
επιστρέφει το µέσο όρο τους
¡  π.χ. average(2,3.5) = 2.75

def average(x,y):
return (x+y)/2

5
Παραδείγµατα συναρτήσεων
n  Άσκηση: Ορίστε µια συνάρτηση µε όνοµα
perimeter που θα παίρνει ως ορίσµατα την ακτίνα
ενός κύκλου και θα επιστρέφει την περίµετρό του
¡  π.χ. perimeter(1) = 6.283185307179586

def perimeter(x):
from math import pi
return 2*pi*x

Παραδείγµατα συναρτήσεων
n  Άσκηση: Ορίστε µια συνάρτηση που θα παίρνει ως
όρισµα ένα όνοµα και θα τυπώνει ‘Hello όνοµα’
¡  π.χ. >>>hello('John')
hello John!

Η συνάρτηση hello() τυπώνει


def hello(x):
κάτι, αλλά δεν επιστρέφει
print('Hello, '+x+'!') κάτι.
Ποια η διαφορά;

7
Προσοχή
n  Οι f1 και f2 φαίνεται να κάνουν το ίδιο, αλλά
υπάρχουν σηµαντικές διαφορές
def f1(x): def f2(x):
return x**2 + 1 print(x**2 + 1)

>>> f1(2)
5 Επίσης:
>>> f2(2) η y = f2(5) δεν θα
5 καταχωρήσει την τιµή της
>>> f2(2)+5 f2(5) στο y
5
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
f2(2)+5
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' 8

Οι ορισµοί συναρτήσεων είναι


εντολές
n  Τι κάνει το παρακάτω πρόγραµµα;
s = input("Enter square or cube: ")
if s == 'square':
def f(x):
return x*x
else:
def f(x):
return x*x*x

9
Ορισµός πριν την κλήση
n  Πρώτα ορίζουµε µια συνάρτηση, µετά την καλούµε
n  Γιατί θα προκύψει σφάλµα αν εκτελεστεί το
παρακάτω πρόγραµµα;

print(f(2))

def f(x):
return x**2 + 1

10

Ορισµός πριν την κλήση


n  Θα προκύψει σφάλµα από την εκτέλεση του
παρακάτω;

def g(x):
return f(x)

def f(x):
return x**2 + 1

n  Οχι! Οι συναρτήσεις f() και g() δεν εκτελούνται,


παρά µόνο ορίζονται. Μετά τον ορισµό τους
µπορούν να κληθούν χωρίς κανένα πρόβληµα
11
Συναρτήσεις σαν αντικείµενα
n  Οι συναρτήσεις είναι κι αυτές αντικείµενα, όπως οι
αριθµοί, τα αλφαριθµητικά, οι λίστες, κλπ.
n  Μπορούµε να διαπιστώσουµε αν ένα αντικείµενο
είναι συνάρτηση µε την callable
>>> x = 1
>>> y = len
>>> callable(x)
False
>>> callable(y)
True

12

Προσοχή στο return


n  Αν η ροή σε µιά συνάρτηση φτάσει σε ένα return, η
συνάρτηση τερµατίζει άµεσα επιστρέφοντας το
όρισµα του return
n  Ερώτηση: τι θα κάνει η παρακάτω συνάρτηση
όταν κληθεί;
def test(): >>> x = test()
print('Hello', end='') Hello
return >>> x
print(' world') >>> print(x)
return None
Μετά το return οι εντολές
είναι άχρηστες 13
Προσοχή στο return
n  Φροντίστε οι συναρτήσεις σας να επιστρέφουν τις
τιµές που πρέπει σε κάθε περίπτωση κάνοντας
ελέγχους µέσω if
def translate_temp(t):
if (t<5):
return 'It\'s freezing!'
elif (t>25):
return 'It\'s hot!'
else:
return 'It\'s cool.'

>>> temp = int(input("Enter the current temperature: "))


Enter the current temperature: 20
>>> print(translate_temp(temp))
It's cool.
14

Τοπικότητα παραµέτρων
n  Αν αλλάξουµε την τιµή µιας παραµέτρου µέσα στη
συνάρτηση η µεταβλητή που περνάει σαν
παράµετρος δεν αλλάζει στο εξωτερικό πρόγραµµα
για µη µεταβαλλόµενες µεταβλητές.
def try_to_change(n): Η µεταβλητή n µέσα στη
n = 'Mr. Gumby' συνάρτηση έχει τώρα τιµή
'Mr. Gumby’ ανεξάρτητα
name = 'Mrs. Entity' από την τιµή της κατά την
try_to_change(name) κλήση της συνάρτησης
print(name) Η µεταβλητή name
παραµένει αµετάβλητη µετά
την κλήση της
Mrs. Entity
try_to_change
15
Τοπικότητα παραµέτρων
n  Αν αλλάξουµε την τιµή ενός µεταβαλλόµενου
αντικειµένου που περνιέται σαν παράµετρος µέσα
στη συνάρτηση, τότε το αντικείµενο αλλάζει στο
εξωτερικό πρόγραµµα
def change(n): Το αντικείµενο (λίστα) που
n[0] = 'Mr. Gumby' δείχνει η παράµετρος n
αλλάζει και στο εξωτερικό
names = ['Mrs. Entity', 'Mrs. Thing'] πρόγραµµα
change(names)
print(names) Η µεταβλητή names αλλάζει
µετά την κλήση της
συνάρτησης change
['Mr. Gumby', 'Mrs. Thing']
16

Άσκηση
n  Τι θα τυπώσει το παρακάτω πρόγραµµα;

def change(n):
n[0] = 'Mr. Gumby'
Αντιγράφει τη
names = ['Mrs. Entity', 'Mrs. Thing'] µεταβλητή names σε
change(names[:]) άλλη µεταβλητή (άλλη
print(names) λίστα) και η συνάρτηση
change αλλάζει την
άλλη λίστα, όχι τη
['Mrs. Entity', 'Mrs. Thing']
names

17
Πέρασµα µε τιµή/αναφορά
n  Στις γλώσσες προγραµµατισµού γενικά υπάρχουν
2 τρόποι περάσµατος παραµέτρων σε
συναρτήσεις
¡  Πέρασµα µε τιµή: η τιµή της µεταβλητής που µπαίνει
σαν παράµετρος αντιγράφεται σε τοπική µεταβλητή
(µεταβλητή παραµέτρου στη συνάρτηση) – τυχόν
αλλαγές στην τιµή της τοπικής µεταβλητής µέσα στη
συνάρτηση δεν επηρεάζουν την εξωτερική µεταβλητή
¡  Πέρασµα µε αναφορά: η µεταβλητή που µπαίνει σαν
παράµετρος αλλάζει άν η τοπική µεταβλητή (µεταβλητή
παραµέτρου στη συνάρτηση) αλλάξει

18

«Πέρασµα µε αναφορά» µη
µεταβαλλόµενης µεταβλητής
n  Τι κάνουµε στην Python αν η συνάρτησή µας
θέλουµε να αλλάξει την τιµή της παραµέτρου, αν
αυτή είναι µή µεταβαλλόµενη µεταβλητη;
def inc(x): def inc(x):
return x + 1 x[0] = x[0] + 1

y=1 y = [1]
y = inc(y) inc(y)
print(y) print(y)
Α τρόπος: βάζουµε τη Β τρόπος: κάνουµε τη
συνάρτηση να µεταβλητή µας
επιστρέφει τη νέα τιµή µεταβαλλόµενη
και την αναθέτουµε στη
µεταβλητή 19
Παράµετροι: η σειρά µετράει
n  Η αντιστοίχιση των παραµέτρων µε τις εξωτερικές
µεταβλητές γίνεται µε βάση τη σειρά
def my_pow(base, exponent):
value = 1
for i in range(0, exponent):
value *= base
return value
x = int(input('Input base: '))
y = int(input('Input exponent: '))
print('%d to the power of %d = %d' % (x, y, my_pow(x,y)))

Μπορούµε επίσης να γράψουµε:


my_pow(base = x, exponent = y) ή my_pow(exponent = y, base = x)
(µε αυτό τον τρόπο η σειρά δεν έχει σηµασία) 20

Παράµετροι: default τιµές


n  Μπορούµε να ορίσουµε default τιµές για τη
συνάρτηση σε περίπτωση που δεν περαστούν όλες
def hello(greeting='Hello', name='world'):
print('%s, %s!' % (greeting, name))

>>> hello('Geia sou', 'file')


Geia sou, file!
>>> hello('Geia sou')
Geia sou, world!
>>> hello(name = 'aderfe')
Hello, aderfe!
>>> hello()
Hello, world!

21
Παράµετροι: default τιµές
n  Κάντε χρήση default τιµών για µη υποχρεωτικές
παραµέτρους
def hello(name, greeting='Hello', punctuation='!'):
print ('%s, %s%s' % (greeting, name, punctuation))

>>> hello('John')
Hello, John!
>>> hello('John','Howdy')
Howdy, John!
>>> hello('John','Howdy','...')
Howdy, John...
>>> hello('John',punctuation='...')
Hello, John...
>>> hello()
Traceback (most recent call last):
File "<pyshell#62>", line 1, in <module>
hello()
TypeError: hello() missing 1 required positional argument: 'name' 22

Μεταβλητός αριθµός παραµέτρων


n  Με χρήση αστερίσκου * πριν το όνοµα της
παραµέτρου, παίρνουµε µια πλειάδα από αυτές
def print_params(*params):
print(params)

>>> print_params('test1')
('test1',)
>>> print_params('test1',1,2)
('test1', 1, 2)
>>> print_params()
()

23
Μεταβλητός αριθµός παραµέτρων
n  Με χρήση αστερίσκου * πριν το όνοµα της
παραµέτρου, παίρνουµε µια πλειάδα από αυτές
def print_params(title, *params):
print(title) υποχρεωτική
print(params) παράµετρος

>>> print_params('Label',1,2,3)
Label
(1, 2, 3)

24

Μεταβλητός αριθµός παραµέτρων


n  Παράδειγµα

def print_family(*members):
print('My family consists of ',end='')
for x in members[:-1]:
print(x, 'and', end=' ')
print(members[-1])

>>> print_family('dad','mom','sis','bro')
My family consists of dad and mom and sis and bro

25
Μεταβλητός αριθµός παραµέτρων
n  Με χρήση διπλού αστερίσκου ** πριν το όνοµα της
παραµέτρου, παίρνουµε ένα λεξικό από αυτές
def print_params(**params):
print(params)

>>> print_params(x=1, y=2, z=3)


{'y': 2, 'x': 1, 'z': 3}

def print_params(x, y, z=3, *pospar, **keypar):


print (x, y, z)
print (pospar)
print (keypar)

26

Κατανοµή τιµών σε παραµέτρους


n  Η συνάρτησή µας µπορεί να έχει συγκεκριµένο
αριθµό παραµέτρων και να την καλέσουµε δίνοντας
σαν όρισµα µια πλειάδα/λίστα τιµών µε χρήση *
def add(x, y):
return x + y

>>> params=(1,2)
>>> add(*params)
3

27
Κατανοµή τιµών σε παραµέτρους
n  Η συνάρτησή µας µπορεί να έχει συγκεκριµένο
αριθµό παραµέτρων και να την καλέσουµε δίνοντας
σαν όρισµα ένα λεξικό παραµέτρων:τιµών
µε χρήση **
def hello(greeting='Hello', name='world'):
print('%s, %s!' % (greeting, name))

>>> params = {'name': 'Sir Robin', 'greeting': 'Well met'}


>>> hello(**params)
Well met, Sir Robin!

28

Παραδείγµατα
def story(**kwds):
return 'Once upon a time, there was a ' \
'%(obj)s called %(name)s.' % kwds

>>> story(obj='king', name='Gumby')


'Once upon a time, there was a king called Gumby.'
>>> story(name='Sir Robin', obj='brave knight')
'Once upon a time, there was a brave knight called Sir Robin.'
>>> params = {'obj': 'language', 'name': 'Python'}
>>> story(**params)
'Once upon a time, there was a language called Python.'
>>> del params['obj']
>>> story(obj='stroke of genius', **params)
'Once upon a time, there was a stroke of genius called Python.'
29
Παραδείγµατα
def power(x, y, *others):
if others:
print ('Received redundant parameters:', others)
return pow(x, y)

>>> power(2,3)
8
>>> power(y=3,x=2)
8
>>> params = (5,) * 2
>>> power(*params)
3125
>>> power(3, 3, 'Hello, world')
Received redundant parameters: ('Hello, world',)
27
30

Παραδείγµατα
def interval(start, stop=None, step=1): Περιγραφή συνάρτησης
'Imitates range() for step > 0' (σαν σχόλιο)
if stop is None: # If the stop is not supplied...
start, stop = 0, start # shuffle the parameters
result = []
i = start # We start counting at the start index
while i < stop: # Until the index reaches the stop index...
result.append(i) # ...append the index to the result...
i += step # ...increment index
>>> interval(10)
return result [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> interval(1,5)
[1, 2, 3, 4]
>>> interval(3,12,4)
[3, 7, 11]
>>> power(*interval(3,7))
Received redundant parameters: (5, 6)
81
31
Εµβέλεια µεταβλητών
n  Όταν δίνουµε τιµή σε µια µεταβλητή είναι σαν να
δίνουµε τιµή στο κλειδί µε το όνοµα της µεταβλητής
σε ένα λεξικό
n  vars(): επιστρέφει το built-in λεξικό της Python για τις
µεταβλητές
ΠΡΟΣΟΧΗ: Γενικά µην
>>> x = 1 αλλάζετε το λεξικό
>>> vars()['x'] µεταβλητών της Python,
1 αλλά να ορίζετε και να
>>> vars()['x']+=1 αλλάζετε τις µεταβλητές µε
>>> x τον παραδοσιακό τρόπο
2

32

Εµβέλεια µεταβλητών
n  σφαιρική µεταβλητή: είναι µια µεταβλητή που
ορίζεται και χρησιµοποιείται σε όλο το πρόγραµµα
n  τοπική µεταβλητή: είναι µια µεταβλητή που ορίζεται
και χρησιµοποιείται µέσα σε µια συνάρτηση
ΠΡΟΣΟΧΗ: Η x µέσα στη
>>> def foo(): x = 42 συνάρτηση είναι τοπική
µεταβλητή
>>> x = 1
>>> foo()
>>> x ΠΡΟΣΟΧΗ: Μετά την κλήση της foo() η
1 σφαιρική µεταβλητή x δεν αλλάζει

n  Η Python ορίζει ένα τοπικό λεξικό µεταβλητών


µέσα σε κάθε συνάρτηση 33
Εµβέλεια µεταβλητών
n  Οι παράµετροι µιας συνάρτησης αντιγράφονται ως
τοπικές µεταβλητές
¡  Αλλαγή στις τιµές των παραµέτρων δεν επηρεάζουν τις
εξωτερικές (σφαιρικές) µεταβλητές
¡  Προσοχή: αν η τοπική µεταβλητή δείχνει στο ίδιο
µεταβαλλόµενο αντικείµενο όπως η σφαιρική, το
αντικείµενο αλλάζει µέσα στη συνάρτηση
>>> def output(x): print(x); x += 1; print(x)
>>> y=2
>>> output(y) >>> def add0(l): l.append(0)
2 >>> lst = []
3 >>> add0(lst)
>>> y >>> lst
2 [0] 34

Εµβέλεια µεταβλητών
n  Οι εξωτερικές (π.χ. σφαιρικές) µεταβλητές µπορούν
να διαβαστούν µέσα σε µια συνάρτηση, αλλά δεν
µπορούν να πάρουν νέα τιµή
>>> def combine(param): print (param + external)

>>> external = 'berry'


>>> combine('black') προσπέλαση εξωτερικής
blackberry µεταβλητής µέσα στη
συνάρτηση combine()

35
Επισκίαση
n  Η επισκίαση (shadowing) µιας µεταβλητής συµβαίνει
όταν έχει οριστεί εξωτερικά, αλλά δεν µπορεί να
προσπελαστεί µέσα σε µια συνάρτηση επειδή
υπάρχει µια τοπική µεταβλητή µε το ίδιο όνοµα
def dosomething():
y=5
Αν ήθελα στο σηµείο αυτό να
x=3
χρησιµοποιήσω την εξωτερική
print(x,y)
µεταβλητή x δεν θα µπορούσα γιατί το x
πλέον αναφέρεται στην τοπική
x=1
µεταβλητή x
dosomething()
print(x)

36

Επισκίαση
n  Η προσπέλαση µιας σφαιρικής µεταβλητής που
επισκιάζεται σε µια συνάρτηση επισκίαση, µπορεί να
γίνει µέσω του λεξικού που επιστρέφει η globals()
def dosomething():
y=5 Αναφορά στη σφαιρική µεταβλητή x
x=3
print(x,y,globals()['x'])

x=1
dosomething()
print(x)

¡  Το λεξικό που επιστρέφει η locals() περιέχει τις


µεταβλητές που έχουν τοπική εµβέλεια (στη συνάρτηση) 37
«Δέσιµο» τοπικής µεταβλητής σε
σφαιρική
n  Αν θέλουµε να αλλάξουµε µια σφαιρική µεταβλητή
µέσα σε µια συνάρτηση µπορούµε να τη δηλώσουµε
ως σφαιρική µεταβλητή της συνάρτησης

>>> x = 1 Η τοπική µεταβλητή x «δένεται»


>>> def change_global(): στην αντίστοιχη σφαιρική
global x
x=x+1

>>> change_global()
>>> x
2

38

Αναδροµικές Συναρτήσεις
Ορισµός και ιδιότητες
n  Μια συνάρτηση είναι αναδροµική αν καλεί τον εαυτό
της
n  Οι περισσότερες γλώσσες προγραµµατισµού
υποστηρίζουν αναδροµικές συναρτήσεις
n  Οι αναδροµικές συναρτήσεις είναι πολλές φορές πιο
διαισθητικές από τις αντίστοιχες επαναληπτικές
¡  Η εκσφαλµάτωσή τους είναι όµως δυσκολότερη, οπότε
πρέπει να χρησιµοποιούνται µε προσοχή
¡  Επίσης οι αναδροµικές συναρτήσεις µπορεί να
επιβαρύνουν τη µνήµη του συστήµατος και να είναι πιο
αργές
2

Αναδροµικές συναρτήσεις στα


µαθηµατικά
n  Παράδειγµα:
⇢ παραγοντικό
1 if n = 0 or n = 1,
n! =
n(n − 1)! otherwise.
«βασική»
περίπτωση επαναληπτική συνάρτηση:

def fact(n): def fact(n):


if n==0 or n==1: f=1
return 1 for i in range(1,n+1):
else: f *= i
return n*fact(n-1) return f
αναδροµική περίπτωση
3
Παράδειγµα: ύψωση σε δύναµη
αναδρομική συνάρτηση:
επαναληπτική συνάρτηση:

def power(x, n): def power(x, n):


if n == 0: result = 1
return 1 for i in range(n):
else: result *= x
return x * power(x, n-1) return result

Παράδειγµα: αριθµοί Fibonacci


n  Μια ακολουθία αριθµών:
¡  1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,...
n  Ορίζονται µε την αναδροµική συνάρτηση:

1 if n = 1 or n = 2,
Fn =
Fn−1 + Fn−2 otherwise.

n  Χρήσεις και εµφάνιση: Fn−1


limn→∞ =ϕ
¡  Μαθηµατικα: συνδεση µε τη χρυσή τοµή Fn

¡  Φύση: διακλαδώσεις δέντρων, διάταξη φύλλων, κλπ.

5
Παράδειγµα: αριθµοί Fibonacci
αναδρομική συνάρτηση:
επαναληπτική συνάρτηση:

def rfib(n): def fib(n):
if n==1 or n==2: if n<=1: return -1 # undefined
return 1 p = 1 # first number
else: c = 1 # second number
return rfib(n-1)+rfib(n-2) for i in range(n-2):
# c becomes p, compute new c
p, c = c, p +c
return c

p (previous) = προηγούµενος αριθµός


c (current) = τρέχων αριθµός
6

Αναδροµικές συναρτήσεις σε
γλώσσα προγραµµατισµού
n  Πιο περίπλοκες από τις µαθηµατικές αναδροµές
n  Μπορούν να δηµιουργήσουν προβλήµατα αν δεν
οριστούν σωστά
Η «βασική» περίπτωση
n  Άσκηση: ορίζει τη συνθήκη
¡  Τι κάνει η παρακάτω συνάρτηση; τερµατισµού
¡  Ποιο είναι το πρόβληµα της παρακάτω συνάρτησης;
¡  Πως θα φτιάξουµε το πρόβληµα;
def countdown(n): def countdown(n):
print(n) print(n)
if n==0: print('blast off!'); return
countdown(n-1) countdown(n-1)
7
Αναδροµικές συναρτήσεις σε
γλώσσα προγραµµατισµού
def countdown(n):
print(n)
if n==0: print('blast off!'); return
countdown(n-1)

countdown(3) countdown(2) countdown(1) countdown(0)


print(3) print(2) print(1) print(0)
countdown(2) countdown(1) countdown(0) print('blast off!'))

Η Python δηµιουργεί µια «στοίβα» όπου κρατάει τη «µνήµη» για κάθε


αναδροµική κλήση:
•  τοπικές µεταβλητές
•  σηµείο της συνάρτησης από το οποίο πρέπει να συνεχίσει µετά την
επιστροφή από την αναδροµική κλήση
8

Αναδροµικές συναρτήσεις σε
γλώσσα προγραµµατισµού
n  Το παράδειγµά µας εξακολουθεί να έχει
προβλήµατα:
¡  Αν καλέσουµε countdown(-1) η συνάρτηση δεν τερµατίζει
¡  Αν καλέσουµε countdown(10000) το πρόγραµµα θα
«κολλήσει» µετά από περίπου 1000 κλήσεις αναδροµής
n  ... η «στοίβα» του προγράµµατος θα γεµίσει
n  RuntimeError: maximum recursion depth exceeded

def countdown(n):
print(n)
if n==0: print('blast off!'); return
countdown(n-1)

9
Σκεπτόµενοι αναδροµικά
n  Άσκηση: φτιάξτε µια αναδροµική συνάρτηση
vertical, η οποία να τυπώνει τα ψηφία ενός
αριθµού «κάθετα» από το περισσότερο στο
λιγότερο σηµαντικό
n  Επιθυµητή συµπεριφορά:
>>> vertical(3124)
3
1
2
4

10

Σκεπτόµενοι αναδροµικά
n  Βήµα 1: ποια είναι η «βασική» περίπτωση;
>>> vertical(6)
6

¡  αν ο αριθµός έχει ένα µόνο ψηφίο, απλά τύπωσε το


ψηφίο
¡  άρα η συνάρτησή µας πρέπει να έχει τη µορφή:
def vertical(n):
if n<10: # base case: n has 1 digit
print(n) # just print n
else: # recursive case: n has 2 or more digits
# remainder of function

11
Σκεπτόµενοι αναδροµικά
n  Βήµα 2: ποια είναι η «αναδροµική» περίπτωση;
¡  αν ο αριθµός έχει περισσότερα από ένα ψηφία (=n),
τότε σπάσε τον σε δύο µέρη:
n  στο τελευταίο ψηφίο
n  σε όλα τα υπόλοιπα µαζί (δηλ. τα πρώτα n-1 ψηφία)
n  π.χ. το 3124 σπάει σε 312 και 4
¡  πρώτα χρειριζόµαστε τα πρώτα ψηφία
(υποπρόβληµα), µετά το τελευταίο ψηφίο
n  τα πρώτα n-1 ψηφία µπορούν να τυπωθούν µε τη σωστή σειρά
µε µια αναδροµική κλήση
n  ο χειρισµός του τελευταίου ψηφίου είναι η «βασική»
περίπτωση

12

Σκεπτόµενοι αναδροµικά
def vertical(n):
if n<10: # base case: n has 1 digit
print(n) # just print n
else: # recursive case: n has 2 or more digits
vertical(n//10) # recursively print all but last digit
print(n%10) # print last digit of n

>>> vertical(3124)
3
1
2
4

vertical(3124) vertical(312) vertical(31) vertical(3) print(3)


print(4) print(2) print(1)
13
14

Άσκηση
n  Τι κάνει η παρακάτω συνάρτηση;
def vertical(n):
if n<10: # base case: n has 1 digit
print(n) # just print n
else: # recursive case: n has 2 or more digits
print(n%10) # print last digit of n
vertical(n//10) # recursively print all but last digit

>>> vertical(3124)
4
2
1
3
15
Σκεπτόµενοι αναδροµικά
n  Άσκηση: φτιάξτε µια αναδροµική συνάρτηση
pattern που να τυπώνει αστεράκια όπως στα
παρακάτω παραδείγµατα
>>> pattern(0) >>> pattern(2) >>> pattern(3)
>>> pattern(1) * *
* ** **
* *
***
*
**
*

16

Σκεπτόµενοι αναδροµικά
n  Βήµα 1: ποια είναι η «βασική» περίπτωση;
>>> vertical(0)
>>>

¡  αν το όρισµα είναι 0, µήν κάνεις τίποτα


¡  άρα η συνάρτησή µας πρέπει να έχει τη µορφή:
def pattern(n):
if n==0:
return # base case for n=0
else: # recursive case: n>0
# remainder of function

17
Σκεπτόµενοι αναδροµικά
n  Βήµα 2: ποια είναι η «αναδροµική» περίπτωση;
¡  µε ανάλυση της επιθυµητής συµπεριφοράς και λίγη
σκέψη...
>>> pattern(1) >>> pattern(2) >>> pattern(3)
1 φορά ‘*’ * pattern(1)
* * pattern(2)
2 φορές ‘*’
pattern(0) ** **
* pattern(1) *
3 φορές ‘*’
***
* pattern(2)
**
*

18

Σκεπτόµενοι αναδροµικά
def pattern(n):
if n==0:
return # base case for n=0
else: # recursive case: n>0
pattern(n-1) # recursively print pattern for n-1
print(n*'*') # print n stars
pattern(n-1) # recursively print pattern for n-1

19
Πόσο γρήγορη είναι η
συνάρτησή µας;
n  Όταν σχεδιάζουµε µια συνάρτηση, πρέπει να
σκεφτόµαστε και την ταχύτητά της
Η συνάρτηση rfib είναι πολύ πιο αργή από τη fib
¡ 
αναδρομική συνάρτηση:
επαναληπτική συνάρτηση:

def rfib(n): def fib(n):
if n==1 or n==2: if n<1: return -1 # undefined
return 1 p = 1 # first number
else: c = 1 # second number
return rfib(n-1)+rfib(n-2) for i in range(n-2):
# c becomes p, compute new c
p, c = c, p +c
return c

20

Πόσο γρήγορη είναι η


συνάρτησή µας;
n  Άσκηση: όταν εκτελούµε τη fib(7) πόσες
επαναλήψεις εκτελούνται;

επαναληπτική συνάρτηση:

n  Η fib(n) χρειάζεται
περίπου n def fib(n):
επαναλήψεις if n<1: return -1 # undefined
p = 1 # first number
n  Άρα ο χρόνος της c = 1 # second number
for i in range(n-2):
fib(n) είναι ανάλογος # c becomes p, compute new c
του n p, c = c, p +c
return c

21
Πόσο γρήγορη είναι η
συνάρτησή µας;
n  Άσκηση: όταν εκτελούµε την rfib(7) πόσες φορές
εκτελείται η rfib(3);
αναδρομική συνάρτηση:

def rfib(n):
if n==1 or n==2:
return 1
else:
return rfib(n-1)+rfib(n-2)

n  H rfib κάνει τους ίδιους υπολογισµούς πολλές φορές! 22

Πόσο γρήγορη είναι η


συνάρτησή µας;
n  Άσκηση: µελετήστε την παρακάτω συνάρτηση και
σκεφτείτε πως µπορούµε να την κάνουµε πιο
γρήγορη def my_pow(base, exponent):
value = 1
for i in range(0, exponent):
value *= base
return value

>>> my_pow(1.00000001,100000000)
2.71828179834636
>>> 1.00000001**100000000
2.7182817983473577 23
Πόσο γρήγορη είναι η
συνάρτησή µας;
n  Λύση: πως µπορούµε να ορίσουµε τη συνάρτηση
my_pow αναδροµικά;
n  an = an/2*an/2 αν ο n είναι ζυγός
n  αν είναι µονός;
¡  an = a*an/2*an/2
n  και στις 2 περιπτώσεις το an/2 χρειάζεται να
υπολογιστεί µόνο 1 φορά
n  Πόσες αναδροµικές κλήσεις απαιτούνται για τον
υπολογισµό του an;
¡  περίπου log2n
24

Πόσο γρήγορη είναι η


συνάρτησή µας;
def my_pow(base, exponent):
if exponent==0: # base case «βασική»
return 1 περίπτωση
tmp = my_pow(base, exponent//2)
if exponent % 2 == 0: ζυγός εκθέτης
return tmp*tmp
else: µονός εκθέτης
return base*tmp*tmp

25
Αναζήτηση και Ταξινόµηση

Αναζήτηση και Ταξινόµηση


n  Βασικές λειτουργίες σε προγράµµατα
n  Αναζήτηση (searching): Βρες ένα ζητούµενο
στοιχείο σε µια δοθείσα ακολουθία στοιχείων
n  Ταξινόµηση (sorting): Ταξινόµησε µια δοθείσα
ακολουθία στοιχείων
n  Οι περισσότερες µοντέρνες γλώσσες
προγραµµατισµού έχουν υλοποιηµένες αυτές τις
λειτουργίες σαν συναρτήσεις (ή µεθόδους)
n  Εµείς θα µάθουµε κάποιους αλγορίθµους και πως
υλοποιούνται στην Python
2
Έτοιµες συναρτήσεις
αναζήτησης στην Python
n  Η µέθοδος index() επιστρέφει τη θέση ενός στοιχείου
σε µια ακολουθία. Αν το στοιχείο υπάρχει πολλές
φορές, τότε επιστρέφει την πρώτη θέση.
>>> s = 'abcdefab' Η μέθοδος find() έχει παρόμοια
>>> s.index('b') συμπεριφορά, αλλά ισχύει μόνο
1 για αλφαριθμητικά.

>>> l = [1,2,3,4,5,6,1,2,3,4,5]
>>> l.index(3) Η μέθοδος get() «ψάχνει» σε
2 λεξικά.

>>> l.index(99)
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
l.index(99)
ValueError: 99 is not in list
3

Συνάρτηση αναζήτησης
n  Άσκηση: γράψτε µια συνάρτηση search_list, η οποία
παίρνει σαν όρισµα µια λίστα και ένα στοιχείο και
επιστρέφει
¡  την πρώτη θέση του στοιχείου στη λίστα αν το στοιχείο
υπάρχει
¡  -1 αλλιώς def search_list(l, x):
for i in range(len(l)):
>>> l = [1,2,3,4,5,6,1,2,3,4,5] if x == l[i]:
>>> search_list(l, 4) return I
3 return -1
>>> search_list(l, 99)
-1 if x in l:
return l.index(x)
4
Συνάρτηση αναζήτησης
n  Άσκηση: γράψτε µια συνάρτηση search_list2, η
οποία παίρνει σαν όρισµα µια λίστα και ένα στοιχείο
και επιστρέφει όλες τις θέσεις του στοιχείου στη
λίστα
def search_list2(l, x):
pos = []
>>> l = [1,2,3,4,5,6,1,2,3,4,5] for i in range(len(l)):
>>> search_list2(l, 4) if x == l[i]:
[3, 9] pos.append(i)
>>> search_list2(l,99)
[]
return pos

Γραµµική αναζήτηση
n  Οι search_list, search_list2 υλοποιούν τη γραµµική
αναζήτηση (linear search), όπου κοιτάµε ένα-ένα
τα στοιχεία της ακολουθίας µέχρι να βρούµε το
στοιχείο (ή τα στοιχεία) που ψάχνουµε
n  Η γραµµική αναζήτηση δεν προϋποθέτει τίποτα
σχετικά µε την οργάνωση των στοιχείων στην
ακολουθία
¡  ο απλούστερος δυνατός τρόπος αναζήτησης
¡  συγκρίνει όλα τα στοιχεία της ακολουθίας µε το στοιχείο
προς εύρεση
¡  χρήσιµος για µικρές, µη ταξινοµηµένες ακολουθίες
6
Δυαδική αναζήτηση
n  Μπορούµε να εφαρµόσουµε δυαδική αναζήτηση
(binary search), αν η ακολουθία µας είναι
ταξινοµηµένη.
n  Π.χ. ψάχνουµε το στοιχείο key στη λίστα lst
n  Βασική ιδέα:
¡  mid = len(lst)/2 (το µεσαία θέση στη λίστα)
¡  αν lst[mid] == key τότε το βρήκαµε!
¡  αν lst[mid] > key τότε ψάχνουµε στο 1ο µισό της λίστας
¡  αν lst[mid] < key τότε ψάχνουµε στο 2ο µισό της λίστας
n  ψάχνουµε αναδροµικά

Δυαδική αναζήτηση
def binarysearchrec(lst, key, low, high): [1,2,3,4,5,6,9,10,15,20]
key = 4
if low>high: «βασική»
return -1 περίπτωση 1: low = 0, high = 9
else: δεν βρέθηκε mid = 4, lst[mid]=5
mid=(low+high)//2
«βασική» [1,2,3,4,5,6,9,10,15,20]
if key==lst[mid]:
περίπτωση 2: low = 0, high = 3
return mid
βρέθηκε! mid = 1, lst[mid]=2
elif key<lst[mid]:
return binarysearchrec(lst, key, low, mid-1)
else: [1,2,3,4,5,6,9,10,15,20]
low = 2, high = 3
return binarysearchrec(lst, key, mid+1, high)
mid = 2, lst[mid]=3

[1,2,3,4,5,6,9,10,15,20]
low = 3, high = 3
mid = 3, lst[mid]=4
return 3
8
Δυαδική αναζήτηση
def binarysearchrec(lst, key, low, high): [1,2,3,4,5,6,9,10,15,20]
key = 11
if low>high:
return -1 low = 0, high = 9
else: mid = 4, lst[mid]=5
mid=(low+high)//2
if key==lst[mid]: [1,2,3,4,5,6,9,10,15,20]
return mid low = 5, high = 9
elif key<lst[mid]: mid = 7, lst[mid]=10
return binarysearchrec(lst, key, low, mid-1)
else: [1,2,3,4,5,6,9,10,15,20]
low = 8, high = 9
return binarysearchrec(lst, key, mid+1, high)
mid = 8, lst[mid]=15

[1,2,3,4,5,6,9,10,15,20]
low = 8, high = 7
return -1
9

Δυαδική αναζήτηση
n  Η δυαδική αναζήτηση είναι πολύ γρήγορη
n  Σε κάθε αναδροµή, το εύρος της ακολουθίας που
εξετάζουµε µειώνεται στο µισό
n  Άσκηση: πόσες φορές καλείται η συνάρτηση
(αναδροµικά) αν η λίστα έχει 1000 στοιχεία;
¡  10 γιατί κάθε φορά ψάχνουµε στο µισό της λίστας από
την προηγούµενη φορά
n  Πόσες φορές καλείται για µια λίστα µήκους n;
¡  log2n στη χειρότερη περίπτωση

10
Δυαδική αναζήτηση
n  Επαναληπτική συνάρτηση

def binarysearch(lst, key, low, high):


while low<=high:
mid=(low+high)//2
if key==lst[mid]:
return mid
elif key<lst[mid]:
high=mid-1
else:
low=mid+1
return -1

11

Ταξινόµηση
n  Στόχος της ταξινόµησης είναι να ανακατατάξει τα
στοιχεία µιας ακολουθίας ώστε να εµφανίζονται µε
σειρά από το µικρότερο στο µεγαλύτερο (η
αντίστροφα)
¡  Η µέθοδος sort ταξινοµεί λίστες της Python
n  Θυµηθείτε ότι τα αλφαριθµητικά και πλειάδες είναι µη
µεταβαλλόµενα και στα λεξικά δεν έχει νόηµα η ταξινόµηση
¡  Η συνάρτηση sorted() επιστρέφει µια ταξινοµηµένη
λίστα απο µια ακολουθία (λίστα, πλειάδα, string) ή
λεξικό
n  Θα δούµε κάποιους αλγορίθµους ταξινόµησης και
πως αυτοί υλοποιούνται στην Python 12
Ταξινόµηση µε επιλογή:
(selection sort)
n  Λογική: Βρες το µικρότερο στοιχείο και βάλτο
πρώτο, µετά το 2ο µικρότερο και βάλτο 2ο, κ.ο.κ.
64, 25, 12, 22, 11

11, 25, 12, 22, 64

11, 12, 25, 22, 64

11, 12, 22, 25, 64

11, 12, 22, 25, 64


13

Ταξινόµηση µε επιλογή:
(selection sort)
def SelectionSort(lst):
for pos in range(0, len(lst)):
# find min starting from pos
minpos=FindMin(lst, pos)
# swap elements
lst[pos],lst[minpos] = lst[minpos],lst[pos]

def FindMin(lst, low):


minpos=low
for i in range(low, len(lst)):
if lst[i]<lst[minpos]:
minpos=i
return minpos

14
Βubble sort
n  Λογική:
¡  Συγκρίνουµε το κάθε στοιχείο µε το επόµενό του και
αλλάζουµε τις θέσεις τους αν δεν είναι στη σωστή
σειρά.
¡  Μετά το πρώτο πέρασµα το µεγαλύτερο στοιχείο θα
είναι τελευταίο στη λίστα. Μετά το 2ο πέρασµα το
δεύτερο µεγαλύτερο στοιχείο θα είναι προ-τελευταίο στη
λίστα, κ.ο.κ.

15

Βubble sort: [64, 25, 12, 22, 11]


πρώτο πέρασµα δεύτερο πέρασµα τρίτο πέρασµα

64, 25, 12, 22, 11 25, 12, 22, 11, 64 12, 22, 11, 25, 64
25, 64, 12, 22, 11 12, 25, 22, 11, 64 12, 22, 11, 25, 64
25, 64, 12, 22, 11 12, 25, 22, 11, 64 12, 11, 22, 25, 64
25, 12, 64, 22, 11 12, 22, 25, 11, 64 το 3ο µέγιστο στοιχείο
25, 12, 64, 22, 11 12, 22, 25, 11, 64
25, 12, 22, 64, 11 12, 22, 11, 25, 64
25, 12, 22, 64, 11 το 2ο µέγιστο στοιχείο
25, 12, 22, 11, 64
το µέγιστο στοιχείο ...
16
Bubble sort
def BubbleSort(lst):
for i in range(len(lst)): # rounds
for j in range(0,len(lst)-i-1): # i-th round
if lst[j]>lst[j+1]:
lst[j],lst[j+1] = lst[j+1],lst[j]

17

Insertion sort
n  Λογική: Αρχίζοντας από το 2ο στοιχείο, βάλε το
κάθε στοιχείο στη σωστή σειρά σε σχέση µε τα
προηγούµενά του
¡  Τελειώνοντας το ν-στο στοιχείο τα πρώτα ν στοιχεία
είναι ταξινοµηµένα
2ο στοιχείο 4ο στοιχείο 5ο στοιχείο
64, 25, 12, 22, 11 12, 25, 64, 22, 11 12, 22, 25, 64, 11
25, 64, 12, 22, 11 12, 25, 22, 64, 11 12, 22, 25, 11, 64
3ο στοιχείο 12, 22, 25, 64, 11 12, 22, 11, 25, 64
25, 64, 12, 22, 11 12, 11, 22, 25, 64
25, 12, 64, 22, 11 11, 12, 22, 25, 64
12, 25, 64, 22, 11 18
Insertion sort
def InsertionSort(lst):
for i in range(1,len(lst)): # 2nd, 3rd, etc.
pos = i
#swap with previous element while smaller
while pos>0 and lst[pos]<lst[pos-1]:
lst[pos],lst[pos-1] = lst[pos-1],lst[pos]
pos = pos-1

19

Merge sort
n  Λογική: Ταξινόµησε αναδροµικά το πρώτο µισό και
το δεύτερο µισό της λίστας και µετά «συγχώνευσε»
τα δύο µισά σε µια ταξινοµηµένη λίστα.
MergeSort(64, 5, 25, 12, 22, 11)
αναδρομικές κλήσεις

merge

MergeSort(64, 5, 25) 5, 25, 64
5 11 12 22 25 64
MergeSort(12, 22, 11) 11, 12, 22

20
Merge sort
def MergeSort(lst):
if len(lst)<=1: # base case: already sorted
return lst
else: # recursive case
mid = (len(lst))//2
lst1 = MergeSort(lst[:mid]) # sort first half
lst2 = MergeSort(lst[mid:]) # sort second half
outl = [] # merged list to be returned
i = j = 0 # pointers to positions of sorted halves
while i<len(lst1) and j<len(lst2):
if lst1[i]<=lst2[j]:
outl.append(lst1[i])
i += 1
else:
outl.append(lst2[j])
j += 1
outl.extend(lst1[i:]) # add remainders
outl.extend(lst2[j:])
return outl 21

Άλλοι αλγόριθµοι ταξινόµησης


n  Heap sort: βέλτιστος χρόνος στη χειρότερη
περίπτωση (όπως και ο merge sort)
n  Quick sort: βέλτιστος χρόνος στην πράξη
n  Counting/Bucket sort: βέλτιστος χρόνος σε ειδικές
περιπτώσεις
n  Λεπτοµέρειες και ανάλυση στο µάθηµα:
«Δοµές Δεδοµένων»

22
Αρχεία

Διαχείριση αρχείων
n  Ως τώρα έχουµε δει πως µπορούµε να πάρουµε την
είσοδο ενός προγράµµατος από το χρήστη και πως
να τυπώνουµε την έξοδό του στην οθόνη.
n  Σε πολλές εφαρµογές, θέλουµε να πάρουµε την
είσοδο ενός προγράµµατος από ένα αρχείο του
υπολογιστή, ή να γράψουµε σε ένα αρχείο.
n  Η Python παρέχει συναρτήσεις για διάβασµα και
γράψιµο σε αρχεία.

2
Τύποι αρχείων
n  Αρχεία κειµένων (text files): Περιέχουν
χαρακτήρες ASCII µόνο και µπορούµε να τα
διαβάσουµε ανοίγοντάς τα µε έναν απλό
επεξεργαστή κειµένου (π.χ. αρχεία µε κατάληξη txt)
ή τυπώνοντάς τα στην κονσόλα του λειτουργικού
συστήµατος
n  Δυαδικά αρχεία κειµένων (binary files): Περιέχουν
κωδικοποιηµένη πληροφορία σε δυαδική µορφή. Δεν
µπορούµε να τα διαβάσουµε µε έναν απλό
επεξεργαστή κειµένου ή τυπώνοντάς τα στην
κονσόλα του λειτουργικού συστήµατος
3

Που βρίσκονται τα αρχεία;


n  Τα αρχεία αποθηκεύονται στο δίσκο του
συστήµατος (δευτερεύουσα µνήµη) και η
πληροφορία που γράφεται σε αυτά είναι µόνιµη
¡  παραµένει και µετά το σβήσιµο του υπολογιστή
n  Τα αρχεία οργανώνονται σε φακέλους (folders) ή
αλλιώς καταλόγους (directories) ιεραρχικά στο
δίσκο
n  Το κάθε αρχείο έχει ένα όνοµα και µια διεύθυνση
µονοπατιού στο δίσκο
¡  Π.χ. όνοµα: ‘testfile.txt’,
διεύθυνση µονοπατιού ‘C:\files\testfile.txt’
4
Που βρίσκονται τα αρχεία;
n  Ένα πρόγραµµα που τρέχει στον υπολογιστή
αναφέρεται σε έναν «τρέχοντα κατάλογο»
n  Αν το πρόγραµµα δηµιουργήσει ένα αρχείο, χωρίς
να προσδιορίσει το φάκελό του (δηλ. δίνοντας ένα
όνοµα και όχι µια πλήρη διεύθυνση µονοπατιού)
τότε το αρχείο γράφεται στον τρέχοντα κατάλογο.
n  Επίσης, αν το πρόγραµµα ανοίγει και διαβάζει ένα
αρχείο µε βάση το όνοµά του µόνο, το πρόγραµµα
υποθέτει ότι το αρχείο βρίσκεται στον τρέχοντα
κατάλογο
5

Διαδικασία διαχείρισης αρχείου


µέσα σε ένα πρόγραµµα
n  Άνοιξε το αρχείο
n  Διάβασε από το αρχείο ή/και γράψε σε αυτό
n  Κλείσε το αρχείο
¡  Το κλείσιµο δεν είναι υποχρεωτικό (µπορεί να γίνει
αυτόµατα στο τέλος του προγράµµατος), αλλά µας
βοηθάει να σιγουρευτούµε ότι το περιεχόµενου του
αρχείου µας στο δίσκο συµφωνεί µε τις ενέργειές µας
στο πρόγραµµα

6
«Άνοιγµα» ενός αρχείου
n  Γίνεται µε τη συνάρτηση open(filename)
n  Η συνάρτηση ανοίγει το αρχείο µε το όνοµα filename
ή δίνει σφάλµα αν δεν υπάρχει αρχείο µε αυτό το
όνοµα
µεταβλητή που δείχνει στο αντικείµενο αρχείου
µπορούµε να δώσουµε και πλήρη
>>> f = open('testfile.txt') διεύθυνση του αρχείου στο δίσκο
>>> f = open('testfile') (π.χ. ‘C:\files\testfile.txt’)
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
f = open('testfile')
FileNotFoundError: [Errno 2] No such file or
directory: 'testfile'
7

«Άνοιγµα» ενός αρχείου


n  Το άνοιγµα ενός αρχείου αντιστοιχίζει το αρχείο σε
µια µεταβλητή (αντικείµενο αρχείου)
n  Μέσω της µεταβλητής µπορούµε να διαβάσουµε τα
περιεχόµενα του αρχείου
n  Η open παίρνει και πρόσθετα προαιρετικά ορίσµατα
¡  Αν δε βάλουµε άλλα ορίσµατα, σηµαίνει ότι ανοίγουµε το
αρχείο για διάβασµα
¡  Μπορούµε επίσης να ανοίξουµε ένα αρχείο για γράψιµο,
για προσθήκη δεδοµένων µόνο, για γράψιµο και
διάβασµα, για γράψιµο ή/και διάβασµα δυαδικής
πληροφορίας
8
«Άνοιγµα» ενός αρχείου
άνοιγµα για διάβασµα:
>>> f = open('testfile.txt') το ίδιο σαν να µη βάζαµε
δεύτερο όρισµα
>>> f = open('testfile.txt','r') άνοιγµα για γράψιµο
>>> f = open('testfile.txt','w') αρχικοποιεί νέο αρχείο
>>> f = open('testfile.txt','a') άνοιγµα για προσθήκη στο
>>> f = open('testfile.txt','r+') τέλος του αρχείου (append)
>>> f = open('testfile.txt','rb') διάβασµα και γράψιµο
>>> f = open('testfile.txt','rb+') διάβασµα δυαδικού αρχείου
διάβασµα και γράψιµο
δυαδικού αρχείου

τα + και b µπορούν να προστεθούν στα r, w και a


9

Γράψιµο σε αρχείο
n  Μέσω της µεθόδου write

άνοιγµα για γράψιµο


>>> f = open('testfile.txt','w')
>>> f.write('Hello, ') γράψε ‘Hello, ’
7 γράφτηκαν 7 χαρακτήρες
>>> f.write('World!')
«κλέισιµο» αρχείου
6 πιστοποιεί το ότι οτιδήποτε
>>> f.close() γράψαµε θα είναι στο αρχείο
στο δίσκο

H f.close() χρειάζεται οπωσδήποτε στην εγγραφή γιατί µπορεί ο


υπολογιστής να έχει κρατήσει τα δεδοµένα που θέλουµε να
γράψουµε σε buffer και να µην τα έχει σώσει στο αρχείο.
10
Διάβασµα από αρχείο
n  Μέσω της µεθόδου read

άνοιγµα για διάβασµα


>>> f = open('testfile.txt', 'r')
>>> διάβασε 4 χαρακτήρες
>>> f.read(4)
επιστρέφει αυτό που διάβασε
'Hell'
>>> s = f.read() διαβάζει όλα από την
>>> s τρέχουσα θέση και µετά
'o, World!'
H f.close() δεν χρειάζεται οπωσδήποτε όταν διαβάζουµε ένα αρχείο.

11

Τυχαία Προσπέλαση
n  Μπορούµε να µετακινηθούµε σε µια συγκεκριµένη
θέση του αρχείου και να διαβάσουµε, ή να γράφουµε
εκέι µέσω της µεθόδου seek
>>> f = open('testfile.txt','r') testfile.txt
>>> f.seek(4) πήγαινε στη Hello, World!
4 θέση 4
>>> f.read(3)
'o, '
>>> f.tell() επιστρέφει την
7 τρέχουσα θέση
στο αρχείο

12
Παράδειγµα µε seek και write
n  Μπορούµε να µετακινηθούµε σε µια συγκεκριµένη
θέση του αρχείου και να διαβάσουµε, ή να γράφουµε
εκέι µέσω της µεθόδου seek
testfile.txt
>>> f = open('testfile.txt','r+') Hello, World!
>>> f.seek(3)
3
>>> f.write('p ')
2 testfile.txt
>>> f.seek(0) Help , World!
0
>>> f.read()
'Help , World!'
13

readline, readlines, writelines


n  Η µέθοδος readline() διαβάζει την επόµενη
γραµµή του αρχείου.
n  Το τέλος µίας γραµµής υποδηλώνεται από το
χαρακτήρα \n.
testfile.txt
>>> f = open('testfile.txt')
>>> for i in range(2): Hello, World!
print(str(i)+':', f.readline()) How are you?

0: Hello, World!
1: How are you?

14
readline, readlines, writelines
n  Η µέθοδος readlines() διαβάζει όλες τις
γραµµές του αρχείου και τις επιστρέφει σε µία
λίστα.

testfile.txt
>>> f = open('testfile.txt')
>>> l = f.readlines() Hello, World!
>>> l How are you?
['Hello, World!\n', 'How are you?']
Το \n είναι ειδικός χαρακτήρας
που σηµαίνει «αλλαγή γραµµής»

15

readline, readlines, writelines


n  Η µέθοδος writelines() παίρνει µία λίστα από
αλφαριθµητικά και τα γράφει στο αρχείο.
Πρέπει εµείς να προσθέσουµε τα \n για να
δηλώσουµε που αλλαζουν οι γραµµές
testfile.txt
>>> f = open('testfile.txt') Hello, World!
>>> l = f.readlines() How are you?
>>> l[0] = 'Howdy Johnny\n'
>>> f2 = open('testfile2.txt','w') testfile2.txt
>>> f2.writelines(l)
Howdy Johnny
>>> f2.close()
How are you?

16
Διαβάζοντας µε επαναλήψεις
n  Μπορούµε να καλούµε τις µεθόδους read και
readline επαναληπτικά µέχρι να φτάσουµε στο
τέλος του αρχείου
>>> f = open('testfile.txt') testfile.txt
>>> char = f.read(1) Hello, World!
>>> while char: How are you?
print(char,end='')
char = f.read(1)
ενόσω ο τρέχων χαρακτήρας που
Hello, World! διαβάσαµε δεν είναι κενός, που
σηµαίνει ότι το αρχείο δεν έχει
How are you?
τελειώσει
>>>
17

Διαβάζοντας µε επαναλήψεις
n  Μπορούµε να καλούµε τις µεθόδους read και
readline επαναληπτικά µέχρι να φτάσουµε στο
τέλος του αρχείου
>>> f = open('testfile.txt') testfile.txt
>>> l = f.readline() Hello, World!
>>> while l: How are you?
print(l, end='')
l = f.readline()
χρειάζεται, γιατί η κάθε γραµµή
περιέχει το \n στο τέλος
Hello, World!
How are you?
>>>
18
Διαβάζοντας µε επαναλήψεις
n  Το ίδιο µε while-True / break

>>> f = open('testfile.txt') testfile.txt


>>> while True: Hello, World!
l = f.readline() How are you?
if not l: break
print(l, end='')
αποφεύγουµε να γράψουµε το
Hello, World! l = f.readline()
δύο φορές, άρα το πρόγραµµά
How are you?
µας είναι πιο ευανάγνωστο
>>>
19

Διάβασµα όλου του αρχείου


(αν είναι µικρό)
n  Μπορούµε να διαβάσουµε «όλο» το αρχείο και
να εξετάσουµε τους χαρακτήρες του έναν-έναν
ή τις γραµµές µία-µία
>>> f = open('testfile.txt') >>> f = open('testfile.txt')
>>> for char in f.read(): >>> for l in f.readlines():
print(char, end='') print(l, end='')

Hello, World! Hello, World!


How are you? How are you?
>>> >>>

20
Διάβασµα γραµµή-γραµµή µε
χρήση for
n  Εναλλακτικός επαναληπτικός τρόπος
διαβάσµατος για κάθε γραµµή l που
>>> f = open('testfile.txt') διαβάζεται από το αρχείο
>>> for l in f: (το read εδώ υπονοείται)
print(l,end='') testfile.txt

Hello, World! Hello, World!


How are you? How are you?

>>> for l in open('testfile.txt'):


print(l,end='') πιο σύντοµος τρόπος, αλλά δεν
µπορούµε να κάνουµε close. Το
Hello, World! close θα γίνει µετά το τέλος του
How are you? προγράµµατος/συνάρτησης 21

list(open(filename))
n  Μπορoύµε να µετατρέψουµε τα περιεχόµενα
του αρχείου σε λίστα χρησιµοποιώντας
list(open(filename))
¡  Αντίστοιχα µε το list(range(5))

>>> l = list(open('testfile.txt')) testfile.txt


>>> l
Hello, World!
['Hello, World!\n', 'How are you?']
How are you?

22
Παράδειγµα
>>> f = open('testfile2.txt','w')
>>> f.write('First line\n')
11
>>> f.write('Second line\n')
12
>>> f.write('Third line\n')
11
>>> f.close()
>>> first, second, third = open('testfile2.txt')
>>> first
'First line\n' ανοίγει το αρχείο και
>>> second διαβάσει τις γραµµές
'Second line\n' στις µεταβλητές
>>> third ταυτόχρονα
'Third line\n'
23

Άσκηση
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει
σαν όρισµα ένα όνοµα αρχείου και ένα
αλφαριθµητικό και θα επιστρέφει πόσες φορές
εµφανίζεται το αλφαριθµητικό µέσα στο αρχείο
¡  π.χ. stringCount('testfile.txt','you') = 1
testfile.txt
def stringCount(filename, s): Hello, World!
f = open(filename) How are you?
content = f.read()
return content.count(s)
διαβάζει όλο το αρχείο και
βάζει τα περιεχόµενά του
στο αλφαριθµητικό content
24
Άσκηση
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει
σαν όρισµα ένα όνοµα αρχείου και θα
επιστρέφει τον αριθµό των λέξεων σε αυτό
¡  π.χ. wordCount('testfile.txt') = 5

testfile.txt
def wordCount(filename): Hello, World!
f = open(filename) How are you?
content = f.read()
return len(content.split())

25

Άσκηση
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν όρισµα
ένα όνοµα αρχείου και θα επιστρέφει τις λέξεις του σε
µια λίστα, χωρίς σηµεία στίξης (!,.:;?)
¡  π.χ. words('testfile.txt') = ['Hello', 'World', 'How', 'are', 'you']
def words(filename):
f = open(filename)
content = f.read()
lout = [] testfile.txt
for s in content.split(): Hello, World!
chars = list(s) How are you?
l = []
for c in chars:
if c not in '!,.:;?':
l.append(c)
lout.append(''.join(l))
return lout 26
Άσκηση
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν όρισµα
ένα όνοµα αρχείου και θα επιστρέφει τις λέξεις του σε
µια λίστα, χωρίς σηµεία στίξης (!,.:;?)
¡  π.χ. words('testfile.txt') = ['Hello', 'World', 'How', 'are', 'you’]
¡  Με χρήση translate testfile.txt
Hello, World!
def words(filename):
How are you?
trantab = str.maketrans('!,.:;?', ' ')
δηµιουργεί πίνακα
f = open(filename) µετάφρασης trantab, που
αντιστοιχίζει κάθε σηµείο
content = f.read() στίξης σε ένα διάστηµα
newcontent = content.translate(trantab)
return newcontent.split() «µεταφράζει» το content
µε βάση το trantab
27

Άσκηση
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν όρισµα
ένα όνοµα αρχείου και ένα αλφαριθµητικό και θα
τυπώνει τις γραµµές του αρχείου που περιέχουν το
αλφαριθµητικό
¡  π.χ. grep('testfile.txt','are') >>> How are you?

def grep(filename, w): testfile.txt


for l in open(filename): Hello, World!
if w in l: How are you?
print(l,end='')

28
close και flush
n  Όταν ανοίγουµε ένα αρχείο για γράψιµο και γράφουµε
σε αυτό, οι αλλαγές στο αρχείο γίνονται πρώτα στη
µνήµη του υπολογιστη: δεν υπάρχει εγγύσηση ότι το
αρχείο στο δίσκο έχει αλλάξει.
¡  Η f = open(‘filename’,’w’) δε δηµιουργεί το αρχείο στο δίσκο
απ’ ευθείας
¡  Η f.write(‘something’) δεν γράφει απ’ευθείας στο αρχείο του
δίσκου
n  Οι αλλαγές γίνονται σε ένα buffer της µνήµης
n  Η f.close() γράφει όλα τα δεδοµένα του buffer στο
αρχείο και κλείνει το αρχείο
n  Η f.flush() γράφει όλα τα δεδοµένα του buffer στο
αρχείο χωρίς να το κλείσει
29

Άσκηση: openLog
n  Γράψτε µια συνάρτηση, openLog() η οποία θα
ανοίγει ένα αρχείο (όπως η open()) και θα
καταγράφει σε ένα αρχείο log.txt το ιστορικό
των ανοιγµάτων αρχείων µέσω της openLog()
n  Παράδειγµα επιθυµητής συµπεριφοράς:

>>> f = openLog('testfile.txt','r’)

log.txt

Wednesday Dec/03/14 12:38 PM: File testfile.txt opened.

30
Άσκηση: openLog, βήµα 1
n  Ας αρχίσουµε από το βασικό: θέλουµε η
openLog() να κάνει ότι και η open() :
def openLog(filename, mode):
f = open(filename, mode)
return f

n  Είναι εντάξει το παραπάνω;


¡  ΟΧΙ:
def openLog(filename, mode = 'r'):
f = open(filename, mode)
return f

31

Άσκηση: openLog, βήµα 2


n  Θέλουµε η openLog() να γράφει στο τέλος του
αρχείου log.txt το ότι ανοίξαµε το αρχείο:
def openLog(filename, mode='r'):
f = open(filename, mode)

logfile = open('log.txt', 'a')


logfile.write('File %s opened.\n' % filename)
logfile.close()

return f

n  Αυτό που µένει είναι να γράψουµε το χρόνο


32
time module
n  Το module time έχει µεθόδους προσπέλασης
του χρόνου η µέθοδος time() επιστρέφει τον
αριθµό των δευτερολέπτων που
έχουν περάσει από τη στιγµή
>>> import time
epoch
>>> time.time()
epoch: 00:00:00 of Jan. 1, 1970
1417606322.112668
>>> time.gmtime(0) epoch
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1,
tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1,
tm_isdst=0)
>>> time.localtime() τοπική ώρα
time.struct_time(tm_year=2014, tm_mon=12, tm_mday=3,
tm_hour=13, tm_min=37, tm_sec=35, tm_wday=2,
tm_yday=337, tm_isdst=0)
33

time module
n  Η µέθοδος strftime µετατρέπει ένα αντικείµενο
χρόνου σε ένα κατανοητό αλφαριθµητικό
>>> time.strftime('%A %b/%d/%y %I:%M %p', time.localtime())
'Tuesday Mar/16/10 02:06 PM'

34
time module
n  Η µέθοδος strftime µετατρέπει ένα αντικείµενο
χρόνου σε ένα κατανοητό αλφαριθµητικό

35

Άσκηση: openLog, βήµα 3


n  Θέλουµε η openLog() να γράφει στο τέλος του
αρχείου log.txt το ότι ανοίξαµε το αρχείο και
πότε το κάναµε:
def openLog(filename, mode='r'):
import time

f = open(filename, mode)

logfile = open('log.txt', 'a')


opentime = time.strftime('%A %b/%d/%y %I:%M %p', time.localtime())
logfile.write('%s: File %s opened.\n' % (opentime, filename))
logfile.close()

return f
36
Σφάλµατα, εξαιρέσεις,
εκσφαλµάτωση

Τύποι Σφαλµάτων
n  Συντακτικά λάθη (syntax errors)
n  Λάθη κατά την εκτέλεση (run-time errors)
n  Λογικά σφάλµατα

2
Συντακτικά Λάθη
n  Είναι σηµαντικό να καταλάβουµε το συντακτικό
λάθος και να το διορθώσουµε
break.py
from math import sqrt
for n in range(99, 0, -1):
root = sqrt(n)
if root == int(root):
print (n)
break

python3 break.py
File "break.py", line 6
break
^
IndentationError: unindent does not match
any outer indentation level 3

Συντακτικά Λάθη
n  Είναι σηµαντικό να καταλάβουµε το συντακτικό
λάθος και να το διορθώσουµε
test.py
suits = ['\u2660', '\u2661', '\u2662', '\u2663']
print((suits)
x=5

python3 test.py
File "test.py", line 3
x=5
^
SyntaxError: invalid syntax

4
Συντακτικά Λάθη
n  Είναι σηµαντικό να καταλάβουµε το συντακτικό
λάθος και να το διορθώσουµε
>>> (3+4]
SyntaxError: invalid syntax
>>> if x==5
SyntaxError: invalid syntax
>>> print 'hello'
SyntaxError: invalid syntax
>>> lst = [1;2;3]
SyntaxError: invalid syntax
>>> for i in range(10):
print(i)
SyntaxError: expected an indented block

Λάθη κατά την εκτέλεση


n  Δεν υπάρχει συντακτικό λάθος, αλλά το το
πρόγραµµά µας τερµατίζει γιατί µπαίνει σε µια µη
εγκυρη κατάσταση.
>>> 4/0
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
4/0
ZeroDivisionError: division by zero
>>> lst = [1,2,3]
>>> lst[3]
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
lst[3]
IndexError: list index out of range
6
Λάθη κατά την εκτέλεση
n  Πρέπει να διαβάσουµε και να καταλάβουµε το
σφάλµα
>>> y + 5
Traceback (most recent call last):
File "<pyshell#46>", line 1, in <module>
y+5
NameError: name 'y' is not defined
>>> '2' * '3'
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
'2' * '3'
TypeError: can't multiply sequence by non-int of type 'str'

Λάθη κατά την εκτέλεση


n  Πρέπει να διαβάσουµε και να καταλάβουµε το
σφάλµα
>>> int('4.5')
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
int('4.5')
ValueError: invalid literal for int() with base 10: '4.5'
>>> 2.0**10000
Traceback (most recent call last):
File "<pyshell#49>", line 1, in <module>
2.0**10000
OverflowError: (34, 'Result too large')

8
Εξαιρέσεις
n  Όταν το πρόγραµµα µπει σε µια µη έγκυρη κατάσταση
δηµιουργεί µια εξαίρεση (exception)
¡  Η εξαίρεση είναι κι αυτή αντικείµενο
n  Κάθε εξαίρεση ανήκει σε ένα τύπο
¡  Ο τύπος µας βοηθάει να καταλάβουµε το σφάλµα
Εξαίρεση Εξήγηση
KeyboardInterrupt Ο χρήστης διέκοψε το πρόγραµµα µε Crtl-C
OverflowError Ένας float πήρε πολύ µεγάλη τιµή
ZeroDivisionError Διαίρεση µε το 0
FileNotFoundError Το όνοµα αρχείου που επιχειρούµε να ανοίξουµε δεν υπάρχει
IndexError Προσπαθήσαµε να προσπελάσουµε µια µη έγκυρη θέση ακολουθίας
NameError Προσπέλαση µεταβλητής που δεν έχει οριστεί
TypeError Μια λειτουργία εφαρµόζεται σε λάθος τύπο αντικειµένου
ValueError Μια λειτουργία εφαρµόζεται σε µη έγκυρη τιµή 9

Δηµιουργία Εξαιρέσεων
n  Μπορούµε να δηµιουργήσουµε εξαίρεση στο πρόγραµµα
ή τη συνάρτησή µας αν κάτι δεν είναι έγκυρο µε βάση τις
προδιαγραφές µας µε την εντολή raise
x = int(input('Input a number between 10 and 20: '))
if x<10 or x>20:
raise Exception('Number outside valid range')
print(x**2)
περιγραφή της εξαίρεσης
Input a number between 10 and 20: 12
144
Input a number between 10 and 20: 3
Traceback (most recent call last):
File "test.py", line 3, in <module>
raise Exception('Number outside valid range')
Exception: Number outside valid range
10
«Πιάσιµο» Εξαιρέσεων
n  Μπορούµε να αποφύγουµε να τερµατίσει το πρόγραµµά
µας, φροντίζοντας να «πιάνουµε» τυχόν εξαιρέσεις
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
print (x/y)
except ZeroDivisionError:
print("The second number can't be zero!")
print("program finished normally...")

Enter the first number: 3


Enter the second number: 4
0.75
program finished normally...
11

«Πιάσιµο» Εξαιρέσεων
n  Μπορούµε να αποφύγουµε να τερµατίσει το πρόγραµµά
µας, φροντίζοντας να «πιάνουµε» τυχόν εξαιρέσεις
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
print (x/y)
except ZeroDivisionError:
print("The second number can't be zero!")
print("program finished normally...")

Enter the first number: 3


Enter the second number: 0
The second number can't be zero!
program finished normally...
12
Αλλά...
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
print (x/y)
except ZeroDivisionError:
print("The second number can't be zero!")
print("program finished normally...")

Enter the first number: 3a


Traceback (most recent call last):
File "/Users/Nikos/Dropbox/courses/course_python/py/test.py", line 2,
in <module>
x = eval(input('Enter the first number: '))
File "<string>", line 1
3a
^
SyntaxError: unexpected EOF while parsing 13

«Πιάσιµο» Εξαιρέσεων
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
print (x/y) οι εξαίρεσεις
except ZeroDivisionError: εξετάζονται
print("The second number can't be zero!") µε αυτή τη
except NameError: σειρά
print("You did not give a number")
except SyntaxError:
print("You did not give a number”)

14
«Πιάσιµο» Εξαιρέσεων
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
print (x/y)
except ZeroDivisionError:
print("The second number can't be zero!")
except:
print("Something wrong happened")

αν δεν προσδιορίσουµε συγκεκριµένο


τύπο εξαίρεσης µετά το except, τότε
εννοούµε οποιαδήποτε εξαίρεση
το σκέτο except πρέπει να µπαίνει µε
προσοχή γιατί πιάνει τα πάντα (ακόµα
και το Ctrl-C) 15

«Πιάσιµο» Εξαιρέσεων
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
print (x/y)
except (ZeroDivisionError, NameError, SyntaxError):
print("Something wrong with your numbers")

µπορούµε να βάλουµε πολλούς τύπους


εξαιρέσεων

16
«Πιάσιµο» Εξαιρέσεων
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
print (x/y)
except (ZeroDivisionError, NameError, SyntaxError) as e:
print(e)

αποθηκεύει το περιεχόµενο
της εξαίρεσης (ένα
Enter the first number: 3a αλφαριθµητικό) στη
unexpected EOF while parsing (<string>, line 1) µεταβλητή e

17

Χρήση try/except/else
while True:
try:
x = eval(input('Enter the first number: '))
y = eval(input('Enter the second number: '))
value = x/y
print ('x/y is', value) τυπώνουµε την εξαίρεση
except Exception as e: για να ξέρει ο χρήστης τι
print('Invalid input: ',e) πήγε στραβά
print('Please try again.')
else:
break
αν δε δηµιουργήθηκε
εξαίρεση, τότε όλα πήγαν
καλά και ο βρόγχος
τερµατίζει
18
Παράδειγµα
n  Γράψτε µια συνάρτηση που θα µετατρέπει την πρώτη γραµµή
ενός αρχείου σε ακέραιο και µετά θα τυπώνει τον ακέραιο
def readAge(filename):
try:
infile = open(filename)
strAge = infile.readline()
age = int(strAge)
print('age is',age)
except IOError:
print('Input/Output error.')
except ValueError:
print('Value cannot be converted to integer.')
except:
print('Other error.')

19

Εξαιρέσεις και συναρτήσεις


n  Αν δηµιουργηθεί εξαίρεση (σφάλµα) µέσα σε µια συνάρτηση,
τότε η συνάρτηση σταµατάει και επιστέφει
n  Μπορούµε να «πιάσουµε» εξαιρέσεις µέσα στη συνάρτηση
και να τις χειριστούµε
n  Επίσης µπορούµε να «πιάσουµε» µια εξαίρεση που
δηµιουργήθηκε σε µια συνάρτηση έξω από τη συνάρτηση
¡  Μια εξαίρεση που δηµιουργείται σε µια συνάρτηση, αν δεν τη
χειριστούµε εκεί, «µεταφέρεται» στο σηµείο που καλείται η
συνάρτηση, και µε τον ίδιο τρόπο µέχρι το κυρίως πρόγραµµα
¡  Αν δεν χειριστούµε την εξαίρεση κάπου, το πρόγραµµα τερµατίζει µε
σφάλµα δείχνοντας όλα τα σηµεία από όπου πέρασε η εξαίρεση
(στοίβα εκτέλεσης προγράµµατος).

20
Εξαιρέσεις και συναρτήσεις
def faulty():
raise Exception('Something is wrong')
def ignore_exception():
faulty()
def handle_exception():
try: faulty()
except: print('Exception handled')

>>> ignore_exception()
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
ignore_exception()
File "test.py", line 5, in ignore_exception
faulty()
File "test.py", line 3, in faulty
raise Exception('Something is wrong')
Exception: Something is wrong
21

Εξαιρέσεις και συναρτήσεις


def faulty():
raise Exception('Something is wrong')
def ignore_exception():
faulty()
def handle_exception():
try: faulty()
except: print('Exception handled')

>>> handle_exception()
Exception handled

22
Εξαιρέσεις και συναρτήσεις

23

Παράδειγµα
n  Έστω ότι αποθηκεύουµε τα στοιχεία προσώπων σαν λεξικά
n  Αν ένα πρόσωπο δέν έχει κάποια στοιχεία, ή δεν τα
γνωρίζουµε, απλά δεν υπάρχουν στο λεξικό του

>>> john = {'age':34, 'name':'John'}


>>> steve = {'age':23, 'occupation':'locksmith'}
>>> john['age']
34
>>> john['occupation']
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
person['occupation']
KeyError: 'occupation'

24
Παράδειγµα
n  Θέλουµε να γράψουµε µια συνάρτηση describePerson() που
να τυπώνει τα υπάρχοντα στοιχεία του προσώπου που της
δίνεται σαν όρισµα
n  Το name είναι υποχρεωτικό κλειδί στο όρισµα της
συνάρτησης, τα υπόλοια στοιχεία, προαιρετικά
>>> john = {'age':34, 'name':'John'}
>>> steve = {'name':'Steve', 'occupation':'locksmith'}
>>> describePerson(john)
Description of John
Age: 34
>>> describePerson(steve)
Description of Steve
Occupation: locksmith

25

Παράδειγµα
n  Θέλουµε να γράψουµε µια συνάρτηση describePerson() που
να τυπώνει τα υπάρχοντα στοιχεία του προσώπου που της
δίνεται σαν όρισµα
def describePerson(person):
print('Description of', person['name'])
if 'age' in person:
print('Age:', person['age'])
if 'occupation' in person:
print('Occupation:', person['occupation'])
if 'marital' in person:
print('Marital Status:', person['marital'])

n  Βάζουµε ένα if για κάθε πιθανό στοιχείο!


26
Παράδειγµα
n  Θέλουµε να γράψουµε µια συνάρτηση describePerson() που
να τυπώνει τα υπάρχοντα στοιχεία του προσώπου που της
δίνεται σαν όρισµα
n  Με χρήση εξαιρέσεων:
def describePerson(person):
print('Description of', person['name'])
try: print('Age:', person['age'])
except KeyError: pass
try: print('Occupation:', person['occupation'])
except KeyError: pass
try: print('Marital Status:', person['marital'])
except KeyError: pass

27

Αποσφαλµάτωση
n  Αν το πρόγραµµά µας δε λειτουργεί σωστά (π.χ. έχει
λογικό σφάλµα) και δεν ξέρουµε που είναι το
σφάλµα, πρέπει να χρησιµοποιήσουµε µια µέθοδο
εκσφαλµάτωσης (debugging).
n  Η εκσφαλµάτωση µπορεί να γίνει µε ειδικά
προγράµµατα (debuggers)
¡  Ο debugger προσοµοιώνει την εκτέλεση του
προγράµµατος εντολή-προς-εντολή και δίνει ανά πάσα
στιγµή τις τιµές των µεταβλητών και τη στοίβα του
προγράµµατος
n  Τα περισσότερα IDE (integrated development
interfaces) εµπεριέχουν debugger 28
Αποσφαλµάτωση
n  Τυπική µεθοδολογία εκσφαλµάτωσης:
¡  Επανάληψη του προγράµµατος (ώστε να εντοπιστεί το
σφάλµα)
¡  Αποµόνωση του σηµείου που εµφανίζεται το σφάλµα
¡  Αναγνώριση της αιτίας που το προκαλεί (π.χ. από
απροσεξία ή από λογικό σφάλµα)
¡  Διόρθωση του σφάλµατος
¡  Επιβεβαίωση της διόρθωσης (επανάληψη του
προγράµµατος, δοκιµή µε διαφορετικές εισόδους)
n  Τα παραπάνω βήµατα είναι τυπικά. Κάποιοι
προγραµµατιστές µπορεί να ακολουθούν µια
παραλλαγή της µεθοδολογίας αυτής 29

Συµβουλές για την πρόληψη


σφαλµάτων
n  Σχεδιάστε πρώτα τον αλγόριθµό σας στο χαρτί και
βεβαιωθείτε ότι δεν έχει λογικά λάθη
n  Γράφετε το πρόγραµµά σας λίγο-λίγο και εκτελείτε το
δοκιµάζοντας την ορθότητά του (π.χ. µε εντολές print) πριν
προχωρήσετε στο να γράψετε τις επόµενες γραµµές του
¡  Δοκιµάζετε πάντα την ορθότητα µε µια ποικιλία δεδοµένων εισόδου
και βεβαιωθείτε ότι είναι σωστό για όλες τις πιθανές εισόδους
n  Κάντε χρήση συναρτήσεων ώστε να σπάσετε το πρόγραµµα
σε µικρά υπο-προγράµµατα τα οποία είναι ευκολότερο να
ελεγχθούν
n  Εισάγετε σχόλια ώστε να µπορέσετε να θυµηθείτε τη
λειτουργία τµηµάτων κώδικα που θα πρέπει να αλλάξετε σε
περίπτωση σφάλµατος 30
Σύνολα

Σύνολα στα Μαθηµατικά


n  Στα µαθηµατικά, ένα σύνολο τιµών ή
στοιχείων είναι διακριτό και τα στοιχεία δεν
έχουν κάποια συγκεκριµένη σειρά
¡  Αντίθετα, σε µια ακολουθία στοιχείων η σειρά έχει
σηµασία και ένα στοιχείο µπορεί να εµφανίζεται
πολλές φορές
n  Διακριτό: Α={1,2,3}, Β={1,2,2,3}
n  Η σειρά δεν έχει σηµασία: Α={1,2,3}={2,1,3}

2
Σύνολα στην Python
n  Στην Python, τα σύνολα, µοιάζουν µε τα λεξικά, αλλά
δεν έχουν ζευγάρια (κλειδί,τιµή)
¡  είναι σαν λεξικά που έχουν µόνο κλειδιά
n  Ορίζονται µε χρήση {}, όπως και τα λεξικά
n  Υποστηρίζονται από βασικές συναρτήσεις και
τελεστές ακολουθιών
>>> A = {1,2,3}
>>> len(A)
3
>>> 2 in A
True
3

Βασικές λειτουργίες
n  Ένωση, τοµή, διαφορά συνόλων όπως στα
µαθηµατικά
>>> A = {1,2,3} τελεστής ένωσης
>>> B = {3,4,5}
>>> A | B τελεστής τοµής
{1, 2, 3, 4, 5}
>>> A & B
τελεστής διαφοράς
{3}
>>> A - B
συµµετρική διαφορά
{1, 2}
>>> A ^ B
{1, 2, 4, 5}
4
Τελεστές συνόλων
n  Ισότητα, ανισότητα, (γνήσιο) υποσύνολο
>>> A={1,2,3}
>>> B={3,4,5}
>>> C={2,3}
>>> A == B
False
>>> A != B υποσύνολο
True
>>> C <= A γνήσιο υποσύνολο
True
>>> C < A
True
>>> C <= B
False
5

Μέθοδοι συνόλων
n  Πρόσθεση, αφαίρεση στοιχείων, καθαρισµός
>>> x = {'a','b','c'} προσθέτει το ‘d’
>>> x.add('d')
>>> x
{'b', 'a', 'd', 'c'} προσθέτει το ‘b’
>>> x.add('b')
Το ‘b’ υπάρχει ήδη!
>>> x
{'b', 'a', 'd', 'c’} αφαιρεί το ‘c’
>>> x.remove('c')
>>> x
{'b', 'a', 'd'} καθαρίζει το σύνολο
>>> x.clear()
6
Άσκηση
n  Φτιάξτε µια συνάρτηση union(lst) η οποία παίρνει
σαν όρισµα µια λίστα lst από σύνολα και επιστρέφει
την ένωση όλων των συνόλων
def union(lst): αρχικοποιεί ένα άδειο
u = set() σύνολο
for s in lst:
u=u|s
return u

Άσκηση
n  Φτιάξτε µια συνάρτηση elim(lst) η οποία παίρνει
σαν όρισµα µια λίστα lst από αριθµούς και
επιστρέφει µια λίστα µε τα ίδια στοιχεία όπως η lst
χωρίς όµως διπλά στοιχεία. Κάντε χρήση
συνόλων.

def elim(lst): αρχικοποιεί ένα σύνολο


εισάγοντας τα στοιχεία της
return list(set(lst)) λίστας που παίρνει σαν
όρισµα

8
Γραφικά Περιβάλλοντα

Γραφικό Περιβάλλον
n  Οι περισσότερες εφαρµογές συνοδεύονται µε
ένα γραφικό περιβάλλον
¡  Ο χρήστης επικοινωνεί µε την εφαρµογή µέσω του
περιβάλλοντος
n  Το γραφικό περιβάλλον βοηθάει το χρήστη να
εισάγει τα δεδοµένα του και να βλέπει τα
αποτελέσµατα µέσω παραθύρων.

2
Ανάπτυξη Γραφικού
Περιβάλλοντος στην Python
n  Μέσω του module tkinter
n  Επιτρέπει σχεδιασµό βασικών στοιχείων σε
παραθυρικά περιβάλλοντα, όπως κουµπιά,
ετικέττες, φόρµες εισαγωγής κειµένου, µενού,
κλπ.
n  Τα στοιχεία αυτά αποκαλούνται widgets
n  Θα κάνουµε µια µικρή εισαγωγή στη χρήση
του module tkinter

Το βασικό παράθυρο

>>> from tkinter import Tk δηµιουργεί το βασικό


>>> root = Tk() παράθυρο σαν αντικείµενο
και το αποθηκεύει στη
>>> root.mainloop() µεταβλητή root

µέθοδος που εµφανίζει το


παράθυρο root

4
Βάζοντας ετικέττες
>>> from tkinter import Tk, Label δηµιουργεί µια ετικέττα
>>> root = Tk() και την τοποθετεί στο root
>>> hello = Label(master = root, text = 'Hello GUI world!')
>>> hello.pack()
ορίζει αυτόµατα το πως θα
>>> root.mainloop() εµφανιστεί η ετικέττα

Παρουσίαση εικόνων
from tkinter import Tk, Label, PhotoImage
root = Tk() # the window
# transform GIF image to a format tkinter can display
photo = PhotoImage(file='car07a.gif')

car = Label(master=root, προεραιτικά ορίσµατα για


image=photo, το µέγεθος του παραθύρου
width=320, # width of label, in pixels
height=150) # height of label, in pixels

car.pack()
root.mainloop()

6
Πακετάρισµα πολλών
widgets
from tkinter import Tk, Label, PhotoImage,BOTTOM,LEFT,RIGHT
root = Tk()
photo1 = PhotoImage(file='wheel.gif')
photo2 = PhotoImage(file='car07a.gif')
txt = Label(master=root,text = 'Driving my car with a steering wheel')
txt.pack(side=BOTTOM)
car = Label(master=root,image=photo1)
car.pack(side=LEFT)
car = Label(master=root,image=photo2)
car.pack(side=RIGHT)
root.mainloop()

Χρήση σχάρας αντί


πακεταρίσµατος
from tkinter import Tk, Label, RAISED
root = Tk()
labels = [['1', '2', '3'], # phone dial labels
['4', '5', '6'], # organized in a grid
['7', '8', '9'],
['*', '0', '#']]
for r in range(4):
for c in range(3):
# create label for row r and column c
label = Label(root,
relief=RAISED, #raised border
padx=10, #make label wide
text=labels[r][c]) # label text
# place label in row r and column
label.grid(row=r, column=c)
root.mainloop()

8
Άσκηση
n  Φτιάξτε µια συνάρτηση cal(year, month), που θα
παίρνει σαν όρισµα ένα έτος και ένα µήνα και θα
δείχνει σε ένα παράθυρο το αντίστοιχο ηµερολόγιο
n  Π.χ.
>>> cal(2012, 2)

Άσκηση
n  Για να λύσουµε την άσκηση θα χρησιµοποιήσουµε
το module calendar:
>>> from calendar import monthrange
>>> monthrange(2012, 2) # year 2012, month 2 (February)
(2, 29)

σηµαίνει Wednesday
0: Monday, 1: Tuesday, …
σηµαίνει ότι ο µήνας έχει
29 µέρες

10
Άσκηση
from tkinter import Tk, Label
from calendar import monthrange
def cal(year, month):
root = Tk()
daysofweek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
for i in range(7):
label = Label(root, text=daysofweek[i])
label.grid(row=0,column=i)
weekday, nodays = monthrange(year, month)
week = 1
for i in range(1,nodays+1):
label = Label(root, text=str(i))
label.grid(row=week,column=weekday)
weekday += 1
if weekday>6:
weekday=0
week +=1
root.mainloop()
11

Widgets που αποκρίνονται σε


ενέργειες του χρήστη
n  Κουµπιά, φόρµες εισόδου, κλπ.
n  Προγραµµατισµός µε βάση γεγονότα (event-
driven programming)
¡  Προγράµµατα στα οποία η ροή ελέγχεται µε βάση
την διαδραστικότητα του χρήστη µε το
περιβάλλον
n  Π.χ. µια συνάρτηση καλείται όταν πατήσει ένα
κουµπί ο χρήστης

12
Παράδειγµα µε κουµπί

>>>
Day: 14 Dec 2014
Time: 08:27:44 AM

13

Παράδειγµα µε κουµπί (Button)


from tkinter import Tk, Button
from time import strftime, localtime
def clicked():
'prints day and time info'
time = strftime('Day: %d %b %Y\nTime: %H:%M:%S %p\n’, localtime())
print(time)
root = Tk()
# create button labeled 'Click it' and event handler clicked()
button = Button(root,
text='Click it', # text on top of button
command=clicked) # button click event handler
button.pack()
root.mainloop()

συνάρτηση που θα κληθεί


όταν πατηθεί το κουµπί
(χειριστής γεγονότος)
14
Παράδειγµα µε κουµπί
from tkinter import Tk, Button
from tkinter.messagebox import showinfo
from time import strftime, localtime
def clicked():
'prints day and time info'
time = strftime('Day: %d %b %Y\nTime: %H:%M:%S %p\n’, localtime())
showinfo(message = time) δείχνει µήνυµα σε
root = Tk() παράθυρο
# create button labeled 'Click it' and event handler clicked()
button = Button(root,
text='Click it', # text on top of button
command=clicked) # button click event handler
button.pack()
root.mainloop()

συνάρτηση που θα κληθεί


όταν πατηθεί το κουµπί
(χειριστής γεγονότος) 15

Παράδειγµα µε κουµπί

16
Ερµηνεία της root.mainloop()
n  Όταν καλείται η root.mainloop() η Python τρέχει το
εξής ατέρµον loop:
n  while True:
περίµενε να συµβεί κάποιο γεγονός
κάλεσε τη συνάρτηση που χειρίζεται το γεγονός
n  Ο παραπάνω βρόγχος τερµατίζει από µια
συνάρτηση χειρισµού
¡  Π.χ. πατώντας το κουµπάκι που κλείνει το κυρίως
παράθυρο

17

Άσκηση
n  Αλλάξτε την άσκηση στη διαφάνεια 8 ώστε οι
ετικέττες να «πατιούνται» και να τυπώνεται ο
αριθµός και το σύµβολο που πατιούνται κάθε φορά

>>>
25470#51456#02

18
Άσκηση
from tkinter import Tk, Button
root = Tk()
labels = [['1', '2', '3'], # phone dial labels
['4', '5', '6'], # organized in a grid
['7', '8', '9'],
['*', '0', '#']] Συναρτήσεις
for r in range(4): χειρισµού
for c in range(3): κουµπιών
def clicked(x=labels[r][c]):
print(x,end='')
but = Button(root,
text=labels[r][c],
command=clicked)
but.grid(row=r, column=c)
root.mainloop()

19

Παράδειγµα µε φόρµα
label entry

button

messagebox
20
Παράδειγµα µε φόρµα (Entry)
from tkinter import Tk, Button, Entry, Label, END
from time import strptime, strftime
from tkinter.messagebox import showinfo
def compute(): Μετατρέπει
global dateEnt # dateEnt is a global variable αλφαριθµητικό
date = dateEnt.get() # read date from entry dateEnt σε αντικείµενο
# compute weekday corresponding to date χρόνου
weekday = strftime('%A', strptime(date, '%b %d, %Y'))
# display the weekday in a pop-up window
showinfo(message = '%s was a %s' % (date, weekday))
dateEnt.delete(0, END) # delete date from entry dateEnt
root = Tk()
label = Label(root, text='Enter date')
label.grid(row=0, column=0)
dateEnt = Entry(root) Πιάνει 2 στήλες
dateEnt.grid(row=0, column=1)
button = Button(root, text='Enter', command=compute)
button.grid(row=1, column=0, columnspan=2)
root.mainloop() 21

Μέθοδοι φορµών
n  e.get() Επιστρέφει το αλφαριθµητικό που υπάρχει
στη φόρµα e
n  e.insert(index, text) Εισάγει το αλφαριθµητικό text
µέσα στη φόρµα e στη θέση index. Αν index=END το
text προστίθεται στο τέλος
n  e.delete(from, to) Διαγράφει όλους τους
χαρακτήρες από τη θέση from στη θέση to. Π.χ. η
delete(0, END) διαγράφει όλο το κείµενο από τη
φόρµα

22
Άσκηση
n  Φτιάξτε ένα πρόγραµµα που θα παίρνει από το
χρήστη ένα ποσό, ένα επιτόκιο (%) και έναν αριθµό
ετών και θα υπολογίζει πόσο θα έχει γίνει το ποσό
µετά τον αριθµό ετών

23

Άσκηση
from tkinter import Tk, Button, Entry, Label, END
from tkinter.messagebox import showinfo
def compute():
global amountEnt # amountEnt is a global variable
amount = amountEnt.get() # read amount from entry amountEnt
global rateEnt # rateEnt is a global variable
rate = rateEnt.get() # read rate from entry rateEnt
global yearsEnt # yearsEnt is a global variable
years = yearsEnt.get() # read years from entry yearsEnt
# compute amount plus interest
result = eval(amount)
for i in range(int(years)):
result = result*(1+eval(rate)/100)
# display the result in a pop-up window
showinfo(message = 'Your amount after %s years will be %.2f' % (years, result))
amountEnt.delete(0, END) # delete amount
rateEnt.delete(0, END) # delete rate
yearsEnt.delete(0, END) # delete years συνεχίζεται

24
Άσκηση
root = Tk() Ορίζει τον τίτλο του παραθύρου
root.title("Interest")
label1 = Label(root, text='Amount:’)
label1.grid(row=0, column=0)
amountEnt = Entry(root)
amountEnt.grid(row=0, column=1)
label2 = Label(root, text='Rate:’)
label2.grid(row=1, column=0)
rateEnt = Entry(root)
rateEnt.grid(row=1, column=1)
label3 = Label(root, text='Years:’)
label3.grid(row=2, column=0)
yearsEnt = Entry(root)
yearsEnt.grid(row=2, column=1)
button = Button(root, text='Calculate', command=compute)
button.grid(row=3, column=0, columnspan=2)
root.mainloop()

25

Παράδειγµα µε κείµενο

text

>>>
char = h
char = e
char = l
char = l
char = o
char = space
char = w
char = o
26
Παράδειγµα µε κείµενο (Text)
from tkinter import Tk, Text, BOTH
def record(event):
'''event handling function for key press events;
input event is of type tkinter.Event'''
print('char = %s' % event.keysym) # print key symbol
root = Tk()
text = Text(root,
width=20, # set width to 20 characters
height=5) # set height to 5 rows of characters
# Bind a key press event with the event handling function record()
text.bind('<KeyPress>', record)
# widget expands if the master does
text.pack(expand=True, fill=BOTH)
root.mainloop()
συνάρτηση που καλείται για κάθε
γεγονός τύπου <KeyPress>
Πρέπει να έχει σαν όρισµα το event
27

Μέθοδοι widget κειµένου


n  t.insert(index, text) Εισάγει το αλφαριθµητικό text
µέσα στο t πριν τη θέση index
n  t.get(from, to) Επιστρέφει το υπο-αλφαριθµητικό
από τη θέση from µέχρι τη θέση to
n  t.delete(from, to) Διαγράφει όλους τους
χαρακτήρες από τη θέση from στη θέση to

28
«Δέσιµο» γεγονότος σε
συνάρτηση χειρισµού
n  text.bind('<KeyPress>', record)
n  Δένει το γεγονός που περιγράφεται µε το
αλφαριθµητικό '<KeyPress>' στη συνάρτηση record
n  Γενικά οι τύποι γεγονότων έχουν τη µορφή:
¡  <modifier-type-detail>
n  Παραδείγµατα:
¡  <Control-Button-1>: Ctrl + left mouse button
¡  <Button-1><Button-3>: left mouse button, then right
mouse button
¡  <KeyPress-D><Return>: D, then Enter/Return
29

Παραδείγµατα Γεγονότων
n  <modifier-type-detail>

30
Η συνάρτηση χειρισµού
παίρνει σαν όρισµα το γεγονός
n  def record(event):
print('char = %s' % event.keysym)
n  Ένα αντικείµενο γεγονότος έχει διάφορα
χαρακτηριστικά τα οποία µπορούµε να χειριστούµε
µέσα στη συνάρτηση

31

Παράδειγµα µε καµβά

canvas

32
Παράδειγµα µε καµβά (canvas)
from tkinter import Tk, Canvas
def begin(event):
'initializes the start of the curve to mouse position'
global oldx, oldy
oldx, oldy = event.x, event.y
def draw(event):
'draws a line segment from old mouse position to new one'
global oldx, oldy, canvas # oldx and oldy will be modified
newx, newy = event.x, event.y # new mouse position
# connect previous mouse position to current one
canvas.create_line(oldx, oldy, newx, newy)
oldx, oldy = newx, newy # new position becomes previous
root = Tk()
oldx, oldy = 0, 0 # mouse coordinates (global variables)
canvas = Canvas(root, height=100, width=150) # canvas
# bind left mouse button click event to function begin()
canvas.bind("<Button-1>", begin)
# bind mouse motion while pressing left button event
canvas.bind("<Button1-Motion>", draw)
canvas.pack()
root.mainloop()
33

Μέθοδοι widget καµβά


n  create_line(x1, y1, x2, y2, ...) Ενώνει τα σηµέια (x1, y1),
(x2, y2), κλπ. µε ευθύγραµµα τµήµατα
n  create_rectangle(x1, y1, x2, y2) Δηµιουργεί ορθογώνιο µε
γωνίες στις συντενταγµένες (x1, y1) και (x2, y2)
n  create_oval(x1, y1, x2, y2) Δηµιουργεί οβάλ µεσα σε
ορθογώνιο µε γωνίες τις συντενταγµένες (x1, y1) και (x2, y2)
n  Οι παραπάνω συναρτήσεις επιστρέφουν το ID του
αντικειµένου που ζωγραφίζουν
n  Η delete(ID) σβήνει το αντικείµενο που έχει το ID
n  Η move(ID, dx, dy) µετακινεί το αντικείµενο που έχει το ID dx
pixels στον χ άξονα και dy pixels στον y

34
Επαναληπτικές Ασκήσεις

Λίστες
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα 2 λίστες και θα επιστρέφει το γινόµενo των
2 «µεσαίων» στοιχείων τους.
¡  Π.χ. L1 = [5,1,3,2,4], L2 = [9,2,1,8,0]
¡  median(L1) = 3, median(L2) = 2
¡  result = 6

def multimedians(L1,L2):
L1.sort()
L2.sort()
return L1[len(L1)//2]*L2[len(L2)//2]

2
Αλφαριθµητικά
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα ένα αλφαριθµητικό, το οποίο θα είναι ένα
κείµενο, και θα επιστρέφει τη λέξη µε τους
περισσότερους χαρακτήρες. Η συνάρτηση θα
πρέπει να µην υπολογίζει τυχόν τελείες ως µέρη
των λέξεων. def longest(s):
¡  Π.χ. s = ‘I went to the shops s2 = s.replace('.',' ')
today. I bought a cake.’ l = s2.split()
¡  result = ‘bought’ res = ''
for w in l:
if len(w)>len(res):
res = w
return res
3

Αλφαριθµητικά
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα ένα αλφαριθµητικό και θα επιστρέφει ένα
αντίγραφό του, όπου οι τελευταίοι 5 χαρακτήρες
θα είναι µε ανεστραµµένη σειρά.
¡  Π.χ. s = ‘I went to the market’
¡  result = ‘I went to the mtekra’

def rev(s):
x = s[-5:]
l = list(x)
l.reverse()
y = ''.join(l)
return s[:-5]+y

4
Λεξικά
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν όρισµα
ένα αλφαριθµητικό, το οποίο θα είναι ένα κείµενο, και θα
επιστρέφει ένα λεξικό, όπου για κάθε µήκος θα
καταγράφεται πόσες λέξεις έχουν αυτό το µήκος. Η
συνάρτηση θα πρέπει να µην υπολογίζει τυχόν τελείες ως
µέρη των λέξεων. def lengths(s):
¡  Π.χ. s = ‘I went to the shops s2 = s.replace('.',' ')
today. I bought a cake.’ l = s2.split()
¡  result = d = {}
{1: 3, 2: 1, 3: 1, 4: 2, 5: 2, 6: 1} for w in l:
if len(w) in d:
d[len(w)] += 1
else:
d[len(w)] = 1
return d 5

Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα µια λίστα και θα επιστρέφει µια νέα λίστα,
η οποία θα έχει µόνο τα στοιχεία που δεν είναι 0.
¡  Π.χ. L = [3,2,1,0,3,2,0,2]
¡  result = [3,2,1,3,2,2]

def nozeros(L):
L2 = []
for x in L:
if x != 0:
L2.append(x)
return L2

6
Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα µια λίστα και θα επιστρέφει µια νέα λίστα, η
οποία θα έχει µόνο τα στοιχεία µέχρι το πρώτο 0.
¡  Π.χ. L = [3,2,1,0,3,2,0,2]
¡  result = [3,2,1]

def untilzero(L):
L2 = []
for x in L:
if x == 0:
break
L2.append(x)
return L2

Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα µια λίστα και θα επιστρέφει µια νέα λίστα, η
οποία θα έχει µόνο τα στοιχεία µέχρι το πρώτο 0,
αλλά χωρίς τα 2.
¡  Π.χ. L = [3,2,1,0,3,2,0,2] def untilzeronotwos(L):
¡  result = [3,1] L2 = []
for x in L:
if x == 0:
break
if x != 2:
L2.append(x)
return L2

8
Έλεγχος ροής
n  Γράψτε την προηγούµενη συνάρτηση ξανά, αλλά µε
χρήση while αντί για if.
def untilzeronotwos2(L):
L2 = []
while L:
x = L.pop(0)
if x == 0:
break
if x != 2:
L2.append(x)
return L2

Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα ένα θετικό ακέραιο n και θα τυπώνει τις
δυνάµεις του 2 απο το 21 εώς το 2n χωρισµένες µε
διαστήµατα
¡  Π.χ. n = 6
¡  result = 2 4 8 16 32 64

def powers(n):
for i in range(1,n+1):
print(pow(2,i), end=' ')

10
Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα µια λίστα αριθµών και θα επιστρέφει True αν
η λίστα είναι αριθµητική ακολουθία, αλλιώς False.
¡  Αριθµητική ακολουθία: η διαφορά µεταξύ συνεχόµενων
στοιχείων είναι σταθερή
¡  Π.χ.
def arithmetic(L):
¡  L = [3,6,9,12,15] True if len(L)<2:
¡  L = [3,6,9,10,13] False return True
¡  L = [3] True diff = L[1]-L[0]
for i in range(1,len(L)-1):
if L[i+1]-L[i] != diff:
return False
return True
11

Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα ένα αλφαριθµητικό και θα επιστρέφει το
ακρώνυµό του. Η συνάρτηση θα πρέπει να
µετατρέπει τα πεζά σε κεφαλαία όπου χρειάζεται
¡  Π.χ. s = ‘central processing unit’
¡  result = ‘CPU’
def acronym(s):
L = s.split()
res = ''
for w in L:
res = res + w[0].upper()
return res

12
Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα µια λίστα L θα µετατρέπει κάθε στοιχείο L[i]
της L στο άθροισµα των στοιχείων απο τη θέση i και
µετά
¡  Π.χ. L = [2, 5, 6, 4, 3, 0]
L = [20, 18, 13, 7, 3, 0]
def rangesum(A):
for i in range(len(A)-1):
A[i] = sum(A[i:])

def rangesum(A):
if len(A)>1:
for i in range(len(A)-2,-1,-1):
A[i] += A[i+1]
13

Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα µια λίστα L, θα βρίσκει την υπολίστα της L µε
το µέγιστο άθροισµα και θα επιστρέφει το άθροισµα.
¡  Π.χ. L = [2, -5, 6, 4, -3, 10, -2, 1]
result = 17

def maxsublist(L):
m = L[0] # first elem of L
for i in range(len(L)): #start index
for j in range(i,len(L)): #end index
if sum(L[i:j]) > m:
m = sum(L[i:j])
return m

14
Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα ένα δισδιάστατο πίνακα Α και θα τον
µετατρέπει ώστε κάθε στοιχείο στην πρώτη στήλη να
είναι το άθροισµα όλων των στοιχείων της γραµµής
του
¡  Π.χ. A = [[2, 5],
[6, 4]]
A = [[7, 5],
[10, 4]]

def rowsum(A):
for i in range(len(A)):
A[i][0] = sum(A[i])
15

Έλεγχος ροής
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα ένα θετικό ακέραιο n και θα επιστρέφει
πόσες φορές µπορούµε να διαιρέσουµε το n µε το 2
(ακέραια διαίρεση) µέχρι το n να γίνει 1
¡  Π.χ. n = 25
result = 4

def intlog(n):
i=0
while n>1:
n//=2
i+=1
return i
16
Συναρτήσεις
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
υποχρεωτικά ορίσµατα δύο αριθµούς x και y και
ένα προεραιτικό όρισµα z (z=1 αν δεν ορίζεται) και
θα επιστρέφει τον αριθµό των βηµάτων από τον x
µέχρι τον y αν το κάθε βήµα είναι z.
¡  Π.χ. x = 4, y = 11, z =2
¡  result = 4 def numsteps(x,y,z=1):
(4-6, 6-8, 8-10, 10-11) if y<=x: return 0
numsteps = (y-x)//z
if (y-x)%z:
numsteps +=1
return numsteps

17

Αναδροµικές Συναρτήσεις
n  Γράψτε µια αναδροµική συνάρτηση, η οποία θα
υπολογίζει τον µέγιστο κοινό διαιρέτη δύο αριθµών
χρησιµοποιώντας τον αλγόριθµο του Ευκλείδη:
¡  gcd(a,0) = a
¡  gcd(a,b) = gcd(b, a mod b) def gcd(a,b):
¡  Π.χ. gcd(48,18) = if b==0: return a
gcd(18, 12) = return gcd(b, a%b)
gcd(12, 6) =
gcd(6, 0) =
6
# non-recursive
def gcd(a,b):
while b: a, b = b, a%b
return a
18
Αναδροµικές Συναρτήσεις
n  Γράψτε µια αναδροµική συνάρτηση, η οποία θα
παίρνει σαν όρισµα ένα θετικό ακέραιο n και θα
επιστρέφει πόσες φορές µπορούµε να διαιρέσουµε
το n µε το 2 (ακέραια διαίρεση) µέχρι το n να γίνει 1
¡  Π.χ. n = 25
result = 4

def intlog_rec(n):
if n<=1: return 0
return 1 + intlog_rec(n//2)

19

Ταξινόµηση
n  Τροποποιήστε τη bubblesort ώστε να ταξινοµεί µια
λίστα αριθµών βάζοντας πρώτα τους ζυγούς σε
αύξουσα σειρά και µετά τους µονούς σε φθίνουσα
σειρά def BubbleSort(lst):
¡  Π.χ. for i in range(len(lst)): # rounds
[2, 5, 6, 4, 3, 0] -> for j in range(0,len(lst)-i-1): # i-th round
[0, 2, 4, 6, 5, 3] if lst[j]%2 : # odd number
if lst[j+1] % 2 == 0 or lst[j]<lst[j+1]:
lst[j],lst[j+1] = lst[j+1],lst[j]
else: # even number
if lst[j+1] % 2 == 0 and lst[j]>lst[j+1]:
lst[j],lst[j+1] = lst[j+1],lst[j]

20
Αρχεία
n  Γράψτε µια συνάρτηση, η οποία θα παίρνει σαν
όρισµα ένα όνοµα αρχείου, θα διαβάζει το αρχείο
και θα γράφει σέ ένα άλλο αρχείο µε όνοµα
stats.txt, τον αριθµό των χαρακτήρων, λέξεων, και
γραµµών. def fstats(filename):
¡  Π.χ. try:
testfile.txt f = open(filename)
s = f.read()
Hello, World! except IOError:
How are you? print('Error reading',filename)
return
stats.txt g = open('stats.txt','w')
g.write('%d,%d,%d' %
26,5,2 (len(s),len(s.split()),s.count('\n')+1))
21

Εξαιρέσεις
n  Γράψτε µια συνάρτηση, η οποία θα ζητάει από το χρήστη να
δίνει αριθµούς µέχρι να δώσει κενό. Η συνάρτηση να
επιστρέφει τότε το µέσο όρο και τον µεσαίο (median) των
αριθµών που έχουν εισαχθεί σαν µια πλειάδα. Αν ο χρήστης
εισάγει µη έγκυρο αριθµό, η συνάρτηση θα επιστρέφει τα
στατιστικά των µεχρι τότε αριθµών
¡  Π.χ.
13
1
2
4
4x
result = (5, 4)

22
Εξαιρέσεις (συνέχεια)
def stats():
L = []
while True:
s = input()
if not s: break
try:
L.append(eval(s))
except:
break
L.sort()
if len(L)>0:
return (float(sum(L))/len(L), L[len(L)//2])

23

You might also like