Συναρτήσεις

Κλήση συναρτήσεων

Στο πλαίσιο του προγραμματισμού, μια συνάρτηση είναι μια ομάδα εντολών, που τους έχει αποδοθεί ένα όνομα και εκτελούν έναν υπολογισμό. Όταν ορίζετε μια συνάρτηση, καθορίζετε το όνομα και τη ακολουθία των εντολών. Αργότερα, μπορείτε να “καλέσετε” τη συνάρτηση με το όνομά της. Έχουμε ήδη δει ένα παράδειγμα κλήσης συνάρτησης:

>>> type(32)
<class 'int'>

Το όνομα της συνάρτησης είναι type. Η έκφραση στην παρένθεση καλείται όρισμα της συνάρτησης. Το όρισμα είναι μια τιμή ή μεταβλητή που μεταβιβάζουμε στη συνάρτηση ως είσοδό της. Το αποτέλεσμα, της συνάρτησης type, είναι ο τύπος του ορίσματος.

Συνηθίζουμε να λέμε ότι μια συνάρτηση “δέχεται” ένα όρισμα και “επιστρέφει” ένα αποτέλεσμα. Το αποτέλεσμα ονομάζεται τιμή επιστροφής.

Ενσωματωμένες συναρτήσεις

Η Python παρέχει μια σειρά σημαντικών ενσωματωμένων συναρτήσεων που μπορούμε να χρησιμοποιήσουμε χωρίς να χρειαστεί να τις ορίσουμε. Οι δημιουργοί της Python έγραψαν ένα σύνολο λειτουργιών για την επίλυση κοινών προβλημάτων και τις συμπεριέλαβαν σε αυτήν για να τις χρησιμοποιήσουμε.

Οι συναρτήσεις max και min μας δίνουν την μεγαλύτερη και την μικρότερη τιμή μιας λίστας, αντίστοιχα:

>>> max('Γειά σου κόσμε')
'ό'
>>> min('Γειά σου κόσμε')
' '
>>>

Η συνάρτηση max μας λέει τον “μεγαλύτερο χαρακτήρα” της συμβολοσειράς (που αποδεικνύεται ότι είναι το γράμμα “ό”) και η συνάρτηση min μας δείχνει τον μικρότερο χαρακτήρα (που αποδεικνύεται ότι είναι το κενό).

Μια άλλη πολύ συνηθισμένη ενσωματωμένη συνάρτηση είναι η συνάρτηση len, που μας λέει πόσα στοιχεία υπάρχουν στο όρισμα της. Εάν το όρισμα στη len είναι μια συμβολοσειρά, επιστρέφει τον αριθμό των χαρακτήρων στη συμβολοσειρά.

>>> len('Γειά σου κόσμε')
14
>>>

Αυτές οι συναρτήσεις δεν περιορίζονται στην εξέταση συμβολοσειρών. Μπορούν να λειτουργήσουν σε οποιοδήποτε σύνολο τιμών, όπως θα δούμε σε επόμενα κεφάλαια.

Θα πρέπει να αντιμετωπίζετε τα ονόματα των ενσωματωμένων συναρτήσεων ως δεσμευμένες λέξεις (δηλαδή, αποφύγετε τη χρήση του “max” ως όνομα μεταβλητής).

Συναρτήσεις μετατροπής τύπου

Η Python παρέχει επίσης ενσωματωμένες συναρτήσεις που μετατρέπουν τιμές από τον ένα τύπο στον άλλο. Η συνάρτηση int παίρνει οποιαδήποτε τιμή και τη μετατρέπει σε ακέραιο, αν μπορεί, ή διαφορετικά παραπονιέται:

>>> int('32')
32
>>> int('Γειά')
ValueError: invalid literal for int() with base 10: 'Γειά'

Η int μπορεί να μετατρέψει τιμές κινητής υποδιαστολής (floating-point) σε ακεραίους, αλλά δεν τις στρογγυλοποιεί, απλά αποκόπτει το δεκαδικό μέρος:

>>> int(3.99999)
3
>>> int(-2.3)
-2

Η float μετατρέπει ακεραίους και συμβολοσειρές σε αριθμούς κινητής υποδιαστολής:

>>> float(32)
32.0
>>> float('3.14159')
3.14159

Τέλος, η str μετατρέπει το όρισμά της σε μια συμβολοσειρά:

>>> str(32)
'32'
>>> str(3.14159)
'3.14159'

