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

\begin{document} %Cours

\setcounter{chapter}{10}
% 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. 

\subsection{Fonction personnelle (rappel)}

Voir Python 1.4.7 au besoin.

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

\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
    
n = double(12)       # Appel
\end{minted}

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

\remarque{B - Lancer un appel de fonction}

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

\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 réponse à l'endroit d'où l'appel a été lancé.
\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} : variable locale servant à récupérer l'une des entrées. Son nom figure dans la déclaration de la fonction. On parle également de paramètre formel.

\paragraph{Argument} : l'une des entrées qu'on envoie lors d'un appel. On parle également de paramètre effectif. 

\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}


(p)aramètre <-> (d)éclaration.

(A)rgument <-> (A)ppel.



\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;
\item le type et le contenu de la réponse.
\end{itemize}


\subsection{DOCUMENTATION rapide}

\paragraph{Signature d'une fonction}

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

\paragraph{Prototype d'une fonction}

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

\paragraph{Spécification}

Spécifier une fonction consiste à donner :

\begin{itemize}
\item Le PROTOTYPE qui fixe les TYPES;
\item Une DOCSTRING (Documation string) qui complète les informations
\end{itemize}

La spécification fournit donc toutes les informations nécessaires à sa bonne utilisation.

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

\end{multicols}

\subsection{DOCUMENTATION longue}

On utilise 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...}

On peut mal utiliser les fonctions qui renvoient None. Le cas typique est 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
# Pas de réponse car t contient None
\end{minted}


Attention : si on utilise \fo{append()}, il ne s'agit plus d'un tableau statique mais d'un \gras{tableau dynamique}. Nous les utiliserons plus tard dans l'année.


\subsubsection{C - None et les booléens}

Lorsqu'on veut évaluer un contenu sous forme de booléen, \fo{None} est considéré comme le cas nul ou vide.

\begin{minted}{python}
>>> bool(None)
False
\end{minted}


Mais attention : \fo{None} n'est identique à \fo{False}.

\begin{minted}{python}
>>> a = None
>>> a == False
False
 
>>> bool(a) == False
True
\end{minted}

\end{multicols}



\section{Compléments sur les paramètres - hors programme}

Aucune connaissance à avoir à part connaître leurs existences. Aller voir sur le site pour les infos. Rien dans le DS.
\begin{multicols}{2}

\subsection{Paramètres par défaut}

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

Si on lance un appel \fo{aleatoire(12)}, le paramètre \fo{fin} référencera ce 12 mais \fo{debut} ne récupère rien. Par défaut, il référencera donc 1.

Par contre, sur un appel \fo{aleatoire(12, 3)}, on aura le fonctionnement normal : \fo{fin} référence 12 et \fo{debut} référence 3.

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

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

On peut lancer un appel en fournissant l'ordre qu'on veut pourvu qu'on nomme les paramètres : l'appel \fo{aleatoire(debut=3, fin=12)} est compris par Python qui placera les bonnes arguments dans les bons paramètres.

On peut empêcher l'utilisateur d'utiliser les paramètres nommées sur certains paramètres en plaçant ces paramètres devant un slash :

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

Ici, on empêche alors fin d'être utilisé de façon nommé : il faut nécessairement qu'il soit le premier lors de l'appel.


\subsection{Documentation des types construits}

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

Première exemple : on signale qu'on veut un tableau d'entier.

Deuxième exemple : on signale qu'on veut un dictionnaire dont les clés sont des strings et les valeurs associées sont des entiers.

\end{multicols}



\input{licence}

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

{}
\makeatother

