\makeatletter
\@ifundefined{complet}
{\documentclass[10pt]{report}
\title{Python}
\newcommand{\categorie}{Python}
\input{latex_entete_perso}

\begin{document} %Cours

\setcounter{chapter}{7}
% xelatex -shell-escape cours_python
}
{}
\makeatother



\chapter{Fonctions et variables}

\section{Fonctions, paramètres, arguments}

\begin{multicols}{2}

\subsection{Fonction : notion (rappel)}

%\begin{equation}
ENTREE(S) $\Rightarrow$ Fonction $\Rightarrow$ SORTIE
%\end{equation}

\subsection{Fonction native (rappel)}

C'est une fonction présente de base dans Python. 

\begin{minted}{python}
>>> max(10, 0, 50, 40)
50
\end{minted}


\subsection{Fonction personnelle (rappel)}

Voir Python 1.4.7 au besoin.

\remarque{A - Déclarer une fonction} : stocker des instructions.

On écrit dans l'ordre

\begin{itemize}
\item le mot-clé \fo{def}.
\item le nom de la fonction
\item les variables d'entrée (parenthèses et virgules)
\item le caractère \fo{:}
\item les instructions du bloc \gras{tabulé}
\end{itemize}

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def double(x):
    return 2 * x
\end{minted}

Le mot-clé \fo{return} indique ce que la fonction va renvoyer.

\remarque{B - Lancer un appel de fonction} : fournir les entrées et attendre la réponse.

Sur l'exemple, l'appel se fait LIGNE 4.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def double(x):      # Déclaration
    return 2 * x    # Déclaration

n = double(12)      # Appel
\end{minted}

\gras{Déroulé}

\small{L1(déclaration) L4(appel)-L1-L2-L4(reponse)}

\begin{itemize}
\item L1 : déclaration d'une fonction \ff{double()} qui va recevoir une donnée qu'on placera dans une variable \fo{x}.
\item L4 (partie droite): appel à \ff{double()} en lui envoyant 12.
\item L1 : On place 12 dans \fo{x}.
\item L2 : la fonction répond 24
\item L4 (partie gauche): on stocke 24 dans \fo{n}.
\end{itemize}


\subsection{Fonction plus complexe (rappel)}

Une fonction peut contenir des boucles, des instructions conditionnelles, ect...



\subsection{Une déclaration pas à pas}

\small{
\begin{minted}{python}
def                  # mot-clé def
def nouvelle         # nom de la fonction
def nouvelle()       # rajout parenthèses
def nouvelle(note)   # rajout des paramètres
def nouvelle(note):  # n'oubliez pas ce :
    les instructions # les instructions tabulées
    return truc      # on renvoie la réponse
\end{minted}
}

\subsection{return : on peut utiliser directement une expression}

Lorsque l'interpréteur rencontre le mot-clé return, il réalise deux choses :

\begin{itemize}
\item Il évalue l'expression située derrière lui.
\item Il renvoie la valeur trouvée à l'entité qui a lancé l'appel initialement.
\end{itemize}


Deux choix de conception : répondre indirectement ou directement.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def fois2_via_variable(x):
    resultat = x * 2
    return resultat

def fois2_via_expression(x):
    return x * 2
\end{minted}


\subsection{Paramètre et argument}

\paragraph{Paramètre} : nom qu'on donne à une variable locale servant à récupérer l'une des entrées. Son nom figure donc dans la déclaration de la fonction. On parle également de paramètre formel. (p)aramètre <-> (d)éclaration.

\paragraph{Argument} : nom qu'on donne à l'une des entrées qu'on envoie lors d'un appel de fonction. On parle également de paramètre effectif. (A)rgument <-> (A)ppel.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
# d et u sont les paramètres déclarés
def valeur(d, u):  
    resultat = d*10 + u
    return resultat

# 5 et 3 sont les arguments de l'appel	 
valeur(5, 3)  
\end{minted}

\end{multicols}






\section{Documentation : expliquer comment utiliser}

\begin{multicols}{2}



\subsection{COMMENTAIRES(rappel)}

Les commentaires sont \gras{destinés à un lecteur humain} et ils visent à \gras{rendre le code interne facile à comprendre}.

\small{Voir Python Programme : 7.1.2}




\subsection{DOCUMENTATION}