Μαθηματικές συναρτήσεις - Math

Η Python διαθέτει το άρθρωμα (module) math που περιέχει τις περισσότερες από τις γνωστές μαθηματικές συναρτήσεις. Πριν μπορέσουμε να χρησιμοποιήσουμε τo άρθρωμα, πρέπει να το εισαγάγουμε:

>>> import math

Αυτή η εντολή δημιουργεί ένα αντικείμενο αρθρώματος - module object, που ονομάζεται math. Εάν εκτυπώσετε το αντικείμενο αρθρώματος, θα λάβετε μερικές πληροφορίες σχετικά με αυτό:

>>> print(math)
<module 'math' (built-in)>

Το αντικείμενο του αρθρώματος περιέχει τις συναρτήσεις και τις μεταβλητές που ορίζονται στο module. Για να αποκτήσετε πρόσβαση σε μία από τις συναρτήσεις, πρέπει να καθορίσετε το όνομα του modume και το όνομα της συνάρτησης, χωρισμένα με μια τελεία.

>>> λόγος = ισχύς_σήματος / ισχύς_θορύβου
>>> decibels = 10 * math.log10(λόγος)

>>> ακτίνια = 0.7
>>> ύψος = math.sin(ακτίνια)

Το πρώτο παράδειγμα υπολογίζει τον λογάριθμο με βάση 10 του λόγου σήματος-θορύβου. Το module math παρέχει επίσης μια συνάρτηση που ονομάζεται log και υπολογίζει το νεπέριο λογάριθμο, λογάριθμο δηλαδή με βάση το e.

Το δεύτερο παράδειγμα βρίσκει το ημίτονο των ακτινίων. Το όνομα της μεταβλητής είναι μια υπόδειξη ότι το sin και οι άλλες τριγωνομετρικές συναρτήσεις (cos, tan κ.λπ.) δέχονται ορίσματα σε ακτίνια. Για να μετατρέψετε από μοίρες σε ακτίνια, διαιρέστε με 360 και πολλαπλασιάστε με 2π:

>>> μοίρες = 45
>>> ακτίνια = μοίρες / 360.0 * 2 * math.pi
>>> math.sin(ακτίνια)
0.7071067811865476

Η έκφραση math.pi λαμβάνει τη μεταβλητή π από την ενότητα μαθηματικών. Η τιμή αυτής της μεταβλητής είναι μια προσέγγιση του π, με ακρίβεια περίπου 15 ψηφίων.

Εάν γνωρίζετε τριγωνομετρία, μπορείτε να ελέγξετε το προηγούμενο αποτέλεσμα συγκρίνοντάς το με την τετραγωνική ρίζα του δύο, δια του δύο:

>>> math.sqrt(2) / 2.0
0.7071067811865476

Τυχαίος αριθμός

Με τις ίδιες εισόδους, τα περισσότερα προγράμματα υπολογιστών παράγουν τις ίδιες εξόδους κάθε φορά, επομένως λέμε ότι είναι αιτιοκρατικά. Η αιτιοκρατία (ντετερμινισμός) είναι συνήθως καλό πράγμα, αφού περιμένουμε ότι ο ίδιος υπολογισμός θα δώσει το ίδιο αποτέλεσμα. Για ορισμένες εφαρμογές, ωστόσο, θέλουμε ο υπολογιστής να είναι απρόβλεπτος. Τα παιχνίδια είναι ένα προφανές παράδειγμα, αλλά υπάρχουν περισσότερα.

Το να κάνετε ένα πρόγραμμα πραγματικά μη ντετερμινιστικό αποδεικνύεται ότι δεν είναι τόσο εύκολο, αλλά υπάρχουν τρόποι να το κάνετε τουλάχιστον να φαίνεται μη ντετερμινιστικό. Ένας από αυτούς είναι η χρήση αλγορίθμων που δημιουργούν ψευδοτυχαίους αριθμούς. Οι ψευδοτυχαίοι αριθμοί δεν είναι πραγματικά τυχαίοι επειδή παράγονται από έναν ντετερμινιστικό υπολογισμό, αλλά κοιτάζοντας απλά τους αριθμούς αυτούς είναι αδύνατο να διακριθούν από τους τυχαίους.

Το άρθρωμα (module) random παρέχει συναρτήσεις που δημιουργούν ψευδοτυχαίους αριθμούς (τους οποίους θα αποκαλώ απλώς “τυχαίους” από εδώ και πέρα).

