-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathchercher.tex
More file actions
331 lines (208 loc) · 15.6 KB
/
Copy pathchercher.tex
File metadata and controls
331 lines (208 loc) · 15.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
\documentclass[11pt,class=report,crop=false]{standalone}
\usepackage[screen]{../python}
\begin{document}
%====================================================================
\chapitre{Chercher et remplacer}
%====================================================================
\objectifs{Chercher et remplacer sont deux tâches très fréquentes. Savoir les utiliser et comprendre comment elles fonctionnent te permettra d'être plus efficace.}
\index{chercher}
\index{remplacer}
\insertvideo{pfu9IJR0vZY}{Chercher et remplacer - partie 1}
\insertvideo{GL446gvcN-U}{Chercher et remplacer - partie 2}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Activité 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{activite}[Chercher]
\objectifs{Objectifs : apprendre différentes façons de chercher avec \Python.}
\begin{enumerate}
\item \textbf{L'opérateur \og{}in\fg{}.}
\index{in@\ci{in}}
La façon la plus simple de savoir si une sous-chaîne est présente dans une chaîne de caractères est d'utiliser l'opérateur \og{}\ci{in}\fg{}. Par exemple, l'expression :
\mycenterline{\ci{"PAS" in "ETRE OU NE PAS ETRE"}}
vaut \og{}vrai\fg{} car la sous-chaîne \mot{PAS} est bien présente dans la phrase
\mot{ETRE OU NE PAS ETRE}.
Déduis-en une fonction \ci{chercher_in(chaine,sous_chaine)} qui renvoie \og{}vrai\fg{} ou \og{}faux\fg{}, selon que la sous-chaîne est (ou non) présente dans la chaîne.
\item \textbf{La méthode \ci{find()}.}
\index{find@\ci{find}}
La méthode \ci{find()} s'utilise sous la forme \ci{chaine.find(sous_chaine)} et renvoie la position à laquelle la sous-chaîne a été trouvée.
Teste ceci sur l'exemple précédent. Que renvoie la fonction si la sous-chaîne n'est pas trouvée ?
\item \textbf{La méthode \ci{index()}.}
\index{index@\ci{index}}
La méthode \ci{index()} a la même utilité, elle s'utilise sous la forme \ci{chaine.index(sous_chaine)} et renvoie la position à laquelle la sous-chaîne a été trouvée.
Teste ceci sur l'exemple précédent. Que renvoie la fonction si la sous-chaîne n'est pas trouvée ?
\item \textbf{Ta fonction \ci{chercher()}.}
Écris ta propre fonction \ci{chercher(chaine,sous_chaine)} qui renvoie la position de départ de la sous-chaîne si elle est trouvée (et renvoie \ci{None} si elle ne l'est pas).
Tu n'as pas le droit d'utiliser les fonctions \Python{}, tu as seulement droit de tester si deux caractères sont égaux !
\end{enumerate}
\end{activite}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Activité 2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{activite}[Remplacer]
\objectifs{Objectifs : remplacer des portions de texte par d'autres.}
\begin{enumerate}
\item La méthode \ci{replace()} s'utilise sous la forme :
\mycenterline{\ci{chaine.replace(sous_chaine,nouv_sous_chaine)}}
\index {replace@\ci{replace}}
Chaque fois que la séquence \ci{sous_chaine} est trouvée dans \ci{chaine}, elle est remplacée par \ci{nouv_sous_chaine}.
Transforme la phrase \mot{ETRE OU NE PAS ETRE} en \mot{ETRE OU NE PLUS ETRE}, puis en
\mot{AVOIR OU NE PLUS AVOIR}.
\item Écris ta propre fonction \ci{remplacer()} que tu appelleras sous la forme suivante :
\mycenterline{\ci{remplacer(chaine,sous_chaine,nouv_sous_chaine)}}
et qui remplace seulement la première occurrence de \ci{sous_chaine} trouvée. Par exemple \ci{remplacer("ABBA","B","XY")} renvoie \ci{"AXYBA"}.
\emph{Indication.} Tu peux utiliser ta fonction \ci{chercher()} de l'activité précédente pour trouver la position de départ de la séquence à remplacer.
\item Améliore ta fonction pour construire une fonction \ci{remplacer_tout()} qui remplace cette fois toutes les occurrences rencontrées.
\end{enumerate}
\end{activite}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{cours}[Expressions rationnelles \emph{regex}]
\index{regex@\emph{regex}}
\index{expression rationnelle}
Les \defi{expressions rationnelles} permettent de chercher des sous-chaînes avec une plus grande liberté : par exemple on autorise un caractère joker ou bien plusieurs choix possibles pour un caractère.
Il existe plein d'autres possibilités, mais nous étudions seulement ces deux-là.
\begin{enumerate}
\item On s'autorise une lettre joker symbolisée par un point \og \mot{.} \fg{}. Par exemple si on cherche l'expression \og \mot{P\,.\,R} \fg{} alors :
\begin{itemize}
\item \mot{PAR}, \mot{EMPIRE}, \mot{PURE}, \mot{APPORTE} contiennent ce groupe (par exemple pour \mot{PAR} le point joue le rôle de \mot{A}),
\item mais pas les mots \mot{CAR}, \mot{PEUR}, \mot{RAP}.
\end{itemize}
\item On cherche toujours des groupes de lettres, on s'autorise maintenant plusieurs options. Par exemple \og \mot{[CT]} \fg{} signifie \og \mot{C} ou \mot{T} \fg{}. Ainsi le groupe de lettres \og \mot{[CT]O} \fg{} correspond aux groupes de lettres \og \mot{CO} \fg{} ou \og \mot{TO} \fg{}. Ce groupe est donc contenu dans \mot{TOTEM}, \mot{COTE}, \mot{TOCARD} mais pas dans \mot{VOTER}. De même \og \mot{[ABC]} \fg{} désignerait \og \mot{A} ou \mot{B} ou \mot{C} \fg{}.
% \item On cherche maintenant des groupes de lettres qui ne contiennent pas certaines lettres données. Un point d'exclamation devant une lettre signifie que l'on ne veut pas cette lettre. Par exemple \og p\!!a \fg{} correspond à un groupe de lettres avec un \og p \fg{} suivi d'une lettre \emph{qui n'est pas} un \og a \fg{}. Par exemple \mot{pitre} contient \og p\!!a \fg{} mais pas \mot{papa}. Par contre \mot{papi} le contient grâce aux deux lettres \og pi \fg{}. Autre exemple avec \og \!!ap \fg{} : on cherche une lettre qui n'est pas un \og a \fg{} et qui est suivie d'un \og p \fg{}.
\end{enumerate}
\bigskip
Nous utiliserons les expressions rationnelles à travers la commande : \mycenterline{\ci{python_regex_chercher(chaine,exp)}}
\index{module!re@\ci{re}}
\begin{lstlisting}
from re import *
def python_regex_chercher(chaine,exp):
trouve = search(exp,chaine)
if trouve:
return trouve.group(), trouve.start(), trouve.end()
else:
return None
\end{lstlisting}
Programme-la et teste-la. Elle renvoie : (1) la sous-chaîne trouvée, (2) la position de début et (3) la position de fin.
\begin{fonctionpython}[\ci{python : re.search() - python_regex_chercher()}]
Usage : \ci{search(exp,chaine)} \\
\hspace*{9ex} ou \ci{python_regex_chercher(chaine,exp)}\\
Entrée : une chaîne de caractères \ci{chaine} et une expression rationnelle \ci{exp} \\
Sortie : le résultat de la recherche (la sous-chaîne trouvée, sa position de début, celle de fin)
\medskip
Exemple avec \ci{chaine = "ETRE OU NE PAS ETRE"}
\begin{itemize}
\item avec \ci{exp = "P.S"}, alors \ci{python_regex_chercher(chaine, exp)} renvoie
\ci{('PAS', 11, 14)}.
\item avec \ci{exp = "E..E"}, la fonction renvoie
\ci{('ETRE', 0, 4)}.
\item avec \ci{exp = "[OT]U"}, la fonction renvoie
\ci{('OU', 5, 7)}.
\item avec \ci{exp = "[MN]..P[AI]S"}, la fonction renvoie \ci{('NE PAS', 8, 14)}.
\end{itemize}
\end{fonctionpython}
\end{cours}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Activité 3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{activite}[Expressions rationnelles \emph{regex}]
\objectifs{Objectifs : programmer la recherche d'expressions rationnelles simples.}
\begin{enumerate}
\item Programme ta fonction \ci{regex_chercher_joker(chaine,exp)}
qui cherche une sous-chaîne qui peut contenir un ou plusieurs jokers \og{}\mot{.}\fg{}.
La fonction doit renvoyer : (1) la sous-chaîne trouvée, (2) la position de début et (3) la position de fin (comme pour la fonction \ci{python_regex_chercher()} ci-dessus).
\item Programme ta fonction \ci{regex_chercher_choix(chaine,exp)}
qui cherche une sous-chaîne qui peut contenir un ou plusieurs choix contenus dans des balises \og{}\mot{[]}\fg{}. La fonction doit de nouveau renvoyer : (1) la sous-chaîne trouvée, (2) la position de début et (3) la position de fin.
\emph{Indication.} Tu peux commencer par écrire une fonction \ci{genere_choix(exp)} qui génère toutes les chaînes possibles à partir de \ci{exp}. Par exemple si
\ci{exp = "[AB]X[CD]Y"} alors \ci{genere_choix(exp)} renvoie la liste formée de :
\ci{"AXCY"}, \ci{"BXCY"}, \ci{"AXDY"} et \ci{"BXDY"}.
\end{enumerate}
\end{activite}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\rzero}{{\color{red}\textbf{0}}}
\newcommand{\run}{{\color{blue}\textbf{1}}}
\begin{cours}[Remplacer des $0$ et des $1$ et recommencer !]
On considère une \og{}phrase\fg{} composée de seulement deux lettres possibles
\rzero{} et \run. Dans cette phrase nous allons chercher un motif (une sous-chaîne) et le remplacer par un autre.
\begin{exemple}
Appliquer la transformation \rzero\run{} $\rightarrow$ \run\rzero{}
à la phrase \run\rzero\run\run\rzero.
On lit la phrase de gauche à droite, on trouve le premier motif \rzero\run{} à partir de la seconde lettre, on le remplace par \run\rzero{} :
\mycenterline{\run(\rzero\run)\run\rzero{} \quad $\longmapsto$ \quad \run(\run\rzero)\run\rzero}
On peut recommencer à partir du début de la phrase obtenue, avec toujours la même transformation \rzero\run{} $\rightarrow$ \run\rzero{} :
\mycenterline{\run\run(\rzero\run)\rzero{} \quad $\longmapsto$ \quad \run\run(\run\rzero)\rzero}
Le motif \rzero\run{} n'apparaît plus dans la phrase \run\run\run\rzero\rzero{} donc
la transformation \rzero\run{} $\rightarrow$ \run\rzero{} laisse maintenant cette phrase inchangée.
Résumons : voici l'effet de la transformation itérée \rzero\run{} $\rightarrow$ \run\rzero{} à la phrase \run\rzero\run\run\rzero{} :
\mycenterline{\run\rzero\run\run\rzero{} \quad $\longmapsto$ \quad \run\run\rzero\run\rzero{} \quad $\longmapsto$ \quad \run\run\run\rzero\rzero}
\end{exemple}
\begin{exemple}
Appliquer la transformation \rzero\rzero\run{} $\rightarrow$ \run\run\rzero\rzero{}
à la phrase \rzero\rzero\run\run.
Une première fois :
\mycenterline{(\rzero\rzero\run)\run{} \quad $\longmapsto$ \quad (\run\run\rzero\rzero)\run}
Une seconde fois :
\mycenterline{\run\run(\rzero\rzero\run) \quad $\longmapsto$ \quad \run\run(\run\run\rzero\rzero)}
Et ensuite la transformation ne modifie plus la phrase.
\end{exemple}
\begin{exemple}
Voyons un dernier exemple avec la transformation \rzero\run{} $\rightarrow$ \run\run\rzero\rzero{} pour la phrase de départ \rzero\rzero\rzero\run{}:
\mycenterline{
\rzero\rzero\rzero\run{} \quad $\longmapsto$ \quad
\rzero\rzero\run\run\rzero\rzero{} \quad $\longmapsto$ \quad
\rzero\run\run\rzero\rzero\run\rzero\rzero{} \quad $\longmapsto$ \quad
\run\run\rzero\rzero\run\rzero\rzero\run\rzero\rzero{} \quad $\longmapsto$ \quad $\cdots$}
On peut itérer la transformation, pour obtenir des phrases de plus en plus longues.
\end{exemple}
\end{cours}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Activité 4
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{activite}[Itérations de remplacements]
\objectifs{Objectifs : étudier quelques transformations et leurs itérations.}
On considère ici uniquement des transformations du type \rzero$^a$\run$^b$ $\rightarrow$ \run$^c$\rzero$^d$, c'est-à-dire un motif avec d'abord des \rzero{} puis des \run{} est remplacé par un motif avec d'abord des \run{} puis des \rzero.
\begin{enumerate}
\item \textbf{Une itération.}
En utilisant ta fonction \ci{remplacer()} de l'activité 1, vérifie les exemples précédents. Vérifie bien que tu ne remplaces qu'un motif à chaque étape (celui le plus à gauche).
Exemple : la transformation \rzero\run{} $\rightarrow$ \run\rzero{} appliquée à la phrase \run\rzero\run, se calcule par \ci{remplacer("101","01","10")} et renvoie \ci{"110"}.
\item \textbf{Plusieurs itérations.}
Programme une fonction \ci{iterations(phrase,motif,nouv_motif)} qui, à partir d'une phrase, itère la transformation. Une fois que la phrase est stabilisée, la fonction renvoie le nombre d'itérations effectuées ainsi que la phrase obtenue. Si le nombre d'itérations n'a pas l'air de s'arrêter (par exemple quand il dépasse $1000$) alors renvoie \ci{None}.
Exemple. Pour la transformation \rzero\rzero\run\run{} $\rightarrow$ \run\run\rzero\rzero{} et la phrase \rzero\rzero\rzero\rzero\run\run\rzero\run\run, les phrases obtenues sont :
{\small
\mycenterline{
\ \rzero\rzero\rzero\rzero\run\run\rzero\run\run{} $\underset{\mathbf{1}}{\longmapsto}$
\rzero\rzero\run\run\rzero\rzero\rzero\run\run{} $\underset{\mathbf{2}}{\longmapsto}$
\run\run\rzero\rzero\rzero\rzero\rzero\run\run{} $\underset{\mathbf{3}}{\longmapsto}$
\run\run\rzero\rzero\rzero\run\run\rzero\rzero{} $\underset{\mathbf{4}}{\longmapsto}$
\run\run\rzero\run\run\rzero\rzero\rzero\rzero{} $\longmapsto$
idem
}
}
\medskip
Pour cet exemple l'appel à la fonction \ci{iterations()} renvoie alors $4$ (le nombre de transformations avant stabilisation) et \ci{"110110000"} (la phrase stabilisée).
\item \textbf{Le plus d'itérations possibles.}
Programme une fonction \ci{iteration_maximale(p,motif,nouv_motif)}
qui, parmi toutes les phrases de longueur $p$, cherche l'une de celles qui met le plus de temps à se stabiliser. Cette fonction renvoie :
\begin{itemize}
\item le nombre maximum d'itérations,
\item la première phrase qui réalise ce maximum,
\item la phrase stabilisée correspondante.
\end{itemize}
Exemple : pour la transformation \rzero\run{} $\rightarrow$ \run\rzero\rzero, parmi toutes les phrases de longueur $p=4$, le maximum d'itérations possibles est $7$. Un tel exemple de phrase est \rzero\run\run\run, qui va se stabiliser (après 7 itérations donc) en \run\run\run\rzero\rzero\rzero\rzero\rzero\rzero\rzero\rzero.
Ainsi la commande \ci{iteration_maximale(4,"01","100")} renvoie :
\mycenterline{\ci{7, '0111', '11100000000'}}
\emph{Indication.} Pour générer toutes les phrases de longueur $p$ formées de \rzero{} et \run{}, tu peux consulter la fiche \og{}Binaire II\fg{} (activité 3).
\item \textbf{Catégories de transformations.}
\begin{itemize}
\item \textbf{Transformation linéaire.}
Vérifie expérimentalement que la transformation \rzero\rzero\run\run{} $\rightarrow$ \run\run\rzero{} est \emph{linéaire}, c'est-à-dire que pour toutes les phrases de longueur $p$, il y aura au plus de l'ordre de $p$ itérations au maximum. Par exemple pour $p=10$, quel est le nombre maximum d'itérations ?
\item \textbf{Transformation quadratique.}
Vérifie expérimentalement que la transformation \rzero\run{} $\rightarrow$ \run\rzero{} est \emph{quadratique}, c'est-à-dire que pour toutes les phrases de longueur $p$, il y aura au plus de l'ordre de $p^2$ itérations au maximum. Par exemple pour $p=10$, quel est le nombre maximum d'itérations ?
\item \textbf{Transformation exponentielle.}
Vérifie expérimentalement que la transformation \rzero\run{} $\rightarrow$ \run\run\rzero{} est \emph{exponentielle}, c'est-à-dire que pour toutes les phrases de longueur $p$, il y aura un nombre fini d'itérations, mais que ce nombre peut être très grand (beaucoup plus grand que $p^2$) avant stabilisation. Par exemple pour $p=10$, quel est le nombre maximum d'itérations ?
\item \textbf{Transformation sans fin.}
Vérifie expérimentalement que pour la transformation \rzero\run{} $\rightarrow$ \run\run\rzero\rzero{}, il existe des phrases qui ne vont jamais se stabiliser.
\end{itemize}
\end{enumerate}
\end{activite}
\end{document}