Aller au contenu

Travail sur les textes en Python

Nous allons découvrir comment avec quelques routines Python, nous pouvons explorer le contenu de certains fichiers numériques.

Il faut pour cela que leur contenu soit dans un format ouvert: c'est le cas de tous les fichiers du web, notamment ceux développés par le W3C comme le fichier image au formet PNG.

En revanche on ne pourra pas lire les fichiers générés par des logiciels propriétaires comme Microsoft ou Apple... ces fichiers étant cryptés.

Ouverture d'un fichier.

Le fichier test

Télécharger ici le fichier sur lequel nous allons tester nos codes python.

Il s'agit d'un fichier texte contenant la constitution française. Nous allons analyser ce fichier texte.

Comment lire et écrire sur des fichiers en Python?

Pour ouvrir le fichier en mode lecture, nous allons utiliser les routines suivantes:

🐍 Script Python
fich = open("test.txt", 'r', encoding = "utf-8") # r comme read
La variable fich est un objet tampon contenant tous les caractères du fichier texte mais ce n'est pas une chaîne de caractères: il faut lire cet objet et stocker l'information dans une variable.
🐍 Script Python
fich = open("test.txt", 'r', encoding = "utf-8") # r comme read
f = fichier.read() #lit tout le texte et l'affecte à la la variable f

Info

La variable f est alors une chaîne de caractères.

Évitez de printer la valeur de f dans la console qui est extrêmement grande!

Taille du texte

Faites afficher dans la console la taille de la variable f et comparez-la à la taille du fichier texte que vous avez ouvert.

La méthode read permet de lire tout le contenu de l'objet fich.

On peut aussi lire ligne par ligne le fichier:

🐍 Script Python
fich = open("test.txt", 'r', encoding = "utf-8") # r comme read
cpt = 1
f = fich.readline() #lit la première ligne 
while f != "":
  f = fich.readline()
  cpt += 1
print(cpt)
La variable f prend à chaque tour de boucle, la valeur de chaque ligne du fichier. La variable cpt compte ici le nombre de ligne dans le fichier.

On peut aussi procéder ainsi pour stocker toutes les lignes dans une liste:

🐍 Script Python
fich = open("test.txt", 'r', encoding = "utf-8") # r comme read
liste_de_lignes = fich.readlines() #stocke chaque ligne dans une liste

On peut aussi:

  • ouvrir un fichier en écriture mais attention: si ce fichier existe déjà son contenu sera alors détruit
  • ouvrir un fichier en ajout pour ajouter à un fichier existant de nouvelles informations.

🐍 Script Python
fich = open("mon_texte.txt", 'w') # ouverture en écriture
fich.write("bonjour!") #écris dans le fichier txt
Si le fichier mon_texte.txt n'existe pas, il est alors créer: s'il existe son contenu est effacé.

🐍 Script Python
fich = open("mon_texte.txt", 'a') # ouverture en écriture en mode append
fich.write("bonjour!") #écris dans le fichier txt
Dans ce mode, si le fichier mon_texte.txt n'existe pas, il est alors créer: s'il existe son contenu est préservé.

Il existe aussi le mode rb pour une lecture binaire(plutôt hexadécimale...) du fichier, mode que nous n'utiliserons pas ici.

Fermer le fichier ouvert

À chaque fois que vous ouvrirez un fichier pour le lire, le modifier ou le créer, il faudra toujours penser à le fermer à la fin du programme par l'instruction fich.close()

Nous allons d'abord travailler sur le fichier test.txt afin de le simplier:

  • on va remplacer toutes les majuscules par des minuscules
  • on va remplacer les caractères accentués les plus usités par le caractère correspondant sans accent (é,è,ù et à).

Prération du fichier

  1. Ouvrez le fichier test.txt en lecture puis stockez son contenu dans une variable texte_original de type string.
  2. Construire un programme Python qui à partir d'une chaîne de caractères, construit une nouvelle chaîne de caractères en remplaçant toutes les majuscules par des minuscules(voir le cours sur les chaînes de caractères...)
  3. Construire un programme Python qui à partir d'une chaîne de caractères, construit une nouvelle chaîne de caractères en remplaçant les caractères accentués usuels par leur correspondant sans accent.
  4. Appliquez les deux programmes précédents à l'objet texte_original pour obtenir la chaîne texte_filtre.
  5. Ouvrez un fichier fichier_test_filtre.txt en écriture et y écrire le contenu de la variable texte_filtre.
  6. N'oubliez pas de fermer les fichiers ouverts!

Transformer des fichiers textes

Voyelles contre voyelles