Η συνάρτηση random επιστρέφει έναν τυχαίο αριθμό κινητής υποδιαστολής μεταξύ των 0,0 και 1,0 (συμπεριλαμβανομένου του 0.0 αλλά όχι του 1.0). Κάθε φορά που καλείται την random, πέρνεται τον επόμενο σε σειρά αριθμό μιας μεγάλης ακολουθίας. Για να δείτε ένα παράδειγμα εκτελέστε τον παρακάτω βρόχο:

import random

for i in range(10):
    x = random.random()
    print(x)

Αυτό το πρόγραμμα παράγει την ακόλουθη λίστα 10 τυχαίων αριθμών μεταξύ 0,0 και 1,0, αλλά χωρίς να περιλαμβάνεται το 1,0.

0.11132867921152356
0.5950949227890241
0.04820265884996877
0.841003109276478
0.997914947094958
0.04842330803368111
0.7416295948208405
0.510535245390327
0.27447040171978143
0.028511805472785867

Άσκηση 1: Εκτελέστε το πρόγραμμα στο σύστημά σας και δείτε ποιοι αριθμοί παράγονται. Εκτελέστε το πρόγραμμα περισσότερες από μία φορές και δείτε ποιοι αριθμοί παράγονται.

Η συνάρτηση random είναι μόνο μία από τις πολλές συναρτήσεις που χειρίζονται τυχαίους αριθμούς. Η συνάρτηση randint δέχεται τις παραμέτρους low και high και επιστέφει έναν ακέραιο μεταξύ των low και high (συμπεριλαμβανομένων και αυτών).

>>> random.randint(5, 10)
5
>>> random.randint(5, 10)
9

Για να επιλέξετε τυχαία ένα στοιχείο μιας σειράς μπορείτε να χρησιμοποιήσετε την choice:

>>> t = [1, 2, 3]
>>> random.choice(t)
2
>>> random.choice(t)
3

Το άρθρωμα random μας παρέχει και συναρτήσεις για τη δημιουργία τυχαίων τιμών από συνεχείς κατανομές, όπως ή κανονική κατανομή, η εκθετική, η γάμμα και μερικές ακόμη.

Προσθήκη νέων συναρτήσεων

Μέχρι στιγμής, χρησιμοποιούσαμε μόνο συναρτήσεις ενσωματωμένες στην Python, αλλά είναι επίσης δυνατή η προσθήκη και νέων συναρτήσεων. Ο ορισμός συνάρτησης καθορίζει το όνομα της νέας συνάρτησης και την ακολουθία των εντολών που εκτελούνται όταν κλιθεί ή συνάρτηση. Μόλις ορίσουμε μια συνάρτηση, μπορούμε να την επαναχρησιμοποιήσουμε, ξανά και ξανά, σε όλο το πρόγραμμά μας.

Ιδού και ένα παράδειγμα:

def print_lyrics():
    print("I'm a lumberjack, and I'm okay.")
    print('I sleep all night and I work all day.')

def είναι η δεσμευμένη λέση που υποδηλώνει τον ορισμό μιας συνάρτησης. Το όνομα της συνάρτησης είναι print_lyrics. Οι κανόνες ονοματολογίας των συναρτήσεων είναι οι ίδιοι με αυτούς για τα ονόματα μταβλητών: γράμματα, ψηφία και κάποια σημεία στίξης επιτρέπονται, αλλά ο πρώτος χαρακτήρας δεν μπορεί να είναι ψηφίο. Δεν μπορείτε να χρησιμοποιήσετε δεσμευμένη λέξη ως όνομα συνάρτησης και πρέπει να αποφεύγετε τη χρήση μεταβλητής και συνάρτησης με το ίδιο όνομα.

Οι κενές παρενθέσεις μετά το όνομα σημαίνουν ότι η συγκεκριμένη συνάρτηση δεν δέχεται κάποιο όρισμα. Αργότερα, θα κατασκευάσουμε συναρτήσεις που δέχονται ορίσματα ως είσοδο.

Η πρώτη γραμμή της συνάρτησης, κατά τον ορισμό της, καλείται επικεφαλίδα, οι υπόλοιπες αποτελούν το σώμα. Η επικεφαλίδα πρέπει να καταλήγει σε άνω κάτω τελεία και το σώμα πρέπει να τοποθετείται σε εσοχή. Κατά σύμβαση, η εσοχη είναι πάντοτε τέσσετα κενά. Το σώμα μπορεί να περιέχει οποιοδήποτε πλήθος δηλώσεων.

