le sujet¶
il s’agit d’écrire un programme qui lit un fichier texte, et calcule la fréquence des mots présents dans ce fichier
par exemple ici nous allons afficher les mots les plus fréquents, avec leur nombre d’apparitions
par exemple avec (ce fichier est fourni)
python frequency.py -n 5 frequency-sample.txt
the 65
he 62
a 52
to 52
it 45un outil bien pratique¶
pour faire ça, on va utiliser un module de la librairie standard,
collections.Counter; entrainez-vous à trouver sa doc sur docs.python.org, et à chercher une méthode qui va nous aider à faire ce qui est demandé ici
une méthode en particulier
et notamment la méthode most_common()
solutions¶
v0: très rustique (marche assez mal)¶
pour montrer comment on utilise Counter, on va couper les mots à la serpe avec
split(), et on va ignorer la ponctuation
pour voir la v0
"""
un programme qui calcule le nombre d'occurrences des mots dans un fichier texte
- on entre le nom du fichier par la ligne de commandes
- par défaut on montre les 3 mots les plus fréquents, on peut changer ce nombre
également sur la ligne de commandes
"""
# dans cette v0 on ignore la ponctuation
# le résultat est donc un peu plus "brut"
# puisque "Hello," ne va pas être compté comme "hello"
from collections import Counter
from argparse import ArgumentParser
def compute_counter(filename) -> Counter:
try:
# ici le fait de lire tout le fichier d'un coup
# simplifie le code
with open(filename) as reader:
text = reader.read().lower().split()
counter = Counter(mots)
return counter
except FileNotFoundError:
print(f"OOPS le fichier {filename} n'existe pas")
return Counter()
def main():
parser = ArgumentParser()
# par défaut on montre les 3 mots les plus fréquents
parser.add_argument(
"-n", "--number", default=3, type=int,
help="the number of words to show")
parser.add_argument("filename")
args = parser.parse_args()
filename = args.filename
n = args.number
counter = compute_counter(filename)
if len(counter) == 0:
print("vide")
else:
for word, occurrences in counter.most_common(n):
print(word, occurrences)
if __name__ == '__main__':
main()
v1: un peu comme pour palindrom¶
ici on va remplacer tous les caractères de ponctuation par des espaces avant de
couper en morceaux avec split(); on montre 3 façons d’obtenir ces caractères
de ponctuation (et le mieux c’est d’importer ce qu’on avait fait pour le
palindrome)
la v1
"""
un programme qui calcule le nombre d'occurrences des mots dans un fichier texte
- on entre le nom du fichier par la ligne de commandes
- par défaut on montre les 3 mots les plus fréquents, on peut changer ce nombre
également sur la ligne de commandes
"""
# v1: un peu mieux car on traite la ponctuation
# mais c'est clairement sous-optimal en termes de complexité
# (près d'un millier de caractères de ponctuation)
from collections import Counter
from argparse import ArgumentParser
# plusieurs options pour calculer une chaine
# qui contient les caractères de ponctuation
# option 0: on entre à la main les caractères de ponctuation
# dans notre texte; bon c'est sous-optimal mais en dernier recours..
# notez l'utilisation de """ comme délimiteur
# PONCTUATION = """,.;'"“”"""
# option 1: ne marche pas bien car seulement ASCII
# from string import punctuation
# option 2: voir le palindrome
from palindrom_v2 import unicode_punctuation
PUNCTUATION = unicode_punctuation()
def compute_counter(filename) -> Counter:
try:
with open(filename) as reader:
text = reader.read().lower()
# on remplace les caractères de ponctuation par un espace
for char in PUNCTUATION:
text = text.replace(char, " ")
mots = text.split()
counter = Counter(mots)
return counter
except FileNotFoundError:
print(f"OOPS le fichier {filename} n'existe pas")
return Counter()
def main():
parser = ArgumentParser()
# par défaut on montre les 3 mots les plus fréquents
parser.add_argument(
"-n", "--number", default=3, type=int,
help="the number of words to show")
parser.add_argument("filename")
args = parser.parse_args()
filename = args.filename
n = args.number
counter = compute_counter(filename)
if len(counter) == 0:
print("vide")
else:
for word, occurrences in counter.most_common(n):
print(word, occurrences)
if __name__ == '__main__':
main()
v2: avec les expressions régulières¶
enfin on montre comment on ferait en vrai; c’est moins lisible car ça utilise les expressions régulières, un sujet disons un peu aride de prime abord, mais comme vous pouvez le voir ça donne une solution beaucoup plus propre, et globablement plus efficace aussi
la v2
"""
un programme qui calcule le nombre d'occurrences des mots dans un fichier texte
- on entre le nom du fichier par la ligne de commandes
- par défaut on montre les 3 mots les plus fréquents, on peut changer ce nombre
également sur la ligne de commandes
"""
# une deuxième version en utilisant les expressions régulières
from collections import Counter
from argparse import ArgumentParser
import re
def compute_counter(filename) -> Counter:
try:
# ici le fait de lire tout le fichier d'un coup
# simplifie le code
with open(filename) as reader:
text = reader.read().lower()
words_stream = re.findall(r'\w+', text)
counter = Counter(words_stream)
return counter
# on aurait pu raccourcir ces 4 lignes en une seule:
# return Counter(re.findall(r'\w+', reader.read().lower()))
except FileNotFoundError:
print(f"OOPS le fichier {filename} n'existe pas")
return Counter()
def main():
parser = ArgumentParser()
# par défaut on montre les 3 mots les plus fréquents
parser.add_argument(
"-n", "--number", default=3, type=int,
help="the number of words to show")
parser.add_argument("filename")
args = parser.parse_args()
filename = args.filename
n = args.number
counter = compute_counter(filename)
if len(counter) == 0:
print("vide")
else:
for word, occurrences in counter.most_common(n):
print(word, occurrences)
if __name__ == '__main__':
main()