Σημειώσεις

Προηγούμενο

Επόμενο

Συναρτήσεις

Ορισμός συνάρτησης με την εντολή def

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

  1. εισάγονται δεδομένα,
  2. γίνονται υπολογισμοί και
  3. εξάγεται και τυπώνεται ένα αποτέλεσμα.
Για παράδειγμα, μπορούμε να βρούμε τον μεγαλύτερο μεταξύ δύο αριθμών ως εξής


x = 5.0
y = 6.0

if x > y:
   m = x
else:
   m = y

print(m)

Οργάνωση του προγράμματος.

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

Μία πρώτη συνάρτηση.

Ας διαχωρίσουμε το παραπάνω πρόγραμμα σε τμήματα. Το τμήμα του προγράμματος το οποίο κάνει τον υπολογισμό του μεγίστου μπορούμε να το διαχωρίσουμε ως εξής


def maximum(x,y):
   if x > y:
      m = x
    else:
      m = y
   return m

Η λέξη def είναι μία εντολή της python και ορίζει μία συνάρτηση. Έχουμε τους εξής κανόνες για τον ορισμό της συνάρτησης.

Βλέπουμε λοιπόν ότι μία γενική μορφή για την συνάρτηση είναι η εξής.


def functionName(variable1,variable2,...):
   statements
   return variable

Ένα ολοκληρωμένο πρόγραμμα με συνάρτηση.

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


a = 5.0
b = 6.0
result = maximum(a,b)
print(result)

Οι παραπάνω εντολές αποτελούν το κύριο πρόγραμμα. Το ολοκληρωμένο πρόγραμμα αποτελείται τώρα από δύο τμήματα: την συνάρτηση και το κύριο πρόγραμμα (το οποίο ακολουθεί τη συνάρτηση)

Ας δούμε σε λεπτομέρεια τι ακριβώς συμβαίνει στο παραπάνω πρόγραμμά μας στο οποίο περιέχεται μία συνάρτηση (maximum(x,y) με τυπικά ορίσματα x,y) και στο οποίο επίσης έχουμε χρησιμοποιήσει στο κύριο πρόγραμμα το όνομά της maximum(a,b).

Παράδειγμα.

Μία μάγισσα χρειάζεται δεδομένα για να κάνει προβλέψεις για το μέλλον. Ειδικότερα, θέλει να ξέρει αν τα μέλη μίας οικογένειας γεννήθηκαν σε δίσεκτα έτη ή όχι. Ας κατασκευάσουμε μία συνάρτηση η οποία θα αποφασίζει αν ένα έτος είναι δίσεκτο. Θα την χρησιμοποιήσουμε μετά για όλα τα μέλη της οικογένειας. [Υπόδειξη. Για να είναι ένα έτος δίσεκτο θα πρέπει να διαιρείται με τον 4, επίσης όμως να μην διαιρείται με το 100 εκτός εάν διαιρείται με το 400.]


def isleap(year):
    longfeb = (year%4 == 0) and (year%100 != 0) or (year%400 == 0)
    return longfeb


momYear = 1968    # το κύριο πρόγραμμα
dadYear = 1967
kidYear = 2000
print(isleap(momYear),isleap(dadYear),isleap(kidYear))

Παράδειγμα.

Γράψτε μία συνάρτηση η οποία να υπολογίζει την τιμή του πολυωνύμου $f(x) = x^2 - 2x + 1$. Καλέστε την από το κύριο πρόγραμμα για μία τιμή του $x$ και τυπώστε τα $x, f(x)$.


def f(x):                # εδώ είναι η συνάρτηση f(x)
    fvalue = x**2 - 2*x + 1
    return fvalue

x = 3.0                      # εδώ είναι το κύριο πρόγραμμα
result = f(x)
print(x,result)

Παράδειγμα.

Γράψτε μία συνάρτηση η οποία να ελέγχει αν το όνομά μας τελειώνει σε "ακης" (akis). Σε αυτή την περίπτωση η τιμή της θα είναι True, αλλιώς η τιμή της συνάρτησης θα είναι False.


def nameEnd(s):
    if s[-4:] == 'akis':
        return True
    else:
        return False

name = input("Give a name: ")
print(nameEnd(name))

Εντολή return και απουσία της.

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

Παράδειγμα.

Ας ορίσουμε μία συνάρτηση η οποία τυπώνει το μήνυμα Hello! όποτε κληθεί:


def sayHello():
    print('Hello!')

Ας την καλέσουμε


sayHello()

θα πάρουμε το αποτέλεσμα


Hello!

Αν γράψουμε


result = sayHello()

τότε η μεταβλητή result παίρνει την τιμή None.

Επίσης, αν γράψουμε print(sayHello(),'Maria!') θα δούμε το μήνυμα None Maria! γιατί None είναι η τιμή η οποία επιστρέφει η συνάρτηση sayHello.

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

Παρατήρηση.

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

Γραφική επανάληψη

Function form

Σχήμα.

Η γενική μορφή μιας συνάρτησης και η κλήση της από το κύριο πρόγραμμα.

Ενσωματωμένες συναρτήσεις (built-in functions)

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

Παρατηρήστε ότι όλες οι παραπάνω παίρνουν ένα όρισμα και επιστρέφουν μία τιμή, όπως ακριβώς οι συναρτήσεις που ορίζονται με την εντολή def.

Επίσης, έχουμε δει ενσωματωμένες συναρτήσεις της python.

Παρατήρηση.

Η χρήση συναρτήσεων είναι ιδαίτερα διαδεδομένη σε μία γλώσσα προγραμματισμού (όπως η python). Αυτό ισχύει και για τις ενσωματωμένες συναρτήσεις και για αυτές τις οποίες γράφει ο προγραμματιστής. Και τα δύο είδη συναρτήσεων χρησιμοποιούνται με τον ίδιο τρόπο.