Nous allons dorénavant travailler sur le fichier fichier_test_filtre.txt.

Permutation de voyelle

Le cerveau a des capacités étonnantes: il est capable de lire un texte dans lequel les voyelles ont été mélangées!! Tentons l'expérience. Construire un fichier fichier_test_melange.txt où on a échangé les e avec les a et les o avec les u. Vous pouvez aussi coder un remplacement aléatoire d'une voyelle par une autre...

Cryptage

Principe

Le terme de cryptage désigne un ensemble de techniques, avec différents protocoles de codage, visant à rendre illisible un message, un texte ou autre contenu sensible.

Nous avons déjà rencontré le codage de César qui consiste à substituer une lettre par une autre en décalant d'une certaine valeur (la clé) les lettres de l'alphabet.

Codage de César avec choix de la clé

  1. Coder le fichier fichier_test_filtre.txt par le codage de César avec la clé de votre choix.
  2. Imaginer un programme Python qui permet de tester l'ensemble des clés possibles pour décoder le texte crypté.

Nous allons améliorer ce codage en changeant la transformation utilisée.

Dans le codage de César avec un clé égale à 4, c'est la fonction \(f\) définie par \(f(x)=x+4\) qui permet le décalage des rangs de l'alphabet. Nous allons choisir maintenant une vraie fonction affine pour transformer: le décodage en sera alors plus difficile.

Codage affine

  1. Reprendre le travail de l'exercice précédent avec la fonction affine \(code\) définie pour tout \(x\) dans \([0,25]\) par \(code(x)=17x+5\).
  2. Construire le fichier fichier_codage_affine.txt obtenu en cryptant le fichier fichier_test_filtre.txt par le codage affine précédent.
  3. Vérifier que la fonction affine \(decode\) définie par \(decode(x)=23x+15\) décode le fichier précédemment codé...

Decryptage

Comment analyser un texte, crypté ou non?

L'une des premières expériences réalisées est l'analyse fréquentielle des caractères constituant ce texte.

L'analyse fréquentielle

L'analyse fréquentielle consiste à déterminer la fréquence d'apparition des lettres (ou autre chose...) dans un texte.

Nous allons mettre en place l'analyse fréquentielle des deux textes fichier_test_filtre.txt et fichier_codage_affine.txt en utilisant les deux fonctions python suivantes:

🐍 Script Python
def freq_lettre(texte, let):
    """
    parameters:
    -----------------
    texte: string
    let: caractere
    returns
    -----------------
    float frequence de let dans texte
    """
    cpt = 0
    for carac in texte:
        if carac == let:
            cpt += 1
    return cpt/len(texte)

def freq_lettre_texte(fichier_src):
    """
    parameters:
    -----------------
    fichier_src: string
    returns
    -----------------
    liste des frequences des minus dans texte
    """
    minus = [chr(i) for i in range(97, 123)] #liste des minuscules
    liste_freq = []
    for elt in minus:
        liste_freq.append(freq_lettre(fichier_src, elt))
    return liste_freq

Analyse des fichiers texte

Utiliser les fonctions précédentes pour analyser les deux textes fichier_test_filtre.txt et fichier_codage_affine.txt.

Pour visualiser les résultats de l'étude précédente, nous allons utiliser un histogramme.

image

Pour construire un tel histogramme, il faut une liste en abscisse et une autre en ordonnée.

🐍 Script Python
import matplotlib.pyplot as plt
import numpy as np

fichier_1 = 'fichier_test_filtre.txt' #fichier d'étude
fichier_etude_1 = open(fichier_1,'r')
f_1 = fichier_etude_1.read()
#########################################################################################################################################
fig, ax = plt.subplots()

minus = [chr(i) for i in range(97, 123)] #liste en abscisse
freq = freq_lettre_texte(f_1) #liste en ordonnee

ax.bar(minus, freq, width = 1)
plt.title(f"Analyse du fichier {fichier_1}")
ax.set(xlim = (-1, 26), xticks = np.arange(0, 26),
       ylim = (0, 0.15), yticks = np.arange(0,0.15,0.02))

plt.show()
#########################################################################################################################################
fichier_etude_1.close()

Faire des histogrammes

  1. Construire l'histogramme des fréquences du fichier fichier_test_filtre.txt.
  2. Construire un autre histogramme des fréquences du fichier fichier_codage_affine.txt.
  3. En analysant ces deux histogrammes, comment pouvons-nous retrouver les clés qui ont permis le codage affine?

Voici mes histogrammes(je les ai représenté sur le même graphique ce qui ne sera peut-être pas évident pour vous...):

image