Αν ορίσετε μια συνάρτηση σε interactive mode, ο διερμηνευτής εκτυπώνει ellipses () στην επόμενη γραμμή για να σας ενημερώσει ότι ο ορισμός δεν έχει ολοκληρωθεί:

>>> def print_lyrics():
...     print("I'm a lumberjack, and I'm okay.")
...     print('I sleep all night and I work all day.')
...

Για να ολοκληρώσετε τη συνάρτηση πρέπει να εισάγετε μια κενή γραμμή (αυτό δεν είναι απαραίτητο σε ένα σενάριο).

Ο ορισμός μιας συνάρτησης δημιουργεί μια μεταβλητή με το ίδιο όνομα.

>>> print(print_lyrics)
<function print_lyrics at 0xb7e99e9c>
>>> print(type(print_lyrics))
<class 'function'>

Η τιμή του print_lyrics είναι ένα αντικείμενο function (συνάρητηση), το οποίο είναι του τύπου “function”.

Η σύνταξη κλήσης της νέας συνάρτησης είναι ίδια όπως και των ενσωματομένων συναρτήσεων:

>>> print_lyrics()
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.

Αφού ορίσετε μια συνάρτηση, μπορείτε να τη χρησιμοποιήσετε μέσα σε μια άλλη συνάρτηση. Για παράδειγμα, για να επαναλάβουμε το προηγούμενο ρεφρέν, θα μπορούσαμε να γράψουμε μια συνάρτηση που ονομάζεται repeat_lyrics:

def repeat_lyrics():
    print_lyrics()
    print_lyrics()

Και στη συνέχεια να καλέσουμε την repeat_lyrics:

>>> repeat_lyrics()
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.

Αλλά στην πραγματικότητα δεν πάει έτσι το τραγούδι.

Ορισμός και χρήση

Συνδυάζοντας τα τμήματα κώδικα από την προηγούμενη ενότητα, ολoκληρωμένο το πρόγραμμα μοιάζει κάπως έτσι:

def print_lyrics():
    print("I'm a lumberjack, and I'm okay.")
    print('I sleep all night and I work all day.')


def repeat_lyrics():
    print_lyrics()
    print_lyrics()

repeat_lyrics()

# Code: http://www.py4e.com/code3/lyrics.py

Αυτό το πρόγραμμα περιέχει δύο ορισμούς συναρτήσεων: print_lyrics και repeat_lyrics. Οι ορισμοί των συναρτήσεων εκτελούνται όπως και κάθε άλλη εντολή, αλλά το αποτέλεσμά τους είναι η δημιουργία αντικειμένων συνάρτησης. Οι εντολές που περιέχονται σε μία συνάρτηση δεν εκτελούνται έως ότου κληθεί η συνάρτηση και ο ορισμός της συνάρτησης δεν παράγει έξοδο.

Όπως θα περίμενε κανείς, πρέπει να δημιουργήσετε μια συνάρτηση πριν την εκτελέσετε. Με άλλα λόγια, ο ορισμός της συνάρτησης πρέπει να εκτελεστεί πριν από την πρώτη φορά που θα κληθεί.

Άσκηση 2: Μετακινήστε την τελευταία γραμμή αυτού του προγράμματος στην αρχή του, έτσι ώστε η κλήση της συνάρτησης να εμφανίζεται πριν από τον ορισμό της. Εκτελέστε το πρόγραμμα και δείτε ποιο μήνυμα λάθους λαμβάνετε.

Άσκηση 3: Μετακινήστε την κλήση συνάρτησης και πάλι στο κάτω μέρος καθώς και τον ορισμό του print_lyrics μετά τον ορισμό του repeat_lyrics. Τι συμβαίνει όταν εκτελείτε αυτό το πρόγραμμα;

Ροή εκτέλεσης

Για να διασφαλίσετε ότι μια συνάρτηση ορίζεται πριν από την πρώτη της χρήση, πρέπει να γνωρίζετε τη σειρά με την οποία εκτελούνται οι εντολές, η σειρά αυτή ονομάζεται ροή εκτέλεσης.

Η εκτέλεση αρχίζει πάντα με την πρώτη εντολή του προγράμματος. Οι εντολές εκτελούνται μία κάθε φορά, με σειρά από πάνω προς τα κάτω.

