#!/usr/bin/env python # coding: utf-8 #
#
TP noté n°1 - éléments de correction
# $\require{color}$ # $\require{xcolor}$ # $\newcommand{\myfbox}[1]{\fcolorbox{red}{white}{$\textrm{#1}$}}$ # $\require{stmaryrd}$ # $\newcommand{\ient}{[\![}$ # $\newcommand{\fient}{]\!]}$ # $\newcommand{\R}{\mathbb R}$ # $\newcommand{\K}{\mathbb K}$ # $\newcommand{\N}{\mathbb N}$ # $\newcommand{\C}{\mathbb C}$ # $\newcommand{\id}{\operatorname{Id}}$ # $\newcommand{\mat}{\operatorname{mat}}$ # $\newcommand{\sp}{\operatorname{Sp}}$ # $\newcommand{\In}{\operatorname{I}}$ # $\newcommand{\vect}{\operatorname{Vect}\ }$ # $\newcommand{\rg}{\operatorname{rg}}$ # $\newcommand{\tr}{\operatorname{Tr}}$ # $\newcommand{\dis}{\displaystyle}$ # $\renewcommand{\Im}{\operatorname{Im}}$ # $\newcommand{\im}{\operatorname{Im}}$ # $\newcommand{\bordermatrix}[3]{ \begin{matrix} \begin{matrix}#1\end{matrix} & \\ #3 & \hspace{-1em} \begin{matrix}#2\end{matrix} \end{matrix}}$ # $\newcommand{\fonction}[5]{#1\ \colon \left\{\begin{array}{ccl}#2 & \longrightarrow & #3\\#4 & \longmapsto & #5\end{array}\right.}$ # $\newcommand{\revdots}{\mathinner{\mkern1mu\raise1pt{\kern7pt\hbox{.}}\mkern2mu\raise4pt\hbox{.}\mkern2mu\raise7pt\hbox{.}\mkern1mu}}$ # $\newcommand{\q}[1]{{\bf Q #1}\rhd}$ # In[1]: import numpy as np #
# Barème et remarque générale #
# Toutes les questions sont sur 3 points, sauf la question 4 de l'exercice 1, qui est sur 1 point. Ainsi, votre note brute est sur 28. # Bien retravailler ce corrigé, notamment pour comprendre ce que l'on entendait par "adapter la fonction précédente" : il ne fallait pas réutiliser la fonction précédente ! #
# Exercice 1 - Nombre d'argent #
#
# L'idée était d'adapter un exercice sur la suite de Fibonacci. #
# $\q{1}$ On peut par exemple écrire la fonction suivante : #
# Revoir les affectations simultanées, c'est très pratiques en Python : #
# In[2]: def pell(n): if n == 0: return n else: u, v = 0, 1 for k in range(n - 1): u, v = v, u + 2 * v return v #
# On vous demandait de faire attention aux cas particuliers ! Ici notamment lorsque $n=0$... #
# In[3]: pell(0) # In[4]: pell(1) # In[5]: pell(4) # In[6]: [pell(n) for n in range(10)] # $\q{2}$ On adapte la fonction précédente de la manière suivante : # In[7]: def rapport(n): assert n > 0, "division par 0" u, v = 0, 1 for k in range(n): # attention à la gestion des indices ! u, v = v, u + 2 * v return v / u #
# Pour les cas "pathologiques", il vaut mieux utiliser une assertion. #
# In[8]: rapport(0) # In[9]: rapport(2) # In[10]: rapport(10) # $\q3$ On adapte encore la fonction précédente de la manière suivante : # In[11]: def argent(eps): u, v, w = 1, 2, 5 r, s = 2, 2.5 while abs(s - r) >= eps: u, v, w = v, w, 2 * w + v r, s = v / u, w / v return r #
# Ici, on a utilisé trois variables pour stocker 3 termes consécutifs de la suite pour pouvoir manipuler 2 rapports successifs. #
# In[12]: argent(1) # In[13]: argent(0.01) # $\q4$ On utilise la fonction précédente : # In[14]: round(argent(1e-5),4) # On peut conjecturer que $\myfbox{$\varphi_2 = 1+\sqrt2$.}$ #
# Exercice 2. Listes et listes de listes #
# $\q1$ On peut par exemple proposer la fonction suivante : # In[15]: def min1D(L): assert len(L) > 0 m, ind = L[0], 0 for i in range(1, len(L)): if L[i] <= m: m, ind = L[i], i return m, ind #
# Attention à bien gérer la condition pour renvoyer le plus grand indice correspondant au minimum, comme demandé dans l'énoncé. #
#
# Pour tester une si une liste est vide, il est préférable de tester si sa longueur est >0. #
# In[16]: min1D([3,4,3,6,2,5,2,8]) # $\q2$ On utilise des listes par compréhension (ce qui a également l'avantage de ne pas provoquer d'effet de bord) : # In[17]: def zero1D(L): assert len(L) > 0 m, ind = min1D(L) return [l - m for l in L] # In[18]: zero1D([4, 1, 6, 5]) # $\q3$ On utilise la fonction précédente : # In[19]: def Lzero2D(L): assert len(L)>0 return [zero1D(ligne) for ligne in L] # In[20]: L_ex = [[1, 2, 6, 3], [6, 12, 3, 42], [404, 2, 5, 1]] # In[21]: Lzero2D(L_ex) # In[22]: np.matrix(_) # pour mieux visualiser la matrice obtenue # $\q4$ Cette question est plus difficile ; on peut par exemple transposer la matrice pour pouvoir utiliser la fonction ```Lzero2D(L)``` : # In[23]: def Czero2D(L): assert len(L)>0 T = [[L[j][i] for j in range(len(L))] for i in range(len(L[0]))] T = Lzero2D(T) return [[T[j][i] for j in range(len(T))] for i in range(len(T[0]))] # In[24]: Czero2D(L_ex) # In[25]: np.matrix(_) #
# Exercice 3 - Chaînes de caractères et dictionnaires #
# $\q1$ On peut utiliser un compteur : # In[26]: def repete(S, c): cpt = 0 for lettre in S: if c == lettre: cpt += 1 if cpt == 2: return True # on arrete dès maintenant return False # atteint que si cpt reste < 2 #
# Attention à l'indentation, et au fait qu'il n'y a pas de "else" dans la boucle... #
# In[27]: repete("bonjour", "a") # In[28]: repete("bonjour", "j") # In[29]: repete("bonjour", "o") # $\q2$ On adapte la fonction précédente afin de créer un dictionnaire et de le mettre à jour progressivement : # In[30]: def dict_repete(S): dico = {} for lettre in S: if lettre in dico: dico[lettre] = True else: dico[lettre] = False return dico # In[31]: dict_repete("buongiorno") # **Variante :** on peut ne mettre à jour la valeur de ```dico[lettre]``` que quand elle vaut ```False``` : # In[32]: def dict_repete(S): dico = {} for lettre in S: if lettre not in dico: dico[lettre] = False elif not dico[lettre]: dico[lettre] = True return dico # In[33]: dict_repete("buongiorno")