La documentation doit expliquer \gras{comment utiliser la fonction sans provoquer d'erreur}.

En Python, pour trouver la documentation, il suffit d'utiliser une fonction native : la fonction \fo{help()}.

\small{
\begin{minted}{python}
>>> help(len)
  Help on built-in function len in module builtins:
 
len(obj, /)
    Return the number of items in a container.
\end{minted}
}

La documentation contient des informations sur

\begin{itemize}
\item Le but de cette fonction
\item le type et le nombre d'arguments à lui envoyer (les ENTREES) et
\item le type et le contenu de la réponse (la SORTIE).
\end{itemize}


\subsection{DOCUMENTATION rapide}

On donne juste le prototype et une phrase.

\paragraph{Signature d'une fonction}

\small{
\begin{minted}{python}
addition(int, int) -> int
\end{minted}
}

\paragraph{Prototype d'une fonction}

Prototyper une fonction consiste à rajouter les noms des paramètres à la signature.

\small{
\begin{minted}{python}
addition(nombre1:int, nombre2:int) -> int
\end{minted}
}

\paragraph{Spécification}

Spécifier une fonction consiste à donner :

\begin{itemize}
\item Le PROTOTYPE qui fixe la SYNTAXE et le TYPAGE
\item Une description nommée DOCSTRING qui fixe clairement la SEMANTIQUE
\end{itemize}

Si on fournit la spécification d'une fonction, on fournt donc toutes les informations nécessaires à sa bonne utilisation.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def addition(nbr1:int, nbr2:int) -> int:
    """Renvoie la somme de nbr1 et nbr2"""
    return nbr1 + nbr2 
\end{minted}


\end{multicols}

\subsection{DOCUMENTATION longue}

On fait la "même" chose mais en utilisant un string multi-ligne plutôt que de noter les informations de type directement dans le prototype.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def vitesse(distance, duree):
    """Renvoie la vitesse connaissant la distance parcourue et la durée
 
    :: param distance(int) :: la distance en m
    :: param duree(int)    :: la durée NON NULLE en s
    :: return (float)      :: la vitesse en m.s-1
 
    """
    return distance / duree
\end{minted}




\section{Return, ou pas Return, sortez !}

\begin{multicols}{2}


\subsection{Sortie immédiate avec return}

Dès que la fonction rencontre un \fo{return} :

\begin{itemize}
\item elle évalue l'expression fournie puis
\item elle renvoie sa réponse, puis
\item son espace local des noms est détruit définitivement.
\end{itemize}




\subsection{\fo{return None}}

\subsubsection{A - Le cas du return absent}

Une fonction Python renvoie au moins la valeur \fo{None} lorsqu'elle se termine sans avoir rencontré return. On parle parfois de \gras{procédure} pour désigner une fonction qui ne répond rien. Les procédures n'existent donc pas vraiment en Python.

La ligne 4 ci-dessous est donc totalement facultative :

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def division(x:int, y:int) -> None:
    mon_petit_calcul = x // y
    return None
\end{minted}


\subsubsection{B - Attention au stockage de la réponse...}

Il arrive souvent qu'on utilise mal de telles fonctions qui renvoient None si on a lu trop vite la documentation.

Le cas typique vient de la méthode \fo{append()} qui permet de rajouter une case à la fin d'un tableau Python : elle modifie le tableau et renvoie \fo{None}.

\begin{minted}{python}
# Exemple de bonne utilisation

>>> t = [10, 20, 30]  
>>> t.append(100)
>>> t
[10, 20, 30, 100]
 
# Exemple de mauvaise utilisation

>>> t = [10, 20, 30]
>>> t = t.append(100)  # TRES MAL
>>> t
\end{minted}

Sur le deuxième exemple, \fo{t} contient maintenant None.


\end{multicols}



\section{Compléments hors programme}

Pour l'instant, on vous demande simplement de vous souvenir à quoi correspondent ces notions. Aller voir sur le site si vous n'en avez aucun souvenir. Lors des évaluations, vous n'aurez jamais à taper ce type de code mais simplement à le comprendre.

\begin{multicols}{2}

\subsection{Paramètres par défaut}

\begin{minted}{python}
    def aleatoire(fin, debut=1):
\end{minted}

\subsection{Paramètres nommés ou positionnels}

\begin{minted}{python}
    def aleatoire(fin, debut=1):
\end{minted}

\subsection{Documentation des types structurés}

\begin{minted}{python}
    def f(x:list[int]):
    def f(x:dict[(str, int)]):
\end{minted}

\end{multicols}



\section{Fonction et conteneur MUABLE}

\begin{multicols}{2}

\paragraph{Une fonction peut ACCEDER à une variable globale}

\ 

Exemple : la fonction va lire l'adresse de \fo{d} et, une fois sur place, on lit la valeur de la clé.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def actualiser_vue():
    ...
    afficher_vaisseau(d['x'], d['y'])
\end{minted}


\paragraph{Une fonction ne peut PAS MODIFIER UNE VARIABLE GLOBALE}

\ 

Le \fo{x} global ne pourra pas modifier de cette façon :
\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
x = 10

def mise_a_zero():
    x = 0   # Juste un x local
\end{minted}

\paragraph{Une fonction peut MODIFIER LE CONTENU d'un CONTENEUR MUABLE GLOBAL}

\

Si la variable globale fait référence à un type structuré, la fonction peut donc accéder à la localisation de la structure. Une fois sur place, elle pourra donc MODIFIER LE CONTENU de la structure.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
def doubler():
    ...
    d['x'] = d['x'] * 2  # OK
\end{minted}

\

\

\

\end{multicols}



\input{licence}

\makeatletter
\@ifundefined{complet}
{\end{document}}

{}
\makeatother

