from codecs import open from urllib.request import urlretrieve from random import choice from itertools import chain class Markov(object): def __init__(self,fichier): self.dicAssoc = {} self.fichier = fichier self.lettres = self.fichierVersLettres() self.baseDeTuplets() def fichierVersLettres(self): """ Renvoie les lettres du texte sous forme d'un itérateur """ data = self.fichier.read() # le fichier entier de type string lettres = map(lambda lettre: ','.join(lettre),data) # on sépare chaque caractère du texte par une virgule return list(chain.from_iterable(lettres)) # on en fait un itérateur def tuplets(self): """ crée un générateur de triplets de lettres successives """ for i in range(len(self.lettres) - 2): yield (self.lettres[i], self.lettres[i+1], self.lettres[i+2]) def baseDeTuplets(self): """ Crée un dictionnaire dont les clés sont des couples de lettres successives et la valeur la liste des successeurs observés. """ for l1,l2,l3 in self.tuplets(): key = l1,l2 if key in self.dicAssoc: self.dicAssoc[key].append(l3) else: self.dicAssoc[key] = [l3] def genereMarkovText(self, nbLettres = 100): """ génère un texte selon la distribution du dictionnaire d'association """ (l1,l2) = choice(list(self.dicAssoc.keys())) # on choisit un couple de lettres au hasard dans le dico gen_lettres = "" # on initialise le texte généré for i in range(nbLettres): gen_lettres += l1 # on écrit l1 dans letexte l1,l2 = l2,choice(self.dicAssoc[(l1,l2)]) # on avance d'un cran print(gen_lettres) # Notre-Dame de Paris urlretrieve('http://www.gutenberg.org/cache/epub/19657/pg19657.txt','ndp.txt') # Fahrenheit 451 urlretrieve('http://sami.is.free.fr/Oeuvres/Bradbury%20Ray%20-%20Fahrenheit%20451-FR.txt','451.txt') # Gone with the wind urlretrieve('http://gutenberg.net.au/ebooks02/0200161.txt','autant.txt') ndp = Markov(open('ndp.txt','r')) # Attention : celui-ci n'est pas en UTF-8 mais en latin-1 fahr = Markov(open('451.txt','r','iso-8859-1')) autant = Markov(open('autant.txt','r')) # exemple : ndp.genereMarkovText(1000)