Python - Corrigé du TD 2
Exercice 1
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
'''
Mélange aléatoirement les lettres internes des mots d'un fichier
ou de l'entrée standard
Usage: blurr [<fichier> <encodage>]
'''
from random import shuffle
# le plus simple est de construire une liste des codes "latin1"
# de ce qu'on veut considérer comme des lettres.
# La méthode "decode" des chaînes convertit en unicode
# On peut ensuite réencoder en ce qu'on veut :
### >>> 'é'.decode('utf8').encode('latin1')
### '\xe9'
letters = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'\xa6', '\xa8', '\xaa', '\xb4', '\xb5', '\xb8', '\xba', '\xbc',
'\xbd', '\xbe', '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5',
'\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd',
'\xce', '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5',
'\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde',
'\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6',
'\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee',
'\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6',
'\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff']
# On lira ensuite tout le fichier, ou l'entrée standard, sous forme d'une
# seule chaîne s. La fonction suivante examine chaque caractère de s.
# Si ce n'est pas une lettre, elle l'insère dans une liste ll, qui sera
# convertie en chaîne à la fin. Si c'est une lettre, elle l'insère dans
# une liste mm, ainsi que toutes les lettres suivantes. Dès qu'on rencontre
# un autre caractère, on mélange les lettres internes de mm, et on concatène
# le résultat à ll:
def blurr(s):
ll = []; i=0
while i in range(len(s)):
mm=[]
while i < len(s) and s[i] in letters:
mm.append(s[i])
i+=1
if mm:
if len(mm)>3:
uu=mm[1:-1]; shuffle(uu) # s'applique à une liste
ll+=[mm[0]]+uu+[mm[-1]] # et la modifie
else:
ll+=mm
continue
else:
while i < len(s) and s[i] not in letters:
ll.append(s[i])
i+=1
return ''.join(ll)
if __name__=="__main__":
# arguments: <fichier> <encodage>
import sys
if len(sys.argv)>2:
s = open(sys.argv[1],'r').read()
e = sys.argv[2]
t = unicode(blurr(s), e)
print t
# ou alors l'entrée standard
else:
s = raw_input('texte: ')
print '---> ', blurr(s)
Le cours 2 montre une solution plus efficace utilisant des expressions
rationnelles.
#!/usr/bin/env python
import random, re, sys
p = re.compile('(\w)(\w+)(\w)', re.M|re.L|re.U)
def touille(m):
milieu = list(m.group(2))
random.shuffle(milieu)
return m.group(1) + ''.join(milieu) +
m.group(3)
if len(sys.argv)==4:
s = open(sys.argv[1]).read().decode(sys.argv[2])
t = p.sub(touille, s).encode(sys.argv[3])
sys.stdout.write(t)
else:
print "Usage: touille <fichier> <encodage>
<encodage>"
Pour construire la liste "letters" sans se fatiguer :
# A exécuter ligne à ligne dans l'intérpréteur
# On construit une liste de tous les caractères encodables en latin1
s=''.join([chr(i).decode('latin1') for i in range(256)])
# On l'imprime
print s
# On efface ce qui n'est pas une lettre
# C'est vite fait car ça marche par tranches
t='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
# et voilà la liste cherchée
letters = [x.encode('latin1') for x in t.decode('utf8')]
print letters
Exercice 2
#!/usr/bin/env python
# -*- encoding: utf8 -*-
"""
Client pour serveur d'injures du capitaine Haddock, en xmlrpc (imite un exemple classique de SOAP)
"""
from xmlrpclib import ServerProxy
from base64 import *
server=ServerProxy("http://monge.univ-mlv.fr:8888")
if "__name__==__main__":
print __doc__
print "Methodes du serveur:\n"
for m in server.system.listMethods(): print m
print
print "Un appel de server.jure() donne: ", server.jure()
print "C'est en base 64, il faut decoder: "
print "\n\t"+decodestring(server.jure()).rstrip()+"!"
open('insultes.txt','w').write(decodestring(server.tous_les_jurons()))
print "Liste récupérée!"
# Un peu de curiosité permet de récupérer le code du serveur
print "\n\t"+decodestring(server.__())
Code du serveur :
# -*- coding: iso-8859-15 -*-
#!/usr/bin/env python
"""
Serveur d'injures du capitaine Haddock. Utilise
le
protocole xmlrpc. Le données sont encodées
en
base 64 à cause des caracteres accentués.
"""
from SimpleXMLRPCServer import SimpleXMLRPCServer as Server
from random import randint
jurons=open('jurons.txt','r').readlines()
def jure():
return jurons[randint(0,len(jurons))].encode('base64')
def help(): return "ENCODAGE=BASE64"
def __():
s=open('haddockServer.py','r').read()
return s.encode('base64')
def tous_les_jurons():
s=open('jurons.txt','r').read()
return s.encode('base64')
server = Server(('193.55.63.80', 8888))
server.register_function(tous_les_jurons)
server.register_function(jure)
server.register_function(help)
server.register_function(__)
server.register_introspection_functions()
try:
server.serve_forever()
finally:
server.server_close()