#!/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")