Pour faire ce TP on utilisera Spyder (Documentation Spyder). On utilisera PythonTutor pour tester les fonctions et observer la mémoire.
On téléchargera l’archive ressources_activite_5.zip et on l’extraira dans le
dossier de votre choix sur l’ordinateur (Extraire un fichier sous Windows 10).
Vous ouvrirez dans Spyder le fichier activite_5.py
contenu dans l’archive.
Lire la section sur les fichiers dans le cours .
Le but de cette section est d’implémenter une fonction remplacer
, qui remplace
une chaîne de caractère par une autre dans un fichier de texte.
activite_5.py
dans lequel vous
travaillez ?star_wars.txt
disponible dans le
dossier txt
du dossier de ressources extrait sur votre ordinateur ?star_wars.txt
si on se situe dans le
dossier de ressources extrait sur votre ordinateur ?Implémentez les fonctions suivantes :
nb_c
prend en entrée un chemin de fichier et renvoie le nombre de
caractères écrits dans le fichier.nb_m
prend en entrée un chemin de fichier et renvoie le nombre de mots
écrits dans le fichier.nb_l
prend en entrée un chemin de fichier et renvoie le nombre de lignes
écrites dans le fichier.On testera les fonctions sur le fichier star_wars.txt
qui contient 14939
caractères, 2092 mots et 73 lignes.
def nb_c(chemin) :
"""
Entrées : chemin, une chaîne de caractère correspondant au
chemin d'un fichier.
Sortie : le nombre de caractères écrits dans le fichier.
"""
fichier = open(chemin, 'r')
texte = fichier.read()
fichier.close()
return len(texte)
def nb_m(chemin) :
"""
Entrées : chemin, une chaîne de caractère correspondant au
chemin d'un fichier.
Sortie : le nombre de mots écrits dans le fichier.
"""
fichier = open(chemin, 'r')
texte = fichier.read()
mots = texte.split()
fichier.close()
return len(mots)
def nb_l(chemin) :
"""
Entrées : chemin, une chaîne de caractère correspondant au
chemin d'un fichier.
Sortie : le nombre de lignes écrites dans le fichier.
"""
fichier = open(chemin, 'r')
lignes = fichier.readlines()
fichier.close()
return len(lignes)
Implémentez une fonction voyelles
qui prend en entrée le chemin vers un
fichier et renvoie le texte original où seules les voyelles sont conservées.
Vous proposerez deux implémentations :
read
.
On construira donc une liste de caractère, v
qu’on convertira en chaîne de
caractère à l’aide de l’instruction ''.join(v)
.Dans la console Spyder, vous récupérer la sortie de la fonction voyelles
sur le fichier citation.txt
dans le dossier txt
. Vous écrirez la chaîne
obtenue dans un fichier voyelles.txt
dans le dossier txt
.
def voyelles(chemin) :
"""
Entrées : chemin, une chaîne de caractère correspondant au
chemin d'un fichier.
Sortie : le texte original où seules les voyelles sont conservées
"""
fichier = open(chemin, 'r')
v = [ c for c in fichier.read() if c in "AEIOUYaeiouy" ]
voyelles = ''.join(v)
fichier.close()
return voyelles
def voyelles(chemin) :
"""
Entrées : chemin, une chaîne de caractère correspondant au
chemin d'un fichier.
Sortie : le texte original où seules les voyelles sont conservées
"""
fichier = open(chemin, 'r')
voyelles = ""
for ligne in fichier :
for c in ligne :
if c in "AEIOUYaeiouy" :
voyelles += c
fichier.close()
return voyelles
s = voyelles("txt/citation.txt")
fichier = open("txt/voyelles.txt", "w")
fichier.write(s)
fichier.close()
Il existe un grand nombre d’algorithmes ayant pour but rechercher de chaîne de caractères dans un texte. On se propose d’utiliser celui de la fenêtre glissante.
Pour chercher un mot de taille $n$ dans un texte de taille $m$, on vérifie pour chaque position $i < m-n$ du texte si les caractère $i$, $i+1$, …, $i+n-1$ forment le mot recherché.
Implémentez une fonction rechercher_i
qui prend trois entrées : une chaîne de
caractère s
, une chaîne de caractère w
et un entier i
et qui renvoie
un booléen vrai si et seulement si le mot w
est une sous-chaîne de s
à
l’indice i
de s
.
Testez votre fonction pour les entrées suivantes :
s = "Nadine aime la grenadine", w = "dine", i = 2
s = "Nadine aime la grenadine", w = "dine", i = 20
s = "Nadine aime la grenadine", w = "dine", i = 1
s = "Nadine", w = "Nadine", i = 0
s = "Yooooohoooo !", w = "ooo", i = 1
s = "Yooooohoooo !", w = "ooo", i = 2
s = "Yooooohoooo !", w = "ooo", i = 8
def recherche_i(s, w, i) :
"""
Entrées : s, w deux chaînes de caractères et i un indice de s.
Sortie : booléen vrai ssi w est une sous-chaîne de s à la position i.
"""
if i > len(s) - len(w) :
return False
for k,c in enumerate(w) :
if c != s[i+k] :
return False
return True
recherche_i
Implémentez une fonction rechercher_0
qui prend trois entrées : une chaîne de
caractère s
, une chaîne de caractère w
et un entier d
et qui cherche le
mot w
dans le texte s
à partir du caractère d’indice d
. La sortie de la
fonction sera l’indice le plus petit de s
où se trouve la première lettre du
mot w
dans s
, -1 si w
n’est pas dans s
.
Pour implémentez cette fonction vous utiliserez la fonction rechercher_i
de
l’exercice précédent.
Testez votre fonction pour les entrées suivantes :
s = "Nadine aime la grenadine", w = "dine", d = 0
s = "Nadine aime la grenadine", w = "dine", d = 20
s = "Nadine aime la grenadine", w = "dine", d = 2
s = "Nadine", w = "Nadine", d = 0
s = "Yooooohoooo !", w = "ooo", d = 0
s = "Yooooohoooo !", w = "ooo", d = 2
s = "Yooooohoooo !", w = "ooo", d = 8
def rechercher_0(s, w, d) :
"""
Entrées : s, w deux chaînes de caractères et d un indice de s.
Sortie : i >= d , le plus petit indice de s tel que w est une
sous-chaîne de s à la position i.
"""
if len(w) > 0 :
for i in range(d,len(s)-len(w)+1) :
if recherche_i(s,w,i) :
return i
return -1
Implémentez une fonction rechercher
qui prend trois entrées : une chaîne de
caractère s
, une chaîne de caractère w
et un entier d
et qui cherche le
mot w
dans le texte s
à partir du caractère d’indice d
. La sortie de la
fonction sera l’indice le plus petit de s
où se trouve la première lettre du
mot w
dans s
, -1 si w
n’est pas dans s
.
def rechercher(s,w,d) :
"""
Entrées : s, w deux chaînes de caractères et d un indice de s.
Sortie : i >= d , le plus petit indice de s tel que w est une
sous-chaîne de s à la position i.
"""
if len(w) > 0 :
for i in range(d,len(s)-len(w)+1) :
j = 0
while j < len(w) and w[j] == s[i+j] :
j += 1
if j == len(w) :
return i
return -1
Testez votre fonction pour les entrées données dans la question précédentes.
En utilisant la fonction rechercher
de la question précédente, implémentez une
fonction rechercher_tout
qui prend deux entrées : une chaîne de
caractère s
et une chaîne de caractère w
. La sortie de la
fonction sera la liste des indices de s
où se trouve la première lettre d’un
mot w
dans s
.
On fera attention que deux mots w
ne se superpose pas. Si c’est le cas on
prendra uniquement l’indice le plus petit. e.g pour le texte : "nananadine"
,
si on cherche "nana"
on trouvera deux positions, 0 et 2. Mais la lettre en
position 2 est déjà une lettre de la première occurrence de “nana”, on renverra
uniquement la position 0. Cela évitera les conflits lorsqu’il s’agira de
remplacer le mot "nana"
def rechercher_tout(s,w) :
"""
Entrées : s, w deux chaînes de caractères.
Sortie : la liste des indices i, tel que w est une sous-chaîne de s à
la position i.
"""
L = []
i = rechercher(s,w,0)
while i != -1 :
L.append(i)
i = rechercher(s,w,i+len(w))
return L
Testez votre fonction pour les entrées suivantes :
s = "Nadine aime la grenadine", w = "dine"
s = "Nadine", w = "Nadine"
s = "Yooooohoooo !", w = "ooo"
En utilisant la console Spyder et la fonction rechercher_tout
donnez la liste
des positions où on peut trouver le mot "nadine"
dans le fichier
"txt/texte_interessant.txt"
.
fichier = open("txt/texte_interressant.txt", "r")
texte = fichier.read()
rechercher_tout(texte,"nadine")
[32, 89, 124, 183, 334, 670, 757, 858, 900, 1095, 1320, 1409, 1540, 2147, 2428, 2632, 2948, 3241, 3695, 3762, 4048, 4569, 4792]
En utilisant la fonction rechercher_tout
de la question précédente,
implémentez une fonction remplacer
qui prend trois entrées : une chaîne de
caractère s
, une chaîne de caractère w
et une chaîne de caractère v
. La
sortie de la fonction sera le texte dans le quel toutes les occurrences de w
seront remplacées par celle de v
.
Il existe plusieurs manière de résoudre ce problème. Les indications ci-dessous ne sont pas forcément utile pour toutes les solutions.
On pourra commencer par supposer que w
et v
sont de même longueurs. Pour
ensuite gérer le cas où v
et w
sont de longueurs différentes on conservera
le décalage induit sur les indices par les remplacements déjà effectués.
On rappelle qu’on peut passer d’une chaîne de caractère à une liste de caractère
grâce à list(s)
. On peut aussi passer d’une liste de caractère à une chaîne de
caractère en faisant ''.join(L)
.
On rappel qu’on peut remplacer plusieurs éléments consécutifs d’une liste
par une autre liste grâce aux slices : L[12:21] = [1,2,4]
.
def remplacer(s,w,v) :
"""
Entrées : s, w, v trois chaînes de caractères.
Sortie : une copie de s chaque occurrence de w est remplacée par v.
"""
L = rechercher_tout(s,w)
s_remplace = list(s)
dec = 0
for i in L :
s_remplace[i+dec:i+dec+len(w)] = v
dec += len(v)-len(w)
return ''.join(s_remplace)
En utilisant la console Spyder et la fonction remplacer
remplacer toutes les
occurrences du mot "Force"
par "Nadine"
dans le fichier "txt/star_wars.txt"
et
écrivez un fichier "txt/nadine_wars.txt"
avec le résultat.
fichier = open("txt/star_wars.txt", "r")
texte = fichier.read()
texte_nadine = remplacer(texte,"Force","Nadine")
fichier_nadine = open("txt/nadine_wars.txt","w")
fichier_nadine.write(texte_nadine)
14984