<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">%!TEX encoding = IsoLatin
\lstset{frame=trlb, frameround=tttt, showstringspaces=false}
\lstset{language=Python, identifierstyle=\sffamily,columns=flexible,mathescape=false} 

\chapter{Dictionnaires} 
\label{cha:dictionnaires}
%\initchapter

\section{Introduction}

\subsection{Présentation}

Les dictionnaires sont des structures de données qui, comme les tableaux, permettent de stocker des collections de valeurs. Ils sont utiles dans de nombreuses situations où les tableaux n'offrent plus assez de souplesse ou d'expressivité pour structurer un jeu de données. La particularité principale qui distingue les dictionnaires des tableaux, est que les données sont stockées sous forme de couples (clef-valeur).\\

\subsection{Différentes façons de stocker et donc d'accéder aux valeurs}

On rappelle que dans les tableaux les valeurs sont dans l'ordre. On peut donc accéder à une valeur en indiquant sa position au moyen d'un indice:\\
\begin{center}
\begin{minipage}{0.7 \linewidth}
\lst{tab\_astro}:
\begin{tabular}{llll}
\textit{indice}&amp;\textit{0}&amp;\textit{1}&amp;\textit{2}\\
\cline{2-4} \textit{valeur}&amp;\multicolumn{1}{|c|}{'Terre'}&amp;\multicolumn{1}{c|}{'Lune'}&amp;\multicolumn{1}{c|}{'Soleil'}\\
\cline{2-4}
\end{tabular}\\
\begin{lstlisting}
print( tab_astro[1] )
'Lune'
\end{lstlisting}
\end{minipage}
\end{center}

Dans un dictionnaire \underline{\textbf{il n'y a pas de notion d'ordre et donc pas de position}}. Pour accéder à une valeur il faut un autre moyen. Ce moyen, c'est une clef unique associée à chaque valeur lors de la définition du dictionnaire.\\
\begin{center}
\begin{minipage}{0.7 \linewidth}
\lst{dico\_astro}:
\begin{tabular}{l|l|l|l|}
\cline{2-4}\textit{clef}&amp;'Planete'&amp;'Satellite'&amp;'Etoile'\\
\cline{2-4}\textit{valeur}&amp;'Terre'&amp;'Lune'&amp;'Soleil'\\
\cline{2-4}\end{tabular}\\
\begin{lstlisting}
print( dico_astro['Satellite'] )
'Lune'
\end{lstlisting}
\end{minipage}
\end{center}
Les dictionnaires sont aussi appelés tableaux associatifs dans le sens où ils associent des valeurs à des clefs (et non à des positions). Dans le dictionnaire \lst{dico\_astro} précédent, trois couples \lst{clef-valeur} sont définis: \lst{'Planete'-'Terre'}, \lst{'Satellite'-'Lune'} et \lst{'Etoile','Soleil'}.\\

On accède donc différemment aux valeurs stockées dans un tableau et dans un dictionnaire. La façon dont on veut accéder aux valeurs stockées va conditionner le choix entre une structure de données ou l'autre. 

Pour certains jeux de données, l'utilisation d'un tableau est naturelle car il y a une correspondance simple entre la valeur et sa position. Pour d'autres jeux de données, cette correspondance n'est pas évidente. Dans de nombreux cas il sera avantageux d'utiliser des dictionnaires.

\section{Définition d'un dictionnaire}

Il existe deux façons de définir un dictionnaire.\\
La première consiste à donner littéralement l'ensemble des couples \lst{clef-valeur} lors de sa déclaration. La collection de couples \lst{clef-valeur} est donnée entre accolades (symboles \lst{\{} et \lst{\}}), et chaque couple est séparé par une virgule. Un couple \lst{clef-valeur} est spécifié littéralement en donnant la clef suivie de la valeur qui lui est associée, les deux étant séparés par deux points (le symbole de ponctuation \lst{:}), soit

\begin{center}\lst{dico = \{ clef\_1:valeur\_1  , clef\_2:valeur\_2  , \dots\}}\end{center}

\begin{lstlisting}
dico_astro = {'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}
\end{lstlisting}

La deuxième façon de définir un dictionnaire, consiste à déclarer un dictionnaire vide, puis de le remplir. La déclaration d'un dictionnaire vide est similaire à celle de la déclaration d'un tableau vide. Les symboles du tableau vide \lst{[]} sont remplacés par les symboles d'un dictionnaire vide \lst{\{\}}:
\begin{lstlisting}
dico_astro2 = {}
\end{lstlisting}

L'ajout de nouveaux couples \lst{clef-valeur}  au dictionnaire \lst{dico\_astro2} ainsi initialisé se fait au moyen de la syntaxe suivante: \lst{dico\_astro2[clef] = valeur}

\begin{lstlisting}
dico_astro2['Planete']		= 'Terre'
dico_astro2['Satellite']	= 'Lune'
dico_astro2['Etoile']		= 'Soleil'
print( str( dico_astro2 ) )
{'Planete': 'Terre', 'Satellite': 'Lune', 'Etoile': 'Soleil'}
\end{lstlisting}

\fairexo{~\ref{exo1}, TD}

\section{Manipulation d'un dictionnaire}

Nous avons vu dans l'introduction que les clefs des dictionnaires jouent en quelque sorte le rôle des indices dans les tableaux:
\begin{itemize}
	\item les clefs permettent d'accéder à une valeur stockée dans le dictionnaire,
	\item les clefs permettent de modifier une valeur stockée dans le dictionnaire.
\end{itemize}
Pour illustrer ces cas nous utiliserons les tableaux et le dictionnaires décrits précédemment dans l'introduction et dont la syntaxe de définition littérale est la suivante: \\

\begin{lstlisting}
tab_astro = ['Terre','Lune','Soleil']

dico_astro = {'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}
\end{lstlisting}

\subsection{Accéder à une valeur}

Dans un tableau la valeur correspondant à l'indice de position i est accessible en faisant suivre le nom du tableau de l'indice donné entre crochets.\\

\begin{lstlisting}
print( str( tab_astro[1] ) )
'Lune'
\end{lstlisting}

Dans un dictionnaire c'est la même chose, à la différence que l'indice de position est remplacé par la clef.\\

\begin{lstlisting}
print( str( dico_astro['Satellite'] ) )
'Lune'
\end{lstlisting}

Lorsqu'on appelle une valeur d'un tableau avec un indice qui dépasse sa taille, l'interpréteur affiche un message d'erreur.\\

\begin{lstlisting}
tab_astro[100]
Traceback (innermost last):
File "&lt;stdin&gt;", line 1, in ?
IndexError: list index out of range
\end{lstlisting}

Il en est de même si on utilise une clef non contenue dans le dictionnaire lors d'un appel de valeur.\\

\begin{lstlisting}
dico_astro['Galaxie']
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
KeyError: 'Galaxie'
\end{lstlisting}

\subsection{Modifier une valeur}

Pour modifier une valeur dans un tableau il suffit d'affecter une nouvelle valeur à une certaine position en spécifiant l'indice de position.\\

\begin{lstlisting}
print( str( tab_astro ) )
['Terre','Lune','Soleil']

tab_astro[0] = 'Mars'

print( str( tab_astro ) )
['Mars','Lune','Soleil']
\end{lstlisting}

De la même façon, dans un dictionnaire il suffit d'affecter une nouvelle valeur à une clef:\\

\begin{lstlisting}
print( str( dico_astro ) )
{'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}

dico_astro['Planete'] = 'Mars'

print( str( dico_astro ) )
{'Planete':'Mars', 'Satellite':'Lune', 'Etoile':'Soleil'}
\end{lstlisting}

\subsection{Ajouter une valeur}

Pour ajouter une valeur dans un tableau il est possible d'utiliser la concatenation de tableau. L'ajout d'une valeur modifie alors la taille du tableau.\\

\begin{lstlisting}
print( str( tab_astro ) )
['Terre','Lune','Soleil']

tab_astro = tab_astro + [ 'Voie Lactee' ]

print( str( tab_astro ) )
['Mars','Lune','Soleil','Voie Lactee' ]
\end{lstlisting}

Pour ajouter une valeur dans un dictionnaire il suffit d'affecter une valeur à une clef non encore utilisée:\\

\begin{lstlisting}
print( str( dico_astro ) )
{'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}

dico_astro['Galaxie'] = 'Voie Lactee'

print( str( dico_astro ) )
{'Planete': 'Terre', 'Satellite': 'Lune', 'Etoile': 'Soleil', 'Galaxie': 'Voie Lactee'}
\end{lstlisting}

Il faut remarquer ici que la syntaxe utilisée pour ajouter une valeur à un dictionnaire est la même que celle employée pour modifier la valeur associée à une clef existante. Pour ajouter une valeur (ou plus exactement ajouter un couple \lst{clef-valeur}), il faut impérativement que la clef ne soit pas encore utilisée dans le dictionnaire. En d'autres termes,
\begin{itemize}
	\item si on utilise une clef existante, la syntaxe conduit à changer la valeur associée à la clef, et le dictionnaire ne change pas de taille,
	\item si on utilise une nouvelle clef, la syntaxe ajoute un couple clef-valeur au dictionnaire et augmente sa taille.
\end{itemize}


\section{Quelques fonctions liées à l'utilisation des dictionnaires}

\subsection{Accéder à la liste des clefs}

Dans certains cas il peut être utile d'avoir accès à la liste des clefs d'un dictionnaire. Cela est réalisé par la fonction \lst{dict.keys(dico)} qui renvoie un tableau dont les éléments sont les clefs du dictionnaire \lst{dico}.\\

\begin{lstlisting}
dico_astro = {'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}

print( str( dict.keys( dico_astro ) ) )
['Planete', 'Satellite', 'Etoile']
\end{lstlisting}

Ici, les trois clefs du dictionnaire sont renvoyées dans le tableau \lst{['Planete', 'Satellite', 'Etoile']}.
 
\textbf{\textsc{Attention:}\\
On rappelle encore qu'il n'y pas de notion d'ordre dans les dictionnaires. Le tableau retourné par la fonction \lst{dict.values()} ne traduit pas l'ordre dans lequel les couple \lst{clef-valeur} ont été définis...}

\subsection{Accéder à la liste des valeurs}

Dans d'autres cas on peut souhaiter parcourir toutes les valeurs d'un dictionnaire indépendamment des clefs auxquelles elles sont associées. Cela est possible en utilisant la fonction \lst{dict.values(dico)} qui renvoie un tableau contenant les valeurs du dictionnaire \lst{dico}.\\

\begin{lstlisting}
dico_astro = {'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}

print( str( dict.values( dico_astro ) ) )
['Terre', 'Lune', 'Soleil']
\end{lstlisting}

Ici, les valeurs correspondant aux 3 clefs du dictionnaire sont renvoyées dans la liste \lst{['Terre', 'Lune', 'Soleil']}.

\textbf{\textsc{Attention (encore):}\\
On rappelle qu'il n'y pas de notion d'ordre dans les dictionnaires. Le tableau retourné par la fonction \lst{dict.keys()} ne traduit pas l'ordre dans lequel les couple \lst{clef-valeur} ont été définis...}

\subsection{Tester si une clef existe}
 \lst{dict.has\_key(mon\_dico, cl)}: Est une fonction booléenne qui renvoie \lst{True} si le dictionnaire \lst{mon\_dico} a la clef \lst{cl} et \lst{False} sinon.
	\begin{center}
	\begin{minipage}{0.7 \linewidth}
\begin{lstlisting}
print( str( dict.has_key( dico_astro , 'Etoile' ) ) )
True

print( str( dict.has_key( dico_astro , 'Galaxie' ) ) )
False
\end{lstlisting}
	\end{minipage}
	\end{center}

Dans le premier cas, la fonction renvoie \lst{True} car le dictionnaire comporte la clef 'Etoile' et \lst{False} dans le second cas car la clef 'Galaxie' est absente du dictionnaire.

\fairexo{~\ref{exo2}, TD}
\fairexo{~\ref{exo3}, TD}
\fairexo{~\ref{exo4}, TD}

\subsection{Supprimer une entrée (\lst{clef-valeur})}
\lst{del(mon\_dico[cl])}: Supprime du dictionnaire la clef \lst{cl} et la valeur qui lui est associée.
	\begin{center}
	\begin{minipage}{0.7 \linewidth}
\begin{lstlisting}
del( dico_astro['Planete'] )

print( str( dico_astro ) )
{'Satellite': 'Lune', 'Etoile': 'Soleil'}
\end{lstlisting}
	\end{minipage}
	\end{center}

Ici, le couple \lst{clef-valeur} correspondant à la clef \lst{'Planete'} est supprimé.

\section{Les clefs des dictionnaires}

\subsection{Utiliser une variable comme clef}

Comme pour les tableaux, il est possible d'utiliser comme clef d'un dictionnaire la valeur affectée à une variable.\\

\begin{lstlisting}
c = 'Etoile'

print( str( dico_astro[ c ] ) )
'Soleil'
\end{lstlisting}

Ici, la clef \lst{c} contient la valeur \lst{'Etoile'}. La commande \lst{dico\_astro[ c ]} sera donc interprétée comme la commande  \lst{dico\_astro[ 'Etoile' ]}.

\subsection{Pour aller plus loin: Les clefs doivent être des constantes}

Un même dictionnaire peut admettre des clefs de différents types:\\

\begin{lstlisting}
semaine = {}

semaine[1] = 'lundi'	# Integer

semaine['Couleur'] = 'rouge'	# String

print( str( semaine ) )
{'Couleur': 'rouge', 1: 'lundi'}
\end{lstlisting}

Ici, le dictionnaire \lst{semaine} admet la clef \lst{1} de type entier et la clef \lst{'Couleur'} de type chaîne de caractères.


Cependant, une limitation importante concernant les clefs des dictionnaires est qu'elles doivent correspondre à des types constants. Par exemple, un entier, un flottant, un booléen, une chaîne de caractères sont des constantes et peuvent être utilisés comme une clef de dictionnaire.\\

\begin{lstlisting}
dico = {}
dico[12735]='Diameter'		# Integer
dico[ 6367.5] = 'Radius'	# Float
dico[True]='Vrai'		# Boolean
dico['Nom'] = 'Gaia'		# String

print( str( dico ) )
{6367.5: 'Radius', True: 'Vrai', 12735: 'Diameter', 'Nom': 'Gaia'}
\end{lstlisting}

Par contre, les tableaux ou les dictionnaires ne sont pas des constantes puisque leur contenu est susceptible d'être modifié. Les utiliser comme clef de dictionnaire provoquera alors un message d'erreur.\\

\begin{lstlisting}
distance = [ 'Terre', 'Lune' ]

planete= {}

planete[ distance ] = 388272
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
TypeError: unhashable type: 'list'
\end{lstlisting}

Ceci explique l'intérêt des tuples. On rappelle que les tuples sont des sortes de tableaux constants, non-modifiables. Il est donc possible de les utiliser comme clef dans un dictionnaire:

\begin{lstlisting}
distance = ( 'Terre', 'Lune' )

planete= {}

planete[ distance ] = 388272
\end{lstlisting}


\section{Les valeurs des dictionnaires}

Comme pour les tableaux, les valeurs stockées dans un dictionnaire peuvent être de types différents, \underline{sans aucune contrainte}. Une valeur d'un dictionnaire peut donc être un nombre entier ou flottant, une chaîne de caractères, un booléen mais aussi des collections contenant d'autres valeurs comme un tableau ou un autre dictionnaire. Par exemple, le dictionnaire suivant contient des données hétérogènes:
\begin{center}
\begin{tabular}{llllll}
\cline{2-6}\textit{clef}&amp;\multicolumn{1}{|c|}{'Satellites'}&amp;\multicolumn{1}{|c|}{'Rayon'}&amp;\multicolumn{1}{|c|}{'Tellurique'}&amp;\multicolumn{1}{|c|}{'Oceans'}&amp;\multicolumn{1}{|c|}{'Superficie'}\\
\cline{2-6}\textit{valeur}&amp;\multicolumn{1}{|c|}{1}&amp;\multicolumn{1}{|c|}{6378.137}&amp;\multicolumn{1}{|c|}{True}&amp;
	\multicolumn{1}{|c|}{
	\begin{tabular}{ll}
		\textit{indice}&amp;\textit{valeur}\\
		\cline{2-2}
		\textit{0}&amp;\multicolumn{1}{|c|}{'Pacifique'}\\
		\cline{2-2}
		\textit{1}&amp;\multicolumn{1}{|c|}{'Atlantique'}\\
		\cline{2-2}
		\textit{2}&amp;\multicolumn{1}{|c|}{'Indien'}\\
		\cline{2-2}
		&amp;
	\end{tabular}
	}&amp;
	\multicolumn{1}{|c|}{
	\begin{tabular}{ll}
		\textit{clef}&amp;\textit{valeur}\\
		\hline
		\multicolumn{1}{|c|}{'Pacifique'}&amp;\multicolumn{1}{c|}{49.7}\\
		\hline
		\multicolumn{1}{|c|}{'Atlantique'}&amp;\multicolumn{1}{c|}{29.5}\\
		\hline
		\multicolumn{1}{|c|}{'Indien'}&amp;\multicolumn{1}{c|}{20.4}\\
		\hline
		&amp;
	\end{tabular}
	}\\
\cline{2-6}\textit{type}&amp;\lst{&lt;int&gt;}&amp;\lst{&lt;float&gt;}&amp;\lst{&lt;bool&gt;}&amp;\lst{&lt;list&gt;}&amp;\lst{&lt;dict&gt;}
\end{tabular}
\end{center}

Il peut être codé de la façon suivante:\\

\begin{lstlisting}
terre= {}
terre['Satellites'] 	= 1
terre['Rayon']		= 6378.137
terre['Tellurique']	= True
terre['Oceans']		= ['Pacifique', 'Atlantique', 'Indien']
terre['Superficie']	= {'Pacifique':49.7, 'Atlantique':29.5,'Indien':20.4}

print( str( terre ) )
{'Satellites': 1, 
 'Superficie': {'Pacifique': 49.700000000000003, 'Atlantique': 29.5, 'Indien': 20.399999999999999},
  'Rayon': 6378.1369999999997,
  'Oceans': ['Pacifique', 'Atlantique', 'Indien'],
  'Tellurique': True}
\end{lstlisting}

Dans le cas où une valeur du dictionnaire est elle même une collection, il doit être possible d'accéder à une valeur de cette collection. La syntaxe est la même que pour accéder à une valeur dans un tableau multi-dimensionnel.\\
Ainsi, à partir du tableau précédent, pour accéder à la superficie de l'océan indien on utilise la syntaxe suivante:\\

\begin{lstlisting}
print( str( planete['Superficie']['Indien'] ) )
20.4
\end{lstlisting}

En effet, le dictionnaire \lst{planete} admet pour clef \lst{'Superficie'} qui à pour valeur un dictionnaire. L'expression \lst{planete['Superficie']} est donc un dictionnaire qui à lui-même pour clef la chaîne de caractère \lst{'Indien'} et dont la valeur est \lst{20.4}.\\
De façon analogue, pour accéder au nom du premier océan, on utilise la syntaxe suivante:\\

\begin{lstlisting}
print( str( planete['Oceans'][0] ) )
'Pacifique'
\end{lstlisting}

En effet, le dictionnaire \lst{planete} admet pour clef \lst{'Oceans'} qui à pour valeur un tableau. L'expression \lst{planete['Ocean']} est donc un tableau dont le premier élément est 'Pacifique'. 

\fairexo{~\ref{exo5}, TD}




\section{Récapitulatif et Comparaison Dictionnaire/Tableau}


\begin{tabular}{lll}
\hline
Opération&amp;Tableau&amp;Dictionnaire\\
\hline
Définition d'un conteneur vide&amp;t = [ ]&amp;d = \{ \}\\
Définition d'un littéral&amp;t = [ val\_1, val\_2, \dots]&amp;d = \{ clef\_1:val\_1 , clef\_2:val\_2 , \dots\}\\
Appel d'une valeur&amp;t[ indice ]&amp; d[ clef ]\\
Ajout d'un élément&amp;t = t + [ nlle\_val ]&amp;d[ nlle\_clef ] = nlle\_val\\
Modification d'une valeur&amp;t[ indice ] = nlle\_val&amp;d[ clef ] = nlle\_val\\
Nombre d'éléments&amp;len( t )&amp;len( d )\\
Suppression d'un élément&amp;del( t[ indice ] )&amp;del( d[ clef ] )\\

\hline

\end{tabular}



%\subsection{Les cas où un tableau est suffisant}
%Pour illustrer différents cas nous nous appuierons sur l'exemple d'un magasin proposant 6 articles à la vente:

%\begin{center}
%\begin{tabular}{|c|c|c|c|c|c|c|}
%	\hline
%	article&amp;Téléviseur&amp;Épluche-légumes&amp;Cafetière&amp;Mixer&amp;Micro-ondes&amp;Réfrigérateur\\
%	\hline
%	prix&amp;400 \euro&amp;2 \euro&amp;150 \euro&amp;40 \euro&amp;150 \euro&amp;400 \euro\\
%	\hline
%\end{tabular}
%\end{center}

%Si vous souhaitez juste passer en revue les différents éléments d'une collection, un tableau suffit. En effet, il n'y a pas de question à se poser sur la façon dont on doit calculer l'indice de position des valeurs à afficher puisqu'il faut toutes les parcourir.\\

%\emph{Par exemple: Si vous souhaitez juste afficher les prix}
%\begin{lstlisting}
%prix = [ 400, 2, 150, 40, 150, 400]
%for p in prix :
%	print( str( p ) )
%\end{lstlisting}

%Si vous souhaitez accéder à une valeur particulière d'un tableau, il vous faut nécessairement connaître sa position. Si par exemple vous souhaitez connaitre la valeur médiane d'un tableau de valeurs numériques (des prix par exemple), il vous faudra alors procéder en plusieurs étapes:  i)  mettre les valeurs dans un tableau, ii) utiliser une fonction de tri pour ordonner les valeurs par ordre croissant, puis iii) calculer la position qui correspond à la moitié de la longueur du tableau.\\

%\emph{Par exemple: Afficher le prix minimum, le prix maximum et le prix médian.}
%\begin{lstlisting}
%prix = [ 400, 2, 150, 40, 150, 400]
%list.sort( prix )
%print( '   Min = ' + str( prix[ 0 ] ) + 
%	' | Max = ' + str( prix[ len( prix ) - 1 ] ) + 
%	' | Med = ' + str( prix[ len( prix ) / 2 ] )  )
%\end{lstlisting}

%
%Par contre, dans de nombreux cas, ces approches deviennent difficiles. Dans ces cas les dictionnaires peuvent être d'une grande aide.\\
%Par exemple, c'est le cas lorsque vos éléments forment des classes.

%\subsection{Cas où l'utilisation d'un dictionnaire rend le code plus simple}

%Un cas courant est de chercher à parcourir une classe d'éléments parmi une collection.\\

%\emph{Par exemple: Afficher les prix qui sont utilisés pour plusieurs articles.}

%Ici la classe est définie par un prix et les éléments d'une classe sont tous les articles qui présentent ce prix. Pour réaliser cela à partir d'un tableau il vous faudrait développer un algorithme relativement compliqué:
%\begin{enumerate}
%	\item mettre les valeur dans le tableau,
%	\item ordonner les valeurs par ordre de prix (croissant ou décroissant), puis
%	\item passer en revue tous ses éléments et
%	\item identifier si 2 éléments consécutifs sont égaux (le même prix).
%		\begin{itemize}
%			\item Si deux éléments consécutifs ont le même prix il faut afficher ce prix
%			\item sinon, passer au suivant.
%		\end{itemize}
%	\item De plus, il faudra envisager le cas ou  plusieurs éléments (articles) consécutifs ont le même prix, pour ne pas afficher 2 fois le même prix.
%\end{enumerate}

%\begin{lstlisting}
%&gt;&gt;&gt; prix = [400, 2, 150, 40, 150, 400]
%&gt;&gt;&gt; list.sort( prix )
%&gt;&gt;&gt; cur_prix = prix[0]
%&gt;&gt;&gt; printed = False
%&gt;&gt;&gt; i = 1
%&gt;&gt;&gt; while i &lt; len( prix ) :
%...	if prix[ i ] == cur_prix :
%...		if not printed :
%...			print cur_prix
%...			printed = True
%...	else :
%...		printed = False
%...	cur_prix = prix[ i ]
%...	i += 1
%150
%400
%\end{lstlisting}

%Dans ce cas l'utilisation d'un dictionnaire simplifie grandement le code et sa lecture. Celui-ci permet de catégoriser les articles en fonction de leur prix (la clef). La valeur associée à une clef (une classe) est la liste des articles qui ont ce prix (les éléments de la classe). Une fois cette catégorisation réalisée, l'accès et le traitement des valeurs ainsi structurées sera grandement simplifiée et le code rendu plus simple et plus expressif.\\

%\begin{center}
%\lst{prix}:
%\begin{tabular}{l|l|l|l|l|}
%\cline{2-5}\textit{clef}&amp;2 \euro&amp;40 \euro&amp;150 \euro&amp;400 \euro\\
%\cline{2-5}\textit{valeur}&amp;\begin{tabular}{l}\\\hline\multicolumn{1}{|c|}{'Épluche-légumes'}\\\hline\\\end{tabular}&amp;\begin{tabular}{ll}\\\hline\multicolumn{1}{|c|}{'Mixer'}\\\hline\\\end{tabular}&amp;\begin{tabular}{l}\\\hline\multicolumn{1}{|c|}{'Cafetière'}\\\hline\multicolumn{1}{|c|}{'Micro-ondes'}\\\hline\\\end{tabular}&amp;\begin{tabular}{l}\\\hline\multicolumn{1}{|c|}{'Réfrigérateur'}\\\hline\multicolumn{1}{|c|}{'Télévision'}\\\hline\\\end{tabular}\\
%\cline{2-5}
%\end{tabular}
%\end{center}

%\begin{lstlisting}
%&gt;&gt;&gt; prix = { 
%		2 : [ 'Épluche-légumes' ] , 40 : [ 'Mixer' ] ,
%		150 : ['Cafetiere', 'Micro-ondes'] ,
%		400 : ['Television', 'Refrigerateur']
%	}
%	
%&gt;&gt;&gt; for clef in dict.keys( prix ) :             # la fonction dict.keys() renvoie la liste des clefs
%...		if len( prix[ clef ] ) &gt; 1 :
%...			print clef
%400
%150
%\end{lstlisting}


%\fairexo{Exercice 2, TD}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{serieexostd}{Dictionnaires}

%--------------------------------------------------------------------------------------------------------------
\exercice{Définition d'un dictionnaire}
\label{exo1}
Définissez le dictionnaire \lst{lunes } représenté ci-dessous. Ce dictionnaire stocke le nombre de satellites de chaque planètes. Dans un premier temps vous définirez de façon littérale le dictionnaire pour les 4 premiers couples \lst{clef-valeur} puis vous ajouterez successivement les 4 derniers couples.

\begin{center}
\begin{tabular}{l|l|l|l|l|l|l|l|l|}
\cline{2-9}\textit{clef}&amp;'Mercure'&amp;'Venus'&amp;'Terre'&amp;'Mars'&amp;'Jupiter'&amp;'Saturne'&amp;'Uranus'&amp;'Neptune'\\
\cline{2-9}\textit{valeur}&amp;0&amp;0&amp;1&amp;2&amp;63&amp;61&amp;27&amp;11\\
\cline{2-9}\end{tabular}\\
\end{center}

Proposez un jeu de tests permettant de vérifier que le dictionnaire est correctement défini.\\

\begin{correction}
Pour la définition du dictionnaire:
\begin{lstlisting}
lunes  = {	'Mercure':0,
		'Venus':0,
		'Terre':1,
		'Mars':2   }	
lunes['Jupiter'] = 63
lunes['Saturne'] = 61
lunes['Uranus'] = 27
lunes['Neptune'] = 11
\end{lstlisting}
%Le test
%\begin{lstlisting}
%&gt;&gt;&gt; lunes['Mercure'] == 0 and lunes['Venus'] == 0 and \
%lunes['Terre'] == 1 and lunes['Mars'] == 2 and \
%lunes['Jupiter'] == 63 and lunes['Saturne'] == 61 and \
%lunes['Uranus'] == 27 and lunes['Neptune'] == 11
%True
%\end{lstlisting}
\end{correction}


%--------------------------------------------------------------------------------------------------------------
\exercice{Exploration d'un dictionnaire}
\label{exo2}
\`A partir du dictionnaire défini dans l'exercice précédent, proposez un programme permettant de:
\begin{itemize}
	\item modifier le dictionnaire précédent pour corriger une erreur qui s'est glissée dans l'énoncé. La planète Neptune comporte en fait 13 satellites.
	\item afficher le nombre de lunes de la Terre,
	\item afficher la liste des planètes,
	\item afficher le tableau des planètes et du nombre de leurs lunes,
	\item afficher le nombre total de lunes.
\end{itemize}

\begin{correction}
\begin{lstlisting}
# Modification de la valeur associée à la clef \lst{'Neptune'}.
lunes['Neptune'] = 13

# Affichage du nombre de lunes de la Terre
print( 'La terre comporte'+ (str)( lunes['Terre'] ) + 'lunes.' )

# Affichage de la liste des planetes
print( 'La liste des planetes est:' + str( dict.keys( lunes ) ) )

# Affichage du nombre de lunes de chaque planete
print( 'Nombre de lunes de chaque planetes:' )
for planete in dict.keys( lunes ) :
	print( planete + '     ' + str( lunes[ planete ] ) )
\end{lstlisting}
Puis, pour le comptage du nombre cumulé de lunes, discuter de la différence entre :
\begin{lstlisting}
# Affichage du nombre cumulé de lunes
tot = 0
for planete in dict.keys( lunes ) :
	tot += lunes[ planete ]
print( 'Le nombre de lunes recencees est :' + str( tot ) )
\end{lstlisting}
et
\begin{lstlisting}
# Affichage du nombre cumulé de lunes
tot = 0
for nb_de_lunes in dict.values( lunes ) :
	tot += nb_de_lunes
print( 'Le nombre de lunes recencees est :' + str( tot ) )
\end{lstlisting}

\end{correction}




%--------------------------------------------------------------------------------------------------------------
\exercice{Nombre d'occurrences des caractères d'un texte}
\label{exo3}
Proposez une fonction \lst{occurrences(texte)} prenant comme paramètre une chaîne de caractères et renvoyant un dictionnaire contenant le nombre d'occurrences de chaque caractère présent dans un texte dont:
\begin{itemize}
	\item les clefs sont les caractères rencontrés dans le texte (et seulement ceux-là) et
	\item les valeurs le nombre de leurs occurrences.
\end{itemize}
Pour implémenter cela, vous aurez besoin :
\begin{itemize}
	\item de la fonction \lst{dict.has\_key( dico , clef )} qui permet de tester si une clef existe dans le dictionnaire. En effet, lors de l'analyse du texte, pour chaque caractère lu, vous devrez tester si il a déjà été vu. Si il a déjà été vu vous incrémenterez son nombre d'occurrences, Si il n'a jamais été vu, vous créerez une nouvelle clef dans le dictionnaire.
	\item de la fonction \lst{dict.keys( dico )} qui renvoie la liste des clefs du dictionnaire \lst{dict}. Cette fonction vous permettra de passer en revue le contenu du dictionnaire pour l'affichage final.
\end{itemize}
Vous donnerez un script de test qui affichera le tableau des occurrences.
\begin{correction}
Avec commentaires:
\begin{lstlisting}
def occurrences(texte) :
	"""
	Renvoie un dictionnaire contenant le nombre d'occurrence de chaque
	caractere du texte passe en parametre
	-----------
	Input :
		texte &lt;string&gt; : le texte a parcourir sur lequel est mesure les
		                    occurrences des carcateres
	-----------
	Output :
		Un dictionnaire dont:
			- les clefs sont les caracteres presents dans le texte,
			- les valeurs sont le nombre d'occurrences de ce caractere
			  dans le texte.
	-----------
	Affichage :
		None
	"""
	# initialisation du dictionnaire des occurrences
	occurrences = {}
	
	# passage en revue de chaque caractere du texte
	for lettre in texte :
		
		# Si la clef existe (le caractere a deja ete rencontre)
		if dict.has_key( occurrences , lettre ) :
			
			# on augmente le nombre d'occurrences de ce caractere
			occurrences[ lettre ] += 1
		else:
			
			# sinon on ajoute une nouvelle entree dans le dictionnaire
			occurrences[ lettre ] = 1
	
	# valeur de retour
	return occurrences
\end{lstlisting}
Sans commentaires:
\begin{lstlisting}
def occurrences(texte) :
	occurrences = {}
	for lettre in texte :
		if dict.has_key( occurrences , lettre ) :
			occurrences[ lettre ] += 1
		else:
			occurrences[ lettre ] = 1
	return occurrences
\end{lstlisting}
\begin{lstlisting}
# message d'invite
print( 'Entrez votre texte' )
text = raw_input()

# calcul de l'occurrence de chaque caractere
occ = occurrences(texte)

# affichage de la frequence des caracteres
print( 'Tableau des occurrences des caractères:' )
print( 'Lettre | Occurrences' )
for lettre in dict.keys( occ ) :
	print( lettre + ' -&gt;  ' + str( occurrences[ lettre ] ) )
\end{lstlisting}
\end{correction}


%--------------------------------------------------------------------------------------------------------------
\exercice{Comptage des points à la Belote Coinchée}
\label{exo4}
La belote coinchée est un jeu qui se joue à 4 joueurs par équipe de 2 et un jeu de 32 cartes. Il se distingue de la Belote par un système d'annonce. Tout à tour, avant de commencer à poser les cartes chaque joueur "passe" ou "annonce" une couleur d'atout et le nombre de points qu'il pense faire en choisissant cet atout. Celui qui propose l'annonce la plus forte définit l'atout pour la partie. Lors du comptage des points en fin de partie, chaque carte remportée par une équipe est convertie en points. Le score d'une équipe correspond au nombre de points associés aux plis qu'elle a remporté. Les règles de calcul sont les suivantes:

\begin{center}
	\begin{tabular}{lll}
		\hline
		&amp;Nb de points&amp;Nb de points\\
		Figure&amp;à l'Atout&amp;Autre Couleur\\
		\hline
		As&amp;11&amp;11\\
		Roi&amp;4&amp;4\\
		Dame&amp;3&amp;3\\
		Valet&amp;20&amp;2\\
		Dix&amp;10&amp;10\\
		Neuf&amp;14&amp;0\\
		Huit&amp;0&amp;0\\
		Sept&amp;0&amp;0\\
		\hline
	\end{tabular}
\end{center}

\begin{enumerate}
	\item Définissez 2 dictionnaires \lst{Atout} et \lst{Autre} dont les couples (clef,valeur) sont respectivement la figure portée par la carte et le nombre de points associés à cette figure lorsqu'elle est de la couleur de l'atout ou d'une autre couleur.
	\item Définissez une fonction \lst{comptage()} prenant comme paramètre les 2 dictionnaires, une couleur d'atout et un ensemble de cartes. La fonction renvoie le nombre de points associés à cet ensemble de cartes. Les cartes seront passées comme une liste de tuples dont
		\begin{itemize}
			\item la première valeur correspond à la figure de la carte (As, Roi, Dame, Valet, Dix, Neuf, Huit, ou Sept) et
			\item la deuxième valeur correspond à la couleur de la carte (Pic, Coeur, Carreau, Trefle)
		\end{itemize}
	\item Calculez le nombre de points que les joueurs se partagent au cours d'une partie sachant que 10 points sont accordés à l'équipe qui remporte le dernier tour de jeu,
	\item Définissez une fonction \lst{affiche\_carte\_point} qui prend comme argument les 2 dictionnaires et la couleur d'atout  et affiche l'ensemble des 32 cartes et leur valeur.
\end{enumerate}
\begin{correction}
Définition des dictionnaires:
\begin{lstlisting}
Atout={'As':11,'Roi':4,'Dame':3,'Valet':20,'Dix':10,'Neuf':14,'Huit':0,'Sept':0}
Autre={'As':11,'Roi':4,'Dame':3,'Valet':2,'Dix':10,'Neuf':0,'Huit':0,'Sept':0}
\end{lstlisting}
Fonction de comptage avec commentaires:
\begin{lstlisting}
def comptage( cartes, couleur_atout, dico_atout, dico_autre ):
	"""
	Renvoie le nombre de points que donne le comptage des cartes.
	-----------
	Input :
		cartes &lt;list&gt;  : une liste de cartes. Une carte est definie comme un tuple
		                  de 2 elements.
		                      * le premier element est la figure de la carte
		                      * le deuxieme element est la couleur de la carte
		                      
		couleur_atout &lt;string&gt; : la couleur de l'atout
		
		dico_atout &lt;dict&gt; : le dictionnaire donnant la conversion entre
		                      la figure d'une carte et le nombre de points
		                      qui lui est associée à l'atout,
		                              
		dico_autre &lt;dict&gt; : le dictionnaire donnant la conversion entre
		                      la figure d'une carte et le nombre de points
		                      qui lui est associée si ce n'est pas de l'atout
	-----------
	Output :
		&lt;int&gt; : le nombre de points associés aux cartes
	-----------
	Affichage :
		None
	"""
	# initialisation du total des points
	total = 0
	
	# iteration sur les cartes
	for c in cartes:
		
		# Si c'est de l'atout
		if c[1] == couleur_atout :
			
			# utilise les regles de conversion pour l'atout
			total += dico_atout[ c[0] ]
		else:
			# utilise les regles de conversion normale
			total += dico_autre[ c[0] ]
	
	# valeur de retour
	return total
\end{lstlisting}
Fonction de comptage sans commentaires:
\begin{lstlisting}
def comptage( cartes, couleur_atout, dico_atout, dico_autre ):
	total = 0
	for c in cartes:
		if c[1] == couleur_atout :
			total += dico_atout[ c[0] ]
		else:
			total += dico_autre[ c[0] ]
	return total
\end{lstlisting}
Exemple d'utilisation:
\begin{lstlisting}
print( str( comptage(Atout,Autre,'Coeur',[('Valet','Coeur')]) ) )
20

print( str( comptage(Atout,Autre,'Coeur',[('Valet','Coeur'),('Dix','Pique')]) ) 
30

print( str( comptage(Atout,Autre,'Coeur',[('Valet','Trefle')]) ) )
2
\end{lstlisting}
Calcul de la somme des points en jeu:
\begin{lstlisting}
total = 10 # le bonus pour les gagnats du dernier tour de jeu
# comptage des points apportes par les cartes Atout
# compte une fois car il y a une seule couleur Atout
for pt in Atout.values():
	total += pt

# Comptage des points apportes par les autres cartes
# compte 3 fois car il y a 3 couleurs que ne sont pas de l'Atout
for pt in Autre.values():
	total += (3*pt)
	
# Affichage du nombre de points en jeu
print( 'Total des points mis en jeu = ' + str(total) )
\end{lstlisting}
Affichage des cartes et des points associés pour une couleur d'atout donnée.
Avec commentaires:
\begin{lstlisting}
def affiche_carte_point(couleur_atout ,dico_atout, dico_autre) :
	"""
	Affiche toutes les cartes du jeu (32) et leur valeur
	-----------
	Input :
		couleur_atout &lt;string&gt; : la couleur de l'atout
		
		dico_atout &lt;dict&gt; : le dictionnaire donnant la conversion entre
		                      la figure d'une carte et le nombre de points
		                      qui lui est associée à l'atout,
		                              
		dico_autre &lt;dict&gt; : le dictionnaire donnant la conversion entre
		                      la figure d'une carte et le nombre de points
		                      qui lui est associée si ce n'est pas de l'atout
	-----------
	Output :
		None
	-----------
	Affichage :
		Les cartes (Figure et couleur) et leur nombre de points
	"""
	# iteration sur les couleurs possibles
	for couleur in ['Pique','Coeur','Carreau','Trefle'] :
		
		# iteration sur les Figures possibles
		for figure in dico_atout.keys():
			
			# affichage de la carte et du nombre de points associé
			if couleur == couleur_atout:
				print( '('+figure+','+couleur+')-&gt;'+ str(dico_atout[ figure ]) )
			else:
				print( '('+figure+','+couleur+')-&gt;'+ str(dico_autre[ figure ]) )
\end{lstlisting}
Sans commentaires:
\begin{lstlisting}
def affiche_carte_point(couleur_atout ,dico_atout, dico_autre) :
	for couleur in ['Pique','Coeur','Carreau','Trefle'] :
		for figure in dico_atout.keys():
			if couleur == couleur_atout:
				print( '('+figure+','+couleur+')-&gt;'+ str(dico_atout[ figure ]) )
			else:
				print( '('+figure+','+couleur+')-&gt;'+ str(dico_autre[ figure ]) )
\end{lstlisting}
On remarquera peut-être ici que les clefs ne sont pas ordonnées (i.e. .keys() ne renvoie pas les clefs dans l'ordre utilisé dans le littéral de la définition).
\end{correction}

%--------------------------------------------------------------------------------------------------------------
\exercice{}
\label{exo5}
Les ARN sont formés d'une séquence de "bases" prises parmi un alphabet de 4 lettres (A, U, C, G).\\
Les protéines sont forment une séquence d'acides aminés pris parmi un alphabet de 20 lettres.\\
On considérera que chaque ARN peut être traduit en protéine si l'on connait le code de conversion appelé "code génétique".\\
Pour traduire un ARN en protéine, on découpe la séquence d'ARN en groupe de 3 bases (un codon). A chaque codon correspond un acide aminé unique. Traduire une séquence d'ARN en protéine et vice versa est donc un exercice de ré-écriture.\\
Par exemple, si l'on considère la séquence \lst{AUG GUU AGG UUG UGA} d'ARN, celle-ci est traduite par la séquence d'acide aminée suivante: \lst{MVRL-}\\Le détail de la traduction est donné par le tableau suivant:

\begin{center}
	\begin{tabular}{|cl|c|c|c|c|c|}
		\hline
		&amp;&amp;codon1&amp;codon2&amp;codon3&amp;codon4&amp;codon5\\
		ARN&amp;code à 3 lettres&amp;AUG&amp;GUU&amp;AGG&amp;UUG&amp;UGA\\
		\hline
		Code génétique&amp;&amp;$\downarrow$&amp;$\downarrow$&amp;$\downarrow$&amp;$\downarrow$&amp;$\downarrow$\\
		\hline
		Acide Aminés&amp;code à 1 lettre&amp;M&amp;V&amp;R&amp;L&amp;-\\
		\hline
	\end{tabular}
\end{center}
Par exemple, le premier codon d'ARN \lst{AUG}, code pour l'acide aminé Méthionine, dont le nom abrégé à une lettre est \lst{M}.\\

Afin de pouvoir travailler sur un vrai code génétique, vous allez devoir télécharger un fichier contenant le code et le lire dans Python. Le fichier qui vous est donné à la forme suivante:

\begin{lstlisting}
AAA		K
AAC		N
AAG		K
AAT		N
ACA		T
...
UUA		L
UUC		F
UUG		L
UUU		F
\end{lstlisting}

\begin{itemize}
	\item chaque ligne correspond à un codon (3 lettres de l'ARN)
	\item La première colonne donne les 3 lettres formant le codon d'ARN.
	\item La deuxième colonne donne la lettre (le nom) de l'acide aminé (protéine) correspondant à ce codon,
	\item Chaque colonne est séparée par une tabulation.
\end{itemize}


Le fichier \lst{CodeGenetique.tsv} téléchargeable à l'adresse:\\

\lst{http://www-lipn.univ-paris13.fr/\~{}santini/data/CodeGenetique.tsv}\\

Il doit être enregistré dans votre répertoire de travail.\\


\begin{question}
Définissez une fonction \lst{lire\_code\_genetique( 'fichier' )} qui prend en paramètre le nom d'un fichier de code génétique (son chemin) et qui renvoie un dictionnaire dont les clefs sont les codons (3 lettres de l'ARN) et les valeurs la lettre de l'acide aminé (protéine) correspondant.
\end{question}

Pour lire un fichier dans Python il faut connaître les opérations suivantes:
\begin{itemize}
	\item \lst{f\_in = open('nom\_du\_fichier' , 'r' )}\\ouvre le fichier en mode lecture(\lst{'r'}) dans la variable \lst{f\_in} et place un curseur de lecture au début de la première ligne,
	\item \lst{raw\_line = file.readline(f\_in)}\\lit \underline{une seule ligne du fichier}, stocke la ligne dans la variable \lst{raw\_line} sous la forme d'une chaîne de caractères et place le curseur de lecture au début de la ligne suivante,
	\item Lorsqu'on arrive à la fin du fichier la fonction \lst{file.readline(f\_in)} renvoie la chaîne de caractères vide \lst{''}.
\end{itemize}

Vous pourrez utiliser la fonction \lst{stringTokenizer()} vue dans un TD/TP précédent pour décomposer la ligne lue.

\begin{correction}
\begin{lstlisting}
def lire_code_genetique( fichier ):
	"""
	Renvoie un dictionnaire de code genetique
	-----------
	Input :
		fichier &lt;string&gt; :	le nom (chemin) contenant un code genetique
						Le fichier est en format TSV et comporte
						2 colonnes:
						- 1ere colonne : un codon forme de
									3 caracteres
						- 2eme colonne: la lettre de l'acide
									amine correspondant
	-----------
	Output :
		Un dictionnaire de couples (clef,valeur):
			- clef:	&lt;string&gt;	un codon (3 caracteres parmis A, U, G, C)
							exemple:	'AUG'
			- valeur:	&lt;string&gt;	le code d'un acide amine (1 caractere)
							exemple:	'M'
	-----------
	Affichage :
		None
	"""
	# initialisation du dictionnaire de retour
	code = {}
	
	# Ouverture du fichier
	f_in = open( fichier , 'r' )
	
	# lit la premiere ligne
	raw_line = file.readline( f_in )
	
	# tant que la ligne n'est pas vide (fin de fichier)
	while raw_line &lt;&gt; '' :
		# decompose la chaine de caractere en un tableau
		# dont le premier element est un codon et le deuxieme
		# la lettre d'un acide amine
		line = []
		stringTokenizer( raw_line , ['\n','\t'] , line)
		
		# Ajout d'une entree au dictionnaire
		code[ line[ 0 ] ] = line[ 1 ]
		
		# lecture de la ligne suivante
		raw_line = file.readline( f_in )
	
	# Valeur de retour
	return( code )	
\end{lstlisting}
Sans commentaires:
\begin{lstlisting}
def lire_code_genetique( fichier ):
	code = {}
	f_in = open( fichier , 'r' )
	raw_line = file.readline( f_in )
	while raw_line &lt;&gt; '' :
		line = []
		stringTokenizer( raw_line , ['\n','\t'] , line)
		code[ line[ 0 ] ] = line[ 1 ]
		raw_line = file.readline( f_in )
	return( code )	
\end{lstlisting}
Script de test:
\begin{lstlisting}
CodeGenetique = lire_code_genetique( 'CodeGenetique.tsv' )

CodeGenetique['AAA'] == 'K'
\end{lstlisting}
\end{correction}



\begin{question}
On rappelle que plusieurs codons (3 lettres de l'ARN) peuvent coder pour un même acide aminé (protéine).\\
Définissez une fonction \lst{reverse\_genetic\_code( code\_genetique )} qui prend pour paramètre le dictionnaire produit la fonction précédente \lst{lire\_code\_genetique()} et qui renvoie un dictionnaire dont les clefs sont les lettres de acides aminés et les valeur la liste (tableau) des codons (3 lettres de l'ARN) codant pour cet acide aminé.\\Il s'agit en quelque sorte "d'inverser" le dictionnaire sans perdre d'information.
A titre d'exemple les évaluations suivantes donnent les résultats indiqués:
\begin{lstlisting}
CodeGenetique = lire_code_genetique( 'CodeGenetique.tsv' )
Codon = reverse_genetic_code( CodeGenetique )

print( str( Codon['R'] ) )
['AGG', 'AGA', 'CGA', 'CGC', 'CGG', 'CGU']

print( str( Codon['E'] ) )
['GAA', 'GAG']
\end{lstlisting}
\end{question}

\begin{correction}
Avec commentaires:
\begin{lstlisting}
def reverse_genetic_code( code_genetique ) :
	"""
	Renvoie le dictionnaire des codons
	-----------
	Input :
		code_genetique	&lt;dict&gt;:	le dictionnaire du code genetique
			- clef:	&lt;string&gt;	un codon (3 caracteres parmis A, U, G, C)
							exemple:	'AUG'
			- valeur:	&lt;string&gt;	le code d'un acide amine (1 caractere)
							exemple:	'M'
	-----------
	Output :
		&lt;dict&gt; le dictionnaire des codons:
			- les clefs: 	&lt;string&gt; une lettre correspondant a un acide amine
					Exemple: 'R' 
			- les valeurs: 	&lt;list&gt;	la liste des codons codant pour cet acide amine
					Exemple: ['AGG', 'AGA', 'CGA', 'CGC', 'CGG', 'CGU']
	-----------
	Affichage :
		None
	"""
	# Initialisation du dictionnaire de retour
	dict_codon = {}
	
	# Parcours des codons qui sont les clef du dictionnaire
	# passe en parametre
	for codon in dict.keys( code_genetique ) :
		
		# la lettre de l'acide amine code par le codon
		# est donne par le dictionnaire passe en parametre
		acid_amine = code_genetique[ codon ]
		
		# si l'acide amine n'a pas encore ete vu
		if not dict.has_key( dict_codon , acid_amine ) :
			# ajoute une nouvelle entree
			dict_codon[ acid_amine ] = [ codon ]
		else :
			# sinon on rajoute le nouveau codon
			# a la liste des codon de l'acide amine
			dict_codon[ acid_amine ] = dict_codon[ acid_amine ] + [ codon ]
	
	# valeur de retour
	return( dict_codon )
\end{lstlisting}
Sans commentaires:
\begin{lstlisting}
def reverse_genetic_code( code_genetique ) :
	dict_codon = {}
	for codon in dict.keys( code_genetique ) :
		acid_amine = code_genetique[ codon ]
		if not dict.has_key( dict_codon , acid_amine ) :
			dict_codon[ acid_amine ] = [ codon ]
		else :
			dict_codon[ acid_amine ] = dict_codon[ acid_amine ] + [ codon ]
	return( dict_codon )
\end{lstlisting}
\end{correction}

%--------------------------------------------------------------------------------------------------------------
\begin{question}
Proposez une fonction \lst{ARN\_to\_Proteine( seq\_ARN , code\_genetique )} qui prend pour paramètre une séquence d'ARN et le dictionnaire du code génétique et renvoie la séquence de la protéine correspondante.
A titre d'exemple les évaluations suivantes donnent les résultats indiqués:
\begin{lstlisting}
print( ARN_to_Proteine( 'AUGGUCCUAAAACGAAGAACCUGGCCGUU' ,CodeGenetique) )
'MVLKRRTWP'
\end{lstlisting}
\end{question}


\begin{correction}
\begin{lstlisting}
def ARN_to_Proteine( seq_ARN , code_genetique ) :
	"""
	Renvoie la sequence proteique correspondant a une sequence d'ARN.
	-----------
	Input :
		seq_ARN			&lt;string&gt;:	une chaine de caracteres decrivant une sequence d'ARN
		code_genetique	&lt;dict&gt;:	le dictionnaire du code genetique
			- clef:	&lt;string&gt;	un codon (3 caracteres parmis A, U, G, C)
							exemple:	'AUG'
			- valeur:	&lt;string&gt;	le code d'un acide amine (1 caractere)
							exemple:	'M'
	-----------
	Output :
		&lt;string&gt; la sequence de la proteine codee par la sequence d'ARN
	-----------
	Affichage :
		None
	"""
	# Initialisation de la sequence proteique de retour
	seq_prot = ''
	
	# iterateur de parcours de la sequence d'ARN
	i = 0
	
	# parcours par groupe de 3 lettres = 1 codon
	while i &lt; len( seq_ARN ) / 3 :
		
		# lecture du codon courant
		codon = seq_ARN[ 3*i : 3*i + 3 ]
		
		# ajout a la sequence proteique de l'acide
		# amine codé par le codon courant
		seq_prot += code_genetique[ codon ]
		
		# iteration sur les codons
		i += 1
	
	# la sequence proteique
	return( seq_prot )
\end{lstlisting}
Sans commentaires
\begin{lstlisting}
def ARN_to_Proteine( seq_ARN , code_genetique ) :
	seq_prot = ''
	i = 0
	while i &lt; len( seq_ARN ) / 3 :
		codon = seq_ARN[ 3*i : 3*i + 3 ]
		seq_prot += code_genetique[ codon ]
		i += 1
	return( seq_prot )
\end{lstlisting}
\end{correction}
%--------------------------------------------------------------------------------------------------------------
\begin{question}
Proposez une fonction \lst{nombre\_de\_sequences( seq\_proteines , codons )} qui prend pour paramètre une séquence de protéine et le dictionnaire des codons et qui renvoie le nombre de séquences possibles d'ARN codant pour la proteine.
A titre d'exemple les évaluations suivantes donnent les résultats indiqués:
\begin{lstlisting}
print( nombre_de_sequences( 'MVLKRRTWP', Codon) )
27648
\end{lstlisting}
\end{question}


\begin{correction}
\begin{lstlisting}
def nombre_de_sequences( seq_prot , codons ) :
	"""
	Renvoie le nombre de sequence possible d'ARN codant pour la sequence
	proteique passee en parametre.
	-----------
	Input :
		seq_prot		&lt;string&gt;:	une chaine de caracteres decrivant une sequence de proteine
		codons 		&lt;dict&gt;:	le dictionnaire des codons:
			- les clefs: 	&lt;string&gt; une lettre correspondant a un acide amine
					Exemple: 'R' 
			- les valeurs: 	&lt;list&gt;	la liste des codons codant pour cet acide amine
					Exemple: ['AGG', 'AGA', 'CGA', 'CGC', 'CGG', 'CGU']
	-----------
	Output :
		&lt;int&gt; le nombre de sequences d'ARN possibles
	-----------
	Affichage :
		None
	"""
	# initialisation du nombre de sequences d'ARN possibles
	# avec le nombre de codon correspondant au premier
	# acide amine
	tot = len( codons[ seq_prot[0] ] )
	
	# iterateur sur les acides amines
	i = 1
	
	# parcours de la sequence de proteine
	while i &lt; len(seq_prot) :
		
		# combinatoire des codons
		tot *= len( codons[ seq_prot[i] ] )
		
		# iteration sur les acides amines
		i += 1
	return( tot )
\end{lstlisting}
Sans commentaires
\begin{lstlisting}
def nombre_de_sequences( seq_prot , codons ) :
	tot = len( codons[ seq_prot[0] ] )
	i = 1
	while i &lt; len(seq_prot) :
		tot *= len( codons[ seq_prot[i] ] )
		i += 1
	return( tot )
\end{lstlisting}
\end{correction}


%--------------------------------------------------------------------------------------------------------------
\exercice{Dictionnaire de dictionnaires}
Nous voulons ici définir un programme permettant de gérer un stock d'articles. Pour cela, nous voulons être capable:
\begin{itemize}
	\item d'ajouter une référence (prix, quantité, et couleur) dans le stock,
	\item de calculer le prix total du stock.
\end{itemize}
Pour cela:
\begin{question} 
Créez une fonction \lst{ajout\_reference()} sans paramètre qui renvoie un dictionnaire dont les couples \lst{clef-valeur} sont:
\begin{center}
\begin{tabular}{ll}
	\hline
	Clef&amp;Valeur\\
	\hline
	"Prix"&amp;&lt;float&gt;\\
	"Quantité"&amp;&lt;int&gt;\\
	"Couleur"&amp;&lt;string&gt;\\
	\hline
\end{tabular}
\end{center}
Pour paramétrer le dictionnaire renvoyé, la fonction demandera à l'utilisateur de saisir itérativement au clavier, les différentes valeurs.
\end{question}

\begin{correction}
\begin{lstlisting}
def ajout_reference():
	"""
	Initialise et renvoie le dictionnaire correspondant à une référence.
	-----------
	Input :
		None
	-----------
	Output :
		&lt;dict&gt; le dictionnaire correspondant a un article
			- clef:	&lt;string&gt;	"Prix", "Quantité" et "Couleur"
			- valeur:	le prix		&lt;int&gt;
					la quantité	&lt;float&gt;
					la couleur	&lt;string&gt;
	-----------
	Affichage :
		Message d'invite pour la saisie des valeurs
	"""
	# Message d'introduction
	print('Saisie d\'un nouvel article')
	
	# initialisation du dictionnaire de retour
	reference = {}
	
	# Saisie du prix
	print('Donner le prix')
	reference['Prix'] = float( raw_input() )
	
	# Saisie de la quantite
	print('Donner la quantite')
	reference['Quantite'] = float( raw_input() )
	
	# Saisie de la couleur
	print('Donner la couleur')
	reference['Couleur'] = str( raw_input() )
	
	# valeur de retour
	return( reference )
\end{lstlisting}
\end{correction}

\begin{question}
Définissez le programme principal permettant, de saisir plusieurs références, puis en fin de saisie, d'afficher le montant total du stock.
\end{question}

\begin{correction}
\begin{lstlisting}
# Définition du dictionnaire contenant le stock.
Stock = {}

# initialisation des numeros de reference
ref = 0

# Menu
menu = 0
while menu &lt;&gt; 2 :
	Stock[ref] = ajout_reference()
	# modification du nuero de la prochaine reference
	ref += 1
	print('Que voulez-vous faire?')
	menu = 0
	while not menu in [1,2]:
		print('Ajout reference: Tapez 1')
		print('Sortir:          Tapez 2')
		menu = int(raw_input())

# Calcul du montant du stock
tot = 0
for article in dict.values(Stock):
	tot += ( article['Prix'] * article['Quantite'])

print('Prix total du stock = '+str(tot))


\end{lstlisting}
\end{correction}
\begin{question}
Pour aller plus loin, vous pourrez enrichir le programme principal de fonctionnalités telles que:
\begin{itemize}
	\item supprimer une référence du stock,
	\item modifier la quantité d'une référence,
	\item Afficher l'état du stock,
	\item \dots
\end{itemize}
\end{question}

\end{serieexostd}

</pre></body></html>