LyonHPC LyonHPC

5. Fonctions et procédures

cloud
%matplotlib inline
import numpy as np
from IPython.display import HTML,display,IFrame,Video
from IPython.display import YouTubeVideo,Markdown
display(Markdown("**Video du cours: Introduction**"))
YouTubeVideo('Q_yFr7sdyc0')

Video du cours: Introduction

Astuce

pour tester les programmes Python, vous pouvez vous connectez sur un serveur Jupyter, par exemple, pour les étudiants Lyon1 https://jupyter.mecanique.univ-lyon1.fr

5.1. Procédure et fonction

5.1.1. Procédure

procédure: algorithme avec des paramètres d’entrée (données) et des paramètres de sortie (résultat)

Algorithme MaFonction(liste de paramètres)
    variables locales
    instructions
    retour (liste de valeurs)

# utilisation
val = MaFonction(param1,param2,..)
display(Markdown("**Video du cours: procédure et fonction**"))
YouTubeVideo('CAsiebHnHAs')

Video du cours: procédure et fonction

5.1.2. Fonction en Python

implémentation d’une procédure = function (C, Python) , subroutine (Fortran)

# définition
def MaFonction(liste arguments):
    instructions
    ....
    return (liste de valeurs)
# utilisation
(val1, val2, ..) = MaFonction(arg1, arg2, ...) 

5.1.3. Passage des arguments

on affecte aux arguments de la fonction la valeur des paramètres d’appel:

def MaFonction(a1, a2, a3):
    ....
    return (v1, v2)
    
(V1, V2) = MaFonction(A1, A2, A3)
  • lors de l’appel, on a a1=A1 a2=A2 a3=A3

  • valeur de retour = liste

    • lors du retour, V1=v1, V2=v2

Exemple Python

utilisation du site : http://pythontutor.com

vous pouvez copier l’exemple de code python sur le site pour l’exécuter

    # definition
    def MaFonc(a1,a2,a3):
        v1 = a1 + a3
        v2 = a2 + a3
        return v1,v2
    # utilisation
    A1 = 1.0
    V1,V2 = mafonc(A1,a.2,4*A1)
display(Markdown("**Visualisation de l'execution sur le site pythontutor**"))
Video("VIDEO_COURS/pythonlive_fonc1.mp4", embed=True,width=700, height=300)

Visualisation de l'execution sur le site pythontutor

5.1.4. Passage des arguments

  • pour les variables scalaires: valeur = valeur de la variable

    • la variable n’est donc pas modifiée

  • pour les listes et tableaux: valeur = adresse des données

    • on peut donc modifier la valeur d’une liste ou tableau en argument

    • mais à condition de ne pas faire de réaffectation

Exemple Initialisation de liste (tableau) : version 1

# definition
def InitTab(X):
    X[:] = [0,0,0]
    n = len(X)
    for i in range(n):
        X[i] = i*i
    return
# utilisation
Z = [1,1,1]
InitTab(Z)
display(Markdown("**Video du cours: arguments d'une fonction**"))
YouTubeVideo('I0uizg3B6LU')

Video du cours: arguments d'une fonction

display(Markdown("**Visualisation de l'execution sur le site pythontutor**"))
Video("VIDEO_COURS/pythonlive_fonc2.mp4", embed=True,width=700, height=300)

Visualisation de l'execution sur le site pythontutor

Initialisation de liste (tableau): version 2

# definition
def InitTab(X):
    X = [0,0,0]
    n = len(X)
    for i in range(n):
        X[i] = i*i
    return
# utilisation
Z = [1,1,1]
InitTab(Z)
display(Markdown("**Visualisation de l'execution sur le site pythontutor**"))
Video("VIDEO_COURS/pythonlive_fonc3.mp4", embed=True,width=700, height=300)

Visualisation de l'execution sur le site pythontutor

Questions ?

  • comparer la valeur de Z après l’appel de la fonction InitTab !

  • à quoi correspond la variable X dans la fonction InitTab

5.2. Exemples de procédures et de fonctions

display(Markdown("**Video du cours: exemple de procédure et fonction**"))
YouTubeVideo('1RWcWyOF2g8')

Video du cours: exemple de procédure et fonction

Attention

Les vidéos utilisent un ancien interpréteur python 2.7, pour lequel print est un mot clé, soit print 'bonjour'. Avec Python 3, print est une fonction et il faut donc utiliser des parenthèses, soit print('bonjour')

5.2.1. Algorithme d’Euclide: calcul du PGCD de 2 entiers

