From 95d24ad97ba8523c57ac7a794c14822bedef9d77 Mon Sep 17 00:00:00 2001 From: Dimitri Merejkowsky Date: Sun, 27 Jan 2019 16:28:38 +0100 Subject: [PATCH] Prepare chapter 5 --- sessions/python-05.md | 337 ++++++++++++++++++++++++++++++++++++++++ sources/06-top-words.py | 90 +++++++---- sources/ruffin.txt | 6 +- sources/topwords/1.py | 15 ++ sources/topwords/2.py | 35 +++++ sources/topwords/3.py | 45 ++++++ sources/topwords/4.py | 53 +++++++ sources/topwords/5.py | 71 +++++++++ sources/topwords/6.py | 73 +++++++++ 9 files changed, 695 insertions(+), 30 deletions(-) create mode 100644 sessions/python-05.md create mode 100644 sources/topwords/1.py create mode 100644 sources/topwords/2.py create mode 100644 sources/topwords/3.py create mode 100644 sources/topwords/4.py create mode 100644 sources/topwords/5.py create mode 100644 sources/topwords/6.py diff --git a/sessions/python-05.md b/sessions/python-05.md new file mode 100644 index 0000000..1855fc3 --- /dev/null +++ b/sessions/python-05.md @@ -0,0 +1,337 @@ +% Programmation avec Python (chapitre 5) +% Dimitri Merejkowsky + + +# + +\center \huge Suite de l'atelier précédent + +# Rappel + +Travail de la dernière fois. + +Les problèmes que j'ai vu: + +* noms +* méthodologie + +# + +\center \huge naming + +# Quelques principes + +* L'un des problèmes les plus compliqué de l'informatique + +* Tout en Anglais +* Pas d'abbréviation +* Pas de redondance + +# Exemples + +* `get_freq` -> `get_frequencies` +* `nom_fich` -> `filename` +* `list_frag` -> `fragments` # le pluriel nous dit que c'est une liste +* `liste_mot` -> `words` + +Essayez de rester cohérents! + +# Exemples (2) + +```python +# Avant +for fragment in list_frag: + fragment_min = fragment.lower() + frag_clean = clean(fragment_min) + liste_mot.append(frag_clean) +``` + +```python +# Après +for fragment in fragments: + fragment = fragment.lower() + fragment = clean(fragment) + liste_mot.append(fragment) +``` + +On peut ré-utiliser le même nom plusieurs fois! + +# + +\center \huge Style + +# Espaces + +* Deux lignes entre chaque fonction +* Des espaces autour des `=` pour les affectations +* Pas d'espace quand c'est un argument nommé + +# + +\center \huge Repartons du début + +# Découper les mots + +Dans la liste se trouvent des mots mal découpés: + +* `peutétre` +* `lhumanité` + +Reprenons depuis le début + +# Tester chaque fonction une par une + +* Spécification +* Test +* Implémentation + +# Découpage en fragments - spécification + +On a: + +> L'univers est, peut-être, « infini! » + +On veut: + +```python +["l", "univers", "est", "peut-être", '«', "infini", '»'] +``` + +On s'occupera d'enlever la ponctuation plus tard. + +# Découpage en fragments - test + +```python +contents = "L'unives est, peut-être, infini!" +fragments = split_fragments(contents) +print(fragments) +``` + +# Découpage en fragments - implémentation + +```python +def split_fragments(contents): + res = list() + for fragment in contents.split(): + if "’" in fragment: + (before, after) = fragment.split("’") + res.append(before) + res.append(after) + else: + res.append(fragment) + return res +``` + +# Découpage en mots - spécification + +On a: + +``` +L'unives est, peut-être, « infini! » +``` + +On veut: + +``` +['l', 'unives', 'est', 'peut-être', 'infini'] +``` + +# Découpage en mots - test + +```python +contents = "L'univers est, peut-être, « infini! »" +words = split_words(contents) +print(words) +``` + +# Découpage en mots - implémentation + +On peut reprendre le code vu ensemble, +avec quelques modifications: + +```python +def split_words(text): + fragments = split_fragments(text) + res = list() + for fragment in fragments: + fragment = fragment.lower() + fragment = clean_fragment(fragment) + if fragment: # le fragment peut-être vide ici + res.append(fragment) + return res +``` + +# clean_fragment() + +Juste une petite modification: + +```python +def clean_fragment(fragment): + result = "" + for c in fragment: + # autorise les tirets et apostrophes à l'intérieur + # des mots + if c.isalpha() or c in ["-", "'"]: + result += c + return result +``` + +# Calcul des fréquences - spécification + +On a: + +```python +["pomme", "poire", "banane", "poire", "banane", "banane"]` +``` + +On veut: + +```python +{"pomme": 1, "poire": 2, "banane": 3} +``` + +\vfill + +Note: par encore d'ordre ici! + +# Calcul des fréquences - test + + +```python +words = [ + "pomme", "poire", "banane", + "poire", "banane", "banane" +] +frequencies = get_frequencies(words) +print(frequencies) +``` + +# Calcul des fréquences - implémentation + + +```python +def get_frequencies(words): + res = dict() + for word in words: + # Si le mot est déjà là, on incrémente + # son compteur: + if word in res: + res[word] += 1 + else: + # Sinon on crée une nouvelle clé + # avec la valeur 1 + res[word] = 1 + return res +``` + + +# Tri - spécification + +On a: + +```python +{'pomme': 1, 'poire': 2, 'banane': 3} +``` + +On veut: + +```python +[ + (3, 'banane'), + (2, 'poire'), + (1 'pomme'), +] +``` + +# Tri - test + +```python +frequencies = {'pomme': 1, 'poire': 2, 'banane': 3} +scores = get_scores(frequencies) +print(scores) +``` + + +# Tri - implémentation + +```python +def get_scores(frequencies): + res = list() + for word, count in frequencies.items(): + res.append((count, word)) + res.sort(reverse=True) + return res +``` + +# Affichage des résultats + +On a : + +```python +scores = [ + (20, "banane"), + (19, "poire"), + ... +] +``` + +On veut: + +``` +20 banane +19 poire +``` + +# Affichage des résultats - test + +```python +scores = [ + (20, "banane"), + (19, "poire"), + ... +] +print_scores(scores) +``` + +# Affichage des résultats - implémentation + + +```python +def print_scores(scores): + for count, word in scores: + print(count, word) +``` + +# Assemblons les morceaux + +```python +def main(): + filename = "ruffin.txt" + file = open(filename) + contents = file.read() + words = split_words(contents) + frequencies = get_frequencies(words) + scores = get_scores(frequencies) + top_words = scores[:20] # le top 20 + print_scores(top_words) + +main() +``` + +# Touches finales + +C'est bien si le nom du fichier est lu depuis la ligne de commande: + +```python +import sys + +def main(): + if len(sys.argv) < 2: + sys.exit("not enough arguments") + filename = sys.argv[1] + ... +``` + +# + +\center \huge Compléments diff --git a/sources/06-top-words.py b/sources/06-top-words.py index 8bdcc54..7bdaa8e 100644 --- a/sources/06-top-words.py +++ b/sources/06-top-words.py @@ -1,37 +1,73 @@ -# On veut obtenir la fréquence de chaque mot +import sys -def get_freq(nom_fich): - fich=open(nom_fich) - contenu=fich.read() - liste_frag=contenu.split() # coupe sur 'espace' et \ - liste_mot=list() - for fragment in liste_frag: - fragment_min=fragment.lower() - frag_clean=clean(fragment_min) - liste_mot.append(frag_clean) +def clean_fragment(fragment): + result = "" + for c in fragment: + if c.isalpha() or c in ["-", "'"]: + result += c - return liste_mot + return result -def clean(fragment): - result="" - for c in fragment: - if c.isalpha(): - result+=c +def split_words(text): + fragments = split_fragments(text) + res = list() + for fragment in fragments: + fragment = fragment.lower() + fragment = clean_fragment(fragment) + if fragment: + res.append(fragment) + return res - return result + +def split_fragments(text): + res = list() + for fragment in text.split(): + if "’" in fragment: + before = fragment.split("’")[0] + after = fragment.split("’")[1] + res.append(before) + res.append(after) + else: + res.append(fragment) + return res + + +def get_frequencies(words): + res = dict() + for word in words: + if word in res: + res[word] += 1 + else: + res[word] = 1 + return res + + +def get_scores(frequencies): + res = list() + for word, count in frequencies.items(): + res.append((count, word)) + res.sort(reverse=True) + return res + + +def print_scores(scores): + for count, word in scores: + print(count, word) +def main(): + if len(sys.argv) < 2: + sys.exit("not enough arguments") + filename = sys.argv[1] + file = open(filename) + contents = file.read() + words = split_words(contents) + frequencies = get_frequencies(words) + scores = get_scores(frequencies) + top_words = scores[:20] + print_scores(top_words) -def tri(d): - list_tuples=list() - for clé, valeur in d.items(): - list_tuples.append((valeur, clé)) - list_tuples.sort(reverse=True) - print(list_tuples) - return d -nom_fich="ruffin.txt" -f=get_freq(nom_fich) -print(f) +main() diff --git a/sources/ruffin.txt b/sources/ruffin.txt index bebe703..30a714f 100644 --- a/sources/ruffin.txt +++ b/sources/ruffin.txt @@ -37,9 +37,9 @@ C’est que, pour les puissants, la croissance remplit une fonction, un rôle id Que proclame, par exemple, le président Macron? Que, comme on l’a encore répété à cette tribune, « sans croissance, il n’y a aucune chance d’avoir de la redistribution. » C’est faux. C’est archi-faux. C’est une imposture. On peut redistribuer. On peut redistribuer tout de suite. Et on peut redistribuer massivement. -Pourquoi, alors, un tel mensonge ? Parce que Macron est l’homme des 500 familles. Des 500 familles qui se gavent. Des 500 familles qu’on retrouve chaque année dans Challenges, qui est, vous le savez, ma lecture favorite. L’an dernier, ce magazine de l’économie écrivait : « Le constat saute aux yeux : le patrimoine des ultra-riches, en France, a considérablement progressé depuis deux décennies. La valeur des 500 fortunes a été multipliée par sept ! Des chiffres qui témoignent du formidable essor des entreprises au bénéfice de leurs actionnaires ». « Résultat : les ’’500’’, qui ne comptaient que pour l’équivalent de 6 % du PlB en 1996, pèsent aujourd’hui 25 % ! » +Pourquoi, alors, un tel mensonge ? Parce que Macron est l’homme des 500 familles. Des 500 familles qui se gavent. Des 500 familles qu’on retrouve chaque année dans Challenges, qui est, vous le savez, ma lecture favorite. L’an dernier, ce magazine de l’économie écrivait : « Le constat saute aux yeux : le patrimoine des ultra-riches, en France, a considérablement progressé depuis deux décennies. La valeur des 500 fortunes a été multipliée par sept ! Des chiffres qui témoignent du formidable essor des entreprises au bénéfice de leurs actionnaires ». « Résultat : les 500, qui ne comptaient que pour l’équivalent de 6 % du PlB en 1996, pèsent aujourd’hui 25 % ! » -Mais cela, c’était l’an dernier : cette année, dans le nouveau classement de Challenges, ces 500 fortunes, qui pesaient l’an dernier 25 % du PIB, représentent aujourd’hui 30 % de ce même PIB ! Ils ont donc gagné 5 % en douze mois seulement. +Mais cela, c’était lan dernier : cette année, dans le nouveau classement de Challenges, ces 500 fortunes, qui pesaient l’an dernier 25 % du PIB, représentent aujourd’hui 30 % de ce même PIB ! Ils ont donc gagné 5 % en douze mois seulement. Et ce qui manquerait, après tout ça, c’est la croissance ? Non, ce qui manque, c’est le partage. Le partage d’abord, le partage tout de suite ! Le gâteau devant nous est énorme, gigantesque : 2 300 milliards d’euros. Voilà le PIB de la France. Deux mille trois cents milliards d’euros ! Une richesse jamais atteinte ! Il y a de quoi déguster pour tout le monde, et même largement. Partageons ! Mais ce mot, partage, vous fait horreur. Partager : c’est pour les riches depuis toujours un cri d’effroi. @@ -47,7 +47,7 @@ Votre raisonnement, alors, c’est-à-dire le raisonnement que l’on nous serin C’est une imposture. C’est une escroquerie. -Un économiste, ou un intellectuel, l’a d’ailleurs dit très clairement : « Il est un mythe savamment entretenu par les économistes libéraux, selon lequel la croissance réduit l’inégalité. Cet argument permettant de reporter ’’à plus tard’’ toute revendication redistributive est une escroquerie intellectuelle sans fondement. » Qui formulait cette brillante analyse ? Qui disait : n’attendez pas la croissance pour redistribuer ? Savez-vous, monsieur le ministre, qui a dit cela ? +Un économiste, ou un intellectuel, l’a d’ailleurs dit très clairement : « Il est un mythe savamment entretenu par les économistes libéraux, selon lequel la croissance réduit l’inégalité. Cet argument permettant de reporter à plus tard toute revendication redistributive est une escroquerie intellectuelle sans fondement. » Qui formulait cette brillante analyse ? Qui disait : n’attendez pas la croissance pour redistribuer ? Savez-vous, monsieur le ministre, qui a dit cela ? Jacques Attali ! Mais en 1973… Depuis, il les a rejoints, les économistes libéraux. Il en a pris la tête, il a répandu cette escroquerie intellectuelle sans fondement. Il a conseillé Ségolène Royal avant de rejoindre Nicolas Sarkozy et de pondre ensuite, aux côtés d’Emmanuel Macron, ses 316 propositions pour libérer la croissance française, symbole de la pensée unique. D’une présidence à l’autre, cette escroquerie intellectuelle se perpétue donc. L’urgence écologique diff --git a/sources/topwords/1.py b/sources/topwords/1.py new file mode 100644 index 0000000..c9ce74b --- /dev/null +++ b/sources/topwords/1.py @@ -0,0 +1,15 @@ +def split_fragments(text): + res = list() + for fragment in contents.split(): + if "’" in fragment: + (before, after) = fragment.split("’") + res.append(before) + res.append(after) + else: + res.append(fragment) + return res + + +contents = "L’univers est, peut-être, « infini! »" +fragments = split_fragments(contents) +print(fragments) diff --git a/sources/topwords/2.py b/sources/topwords/2.py new file mode 100644 index 0000000..51be124 --- /dev/null +++ b/sources/topwords/2.py @@ -0,0 +1,35 @@ +def split_fragments(text): + res = list() + for fragment in contents.split(): + if "’" in fragment: + (before, after) = fragment.split("’") + res.append(before) + res.append(after) + else: + res.append(fragment) + return res + + +def clean_fragment(fragment): + result = "" + for c in fragment: + if c.isalpha() or c in ["-", "'"]: + result += c + + return result + + +def split_words(text): + fragments = split_fragments(text) + res = list() + for fragment in fragments: + fragment = fragment.lower() + fragment = clean_fragment(fragment) + if fragment: + res.append(fragment) + return res + + +contents = "L’univers est, peut-être, « infini! »" +words = split_words(contents) +print(words) diff --git a/sources/topwords/3.py b/sources/topwords/3.py new file mode 100644 index 0000000..eb93bf3 --- /dev/null +++ b/sources/topwords/3.py @@ -0,0 +1,45 @@ +def clean_fragment(fragment): + result = "" + for c in fragment: + if c.isalpha() or c in ["-", "'"]: + result += c + + return result + + +def split_words(text): + fragments = split_fragments(text) + res = list() + for fragment in fragments: + fragment = fragment.lower() + fragment = clean_fragment(fragment) + if fragment: + res.append(fragment) + return res + + +def split_fragments(text): + res = list() + for fragment in text.split(): + if "’" in fragment: + (before, after) = fragment.split("’") + res.append(before) + res.append(after) + else: + res.append(fragment) + return res + + +def get_frequencies(words): + res = dict() + for word in words: + if word in res: + res[word] += 1 + else: + res[word] = 1 + return res + + +words = ["pomme", "poire", "banane", "poire", "banane", "banane"] +frequencies = get_frequencies(words) +print(frequencies) diff --git a/sources/topwords/4.py b/sources/topwords/4.py new file mode 100644 index 0000000..3da2075 --- /dev/null +++ b/sources/topwords/4.py @@ -0,0 +1,53 @@ +def clean_fragment(fragment): + result = "" + for c in fragment: + if c.isalpha() or c in ["-", "'"]: + result += c + + return result + + +def split_words(text): + fragments = split_fragments(text) + res = list() + for fragment in fragments: + fragment = fragment.lower() + fragment = clean_fragment(fragment) + if fragment: + res.append(fragment) + return res + + +def split_fragments(text): + res = list() + for fragment in text.split(): + if "’" in fragment: + (before, after) = fragment.split("’") + res.append(before) + res.append(after) + else: + res.append(fragment) + return res + + +def get_frequencies(words): + res = dict() + for word in words: + if word in res: + res[word] += 1 + else: + res[word] = 1 + return res + + +def get_scores(frequencies): + res = list() + for word, count in frequencies.items(): + res.append((count, word)) + res.sort(reverse=True) + return res + + +frequencies = {"pomme": 1, "poire": 2, "banane": 3} +top_words = get_scores(frequencies) +print(top_words) diff --git a/sources/topwords/5.py b/sources/topwords/5.py new file mode 100644 index 0000000..7b831de --- /dev/null +++ b/sources/topwords/5.py @@ -0,0 +1,71 @@ +def clean_fragment(fragment): + result = "" + for c in fragment: + if c.isalpha() or c in ["-", "'"]: + result += c + + return result + + +def split_words(text): + fragments = split_fragments(text) + res = list() + for fragment in fragments: + fragment = fragment.lower() + fragment = clean_fragment(fragment) + if fragment: + res.append(fragment) + return res + + +def split_fragments(text): + res = list() + for fragment in text.split(): + if "’" in fragment: + try: + (before, after) = fragment.split("’") + except: + breakpoint() + res.append(before) + res.append(after) + else: + res.append(fragment) + return res + + +def get_frequencies(words): + res = dict() + for word in words: + if word in res: + res[word] += 1 + else: + res[word] = 1 + return res + + +def get_scores(frequencies): + res = list() + for word, count in frequencies.items(): + res.append((count, word)) + res.sort(reverse=True) + return res + + +def print_scores(scores): + for count, word in scores: + print(count, word) + + +def main(): + filename = "../ruffin.txt" + file = open(filename) + contents = file.read() + file.close() + words = split_words(contents) + frequencies = get_frequencies(words) + scores = get_scores(frequencies) + top_words = scores[:20] + print_scores(top_words) + + +main() diff --git a/sources/topwords/6.py b/sources/topwords/6.py new file mode 100644 index 0000000..7bdaa8e --- /dev/null +++ b/sources/topwords/6.py @@ -0,0 +1,73 @@ +import sys + + +def clean_fragment(fragment): + result = "" + for c in fragment: + if c.isalpha() or c in ["-", "'"]: + result += c + + return result + + +def split_words(text): + fragments = split_fragments(text) + res = list() + for fragment in fragments: + fragment = fragment.lower() + fragment = clean_fragment(fragment) + if fragment: + res.append(fragment) + return res + + +def split_fragments(text): + res = list() + for fragment in text.split(): + if "’" in fragment: + before = fragment.split("’")[0] + after = fragment.split("’")[1] + res.append(before) + res.append(after) + else: + res.append(fragment) + return res + + +def get_frequencies(words): + res = dict() + for word in words: + if word in res: + res[word] += 1 + else: + res[word] = 1 + return res + + +def get_scores(frequencies): + res = list() + for word, count in frequencies.items(): + res.append((count, word)) + res.sort(reverse=True) + return res + + +def print_scores(scores): + for count, word in scores: + print(count, word) + + +def main(): + if len(sys.argv) < 2: + sys.exit("not enough arguments") + filename = sys.argv[1] + file = open(filename) + contents = file.read() + words = split_words(contents) + frequencies = get_frequencies(words) + scores = get_scores(frequencies) + top_words = scores[:20] + print_scores(top_words) + + +main()