Οι ορισμοί συναρτήσεων δεν αλλάζουν τη ροή εκτέλεσης του προγράμματος, αλλά να θυμάστε ότι οι εντολές που περιλαμβάνονται στη συνάρτηση δεν εκτελούνται μέχρι να κληθεί η συνάρτηση.

Μια κλήση συνάρτησης είναι σαν μια παράκαμψη στη ροή της εκτέλεσης. Αντί να μεταβεί στην επόμενη πρόταση, η ροή μεταβαίνει στο σώμα της συνάρτησης, εκτελεί όλες τις εντολές εκεί και μετά επιστρέφει για να συνεχίσει από εκεί που σταμάτησε.

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

Ευτυχώς, η Python είναι καλή στο να παρακολουθεί πού βρίσκεται η ροή εκτέλεσης του προγράμματος, επομένως κάθε φορά που ολοκληρώνεται μια συνάρτηση, το πρόγραμμα συνεχίζει από εκεί που σταμάτησε στη συνάρτηση όπου πραγματοποιήθηκε η κλήση. Όταν η ροή εκτέλεσης φτάσει στο τέλος του προγράμματος, αυτό τερματίζει.

Ποιο είναι το ηθικό δίδαγμα αυτής της ατυχής ιστορίας; Όταν διαβάζετε ένα πρόγραμμα, δεν είναι πάντα καλό το να διαβάζετε από πάνω προς τα κάτω. Μερικές φορές είναι προτιμότερο να ακολουθείτε τη ροή της εκτέλεσης.

Παράμετροι και ορίσματα

Ορισμένες από τις ενσωματωμένες συναρτήσεις που έχουμε δει απαιτούν ορίσματα. Για παράδειγμα, όταν καλείτε την math.sin περνάτε έναν αριθμό ως όρισμα. Ορισμένες συναρτήσεις λαμβάνουν περισσότερα από ένα όρισμα: η math.pow δέχεται δύο, τη βάση και τον εκθέτη.

Μέσα στη συνάρτηση, τα ορίσματα εκχωρούνται σε μεταβλητές που ονομάζονται παράμετροι. Ακολουθεί ένα παράδειγμα συνάρτησης που ορίζεται από το χρήστη που δέχεται ένα όρισμα:

def print_twice(bruce):
    print(bruce)
    print(bruce)

Αυτή η συνάρτηση εκχωρεί το όρισμα σε μια παράμετρο που ονομάζεται bruce. Όταν καλείται η συνάρτηση, εκτυπώνει την τιμή της παραμέτρου (όποια και αν είναι) δύο φορές.

Η συνάρτηση αυτή λειτουργεί με οποιαδήποτε τιμή μπορεί να εκτυπωθεί.

>>> print_twice('Spam')
Spam
Spam
>>> print_twice(17)
17
17
>>> import math
>>> print_twice(math.pi)
3.141592653589793
3.141592653589793

Οι ίδιοι κανόνες σύνταξης που ισχύουν για τις ενσωματωμένες συναρτήσεις ισχύουν και για τις συναρτήσεις που ορίζονται από το χρήστη, επομένως μπορούμε να χρησιμοποιήσουμε οποιοδήποτε είδος έκφρασης ως όρισμα για το print_twice:

>>> print_twice('Spam '*4)
Spam Spam Spam Spam
Spam Spam Spam Spam
>>> print_twice(math.cos(math.pi))
-1.0
-1.0

Το όρισμα αξιολογείται πριν από την κλήση της συνάρτησης, επομένως στα παραδείγματα οι εκφράσεις 'Spam' *4 και math.cos(math.pi) αξιολογούνται μόνο μία φορά.

Μπορείτε επίσης να χρησιμοποιήσετε ως όρισμα μια μεταβλητή:

>>> michael = 'Eric, the half a bee.'
>>> print_twice(michael)
Eric, the half a bee.
Eric, the half a bee.

Το όνομα της μεταβλητής, που δίνουμε ως όρισμα (michael) δεν έχει καμία σχέση με το όνομα της παραμέτρου (bruce). Δεν έχει σημασία τι όνομα είχε τη τιμή στο προηγούμενο πρόγραμμα (σε αυτό από το οποίο έγινε η κλήση), εδώ στην print_twice αποκαλείται bruce.

Γόνιμες και κενές συναρτήσεις

