The Return of the Functions

1) Rappels sur les fonctions

  • Quand a t'on besoin d'une fonction ?
  • dB or not dB ?
  • Définir ou Utiliser ?

1.1) Quand à t'on besoin d'ecrire une fonction ?

Pas toujours, mais presque...

Appel d'une fonction du système

Cet exemple marche bien avec les systèmes baseés sur unix, qui ont une horloge


In [1]:
''' 
De nombreuses fonction existent déjà
Python permet aussi d'appeller des fonction nouvelles
D'abord nous allons voire les appels au sytème, 
puis des fonctions comme print que nous utilisions toujours 
print(VARIABLE)
''' 

A=!date
# ici A est à un type "IPython.utils.text.SList" c'est une liste
print(A)


['samedi 8 juillet 2017, 15:33:27 (UTC+0200)']

Utilisation des methodes associés aux listes (les methodes sont des fonctions)


In [2]:
# On peux ici se servir le la methode "list" qui va 
date=A.list[0]
# On peux ici se servir le la methode "split" qui va separer la chaine de charactères
#(jour,mois,date,heure,fuseau,annee)=date.split() # Dans certains sytèmes
(jour,date,mois,annee,heure,fuseau)=date.split() # Dans d'autres sytèmes
# Ici je travaille en python 3.5
print('En l\'an de grâces %s les étudiants de l\'ISEP on étudié les Fonctions, c\'était le %s du mois \'%s\'.' % (annee, date, mois))


En l'an de grâces 2017, les étudiants de l'ISEP on étudié les Fonctions, c'était le 8 du mois 'juillet'.

In [3]:
# Comme on voit c'est pas franchement lisible en Français, donc on va traduire...
# On peux utiliser les types que sont les tableaux associatifs appelés "dicts" 
#pour associer un mois a son abreviation 

mois_Month = {'janvier': 'de janvier', 
              'fevrier': 'de février', 
              'mars': 'de mars', 
              'avril': 'd\'avril', 
              'mai':'de mai',
              'juin':'de juin',
              'juillet':'de juillet',
              'août':'d\'août',
              'septembre':'de septembre',
              'octobre':'d\' octobre',
              'novembre':'de novembre',
              'décembre':'de décembre'}
print("En l\'an de grâces {0} les étudiants on étudié les Fonctions, c\'était le {1} du mois {2}." .format(annee, date, mois_Month[mois]))


En l'an de grâces 2017, les étudiants on étudié les Fonctions, c'était le 8 du mois de juillet.

1.2) Quand n'a t'on pas besoin d'ecrire une fonction ?

Pas besoin de définir de nouvelles fonctions si celles-ci existent déja.
Python dispose d'un grand nombre de librairies de fonctions
mais il se peux que l'on n'ai pas besoin de toutes les fonctions 
de cette librairie tout au long du programme....
Donc on a TOUJOURS besoin de connaître les fonctions

In [4]:
# Exemple d'appel d'une fonction dans une librairie 
from math import log10
# Ici je déclare les variables
signal_power = 50 #Watts
noise_power = 5 #Watts
# Là j'utilise une division entre les variables déclareés
ratio = signal_power / noise_power
# Nous allons utiliser une fonction logarithme
decibels = 10 * log10(ratio)
# voila la sortie
print(decibels)


10.0

In [5]:
# Cette operation peux être transformée en fonction
def dB(signal_power,noise_power):
    ratio = signal_power / noise_power
    decibels = 10 * log10(ratio)
    return decibels

In [6]:
#Warning: au moment de l'appeler if faut que le log10 soit défini
from math import log10
signal_power = 50
noise_power = 5
dB(signal_power,noise_power)


Out[6]:
10.0

1.1) Quand doit t'on impérativement utiliser une fonction ?

