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

\begin{document} %Cours

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

\IfFileExists{type_simple.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/tableau/type_simple.png}}

\IfFileExists{type_construit.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/tableau/type_construit.png}}

\IfFileExists{armoire_de_boites.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/variables/armoire_de_boites.png}}

\IfFileExists{liaison_mot_contenus.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/variables/liaison_mot_contenus.png}}

\IfFileExists{mm_principe.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/dictionnaire/mm_principe.png}}

\IfFileExists{string_principe.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/string/string_principe.png}}

\IfFileExists{tableau_principe.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/tableau/tableau_principe.png}}

\IfFileExists{tuple_principe.png}{}{\write18{wget https://doc.infoforall.fr/activite/python/images/tuple/tuple_principe.png}}

\chapter{Types construits}

\section{Principe général}



\begin{multicols}{2}

\subsection{Type Simple, principe}

Le type simple fait référence à un contenu unique.

On peut voir une variable de ce type comme une \gras{liaison} entre un \gras{NOM} et un \gras{CONTENU} en mémoire.

\begin{figure}[H]
\centering
\includegraphics[width=4cm]{type_simple.png}
\caption{Principe du type simple}
\label{Principe-type-simple}
\end{figure}

\subsection{Type Construit, principe}

Le type construit fait plutôt référence à une armoire qui contient plusieurs boites. Ici, un tableau \fo{\gras{t1}} qui fait réference à 10, 100 et 1000.

\begin{figure}[H]
\centering
\includegraphics[width=2cm]{armoire_de_boites.png}
\caption{Armoire}
\label{armoire}
\end{figure}

Il est néanmoins préférable d'y voir un NOM qui permet d'atteindre un ensemble de CONTENUS, et plus un contenu unique.

\begin{figure}[H]
\centering
\includegraphics[width=7cm]{liaison_mot_contenus.png}
\caption{Principe de la liaison}
\label{Principe-de-la-liaison}
\end{figure}

On obtient alors ce schéma de principe~:

\begin{figure}[H]
\centering
\includegraphics[width=7cm]{type_construit.png}
\caption{Principe du type construit}
\label{Principe-type-construit}
\end{figure}

\end{multicols}













\section{Strings}

\begin{multicols}{2}

\subsection{Définition :\small{ voir Type simple 4.2.1}}

\subsection{Déclaration :\small{ voir Type simple 4.2.2}}

\subsection{Opérateurs :\small{ voir Type simple 4.2.3}}

\subsection{Longueur :\small{ voir Type simple 4.2.4}}



\paragraph{Voyons maintenant les nouveautés.}

\subsection{Accéder à une case [i]}

\subsubsection{Accés}

On peut accéder \gras{à l'élément stocké dans une case dont on connait l'indice} en tapant le nom de la variable-string suivie de \remarque{crochets} et de l'indice.

\small{
\begin{minted}{python}
Indice     0123456 
>>> mot = "Bonjour"
\end{minted}
}

\begin{multicols}{3}
\small{
\begin{minted}{python}
>>> mot[0]
'B'
 
>>> mot[1]
'o'
 
>>> mot[2]
'n'
\end{minted}
}
\end{multicols}

\small{
\begin{minted}{python}
>>> mot[7]
IndexError: list index out of range
\end{minted}
}

\subsubsection{Trois choses à distinguer}

\begin{itemize}
\item Le conteneur $\Rightarrow$ \fo{\gras{s}} (le string)
\item Les indices $\Rightarrow$ \fo{\gras{i}}
\item Les contenus $\Rightarrow$ \fo{\gras{s[i]}}
\end{itemize}

\subsection{Immuable en Python}

En Python, les strings sont \gras{immuables} (ou \gras{non mutables} en franglais) : on ne peut \gras{\remarque{pas} modifier le \remarque{contenu} d'une case après la création} du string.

\small{
\begin{minted}{python}
>>> a = "bonjour"
>>> a[0] = "d"
TypeError: 'str' does not support item assignment
\end{minted}
}

\subsection{Parcours par indices}

On utilise une boucle \gras{\fo{for i in range(len(s))}}.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
s = "bonjour"

for i in range(len(s)):
    print(s[i]) 
\end{minted}

\small{
L4 : Pour chaque indice possible de s

L5 : Affiche le contenu de la case i
}

Ce programme est équivalent à :

\small{
\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
s = "bonjour"
 
print(s[0])
print(s[1])
print(s[2])
print(s[3])
print(s[4])
print(s[5])
print(s[6]) 
\end{minted}
}

Ils affichent l'un et l'autre ceci dans la console :


\begin{multicols}{3}
\small{
\begin{minted}{python}
b
o
n
j
o
u
r
\end{minted}
}
\end{multicols}

\subsection{mot-clés in et not in}

\subsubsection{Test d'appartenance ou de présence}

L'opérateur binaire \gras{\fo{in}} qui renvoie un booléen. Pour savoir si le string \gras{\fo{contenu}} est présent dans le string \gras{\fo{s}}, on tape \gras{\fo{contenu in s}}.

\begin{multicols}{2}
\small{
\begin{minted}{python}
>>> "bon" in "bonjour"
True
 
>>> "Bon" in "bonjour"
False
\end{minted}
}
\end{multicols}

\subsubsection{Test de non-appartenance ou d'absence}

L'opérateur binaire \gras{\fo{not in}} qui renvoie un booléen. Pour savoir si le string \gras{\fo{contenu}} n'est pas présent dans le string \gras{\fo{s}}, on tape \gras{\fo{contenu not in s}}.

\small{
\begin{minted}{python}
>>> "bon" not in "bonjour"
False
 
>>> "Bon" not in "bonjour"
True
\end{minted}
}

\end{multicols}










\section{Tableau statique}

\begin{multicols}{2}


\begin{figure}[H]
\centering
\includegraphics[width=7cm]{tableau_principe.png}
\caption{Principe du tableau}
\label{Principe-tableau}
\end{figure}

\subsection{Définition}

Un \remarque{tableau statique} est un tableau comportant \gras{un nombre de cases fixé} à la création.

Un \remarque{tableau} est un conteneur formant une \gras{collection ordonnée d'éléments ayant tous le même type}. On peut donc avoir un tableau d'integers, ou un tableau de floats par exemple.

Les cases sont identifiées par un numéro nommé \remarque{indice}.

Voici un exemple de tableau de caractères de 3 cases (indices 0-1-2) 

\begin{tabular}{cccccccc}
\hline
   Indice & 0 & 1 & 2 \\
   Elément & 'A' & 'B' & 'C' \\
\hline
\end{tabular}

\subsection{Déclaration}

Les tableaux statiques sont implémentés en Python sous forme d'une structure de données dont le type se nomme \gras{\fo{list}}.

\subsubsection{A - Déclaration}

On peut enregistrer une séquence de données dans un tableau statique en utilisant la syntaxe suivante :

\begin{itemize}
\item un crochet \gras{\fo{[}} en ouverture,
\item un crochet \gras{\fo{]}} en fermeture et
\item des virgules pour séparer les valeurs.
\end{itemize}
  
Exemple avec un tableau contenant les notes de quatre élèves~:

\small{
\begin{minted}{bat}
>>> notes = [20, 8, 18, 12]
>>> type(notes)
<class 'list'>
\end{minted}
}

\subsubsection{B - Grand tableau}

On peut déclarer un tableau sur plusieurs lignes en tapant sur ENTREE après chaque virgule. Exemple~:

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
eleves = ["Lisa",
    "Scott",
    "Matthias",
    "Antoine",
    "Ethan",
    "Lucas",
    "Manon"]
\end{minted}

Cela prend plus de lignes mais on comprend un peu mieux ce qu'on place où.

\subsubsection{C - Tableau vide}

Deux solutions

\begin{multicols}{2}
\small{
\begin{minted}{python}
>>> t = []
>>> t
[]
 
>>> t = list()
>>> t
[]
\end{minted}
}
\end{multicols}

\subsection{Opérateurs Python}

\gras{$\rhd$ Concaténation} avec \fo{+} : \fo{list + list -> list}

\small{
\begin{minted}{python}
>>> [10, 20] + [5, 30]
[10, 20, 5, 30]
\end{minted}
}
 
\gras{$\rhd$ Répétition} avec \fo{*} :

\begin{itemize}
\item \fo{list * int -> list}
\item \fo{int * list -> list}
\end{itemize}

\begin{multicols}{2}
\small{
\begin{minted}{python}
>>> [10] * 3
[10, 10, 10]
 
>>> 3 * [12]
[12, 12, 12]
\end{minted}
}
\end{multicols}


\subsection{Accéder à une case [i]}

\subsubsection{Accés}

On peut accéder \gras{à l'élément stocké dans une case dont on connait l'indice} en tapant le nom de la variable-tableau suivie de \remarque{crochets} et de l'indice.

\small{
\begin{minted}{python}
Indice        0  1   2   3 
>>> notes = [20, 8, 18, 12]
\end{minted}
}

\begin{multicols}{2}
\small{
\begin{minted}{python}
>>> notes[0]
20
 
>>> notes[1]
8
 
>>> notes[2]
18
 
>>> notes[3]
12
\end{minted}
}
\end{multicols}

\small{
\begin{minted}{python} 
>>> notes[4]
IndexError: list index out of range
\end{minted}
}

\subsubsection{Trois choses à distinguer}

\begin{itemize}
\item Le conteneur $\Rightarrow$ \fo{\gras{t}} (le tableau)
\item Les indices $\Rightarrow$ \fo{\gras{i}}
\item Les contenus $\Rightarrow$ \fo{\gras{t[i]}}
\end{itemize}

\subsection{Déterminer sa longueur}

La longueur d'un tableau correspond au nombre de "cases-éléments" du tableau.

On utilise la fonction native \gras{\fo{len()}}.

\small{
\begin{minted}{python}
Indice        0  1   2   3 
>>> notes = [20, 8, 18, 12]
>>> len(notes)
4
\end{minted}
} 

4 notes, des indices allant de 0 à 3.

\subsection{Muable en Python}

En Python, les tableaux sont \gras{muables} : on peut \gras{modifier le \remarque{contenu} d'une case après la création} du tableau.

\small{
\begin{minted}{python}
Indice        0  1   2   3 
>>> notes = [20, 8, 18, 12]
>>> notes[1] = 11
>>> notes
[20, 11, 18, 12]
\end{minted}
} 

\remarque{Ce n'est pas une affectation sur le tableau lui-même}. L'affectation est faite sur l'une des cases \gras{\fo{notes[i]}} du tableau.

\subsection{Parcours par indices}

On utilise une boucle \gras{\fo{for i in range(len(t))}}.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
t = [20, 8, 18, 12]
 
for i in range(len(t)): 
    print(t[i])          
\end{minted}

Traduction L3 : Pour chaque indice possible dans t

Traduction L4 : Affiche le contenu de la case i

Ce programme est équivalent à ceci~:

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
t = [20, 8, 18, 12]
print(t[0])
print(t[1])
print(t[2])
print(t[3])
\end{minted}

Ils affichent l'un et l'autre ceci dans la console~:

\begin{multicols}{4}
\begin{minted}{python}
20
8
18
12
\end{minted}
\end{multicols}

\subsection{Mot-clés in et not in}


\subsubsection{Test d'appartenance ou de présence}

L'opérateur binaire \fo{\gras{in}} qui renvoie un booléen. Pour savoir si le \fo{\gras{contenu}} est présent dans le tableau \fo{\gras{t}}, on tape \fo{\gras{contenu in t}}.

\small{
\begin{minted}{python}
>>> "Alice" in ["Alice, "Bob", "Charlie"]
True
 
>>> "Dana" in ["Alice, "Bob", "Charlie"]
False
\end{minted}
}  

\subsubsection{Test de non-appartenance ou d'absence}

L'opérateur binaire \fo{\gras{not in}} qui renvoie un booléen. Pour savoir si le \fo{\gras{contenu}} n'est pas présent dans le tableau \fo{\gras{t}}, on tape \fo{\gras{contenu not in t}}.

\small{
\begin{minted}{python}
>>> "Alice" not in ["Alice, "Bob", "Charlie"]
False
 
>>> "Dana" not in ["Alice, "Bob", "Charlie"]
True
\end{minted}
}   


\end{multicols}










\section{n-uplet}

\begin{multicols}{2}


\begin{figure}[H]
\centering
\includegraphics[width=6cm]{tuple_principe.png}
\caption{Principe du tuple}
\label{Principe-tuple}
\end{figure}


\subsection{Définition}

\paragraph{Généralités}
Un \remarque{n-uplet} est un conteneur formant une \gras{collection ordonnée d'éléments pouvant avoir un type différent les uns des autres}.

Les cases sont identifiées par un \gras{indice}. 

Un 4-uplet dont les indices sont 0-1-2-3~:

\begin{tabular}{cccccccc}
\hline
   Indice & 0 & 1 & 2 & 3 \\
   Elément & '"In Bordeland"' & "Alice" & 18 & True \\
\hline
\end{tabular}

\paragraph{Vocabulaire}

\begin{itemize}
\item 1-uplet : singleton
\item 2-uplet : couple
\item 3-uplet : triplet
\item 4-uplet : quadruplet
\end{itemize}

\subsection{Déclaration}

Les n-uplets sont implémentés en Python sous forme d'une structure de données dont le type se nomme \gras{\fo{tuple}}.

\subsubsection{A - Déclaration}

On peut enregistrer une séquence de données dans un n-uplet en utilisant la syntaxe suivante :

\begin{itemize}
\item une parenthèse \gras{\fo{(}} en ouverture,
\item une parentèhse \gras{\fo{)}} en fermeture et
\item des virgules pour séparer les valeurs.
\end{itemize}
  
Exemple avec un élève : nom, prénom, age, NSI ?~:

\small{
\begin{minted}{python}
>>> eleve = ("In Bordeland", "Alice", 18, True)
>>> eleve
('In Bordeland', 'Alice', 18, True)
\end{minted}
}

\small{
\begin{minted}{bat}
>>> type(eleve)
<class 'tuple'>
\end{minted}
}

\subsubsection{B - Grand n-uplet}

On peut déclarer un tuple sur plusieurs lignes en tapant sur ENTREE après chaque virgule. Exemple~:

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
eleve = ("In Borderland",
    "Alice",
    18,
    True)
\end{minted}

\subsubsection{C - n-uplet vide}

Deux solutions

\begin{multicols}{2}
\small{
\begin{minted}{python}
>>> tup = ()
>>> tup
()
 
>>> t = tuple()
>>> t
()
\end{minted}
}
\end{multicols}

\subsubsection{D - cas du singleton}

Pour déclarer un tuple de 1 élément, il faut \gras{nécessairement placer une virgule}, sinon l'interpréteur Python prendra vos parenthèses comme de simples parenthèses.

\begin{center}\fo{(10,)} correct pour du tuple\end{center}

\begin{center}\fo{(10)} : incorrect pour du tuple\end{center}

\begin{multicols}{2}
\small{
\begin{minted}{bat}
>>> tp1 = (10,)
>>> tp1
(10,)

>>> type(tp1)
<class 'tuple'> 

>>> tp2 = (10)
>>> tp2
10

>>> type(tp2)
<class 'int'>
\end{minted}
}
\end{multicols}

\subsection{Opérateurs Python}

\gras{$\rhd$ Concaténation} avec \fo{+} : \fo{tuple + tuple -> tuple}

\small{
\begin{minted}{python}
>>> (10, 20) + (5, 30)
(10, 20, 5, 30)
\end{minted}
}
 
\gras{$\rhd$ Répétition} avec \fo{*} :

\begin{itemize}
\item \fo{tuple * int -> tuple}
\item \fo{int * tuple -> tuple}
\end{itemize}

\small{
\begin{minted}{python}
>>> (10,) * 3
(10, 10, 10)
 
>>> 3 * (10, 12)
(10, 12, 10, 12, 10, 12)
\end{minted}
}

\gras{$\rhd$ Erreur sémantique courante} Nous avions vu l'erreur sémantique suivante~:

\small{
\begin{minted}{python}
>>> 5,2 + 1,2
(5, 3, 2)
\end{minted}
}

Pour la comprendre, il faut se rendre compte qu'on demande à Python d'interpréter un tuple ! Voici ce que comprend l'intepréteur Python~:

\small{
\begin{minted}{python}
>>> (5,2 + 1,2)
(5, 3, 2)
\end{minted}
}

On lui demande donc d'évalue un triplet contenant 5 sur l'indice 0, 2 + 1 sur l'indice 1 et 2 sur l'indice 2. Moralité : explicite c'est mieux qu'implice.


\subsection{Accéder à une case [i]}

\subsubsection{Accés}

On peut accéder \gras{à l'élément stocké dans une case dont on connait l'indice} en tapant le nom de la variable-tuple suivie de \remarque{crochets} et de l'indice.

\small{
\begin{minted}{python}
Indice               0          1      2   3 
>>> eleve = ("In Bordeland", "Alice", 18, True)
>>> eleve[0]
'In Borderland'
\end{minted}
}


\begin{multicols}{3}
\small{
\begin{minted}{python}
>>> eleve[1]
'Alice'
 
>>> eleve[2]
18
 
>>> eleve[3]
True
\end{minted}
}
\end{multicols}
 
\small{
\begin{minted}{python}
>>> notes[4]
IndexError: list index out of range
\end{minted}
}

\subsubsection{Trois choses à distinguer}

\begin{itemize}
\item Le conteneur $\Rightarrow$ \fo{\gras{tup}} (le n-uplet)
\item Les indices $\Rightarrow$ \fo{\gras{i}}
\item Les contenus $\Rightarrow$ \fo{\gras{tup[i]}}
\end{itemize}

\subsection{Déterminer sa longueur}

La longueur d'un n-uplet correspond au nombre n de "cases-éléments" du tableau.

On utilise la fonction native \gras{\fo{len()}}.

\small{
\begin{minted}{python}
Indice               0          1      2   3 
>>> eleve = ("In Bordeland", "Alice", 18, True)
>>> len(notes)
4
\end{minted}
} 

4 notes, des indices allant de 0 à 3.

\subsection{Immuable en Python}

En Python, les tuples sont \gras{immuables} : on ne peut \gras{\remarque{pas} modifier le \remarque{contenu} d'une case après la création} du n-uplet.

\small{
\begin{minted}{python}
Indice               0          1      2   3 
>>> eleve = ("In Bordeland", "Alice", 18, True)
>>> eleve[2] = 19
TypeError: 'tuple' does not support item assignment
\end{minted}
} 

\subsection{Parcours par indices}

On utilise une boucle \gras{\fo{for i in range(len(tup))}}.

\small{
\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
eleve = ("In Borderland", "Alice", 18, True)
 
for i in range(len(eleve)):
    print(eleve[i])          
\end{minted}
}

Traduction L3 : Pour chaque indice possible dans eleve

Traduction L4 : Affiche le contenu de la case i

Ce programme est équivalent à ceci~:

\small{
\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
eleve = ("In Borderland", "Alice", 18, True)
 
print(eleve[0])
print(eleve[1])
print(eleve[2])
print(eleve[3])
\end{minted}
}

Ils affichent l'un et l'autre ceci dans la console~:

\begin{minted}{python}
'In Borderland'
'Alice'
18
True
\end{minted}

\subsection{Mot-clés in et not in}


\subsubsection{Test d'appartenance ou de présence}

L'opérateur binaire \fo{\gras{in}} qui renvoie un booléen. Pour savoir si le \fo{\gras{contenu}} est présent dans le n-uplet \fo{\gras{tup}}, on tape \fo{\gras{contenu in tup}}.

\small{
\begin{minted}{python}
>>> "Alice" in ("Alice", "Bob", "Charlie")
True
 
>>> "Dana" in ("Alice", "Bob", "Charlie")
False
\end{minted}
}  

\subsubsection{Test de non-appartenance ou d'absence}

L'opérateur binaire \fo{\gras{not in}} qui renvoie un booléen. Pour savoir si le \fo{\gras{contenu}} n'est pas présent dans le n-uplet \fo{\gras{tup}}, on tape \fo{\gras{contenu not in tup}}.

\small{
\begin{minted}{python}
>>> "Alice" not in ("Alice", "Bob", "Charlie")
False
 
>>> "Dana" not in ("Alice", "Bob", "Charlie")
True
\end{minted}
}   


\end{multicols}









\section{Dictionnaire}

\begin{multicols}{2}

\begin{figure}[H]
\centering
\includegraphics[height=3cm]{mm_principe.png}
\caption{Principe du dictionnaire}
\label{Principe-dico}
\end{figure}



\subsection{Définition d'un dictionnaire}

Un dictionnaire est un \gras{tableau associatif}. Il comporte des cases qui portent un nom et possèdent un contenu. On nomme~:

\begin{itemize}
\item \gras{clé (key}) le nom de la case.
\item \gras{valeur (value)} le contenu de la case.
\end{itemize}

\small{
\begin{minted}{python}
Clé     "Alice"   "Bob"   "Charlie"
Valeur     13       8         12
\end{minted}
}

\subsection{Déclaration d'un dictionnaire}

\begin{itemize}
\item Les éléments délimiteurs sont les accolades \fo{\{\}}.
\item On fournit un couple \gras{(cle, valeur)} en utilisant la syntaxe Python suivante : \fo{cle: valeur}.
\item Les couples sont séparés par une \gras{virgule}.
\end{itemize}

\paragraph{Exemple} une ligne ou multiligne

\small{
\begin{minted}{python}
ds = {"Alice": 13, "Bob": 8, "Charlie": 12}
\end{minted}
}

\small{
\begin{minted}{python}
ds = {
    "Alice": 13,
    "Bob": 8,
    "Charlie": 12
    }
\end{minted}
}

\subsection{Lecture, accéder à une valeur}

On accéde à une valeur en tapant le \gras{nom du dictionnaire suivi de la clé entre crochets}.

\small{
\begin{minted}{python}
>>> ds = {"Alice": 13, "Bob": 8, "Charlie": 12}
>>> ds["Bob"]
8

>>> ds["Bob l'éponge"]
KeyError: "Bob l'éponge"
\end{minted}
} 

\subsection{Opérateurs Python}

Ni concaténation, ni répétition. C'est fini.

\subsection{Déterminer sa longueur}

On peut utiliser la fonction native \gras{\fo{len()}} pour obtenir le nombre de couples \gras{\fo{(clé, valeur)}} enregistrés dans un dictionnaire.

Exemple~:

\small{
\begin{minted}{python}
>>> ds = {"Alice": 13, "Bob": 8, "Charlie": 12}
>>> nbr = len(ds)
>>> nbr
3
\end{minted}
}

\subsection{Muable en Python}

En Python, les dictionnaires sont muables : on peut \gras{modifier le contenu d'une case après la création} du dictionnaire.

\subsubsection{Modification d'un couple existant} 

\small{
\begin{minted}{python}
>>> {"Alice": 13, "Bob": 8, "Charlie": 12}
>>> notes["Bob"]
8
 
>>> notes["Bob"] = 11
>>> notes["Bob"]
11
 
>>> notes
{'Alice': 13, 'Bob': 11, 'Charlie': 12}
\end{minted}
} 

Notez bien que \gras{ce n'est pas une affectation sur le dictionnaire}~: l'affectation est faite sur l'un des contenus, pas sur le dictionnaire notes lui-même.

\subsubsection{Rajout d'un nouveau couple}

On peut rajouter de la même façon un couple qui n'existe pas encore. Imaginons un nouvel élève nommé David qui a eu 15.

\small{
\begin{minted}{python}
>>> {"Alice": 13, "Bob": 11, "Charlie": 12}
>>> notes["David"] = 15
 
>>> notes
{'Alice': 13, 'Bob': 11, 'Charlie': 12, 'David': 15}
\end{minted}
} 


\subsection{Parcours par clés}

On utilise une boucle \gras{\fo{for cle in d.keys()}}.

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
ds = {"Alice": 13, 
      "Bob": 8, 
      "Charlie": 12
     }
 
for cle in ds.keys():  
    print(ds[cle])     
\end{minted}

Traduction L6 : Pour chaque cle possible dans ds

Traduction L7 : Affiche la valeur associée à cette clé

Ce programme est équivalent à ceci :

\begin{minted}[linenos=true, bgcolor=lightgray, tabsize=4, gobble=0, fontfamily=courier, fontsize=\small, xleftmargin=20pt, xrightmargin=5pt]{python}
ds = {"Alice": 13, 
      "Bob": 8, 
      "Charlie": 12
}
 
print(ds["Alice"])
print(ds["Bob"])
print(ds["Charlie"])
\end{minted}

Ils affichent l'un et l'autre ceci dans la console :

\begin{multicols}{3}
\small{
\begin{minted}{python}
13
8
12
\end{minted}
}
\end{multicols}

\subsection{Mot-clés in et not in}

\subsubsection{Test d'existence d'une clé}

L'opérateur binaire \fo{in} qui renvoie un booléen. Pour savoir si la \fo{cle} est une clé dans le dictionnaire \fo{d}, on tape \fo{cle in d.keys()} ou \fo{cle in d}.

Version explicite :


\small{
\begin{minted}{python}
>>> d = {"Alice": 12, "Bob": 8}
\end{minted}
} 

\begin{multicols}{2}
\small{
\begin{minted}{python}
# Version explicite
>>> "Alice" in d.keys()
True
 
>>> "Dana" in d.keys()
False
# Version implicite
>>> "Alice" in d
True
 
>>> "Dana" in d
False
\end{minted}
} 
\end{multicols}

Traduction : "Alice" est-elle une clé du dictionnaire d ?

\subsubsection{Test d'absence d'une clé}

L'opérateur binaire \fo{not in} qui renvoie un booléen. Pour savoir si la \fo{cle} n'est pas une clé dans le dictionnaire \fo{d}, on tape \fo{cle not in d.keys()} ou \fo{cle not in d}.

\small{
\begin{minted}{python}
>>> d = {"Alice": 12, "Bob": 8}
\end{minted}
} 

\begin{multicols}{2}
\small{
\begin{minted}{python}
# Version explicite
>>> "Bob" not in d.keys()
False
 
>>> "Da" not in d.keys()
True
# Version implicite
>>> "Bob" not in d
False
 
>>> "Da" not in d
True
\end{minted}
} 
\end{multicols}


Traduction : "Alice" est-elle absente en tant que clé dans le dictionnaire ?

\end{multicols}



\newpage

\section{Convertir en tableau}

\begin{multicols}{2}


\subsection{list -> list avec list()}

On peut créer une copie rapide d'un tableau plutôt que d'en faire un alias vers ce même contenu-tableau.

\small{
\begin{minted}{python}
>>> t = [1, 2, 4]   
# création d'un tableau

>>> t2 = t          
# t2 n'est qu'un alias, un autre nom
   
>>> t3 = list(t)    
# t3 est une copie indépendante1
 
>>> t[0] = 100      
# on modifie le contenu de la case 0 par 100
 
>>> t  
[100, 2, 4]   # Modifié : normal
 
>>> t2  
[100, 2, 4]   # Modifié : normal, alias de t 
 
>>> t3 
[1, 2, 4]     # Non modifié : normal, copie.
\end{minted}
}


\subsection{tuple -> list avec list()}

Crée une copie partielle du contenu immuable qui devient mutable.


\subsection{dict -> list avec list()}

On crée un tableau contenant soit les clés, soit les valeurs, soit des tuples (clé, valeur associée).

\small{
\begin{minted}{python}
>>> d = {'Alice':14, 'Bob':12}   
# création d'un dictionnaire

# IMPLICITE : t contient les clés de d  
>>> t1 = list(d)     
>>> t1 
['Alice', 'Bob']
 
# EXPLICITE : t contient les clés de d 
>>> t2 = list(d.keys())     
>>> t2  
['Alice', 'Bob']
 
# EXPLICITE : t contient les valeurs de d 
>>> t3 = list(d.values())     
>>> t3  
[14, 12]
 
# EXPLICITE : t contient les couples de d
>>> t4 = list(d.items())     
>>> t3  
[('Alice', 14), ('Bob', 12)]
\end{minted}
}


\subsection{str -> list avec list()}

On récupère les caractères, un par case.

\small{
\begin{minted}{python}
>>> nom = "Merlin"
>>> t = list(nom) 
>>> t
['M', 'e', 'r', 'l', 'i', 'n']
\end{minted}
}



\subsection{str -> list avec split()}

La méthode \fo{split()} veut dire séparer et permet justement de "séparer" un string en différentes parties et placer ces parties dans un tableau.


\subsubsection{mots d'une phrase}
\small{
\begin{minted}{python}
>>> nom = "Merlin ou Toto l'asticot"
>>> t = nom.split(' ')
 
>>> t
['Merlin', 'ou', 'Toto', "l'asticot"]
\end{minted}
}

\subsubsection{split sans rien}

Par défaut, il est possible de ne pas préciser le caractère qui servira à scinder le string en plusieurs parties : la méthode est configurée pour considérer qu'il s'agit de l'espace.

\small{
\begin{minted}{python}
>>> nom = "Merlin ou Toto l'asticot"
>>> t = nom.split()
 
>>> t
['Merlin', 'ou', 'Toto', "l'asticot"]
\end{minted}
}

\subsubsection{Récupérer les phrases ?}

Pour récupérer les phrases, on peut considérer qu'il suffit d'utiliser la méthode en considérant que le caractère séparateur est le point.



\end{multicols}



\section{Convertir en tuple}

On peut utiliser \fo{tupe()} : même principe que la partie précédente mais on crée un tuple pas un tableau.



\section{Convertir en dictionnaire}

\begin{multicols}{2}

\subsection{dict -> dict avec dict()}

Utiliser \fo{dict()} sur un autre dictionnaire permet d'en faire une copie peu profonde.

\small{
\begin{minted}{python}
# création d'un dictonnaire
>>> {'Alice': 14, 'Bob': 12} 

# d2 n'est qu'un alias !    
>>> d2 = d 

# d3 est une copie indépendante1                      
>>> d3 = dict(t)               

# on modifie le contenu de la case 'Alice' 
>>> d['Alice'] = 20            

# Modifié : normal 
>>> d  
{'Alice': 20, 'Bob': 12}       

# Modifié : normal, c'est un alias de d !
>>> d2  
{'Alice': 20, 'Bob': 12}       

# Non modifié : normal, c'est une copie.
>>> d3 
{'Alice': 14, 'Bob': 12}      
\end{minted}
}


\subsection{ list|tuple|str  -> dict avec dict()}



On ne peut pas convertir n'importe quel type de list, tuple ou str en dictionnaire.

Nous verrons plus tard dans l'année qu'on peut convertir un type particulier de tableau en dictionnaire : on peut convertir un tableau de couple en dictionnaire.


\end{multicols}





\section{Convertir en str}

\begin{multicols}{2}

\subsection{list|tuple|dict -> str avec str()}

On peut convertir n'importe quel type de list, tuple ou dict en string. Par contre, l'utilité directe est limitée. Cela peut servir pour sauvegarder un tel contenu via un fichier-texte.

\small{
\begin{minted}{python}
>>> str( [14, 12] ) 
"[14, 12]"  
 
>>> str( ('Alice', 12) ) 
"('Alice', 12)"  
 
>>> str( {'Alice': 14, 'Bob': 12} ) 
"{'Alice': 14, 'Bob': 12}"
\end{minted}
}


\subsection{ Créer un str avec join()}


On peut convertir en str des cas particuliers d'autres types construits :

\begin{itemize}
\item Des tableaux list dont les éléments sont des str;
\item Des n-uplets tuple dont les éléments sont des str;
\item Des dictionnaires dict dont les clés sont des str.
\end{itemize}

 \small{
\begin{minted}{python}

>>> t = ["Ahah", "Bonbon", "Coucou"]
 
>>> s = "---".join(t) 
>>> s
'Ahah---Bonbon---Coucou'  
 
>>> s = ";".join(t) 
>>> s
'Ahah;Bonbon;Coucou'  
 

>>> d = {"Alice":14, "Bob":12, "Charlie":8}
 
>>> s = "---".join(d) 
>>> s
'Alice---Bob---Charlie'  
 
>>> s = " ".join(d) 
>>> s
'Alice Bob Charlie' 
\end{minted}
}   
    
\end{multicols}




\input{licence}

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

{}
\makeatother