# Calcul du PGCD
# paramètres d'entrée: 2 entiers positifs a et b
# en sortie: PGCD de a et b
#
Algorithme PGCD(a,b)
    tant que a # b 
        si a>b alors a = a-b 
        sinon b = b - a 
    retour a
#

5.2.1.1. Programme Python

def PGCD(a, b):
    """ 
    Calcul du PGCD de a et b (entiers positifs) 
    """
    while a != b:
        if a > b: 
            a = a - b
        else:   
            b = b - a
    return a
# utilisation
a0, b0 = 15623532, 252568
p = PGCD(a0, b0)
print("PGCD de ", a0, b0, "=", p)
PGCD de  15623532 252568 = 4

5.2.2. Algorithme: calcul de la somme d’une série

\[ S_n = \sum_{i=1}^n \frac{1}{i^2} \mbox{ et } \lim_{n\rightarrow\infty} S_n = \frac{\pi^2}{6}\]
# calcul de la somme Sn et de l'Écart par rapport à la limite
# entrée: n entier   sortie: somme, écart par rapport à limite
Algorithme Somme(n)
    S=0.
    pour i de 1 a n
        S = S + 1./i**2
    err = S - (pi**2/6.)
    retour S,err

5.2.2.1. Programme Python

# fonction Python
def Somme(n):
    """ 
    Calcul de la somme de la série 1/i**2  pour i de 0 a n 
    en sortie: somme et écart par rapport à la limite
    """
    S=0.
    for i in range(1, n + 1):
        S = S + 1. / (i*i)
    ecart = S - (np.pi**2/6.)
    return S, ecart
#
n = 100
S, err = Somme(n)
print("somme=",S," erreur=",err)
print(Somme(1000))
print(Somme(10000))
somme= 1.6349839001848923  erreur= -0.009950166663334148
(1.6439345666815615, -0.0009995001666649461)
(1.6448340718480652, -9.999500016122376e-05)

5.3. Paramètres optionnels d’une fonction

  • En Python possibilité de définir des paramètres optionnels avec une valeur par défaut

  • Nommage des paramètres (ordre indifférent)

  • Très utilisés dans les fonctions des bibliothèques

      # Déclaration
      def MaFonction(par, par1=valdef1, par2=valdef2)
    
      # Appel
      MaFonction(val)
      MaFonction(val, par1=val1)
      MaFonction(val, par2=val2, par1=val1)
    
display(Markdown("**Video du cours: paramètres optionnels**"))
YouTubeVideo('fUDdLOxc2c0')

Video du cours: paramètres optionnels

Attention

Les vidéos utilisent un ancien interpréteur python 2.7, pour lequel print est un mot clé, soit print 'bonjour'. Avec Python 3, print est une fonction et il faut donc utiliser des parenthèses, soit print('bonjour')

5.3.1. Exemple: algorithme de Héron (calcul de \(\sqrt{x}\))

Pour calculer une approximation \(u\) de \(\sqrt{a}\), on note que si \(u\approx\sqrt(a)\) alors \(a/u\approx\sqrt(a)\) et donc \(\frac{u + a/u}{2}\) est sans doute une meilleur approximation de \(\sqrt{a}\).
On peut vérifier que cette méthode babylonienne est en fait un cas particulier de la méthode de Newton pour calculer la racine de \(f(x)=u^2-a\)

5.3.1.1. Algorithme

  Algorithme Heron(a)
      u = a/2
      eps = 1.e-6
      tant que |u**2 - a| > eps
          u = (u + a/u)/2
      fin tantque
      retour u

5.3.1.2. Programme Python

import numpy as np
def Heron(a, eps=1e-03, itmax=100):
    """ 
    calcul une approximation de sqrt(a) avec une precision eps
    et une nombre maxi d'iterations itmax """
    u = a/2.
    it = 0
    while abs(u**2 - a) > eps:
        u  = (u + a/u) / 2.
        it = it + 1
        if it > itmax:
            print("Attention nbre maxi d'iterations atteint", it)
            break
    return u, it
