Entrainement bibliothèque standard
Chaînes
Exercice : Egalité sans casse
Implantez la fonction suivante :
def egal_sans_casse(a, b):
"""a, b des chaînes ne contenant que des lettres, des chiffre et des espaces.
Returne True si a et b contiennent les mêmes caractères, en ignorant la casse.
Ignorer la casse veut dire que les majuscules et minuscules sont considérées comme des lettres similaires
compare_sans_casse("10aB", "10Ab") retourne True
compare_sans_casse("10AA", "10ab") retourne False
"""
pass
Code avec tests
lancer_tests = True ##Mettez a False pour ne pas lancer les tests
afficher_traces = False ##Mettez a True pour afficher la trace complète des erreurs dans le testss
def egal_sans_casse(a, b):
"""a, b des chaînes ne contenant que des lettres, des chiffre et des espaces.
Returne True si a et b contiennent les mêmes caractères, en ignorant la casse.
Ignorer la casse veut dire que les majuscules et minuscules sont considérées comme des lettres similaires
compare_sans_casse("10aB", "10Ab") retourne True
compare_sans_casse("10AA", "10ab") retourne False
"""
pass
############################################
############# PARTIE TESTS #############
############################################
import unittest
if not afficher_traces:
__unittest = True
def checktype(expr, res, exp):
assert type(res) == exp, expr + " doit retourner une valeur de type " + exp.__name__ + ", mais a retourné une valeur de type " + type(res).__name__
def checkval_equal(expr, res, exp):
str_exp = "'" +exp+ "'" if type(exp) == str else str(exp)
str_res = "'" +res+ "'" if type(res) == str else str(res)
assert res == exp, expr + " doit retourner " + str_exp + ", mais a retourné " + str_res
class Test_egal_sans_casse(unittest.TestCase):
def test_chaines_similaires_sans_casse(self):
res = egal_sans_casse('unechaine', 'unechaine')
checktype("egal_sans_casse('unechaine', 'unechaine')", res, bool)
checkval_equal("egal_sans_casse('unechaine', 'unechaine')", res, True)
def test_chaines_similaires_a_majuscules(self):
res = egal_sans_casse('UNECHAINE', 'unechaine')
checktype("egal_sans_casse('UNECHAINE', 'unechaine')", res, bool)
checkval_equal("egal_sans_casse('UNECHAINE', 'unechaine')", res, True)
def test_chaines_similaires_b_majuscules(self):
res = egal_sans_casse('unechaine', 'UNECHAINE')
checktype("egal_sans_casse('unechaine', 'UNECHAINE')", res, bool)
checkval_equal("egal_sans_casse('unechaine', 'UNECHAINE')", res, True)
def test_chaines_similaires_avec_casse(self):
res = egal_sans_casse('UneChAinE', 'UnEChaine')
checktype("egal_sans_casse('UneChAinE', 'UnEChaine')", res, bool)
checkval_equal("egal_sans_casse('UneChAinE', 'UnEChaine')", res, True)
def test_chaines_differentes(self):
res = egal_sans_casse('une chaine', 'unechaine')
checktype("egal_sans_casse('une chaine', 'unechaine')", res, bool)
checkval_equal("egal_sans_casse('une chaine', 'unechaine')", res, False)
if __name__ == '__main__':
s = unittest.TestLoader().loadTestsFromTestCase(Test_egal_sans_casse)
unittest.TextTestRunner().run(s)
L'opérateur ==
permet de comparer deux chaînes
Les méthodes lower()
et upper()
du type str
permettent de mettre une chaîne toute en minuscules et toute en majuscule respectivement.
L'idée est d'appeler lower()
ou upper()
sur les deux chaînes avant des les comparer :
def egal_sans_casse(a, b):
"""a, b des chaînes ne contenant que des lettres, des chiffre et des espaces.
Returne True si a et b contiennent les mêmes caractères, en ignorant la casse.
Ignorer la casse veut dire que les majuscules et minuscules sont considérées comme des lettres similaires
compare_sans_casse("10aB", "10Ab") retourne True
compare_sans_casse("10AA", "10ab") retourne False
"""
return a.lower() == b.lower()
def egal_sans_casse(a, b):
"""a, b des chaînes ne contenant que des lettres, des chiffre et des espaces.
Returne True si a et b contiennent les mêmes caractères, en ignorant la casse.
Ignorer la casse veut dire que les majuscules et minuscules sont considérées comme des lettres similaires
compare_sans_casse("10aB", "10Ab") retourne True
compare_sans_casse("10AA", "10ab") retourne False
"""
return a.upper() == b.upper()
Exercice : rhube
Implantez la fonction suivante :
def rhube(a):
"""a une chaîne
Retourne une copie de a ou tous les 'm' sont remplacés par des 'b'.
rhube("j'aime les morceaux de morue") retourne "j'aibe les borceaux de borue"
"""
pass
Code avec tests
lancer_tests = True ##Mettez a False pour ne pas lancer les tests
afficher_traces = False ##Mettez a True pour afficher la trace complète des erreurs dans le testss
def rhube(a):
"""a une chaîne
Retourne une copie de a ou tous les 'm' sont remplacés par des 'b'.
rhube("j'aime les morceaux de morue") retourne "j'aibe les borceaux de borue"
"""
pass
############################################
############# PARTIE TESTS #############
############################################
import unittest
if not afficher_traces:
__unittest = True
def checktype(expr, res, exp):
assert type(res) == exp, expr + " doit retourner une valeur de type " + exp.__name__ + ", mais a retourné une valeur de type " + type(res).__name__
def checkval_equal(expr, res, exp):
str_exp = "'" +exp+ "'" if type(exp) == str else str(exp)
str_res = "'" +res+ "'" if type(res) == str else str(res)
assert res == exp, expr + " doit retourner " + str_exp + ", mais a retourné " + str_res
class Test_rhube(unittest.TestCase):
def test_rhube_chaine_vide(self):
res = rhube('')
checktype("rhube('')", res, str)
checkval_equal("rhube('')", res, "")
def test_rhube_sans_m(self):
res = rhube('une chaine')
checktype("rhube('une chaine')", res, str)
checkval_equal("rhube('une chaine')", res, "une chaine")
def test_rhube_avec_m(self):
res = rhube('Les abimes de la programmation')
checktype("rhube('Les abimes de la programmation')", res, str)
checkval_equal("rhube('Les abimes de la programmation')", res, "Les abibes de la prograbbation")
if __name__ == '__main__':
s = unittest.TestLoader().loadTestsFromTestCase(Test_rhube)
unittest.TextTestRunner().run(s)
La méthode replace
du type str
permet de substituer des chaînes dans une chaîne.
Exercice : cobid
Implantez la fonction suivante :
def cobid(a):
"""a une chaîne
Retourne une copie de a ou tous les 'm', tous les 'v' et tous les 'w', minuscules et majuscules, sont remplacés par des 'b' ou des 'B'.
cobid("Vieux wagons méchants") retourne "Bieux bagons béchants"
"""
pass
Code avec tests
lancer_tests = True ##Mettez a False pour ne pas lancer les tests
afficher_traces = False ##Mettez a True pour afficher la trace complète des erreurs dans le tests
def cobid(a):
"""a une chaîne
Retourne une copie de a ou tous les 'm', tous les 'v' et tous les 'w', minuscules et majuscules, sont remplacés par des 'b' ou des 'B'.
cobid("Vieux wagons méchants") retourne "Bieux bagons béchants"
"""
pass
############################################
############# PARTIE TESTS #############
############################################
import unittest
if not afficher_traces:
__unittest = True
def checktype(expr, res, exp):
assert type(res) == exp, expr + " doit retourner une valeur de type " + exp.__name__ + ", mais a retourné une valeur de type " + type(res).__name__
def checkval_equal(expr, res, exp):
str_exp = "'" +exp+ "'" if type(exp) == str else str(exp)
str_res = "'" +res+ "'" if type(res) == str else str(res)
assert res == exp, expr + " doit retourner " + str_exp + ", mais a retourné " + str_res
class Test_cobid(unittest.TestCase):
def test_cobid_chaine_vide(self):
res = cobid('')
checktype("cobid('')", res, str)
checkval_equal("rhube('')", res, "")
def test_cobid_sans_m_v_w(self):
res = cobid('une chaine')
checktype("cobid('une chaine')", res, str)
checkval_equal("cobid('une chaine')", res, "une chaine")
def test_cobid_avec_m(self):
res = cobid('Mes abimes de la programmation')
checktype("cobid('Mes abimes de la programmation')", res, str)
checkval_equal("cobid('Mes abimes de la programmation')", res, "Bes abibes de la prograbbation")
def test_cobid_avec_v(self):
res = cobid('Vile voleur')
checktype("cobid('Vile voleur') ", res, str)
checkval_equal("cobid('Vile voleur') ", res, "Bile boleur")
def test_cobid_avec_w(self):
res = cobid('Willy le wagon')
checktype("cobid('Willy le wagon') ", res, str)
checkval_equal("cobid('Willy le wagon') ", res, "Billy le bagon")
def test_cobid_avec_m_v_w(self):
res = cobid('Voici Willy le wagon mangeur de Méchant voleur')
checktype("cobid('Voici Willy le wagon mangeur de Méchant voleur') ", res, str)
checkval_equal("cobid('Voici Willy le wagon mangeur de Méchant voleur') ", res, "Boici Billy le bagon bangeur de Béchant boleur")
if __name__ == '__main__':
s = unittest.TestLoader().loadTestsFromTestCase(Test_cobid)
unittest.TextTestRunner().run(s)
Il vous faut appeler plusieurs fois la méthode replace
. Des variables intermédiaires peuvent être utiles.
def cobid(a):
"""a une chaîne
Retourne une copie de a ou tous les 'm', tous les 'v' et tous les 'w', minuscules et majuscules, sont remplacés par des 'b' ou des 'B'.
cobid("Vieux wagons méchants") retourne "Bieux bagons béchants"
"""
s = a.replace("m","b")
s = s.replace("M", "B")
s = s.replace("v", "b")
s = s.replace("V", "B")
s = s.replace("w", "b")
s = s.replace("W", "B")
return s
n'hésitez pas à regarder la solution d'exploration, qui est plus concise.
Comme replace
est une méthode du type str
qui retourne une str
, on peut pratiquer ce qu'on appelle le method chaining (chaînage de méthode en anglais), qui consiste à appeler directement les méthodes les unes après les autres, sans passer par une variable intermédiaire.
def cobid(a):
"""a une chaîne
Retourne une copie de a ou tous les 'm', tous les 'v' et tous les 'w', minuscules et majuscules, sont remplacés par des 'b' ou des 'B'.
cobid("Vieux wagons méchants") retourne "Bieux bagons béchants"
"""
return a.replace("m","b").replace("M", "B").replace("v", "b").replace("V", "B").replace("w", "b").replace("W", "B")
Exercice : remplacement avec contraintes (Difficile)
Implantez la fonction suivante :
def remplace_mots(a, b, c):
"""a,b,c des chaines. b ne contient pas d'espace et n'est pas vide. a ne contient pas deux mots b successifs.
a ne commence pas par b et ne finis pas par b.
Retourne une copie de a ou tous les mots b ont étés remplacés par c. Un mot est une suite de caractères encadré par des espaces.
remplace_mots("Fabienne a bien fait", "bien", "mal") retourne "Fabienne a mal fait"
"""
pass
Code avec tests
lancer_tests = True ##Mettez a False pour ne pas lancer les tests
afficher_traces = False ##Mettez a True pour afficher la trace complète des erreurs dans le tests
def remplace_mots(a, b, c):
"""a,b,c des chaines. b ne contient pas d'espace et n'est pas vide. a ne contient pas deux mots b successifs.
a ne commence pas par b et ne finis pas par b.
Retourne une copie de a ou tous les mots b ont étés remplacés par c. Un mot est une suite de caractères encadré par des espaces.
remplace_mots("Fabienne a bien fait", "bien", "mal") retourne "Fabienne a mal fait"
"""
pass
############################################
############# PARTIE TESTS #############
############################################
import unittest
if not afficher_traces:
__unittest = True
def checktype(expr, res, exp):
assert type(res) == exp, expr + " doit retourner une valeur de type " + exp.__name__ + ", mais a retourné une valeur de type " + type(res).__name__
def checkval_equal(expr, res, exp):
str_exp = "'" +exp+ "'" if type(exp) == str else str(exp)
str_res = "'" +res+ "'" if type(res) == str else str(res)
assert res == exp, expr + " doit retourner " + str_exp + ", mais a retourné " + str_res
class Test_remplace_mots(unittest.TestCase):
def test_chaine_vide(self):
res = remplace_mots('', 'd', 'dd')
checktype("remplace_mots('', 'd', 'dd')", res, str)
checkval_equal("remplace_mots('', 'd', 'dd')", res, "")
def test_chaine_avec_mots_sans_piege(self):
res = remplace_mots('Bien bien moyen', 'bien', 'mouais')
checktype("remplace_mots('Bien bien moyen', 'bien', 'mouais')", res, str)
checkval_equal("remplace_mots('Bien bien moyen', 'bien', 'mouais')", res, "Bien mouais moyen")
def test_chaine_avec_piege_sans_mot(self):
res = remplace_mots('Natacha', 'cha', 'chien')
checktype("remplace_mots('Natacha', 'cha', 'chien')", res, str)
checkval_equal("remplace_mots('Natacha', 'cha', 'chien')", res, "Natacha")
def test_chaine_avec_piege_avec_mot(self):
res = remplace_mots('Fabienne a bien fait', 'bien', 'mal')
checktype("remplace_mots('Fabienne a bien fait', 'bien', 'mal')", res, str)
checkval_equal("remplace_mots('Fabienne a bien fait', 'bien', 'mal')", res, "Fabienne a mal fait")
if __name__ == '__main__':
s = unittest.TestLoader().loadTestsFromTestCase(Test_remplace_mots)
unittest.TextTestRunner().run(s)
Un mot est une suite de caractères encadrée par des espaces
On encadre b et c pour en faire des mots
def remplace_mots(a, b, c):
"""a,b,c des chaines. b ne contient pas d'espace et n'est pas vide. a ne contient pas deux mots b successifs.
a ne commence pas par b et ne finis pas par b.
Retourne une copie de a ou tous les mots b ont étés remplacés par c. Un mot est une suite de caractères encadré par des espaces.
remplace_mots("Fabienne a bien fait", "bien", "mal") retourne "Fabienne a mal fait"
"""
return a.replace(" " + b + " ", " " + c + " ")
Aléatoire
Exercice : bonjoir
Ecrivez un programme qui demande à l'utilisateur son nom, et qui, aléatoirement, affiche soit Bonjour, nom !
, soit Bonsoir, nom !
.
Exemple de trace d'execution :
Tirez un nombre aléatoire et utilisez un if
pour faire votre choix !
N'oubliez pas d'importer les modules et fonctions dont vous avez besoin !
TP : copie d'un fichier texte
On va écrire un petit programme qui demande à l'utilisateur un nom de fichier, et en effectuera une copie.
- Le programme demande à l'utilisateur un nom de fichier texte (
.txt
). - L'utilisateur entre le nom du fichier. On suppose que le fichier existe et est dans le dossier où le programme a été lancé.
- Le programme lit le fichier et crée une copie de ce dernier, appelée "nomdufichier_copie.txt".
Partie 1 : lecture
Voici un petit rappel du code qui lisait un fichier appelé exemple_fichier.txt
et en affichait le contenu.
Adaptez le code précédent code pour écrire une fonction qui prends en paramètre le nom d'un fichier et retourne son contenu sous forme d'une chaîne de caractères.
Le corps de la fonction est relativement similaire au code présenté dans l'énoncé de l'exercice.
N'hésitez pas à créer un fichier à côté de votre programme et à l'utiliser pour tester votre fonction.
Partie 2 : nom de la copie
Implantez la fonction suivante :
Vous pouvez supprimer une partie d'une chaîne de caractère en utilisant la méthode replace
, et en replaçant la sous-chaîne par une chaîne vide.
Par exemple, si vous voulez supprimer !!!
de AHAHAH!!!
, vous pouvez faire :
def nom_copie(nom):
"""nom : une chaine qui représente le nom d'un fichier texte, et donc se terminant par l'extension .txt
retourne le nom du fichier avec _copie ajouté avant l'extension.
nom_copie("sauvegarde.txt") retourne "sauvegarde_copie.txt"
"""
## on supprime .txt dans le nom en le remplaçant par une chaîne vide :
sans_extension = nom.replace(".txt", "")
## on rajoute _copie.txt à la fin du nom par concaténation
avec_copie = sans_extension + "_copie.txt"
return
La solution décrité précédemment peut se faire en une ligne.
Partie 3 : écriture
On écrit dans un fichier avec la méthode write
de fichier. Pour celà, on va devoir ouvrir le fichier en écriture avec open
, en utilisant le mode "w"
ou "x"
au lieu de "r"
:
Le mode "w"
(write) ouvre un fichier en mode écriture, et le crée si il n'existe pas.
Le mode "x"
crée un fichier et l'ouvre en mode écriture, et si le fichier existe déjà, une erreur est levée.
Le mode "x"
est plus adapté dans notre cas. A votre avis, pourquoi ? Quel problème peut-il poser ?
Le mode "x
" est plus adapté dans notre cas, parce qu'en cas d'erreur dans notre implémentation, on ne risque pas de détruire le contenu d'un fichier déjà existant.
Le désavantage avec cette méthode est qu'il nous faudra supprimer le fichier copie à chaque fois que l'on voudra re-tester notre programme de copie.
Adaptez le code plus haut pour écrire une fonction qui prends en paramètres un nom de fichier et un contenu, et qui crée le fichier et écrit son contenu dedans.
def creer_fichier(nom, contenu):
"""nom : une chaine de caractères, qui représente le nom d'un fichier texte à créer dans le dossier où le programme s'exécute.
contenu : une chaine de caractères
Crée le fichier nom et écrit contenu dans le ficher, uniquement si le fichier n'existe pas. Si le fichier existe déjà, lève l'erreur générer par open en mode x
"""
pass
def creer_fichier(nom, contenu):
"""nom : une chaine de caractères, qui représente le nom d'un fichier texte à créer dans le dossier où le programme s'exécute.
contenu : une chaine de caractères
Crée le fichier nom et écrit contenu dans le ficher, uniquement si le fichier n'existe pas. Si le fichier existe déjà, lève l'erreur générer par open en mode x
"""
with open(nom, "x") as fichier:
fichier.write(contenu)
Partie 5 : fonction main
Ecrivez une fonction main
pour votre programme, qui ne prends aucun argument et qui :
- Demande un nom de fichier à l'utilisateur
- Lit son contenu avec la fonction
lire_fichier
- Crée un nom de copie avec la fonction
nom_copie
- Enregistre une copie du fichier à l'aide de la fonction
creer_fichier
.
Puis appelez cette fonction depuis un bloc if main
.
Vous pouvez télécharger la solution complète en cliquant sur ce lien. Alternativement, vous pouvez la consulter ou la copier depuis le dépliant si dessous :
Code complet de la solution
def lire_fichier(nom):
"""nom : une chaine qui représente le nom d'un fichier texte existant
dans le dossier où le programme a été lancé.
retourne le contenu du fichier sous forme d'une chaîne de caractères.
"""
with open(nom) as fichier:
contenu = fichier.read()
return contenu
def nom_copie(nom):
"""nom : une chaine qui représente le nom d'un fichier texte, et donc se terminant par l'extension .txt
retourne le nom du fichier avec _copie ajouté avant l'extension.
nom_copie("sauvegarde.txt") retourne "sauvegarde_copie.txt"
"""
return nom.replace(".txt","") + "_copie.txt"
def creer_fichier(nom, contenu):
"""nom : une chaine de caractères, qui représente le nom d'un fichier texte à créer dans le dossier où le programme s'exécute.
contenu : une chaine de caractères
Crée le fichier nom et écrit contenu dans le ficher, uniquement si le fichier n'existe pas. Si le fichier existe déjà, lève l'erreur générer par open en mode x
"""
with open(nom, "x") as fichier:
fichier.write(contenu)
def main():
nf = input("Entrez un nom de fichier texte situé dans le dossier d'execution de ce programme : ")
contenu = lire_fichier(nf)
nc = nom_copie(nf)
creer_fichier(nc, contenu)
if __name__=="__main__":
main()
TODO ajouter exo de swap de sous chaines
TODO ajouter un exo de proba genre voir si le gen est équilibré ou truc du genre