Παραδείγματα

Παράδειγμα.

(Αποστάσεις μεταξύ σημείων) Μας δίνεται ένα σύνολο από σημεία στο επίπεδο (x1,y1),(x2,y2),…,(xN,yN) και ένα ακόμη σημείο (x,y) και θέλουμε να βρούμε την απόσταση του σημείου (x,y) από το αρχικό σύνολο σημείων. Θα χρησιμοποιήσουμε τον τύπο για την απόσταση μεταξύ δύο σημείων (x,y) και (a,b) (Πυθαγόρειο θεώρημα): ((x−a)2+(y−b)2)1/2.

Θα βάλουμε τα σημεία μας σε μια λίστα L η οποία θα περιέχει λίστες μήκους 2 (μία λίστα για κάθε σημείο) και το μοναδικό μας σημείο θα αποθηκευθεί στις μεταβλητές x και y.


import math

L = [ [1, 2], [0.1, -2], [3, 4], [-10, -3] ] # Το σύνολο των σημείων
x = 0.1 # Το μοναδικό σημείο
y = 3.0

D = [] # Λίστα για τις αποστάσεις
for p in L:
    d = math.sqrt((x-p[0])**2 + (y-p[1])**2)
    D.append(d)

mindistance = min(D) # Βρίσκουμε το ελάχιστο στοιχείο της λίστας D
print("Η ελάχιστη απόσταση είναι {}".format(mindistance))

Τώρα κατασκευάζουμε μία συνάρτηση mindistance(q, L) η οποία χρησιμοποιεί τον προηγούμενο αλγόριθμο. Το q είναι μία λίστα με δύο στοιχεία η οποία περιέχει το σημείο την απόσταση του οποίου ψάχνουμε και L είναι η λίστα των σημείων. Η συνάρτηση επιστρέφει την ελάχιστη από τις αποστάσεις του q από τα σημεία της L.


import math

def mindistance(q, L):
    D = []
    for p in L:
        d = math.sqrt((q[0]-p[0])**2 + (q[1]-p[1])**2)
        D.append(d)
    
    return min(D)

# Καλούμε τη συνάρτηση με
# q = [0.1, 3] και L = [ [1, 2], [0.1, -2], [3, 4], [-10, -3] ]
md = mindistance([0.1, 3], [ [1, 2], [0.1, -2], [3, 4], [-10, -3] ])
print("Η ελάχιστη απόσταση είναι {}".format(md))

Παρατηρούμε ότι η συνάρτηση mindistance μπορεί να πάρει μία πιο κομψή και κατανοητή μορφή αν απλοποιήσουμε την γραμμή η οποία βρίσκει την απόσταση σημείων. Για τον σκοπό αυτό κατασκευάζουμε μία επιπλέον συνάρτηση dist η οποία δίνει την απόσταση μεταξύ δύο σημείων, τα οποία παριστάνονται ως δύο λίστες a,b με δύο στοιχεία.


import math

def dist(a,b):
    d = math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)
    return d

def mindistance(q, L):
    D = []
    for p in L:
        d = dist(p,q)
        D.append(d)
    
    return min(D)


md = mindistance([0.1, 3], [ [1, 2], [0.1, -2], [3, 4], [-10, -3] ])
print("Η ελάχιστη απόσταση είναι {}".format(md))

Παρατήρηση.

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

Παράδειγμα.

(Άθροιση αριθμών σε λίστα) Έχουμε δει πώς μπορούμε να αθροίσουμε τα στοιχεία μίας λίστας D η οποία έχει στοιχεία αριθμούς. Ας γράψουμε μία συνάρτηση η οποία κάνει την άθροιση.


def sumL(D):
    s = 0.0
    for e in D:
        s += e
    return s

Αν υποθέσουμε ότι έχουμε μία λίστα L η οποία περιέχει λίστες (π.χ., την L = [ [1, 2], [0.1, -2], [3, 4], [-10, -3] ]). Η sumL μπορεί επίσης να χρησιμοποιηθεί για να παράγουμε μια λίστα με τα επιμέρους αθροίσματα κάθε λίστας στην αρχική λίστα.


def listOfSums(L):
    sums = []
    for innerList in L:
        sums.append(sumL(innerList))
    return sums

Η συνάρτηση sumL μπορεί επίσης να χρησιμοποιηθεί για την άθροιση όλων των επιμέρους στοιχείων (αριθμών) μιας λίστας από λίστες.


def sumListOfLists(L):
    s = 0.0
    for innerList in L:
        s += sumL(innerList)
    return s

Μάλιστα, έχοντας τις συναρτήσεις sumL και listOfSums, θα μπορούσαμε να ξαναγράψουμε διαφορετικά, με πολύ συμπαγή τρόπο, την sumListOfLists ως εξής.


def sumListOfLists2(L):
    return sumL(listOfSums(L))

Μελέτη

Βιβλιογραφία

  1. Δημήτριος Καρολίδης, Μαθαίνετε εύκολα python (Εκδόσεις Καρολίδη, 2016).
  2. Κ. Μαγκούτης, Χ. Νικολάου, Εισαγωγή στον αντικειμενοστραφή προγραμματισμό με Python, (Αποθετήριο "Κάλλιπος", 2016) - Κεφάλαιο 4. Συναρτήσεις και εκτέλεση υπό συνθήκη.
  3. J.V. Guttag, Υπολογισμοί και προγραμματισμός με την python, Κεφάλαιο 4.
  4. Παραδείγματα με συναρτήσεις, Σημειώσεις Μ. Κολουντζάκη.