# utilisation
b = 200.
print("sqrt(200) ~",Heron(b))
print("a 10^-8  pres sqrt(200) ~",Heron(b, 1.e-08))
print("a 10^-13 pres sqrt(200) ~",Heron(b, eps=1.e-13))
print("a 10^-14 pres sqrt(200) ~",Heron(b, eps=1.e-14))
print("a 10^-14 pres sqrt(200) ~",Heron(b, itmax=200, eps=1.e-14))
print("valeur avec numpy ",np.sqrt(b))
sqrt(200) ~ (14.142135968022693, 6)
a 10^-8  pres sqrt(200) ~ (14.142135623730955, 7)
a 10^-13 pres sqrt(200) ~ (14.142135623730951, 8)
Attention nbre maxi d'iterations atteint 101
a 10^-14 pres sqrt(200) ~ (14.142135623730951, 101)
Attention nbre maxi d'iterations atteint 201
a 10^-14 pres sqrt(200) ~ (14.142135623730951, 201)
valeur avec numpy  14.142135623730951

5.4. Fonction Lambda

  • permet de définir des mini-fonctions (à la Lisp)

  • utile pour des fonctions simples (mais pas obligatoire!!)

  • définition fonction F(args) où args est la liste des arguments

      F = lambda args : expression(args)
    
import numpy as np
F = lambda x: np.cos(x**2)
print(F(1))
G = lambda x, y: F(x) + y**2
print(G(1, 1))
0.5403023058681398
1.5403023058681398

5.5. Méthodes, classes et fonctions de bibliothèque

5.5.1. Définition

classe = type de structure de données définissant des données + fonctions pour manipuler ces données

méthode = fonction associée à une classe pour manipuler les données de la classe

objet = instance de classe = variable [données + méthodes]

sous Python toute variable (list, string, real, int) est un objet et possède des méthodes (p.e pour l’afficher)

display(Markdown("**Video du cours: notion de classes et méthodes**"))
YouTubeVideo('N6TLygH5p4c')

Video du cours: notion de classes et méthodes

Attention

Les vidéos utilisent un ancien interpréteur python 2.7, pour lequel print est un mot clé, soit print 'bonjour'. Avec Python 3, print est une fonction et il faut donc utiliser des parenthèses, soit print('bonjour')

5.5.2. Syntaxe d’utilisation d’une méthode sous Python

pour un objet A avec un methode func1

A.func1(arg1,arg2,...)

équivalent à

func1(A,arg1,arg2,..)

5.5.3. Exemple en Python

S="mon nom"
print(S.upper())
L=[1,2,3]
L.reverse()
print(L)
X=3.14157
print(X.as_integer_ratio())
MON NOM
[3, 2, 1]
(7074186740679165, 2251799813685248)

5.5.4. Aide sous Ipython

Sous Ipython, pour avoir la liste des méthodes associées à un objet A

A. <tab>   # liste des methodes
A.meth?    # aide sur la methode meth

exemple

np.abs?

renvoie

Call signature:  np.abs(*args, **kwargs)
Type:            ufunc
String form:     <ufunc 'absolute'>
File:            /usr/local/lib/python3.8/dist-packages/numpy/__init__.py
Docstring:      
absolute(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])

Calculate the absolute value element-wise.

``np.abs`` is a shorthand for this function.

Parameters
----------
x : array_like
    Input array.
out : ndarray, None, or tuple of ndarray and None, optional
    A location into which the result is stored. If provided, it must have
    a shape that the inputs broadcast to. If not provided or None,
    a freshly-allocated array is returned. A tuple (possible only as a
    keyword argument) must have length equal to the number of outputs.
where : array_like, optional
    This condition is broadcast over the input. At locations where the
    condition is True, the `out` array will be set to the ufunc result.
    Elsewhere, the `out` array will retain its original value.
    Note that if an uninitialized `out` array is created via the default
    ``out=None``, locations within it where the condition is False will
    remain uninitialized.
**kwargs
    For other keyword-only arguments, see the
    :ref:`ufunc docs <ufuncs.kwargs>`.

Returns
-------
absolute : ndarray
    An ndarray containing the absolute value of
    each element in `x`.  For complex input, ``a + ib``, the
    absolute value is :math:`\sqrt{ a^2 + b^2 }`.
    This is a scalar if `x` is a scalar.

5.5.5. Fonctions d’une bibliothéque

espace de nom = nom de la bibliothéque bibli

import bibli

nom de la fonction func dans la bibliothéque

bibli.func
bibli.sous_bibli.func

simplification du nommage

import bibli as bib
import bibli.sous_bibli as sbib

importation d’une fonction

from bibli import func
import numpy as np
print(np.sqrt(3))
from numpy import tanh
print(tanh(1))
1.7320508075688772
0.7615941559557649

5.6. Bibliographie

  1. Les classes sous Python

    chapitre du livre « Apprendre à programmer avec Python »

5.7. Fin de la leçon

cloud