Κάποιες από τις συναρτήσεις που χρησιμοποιούμε, όπως οι μαθηματικές συναρτήσεις (math) επιστρέφουν αποτελέσματα. Λόγω έλλειψης κάποιου καλύτερου ονόματος, τις αποκαλώ γόνιμες συναρτήσεις (fruitful functions). Άλλες συναρτήσεις, όπως η print_twice, εκτελούν μια λειτουργία αλλά δεν επιστρέφουν κάποια τιμή. Αυτές τις αποκαλώ κενές συναρτήσεις (void functions).

Όταν καλείτε μία γόνιμη συνάρτηση, σχεδόν πάντα θέλετε να κάνετε κάτι με το αποτέλεσμα της. Για παράδειγμα, ίσως θα το εκχωρήσετε σε μία μεταβλητή ή θα το χρησιμοποιήσετε ως μέρος μιας έκφρασης:

x = math.cos(radians)
golden = (math.sqrt(5) + 1) / 2

Όταν καλείτε μια συνάρτηση σε interactive mode, η Python εμφανίζει το αποτέλεσμα:

>>> math.sqrt(5)
2.23606797749979

Αλλά σε ένα σενάριο, αν καλέσετε μια γόνιμη συνάρτηση χωρίς να την εκχωρήσετε σε μια μεταβλητή, η επιστρεφόμενη τιμή εξαφανίζεται στην ομίχλη!

math.sqrt(5)

Αυτό το σενάριο υπολογίζει την τετραγωνική ρίζα του 5, αλλά μιας και δεν αποθηκεύει το αποτέλεσμα σε κάποια μεταβλητή, ούτε εμφανίζει το αποτέλεσμα, δεν είναι πολύ χρήσιμο.

Οι κενές (void) συναρτήσεις μπορεί να εμφανίζουν κάτι στην οθόνη ή να έχουν κάποιο άλλο αποτέλεσμα, αλλά δεν έχουν επιστρεφόμενη τιμή. Αν προσπαθήσετε να εκχωρήσετε το αποτέλεσμα σε μία μεταβλητή, θα πάρετε μια ειδική τιμή την ονομαζόμενη None.

index{None ειδική τιμή}

>>> result = print_twice('Bing')
Bing
Bing
>>> print(result)
None

Η τιμή None δεν είναι ίδια με τη συμβολοσειρά “None”. Είναι μια ειδική τιμή η οποία έχει τον δικό της τύπο:

>>> print(type(None))
<class 'NoneType'>

Για να επιστρέψουμε ένα αποτέλεσμα από τη συνάρτηση, χρησιμοποιούμε την εντολή return στο σώμα της συνάρτησης. Για παράδειγμα, θα μπορούσαμε να κατασκευάσουμε μια πολύ απλή συνάρτηση με όνομα addtwo, η οποία προσθέτει δύο αριθμούς και επιστρέφει το αποτέλεσμα.

def addtwo(a, b):
    added = a + b
    return added

x = addtwo(3, 5)
print(x)

# Code: http://www.py4e.com/code3/addtwo.py

Όταν το παραπάνω σενάριο εκτελείτε, η εντολή print θα εκτυπώσει το “8” γιατί η συνάρτηση addtwo κλήθηκε με ορίσματα το 3 και το 5. Μέσα στη συνάρτηση, οι παράμετροι a και b ήταν 3 και 5 αντίστοιχα. Η συνάρτηση υπολογίζει το άθροισμα των δύο αριθμών και το τοποθετεί στην τοπική μεταβλητή της συνάρτησης με όνομα added. Έπειτα χρησιμοποιεί την εντολή return για να στείλει την υπολογισμένη τιμή πίσω στον καλούντα κώδικα, ως αποτέλεσμα της συνάρτησης, όπου είχε εκχωρηθεί στην μεταβλητή x και την εκτυπώνει.

Γιατί συναρτήσεις;

Ίσως να μην έγινε σαφής ο λόγος για τον οποίο αξίζει να χωρίζουμε ένα πρόγραμμα σε συναρτήσεις. Υπάρχουν αρκετοί λόγοι:

Σε όλο το υπόλοιπο βιβλίο, συχνά θα ορίζουμε μια συνάρτηση για να εξηγήσουμε μια έννοια. Μέρος της ικανότητας δημιουργίας και χρήσης συναρτήσεων είναι να δημιουργείτε μια συνάρτηση που να αποτυπώνει σωστά μια ιδέα όπως “βρείτε τη μικρότερη τιμή σε μια λίστα τιμών”. Αργότερα θα σας δείξουμε κώδικα που βρίσκει τη μικρότερη από μια λίστα τιμών και θα σας τον παρουσιάσουμε ως μια συνάρτηση με το όνομα min, η οποία παίρνει μια λίστα τιμών ως όρισμα και επιστρέφει τη μικρότερη τιμή στη λίστα.

Εκσφαλμάτωση

Αν χρησιμοποιείτε έναν επεξεργαστή κειμένου για να γράψετε τα σενάριά σας, ίσως αντιμετωπίσετε προβλήματα με τα κενά διαστήματα και τους στηλοθέτες (tabs). Ο καλύτερος τρόπος για να αποφύγετε αυτού του είδους προβλήματα είναι να χρησιμοποιείτε αποκλειστικά κενά διαστήματα (όχι στηλοθέτες). Οι περισσότεροι επεξεργαστές κειμένου που είναι συμβατοί με την Python το κάνουν αυτό εξ ορισμού, αλλά κάποιοι άλλοι όχι.

Οι στηλοθέτες και τα κενά διαστήματα είναι συνήθως μη ορατά, κάτι το οποίο κάνει δύσκολη την εκσφαλμάτωση, οπότε προσπαθήστε να βρείτε έναν επεξεργαστή που να μπορεί να διαχειριστεί την ενδοπαραγραφοποίηση.

Επίσης, μην ξεχνάτε να αποθηκεύετε το πρόγραμμά σας πριν το εκτελέσετε. Κάποια προγραμματιστικά περιβάλλοντα το κάνουν αυτόματα, αλλά κάποια άλλα όχι. Σε αυτήν την περίπτωση, το πρόγραμμα που βλέπετε στον επεξεργαστή κειμένου δεν είναι το ίδιο με το πρόγραμμα που εκτελείτε.

Η εκσφαλμάτωση μπορεί να γίνει χρονοβόρα αν εκτελείτε το ίδιο εσφαλμένο πρόγραμμα ξανά και ξανά!

Σιγουρευτείτε πως ο κώδικας που κοιτάτε είναι ο κώδικας που εκτελείτε. Αν δεν είστε σίγουροι, γράψτε κάτι όπως το print("hello") στην αρχή του προγράμματος και εκτελέστε το ξανά. Αν δεν δείτε hello, δεν εκτελείτε το σωστό πρόγραμμα!

Γλωσσάριο