les fonctions recursives (qui s'appellent elles mêmes)

Voici les 3 lois de la recursivité:

  • Une fonction recursive contiens un cas de base
  • Une fonction recursive doit modifier son état pour se ramenner au cas de base
  • Une fonction recursive doit s'appeler soit même

Par exemple: $$ x_0 = 1 \, \mathrm{et} \, x^n=x.x^{n-1} \, \mathrm{si} \, n>1 $$


In [7]:
# On va déclarer une fonction qui renvoie la valeur de la puissance entière d'un nombre
# Cette solution utilise le fait que les nombres peuvent être pairs ou impairs
def expo(a, n):
    if n == 0:
        return 1
    else:
        if n%2 == 0:
            # on utilise la puissance de 2 directerment pour les nombres pairs 
            return expo(a, n//2)**2
            # on utilise pour les impairs, la même methode mais appliquée 
        else:
            return a*(expo(a, (n-1)//2)**2)

# Par exemple...


print("Cette fonction peut s'avèrer utile pour ecrire une suite de nombres bien connue :")
print(expo(2,0),expo(2,1),expo(2,2),expo(2,3),expo(2,4))
print('...')
print(expo(2,11),'\n')


Cette fonction peut s'avèrer utile pour ecrire une suite de nombres bien connue :
1 2 4 8 16
...
2048 


In [8]:
# On peux invoquer une puissance directement grace à son return 
print('Entrez le Nombre a que l\'on veux élever à la puissance n')
a=eval(input('a = '))
n=eval(input('n = '))
print("La puissance au {} de {} est egale à {} ".format(n,a,expo(a,n)))


Entrez le Nombre a que l'on veux élever à la puissance n
a = 2
n = 5
La puissance au 5 de 2 est egale à 32 

In [9]:
# OK... pour les fortiches en math il existe déjà une fonction puissance
x=pow(4,3)
print(x)


64

Il existe des fonction primitives propres a python 3

En anglais Build-In Functions

   ...

On ne doit jamais redéfinir une fonction qui est déja dans le sytème d'ou l'intérêt de savoir ce que contiens une fonction

   ...

Ce qui suit est un exemple de fonction "dangeureuse"


In [10]:
def jetter_les_des_jusquau_double_six():
    """
    Cette fonction importe toutes les fonction de la librairie "random"
    Elle continue de tourner jusqu'au moment ou un double 6 est tiré
    Bonne chance !
    """
    import random
    throw_1 = random.randint(1, 6)
    throw_2 = random.randint(1, 6)
    while not (throw_1 == 6 and throw_2 == 6):
        total = throw_1 + throw_2
        print(total)
        throw_1 = random.randint(1, 6)
        throw_2 = random.randint(1, 6)
    print('12 !!! Double Six thrown!')

In [11]:
jetter_les_des_jusquau_double_six()


8
7
8
5
4
6
8
4
3
2
7
4
5
...
11
2
2
6
5
7
12 !!! Double Six thrown!

2) Reprise des exemples de l'introduction en fonctions

  • Palindrome
  • La racine carrée
  • Anneés Bissextiles

Nous alons reprendre les exemples du premier cours mais cette fois nous transformerons tout en fonctions. L'objectif est de montrer la rapidité d'execution, et la modularité que la programmation à l'aide des fonctions est seulle à permettre.

2.1) Le Palindrome


In [12]:
"""
Programme : estPalindrome(unMot)                  
Objectif : test de Palindrome         

Entrée : unMot, STR contenant une chaine de charactères

Sortie : True or False (Booléen) 

@auteur : VF                  
"""

def estPalindrome(unMot):
    # Declaration des Variables locales
    estPal = True 
    l = len(unMot)
    d = 0
    # On compare les lettres symétriques par rapport au milieu du mot de longueur l
    # qui ont pour indices [d] et [l-1-d], le parcours s'effectue tant que les lettres
    # comparées sont égales et que le milieu n'est pas atteint 
    while estPal and d < l/2:
        if unMot[d] == unMot[l-1-d]: d += 1
        else: estPal = False
    return estPal
####################################################
# Test de la fonction
mot = input("Donner un mot : ") 
# Boucle conditionnelle
if estPalindrome(mot):
    print(mot, "est un palindrome")
else: 
    print(mot, "n'est pas un palindrome")


Donner un mot : ER5R5
ER5R5 n'est pas un palindrome

2.2) Le test d'Héron d'Alexandrie


In [13]:
def RacineCarree(unNombre_Carre,unNombre_Estimateur):
    # Declaration des Variables locales
    EPS = 0.0000000000001 # précision
    val = unNombre_Carre
    racCarreeVal = unNombre_Estimateur
    
    while racCarreeVal * racCarreeVal - val < -EPS or \
          racCarreeVal * racCarreeVal - val > EPS:
        # la valeur absolue de la différence est supérieure à un seuil 
          racCarreeVal = (racCarreeVal + val / racCarreeVal) / 2
    return racCarreeVal
####################################################
# Test de la fonction
unNombre_Carre = 42
unNombre_Carre=float(unNombre_Carre)
unNombre_Estimateur = input("Première estimation de la racine de {} : ".format(unNombre_Carre))
unNombre_Estimateur=float(unNombre_Estimateur)
print(RacineCarree(unNombre_Carre,unNombre_Estimateur))


Première estimation de la racine de 42.0 : 7
6.48074069840786

In [14]:
42**(1/2)


Out[14]:
6.48074069840786

In [15]:
from math import sqrt
sqrt(42)


Out[15]:
6.48074069840786

2.3) Les annees bisextiles


In [16]:
def Annees_Bissextiles(annee_debut,annee_fin):
    bissextile=[]
    for b in range(annee_debut,annee_fin+1): 
                     if ((b % 4 == 0) and (b % 100 != 0)) or (b % 400 == 0):
                         bissextile.append(b)
    return bissextile
####################################################
annees_a_28_fevrier=Annees_Bissextiles(1992,2021)
print(annees_a_28_fevrier)


[1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020]