def is_palindrome(w): return w == w[::-1]
is_palindrome('able was I ere I saw elba')
b) Si on suppose comme dans l'énoncé que la chaîne n'utilise que des lettres non accentuées, l'ensemble (set
)
de ses lettres, une fois converites en minuscules (ou en majuscules) devra avoir exactement 26 éléments.
Un ensemble (set) c'est un dictionnaire dont les clés n'ont pas de valeur
def is_pangram(w): return len({x.lower() for x in w if x.isalpha()}) == 26
is_pangram('Monsieur Jack, vous dactylographiez bien mieux que votre ami Wolf')
c) Pensez à ce que vous feriez avec un paquet de cartes et écrivez le entre []
Noter l'astuce (optionnelle) avec and
pour traiter la liste vide
def remove_adjacent(ll): return ll and [ll[i] for i in range(len(ll)-1) if ll[i+1]!=ll[i] ]+[ll[-1]]
remove_adjacent([1,1,3,3,5,4,2,1,3,3,1,2,1,1])
# autre version
def remove_adjacent(ll): return ll and [ll[i] for i in range(len(ll)) if i==0 or ll[i-1]!=ll[i] ]
remove_adjacent([1,1,3,3,5,4,2,1,3,3,1,2,1,1])
d) Remarquer les fonctions de conversion.
def digits_sum(n): return sum([int(c) for c in str(n)])
digits_sum(2**100)
En Python 3, les chaînes sont en unicode. maketrans
devient une méthode de la classe str
.
open
prend un deuxième argument, encoding.
On écrit une fonction ok(w)
qui teste si une ligne ne contient que les caractères autorisés (et le \n
)
une fois qu'on a traduit les caracères accentués.
On lit le dictionnaire (décodé) sous forme d'une liste de lignes, et on le filtre avec ok
.
On peut ensuite imprimer le mot original, sa version majuscules sans accents, et sa traduction en chiffres.
# Exercice 2, version avec des ensembles
# (on pouvait aussi utiliser un expression régulière)
# On se débarasse des lettres accentuées (le dictionnaire est en iso-8859, alias latin1)
aa ='àâéèêëîïôùûüç'
bb ='aaeeeeiiouuuc'
t1 = str.maketrans(aa,bb)
ll= open('liste.de.mots.francais.frgut.txt', encoding='latin1').readlines()
def ok(w):
return set(w.translate(t1)).issubset(set('ioeshbdlzg\n'))
mm=[x for x in ll if ok(x)]
print ("nombre de mots : ", len(mm))
t2 = str.maketrans('IOESHBDLZG', '1035480729')
for x in mm:
y = x[:-1].translate(t1);
print (x[:-1], y.upper(), y.upper()[::-1].translate(t2))
On cherche maintenant les mots ne contenant que des lettres données, au plus un certain nombre de fois. Il faut donc écrire une fonction qui construit un dictionnaire des nombres d'occurrences de chaque caratère dans une chaîne, puis une fonction qui compare deux tels dictionnaires.
# On lit le dictionnaire sous forme d'une liste de lignes, sans le \n (pour changer)
ll = [w.rstrip() for w in open('liste.de.mots.francais.frgut.txt',encoding='latin1').readlines()]
# On se débarasse des lettres accentuées
aa = 'àâäéèêëîïôöûüùÿç'
bb = 'aaaeeeeiioouuuyc'
tt = str.maketrans(aa,bb)
# et on convertit tout en majuscules
ll = [w.translate(tt).upper() for w in ll]
from string import ascii_uppercase as AA
# Statistiques d'une chaîne : nombre d'occurences de chaque lettre de l'alphabet
def st(w):
return {x:w.count(x) for x in AA}
# On les précalcule pour tout le dictionnaire
statlist = [(w, st(w)) for w in ll]
# Comparaison de deux dictionnaires
def compare(d,e):
return all([d[k]<=e[k] for k in AA])
def lookup(w):
d = st(w)
words = [x[0] for x in statlist if compare(x[1],d)]
m = max(map(len,words))
return [w for w in words if len(w)==m]
lookup('ZERBHGDETGFGFDDGHJ')
lookup('XWRDYTRERASZ')
Il existe une solution courte utilisant une expression régulière, mais elles n'ont pas encore été traitées en cours, et ce n'est pas ce qui était demandé ici.
Il faut comprendre deux choses :
Plutôt que d'essayer de déterminer ce qui est de l'espace ou de la ponctuation, il vaut mieux garder les lettres. x.isalpha()
nous dit si x est considéré comme une lettre.
Le résultat doit être une chaîne que l'on construit caractère par caractère. On empile donc ces caractères dans une liste ll
qu'on écrasera à la fin avec la méthode join
de la chaîne vide.
Au départ, ll
est vide. On va lire un par un les caractères de la chaîne s
que l'on veut brouiller. On la parcourt en gérant un indice i
. Si le caractère s[i]
n'est pas une lettre, on l'insère à la fin de ll
et on passe au suivant. Si c'est une lettre, on l'insère dans une liste auxiliaire mm
et on continue jusqu'à ce qu'on rencontre de nouveau un caractère non alphabétique. mm
contient alors un mot. S'il n'a pas au moins 4 lettres, on ne peut pas le mélanger, on le rajoute donc tel quel à la fin de ll
. Sinon, on le mélange avant de l'ajouter. On réinitialise mm
à la liste vide, on met a jour l'indice i
et c'est reparti.
Pour appeler le programme sur un fichier, on devra préciser l'encodage. Si on ne donne pas d'argument, le script affichera un prompt et demandera du texte.
#!/usr/bin/env python
from random import shuffle
def blurr(s):
ll = []; i=0
while i in range(len(s)):
mm=[]
while i<len(s) and s[i].isalpha():
mm.append(s[i])
i+=1
if mm:
if len(mm)>3:
uu=mm[1:-1]; shuffle(uu) # Mélange la liste en place, il faut lui donner un nom
ll.extend([mm[0]]+uu+[mm[-1]])
else:
ll.extend(mm)
continue
else:
ll.append(s[i]):
i+=1
return ''.join(ll)
if __name__=="__main__":
import sys
try:
s = open(sys.argv[1],encoding=sys.argv[2]).read()
print (blurr(s))
except:
s = input('texte: ')
print ('---> ', blurr(s))
$ cat corbeau.txt Maître Corbeau, sur un arbre perché, Tenait en son bec un fromage. Maître Renard, par l’odeur alléché, Lui tint à peu près ce langage : « Hé ! bonjour, Monsieur du Corbeau. Que vous êtes joli ! que vous me semblez beau ! Sans mentir, si votre ramage Se rapporte à votre plumage, Vous êtes le Phénix des hôtes de ces bois. » À ces mots le Corbeau ne se sent pas de joie ; Et pour montrer sa belle voix, Il ouvre un large bec, laisse tomber sa proie. Le Renard s’en saisit, et dit : « Mon bon Monsieur, Apprenez que tout flatteur Vit aux dépens de celui qui l’écoute : Cette leçon vaut bien un fromage, sans doute. » Le Corbeau, honteux et confus, Jura, mais un peu tard, qu’on ne l’y prendrait plus. $ ./blur3.py corbeau.txt utf8 Mîtrae Craboeu, sur un abrre pecrhé, Tinaet en son bec un fgrmoae. Marîte Renard, par l’oeudr aélclhé, Lui tnit à peu près ce laggane : « Hé ! bonujor, Meiuonsr du Corbeau. Que vous êtes joli ! que vous me slebmez baeu ! Snas mniter, si vrote rmagae Se rapotpre à vrote pumlgae, Vous êtes le Pnhiéx des hôets de ces bois. » À ces mtos le Caorebu ne se sent pas de jioe ; Et puor mrtoner sa blele viox, Il orvue un lrgae bec, lissae tebmor sa porie. Le Rarned s’en sasiit, et dit : « Mon bon Msnieour, Aperenpz que tuot fettlaur Vit aux dpeéns de cueli qui l’éuotce : Ctete loçen vaut bein un foramge, sans dtoue. » Le Coaerbu, houetnx et cunfos, Jrua, mais un peu trad, qu’on ne l’y paneidrrt plus.