dot notation (χωρισμός με τελεία)
Η σύνταξη για την κλήση μιας συνάρτησης, που περιέχεται σε ένα άρθρωμα, καθορίζοντας το όνομα του αρθρώματος ακολουθούμενο από μια τελεία και το όνομα της συνάρτησης.
αιτιοκρατισμός (deterministic)
Αφορά ένα πρόγραμμα που κάνει το ίδιο πράγμα κάθε φορά που εκτελείται, με τις ίδιες εισόδους.
αλγόριθμος
Μια γενική μέθοδος για την επίλυση μιας κατηγορίας προβλημάτων.
αντικείμενο αρθρώματος (module)
Μια τιμή που δημιουργείται από μια εντολή import και παρέχει πρόσβαση στα δεδομένα και τον κώδικα που ορίζονται σε ένα άρθρωμα (module).
αντικείμενο συνάρτηση
Μια τιμή που δημιουργείται από τον ορισμό μιας συνάρτησης. Το όνομα της συνάρτησης είναι μια μεταβλητή που αναφέρεται σε ένα αντικείμενο συνάρτησης.
γόνιμη συνάρτηση (fruitful function)
Μια συνάρτηση που επιστρέφει μια τιμή.
εντολή import
Μια εντολή που διαβάζει ένα αρχείο αρθρώματος και δημιουργεί ένα αντικείμενο αρθρώματος.
επικεφαλίδα
Η πρώτη γραμμή του ορισμού μιας συνάρτησης.
κενή συνάρτηση (void function)
Μια συνάρτηση που δεν επιστρέφει τιμή.
κλήση συνάρτησης
Μια δήλωση που εκτελεί μια συνάρτηση. Αποτελείται από το όνομα της συνάρτησης που ακολουθείται από μια λίστα ορισμάτων.
ορισμός συνάρτησης
Μια δήλωση που δημιουργεί μια νέα συνάρτηση, προσδιορίζοντας το όνομά της, τις παραμέτρους και τις εντολές που εκτελεί.
όρισμα
Μια τιμή που παρέχεται σε μια συνάρτηση όταν η συνάρτηση καλείται. Αυτή η τιμή αποδίδεται στην αντίστοιχη παράμετρο στη συνάρτηση.
παράμετρος
Ένα όνομα (μεταβλητής) που χρησιμοποιείται μέσα σε μια συνάρτηση για να αναφερθούμε στην τιμή που δόθηκε ως όρισμα κατά την κλήση της.
ροή εκτέλεσης
Η σειρά με την οποία εκτελούνται οι εντολές κατά την εκτέλεση ενός προγράμματος.
συνάρτηση
Μια επώνυμη ακολουθία εντολών που εκτελεί κάποια χρήσιμη λειτουργία. Οι συναρτήσεις μπορεί να δέχονται, ή και όχι, ορίσματα και μπορεί να παράγουν ή να μην παράγουν αποτέλεσμα.
σύνθεση (composition)
Η χρήση μιας έκφρασης ως μέρος μιας μεγαλύτερης έκφρασης, ή μιας δήλωσης ως μέρος μιας μεγαλύτερης δήλωσης.
σώμα
Η ακολουθία των εντολών μέσα σε έναν ορισμό συνάρτησης.
τιμή επιστροφής
Το αποτέλεσμα μιας συνάρτησης. Αν η κλήση της συνάρτησης χρησιμοποιηθεί ως έκφραση, η τιμή επιστροφής είναι η τιμή της έκφρασης.
ψευδοτυχαίο
Αφορά μια ακολουθία αριθμών που φαίνεται να είναι τυχαίοι, αλλά παράγονται από ένα ντετερμινιστικό (αιτιοκρατικό) πρόγραμμα.

Ασκήσεις

Άσκηση 4: Ποιος είναι ο σκοπός της δεσμευμένης λέξης “def” στην Python;

a) Είναι αργκό που σημαίνει “ο παρακάτω κώδικας είναι πολύ ωραίος”
b) Υποδεικνύει την αρχή μιας συνάρτησης
c) Υποδεικνύει ότι η ενότητα κώδικα που ακολουθεί σε εσοχή πρόκειται να αποθηκευτεί για αργότερα
d) Ισχύουν το b και το c
e) Κανένα από τα παραπάνω

Άσκηση 5: Τι θα εκτυπώσει το παρακάτω πρόγραμμα Python;

def fred():
   print("Zap")

def jane():
   print("ABC")

jane()
fred()
jane()

a) Zap ABC jane fred jane
b) Zap ABC Zap
c) ABC Zap jane
d) ABC Zap ABC
e) Zap Zap Zap

Άσκηση 6: Ξαναγράψτε τον υπολογισμό του ακαθάριστου μισθού (Άσκηση 1 του 3ου Κεφαλαίου) και δημιουργήστε μια συνάρτηση με όνομα computepay η οποία δέχεται δύο παραμέτρους (hours και rate).

Δώστε Ώρες: 45
Δώστε Ποσό/Ώρα: 10
Μισθός: 475.0

Άσκηση 7: Ξαναγράψτε το πρόγραμμα βαθμολόγησης του προηγούμενου κεφαλαίου, χρησιμοποιώντας τώρα μια συνάρτηση με όνομα computegrade η οποία δέχεται έναν βαθμό ως παράμετρο και επιστρέφει την αντίστοιχη αξιολόγηση ως string.

Βαθμός  Αξιολόγηση
>= 0.9     A
>= 0.8     B
>= 0.7     C
>= 0.6     D
 < 0.6     F
Εισάγετε βαθμολογία: 0.95
A
Εισάγετε βαθμολογία: τέλεια
Άκυρη βαθμολογία
Εισάγετε βαθμολογία: 10.0
Άκυρη βαθμολογία
Εισάγετε βαθμολογία: 0.75
C
Εισάγετε βαθμολογία: 0.5
F

Εκτελέστε το πρόγραμμα επανειλημμένα όπως φαίνεται παραπάνω για να το δοκιμάσετε για τις διαφορετικές τιμές εισόδου.


Αν εντοπίσετε κάποιο λάθος σε αυτό το βιβλίο μην διστάσετε να μου στείλετε τη διόρθωση στο Github.