Solution du TD 2

Exercice 1

In [1]:
# On peut avoir un pas négatif
def is_palindrome(w):
    return w == w[::-1]

is_palindrome('able was I ere I saw elba')
Out[1]:
True
In [2]:
# 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')
Out[2]:
True
In [3]:
# Pensez à ce que vous feriez avec un paquet de cartes et écrivez le entre []
# Noter l'astuce 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])
Out[3]:
[1, 3, 5, 4, 2, 1, 3, 1, 2, 1]
In [4]:
# Remarquer les fonctions de conversion
def digits_sum(n):
    return sum([int(c) for c in str(n)])

digits_sum(2**100)
Out[4]:
115

Exercice 2

In [5]:
# Exercice 2, version avec une expression régulière
# (on pouvait aussi le faire avec des ensembles)
import re, string

# On se débarasse des lettres accentuées (le dictionnaire est en iso-8859, alias  latin1)
aa ='àâéèêëîïôùûü'.decode('utf8').encode('latin1')
bb ='aaeeeeiiouuu'.decode('utf8').encode('latin1')
t1 = string.maketrans(aa,bb)

ll= [string.translate(w,t1).decode('latin-1').encode('utf8')
        for w in
        open('liste.de.mots.francais.frgut.txt').readlines()]

pat=r'[ioeshbdlzg]+\n'
mm=[x for x in ll if re.match(pat,x)]
print "nombre de mots : ", len(mm)

t2 = string.maketrans('IOESHBDLZG', '1035480729')

for x in mm:
    print x[:-1].upper(), string.translate(x[:-1].upper()[::-1],t2)
nombre de mots :  837
BEBE 3838
BEBES 53838
BEE 338
BEES 5338
BEEZ 2338
BEIEZ 23138
BEIGE 39138
BEIGES 539138
BEL 738
BELE 3738
BELE 3738
BELEE 33738
BELEES 533738
BELES 53738
BELES 53738
BELEZ 23738
BELGE 39738
BELGES 539738
BELIEZ 231738
BELLE 37738
BELLES 537738
BIBI 1818
BIBIS 51818
BIBLE 37818
BIBLES 537818
BIDE 3018
BIDES 53018
BIELLE 377318
BIELLES 5377318
BIGLE 37918
BIGLE 37918
BIGLEE 337918
BIGLEES 5337918
BIGLES 537918
BIGLES 537918
BIGLEZ 237918
BIGLIEZ 2317918
BILE 3718
BILE 3718
BILEE 33718
BILEES 533718
BILES 53718
BILES 53718
BILEZ 23718
BILIEZ 231718
BILL 7718
BILLE 37718
BILLES 537718
BILLS 57718
BILOBE 380718
BILOBEE 3380718
BILOBEES 53380718
BILOBES 5380718
BIOLOGIE 31907018
BIOLOGIES 531907018
BIS 518
BISBILLE 37718518
BISBILLES 537718518
BISE 3518
BISE 3518
BISEE 33518
BISEES 533518
BISES 53518
BISES 53518
BISEZ 23518
BISIEZ 231518
BISSE 35518
BISSE 35518
BISSEE 335518
BISSEES 5335518
BISSES 535518
BISSES 535518
BISSEZ 235518
BISSIEZ 2315518
BLE 378
BLED 0378
BLEDS 50378
BLES 5378
BLESE 35378
BLESE 35378
BLESEE 335378
BLESEES 5335378
BLESES 535378
BLESES 535378
BLESEZ 235378
BLESIEZ 2315378
BLESSE 355378
BLESSE 355378
BLESSEE 3355378
BLESSEES 53355378
BLESSES 5355378
BLESSES 5355378
BLESSEZ 2355378
BLESSIEZ 23155378
BOB 808
BOBO 0808
BOBOS 50808
BOBS 5808
BOBSLEIGH 491375808
BOBSLEIGHS 5491375808
BOESSE 355308
BOESSES 5355308
BOGHEI 134908
BOGHEIS 5134908
BOGIE 31908
BOGIES 531908
BOILLE 377108
BOILLES 5377108
BOIS 5108
BOISE 35108
BOISE 35108
BOISEE 335108
BOISEES 5335108
BOISES 535108
BOISES 535108
BOISEZ 235108
BOISIEZ 2315108
BOL 708
BOLDO 00708
BOLDOS 500708
BOLEE 33708
BOLEES 533708
BOLIDE 301708
BOLIDES 5301708
BOLS 5708
BOSS 5508
BOSSE 35508
BOSSE 35508
BOSSEE 335508
BOSSEES 5335508
BOSSELE 3735508
BOSSELEE 33735508
BOSSELEES 533735508
BOSSELES 53735508
BOSSELEZ 23735508
BOSSELIEZ 231735508
BOSSELLE 37735508
BOSSELLES 537735508
BOSSES 535508
BOSSES 535508
BOSSEZ 235508
BOSSIEZ 2315508
DE 30
DE 30
DEBILE 371830
DEBILES 5371830
DEBOISE 3510830
DEBOISE 3510830
DEBOISEE 33510830
DEBOISEES 533510830
DEBOISES 53510830
DEBOISES 53510830
DEBOISEZ 23510830
DEBOISIEZ 231510830
DEBOSSELE 373550830
DEBOSSELEE 3373550830
DEBOSSELEES 53373550830
DEBOSSELES 5373550830
DEBOSSELEZ 2373550830
DEBOSSELIEZ 23173550830
DEBOSSELLE 3773550830
DEBOSSELLES 53773550830
DEDIE 31030
DEDIE 31030
DEDIEE 331030
DEDIEES 5331030
DEDIES 531030
DEDIES 531030
DEDIEZ 231030
DEDIIEZ 2311030
DEDIS 51030
DEDISE 351030
DEDISES 5351030
DEDISIEZ 23151030
DEDISSE 3551030
DEDISSES 53551030
DEDISSIEZ 231551030
DEESSE 355330
DEESSES 5355330
DEGEL 73930
DEGELE 373930
DEGELE 373930
DEGELEE 3373930
DEGELEES 53373930
DEGELES 5373930
DEGELES 5373930
DEGELEZ 2373930
DEGELIEZ 23173930
DEGELS 573930
DEGOBILLE 377180930
DEGOBILLE 377180930
DEGOBILLEE 3377180930
DEGOBILLEES 53377180930
DEGOBILLES 5377180930
DEGOBILLES 5377180930
DEGOBILLEZ 2377180930
DEGOBILLIEZ 23177180930
DEGOISE 3510930
DEGOISE 3510930
DEGOISEE 33510930
DEGOISEES 533510930
DEGOISES 53510930
DEGOISES 53510930
DEGOISEZ 23510930
DEGOISIEZ 231510930
DELEBILE 37183730
DELEBILES 537183730
DELIE 31730
DELIE 31730
DELIEE 331730
DELIEES 5331730
DELIES 531730
DELIES 531730
DELIEZ 231730
DELIIEZ 2311730
DELISSE 3551730
DELISSE 3551730
DELISSEE 33551730
DELISSEES 533551730
DELISSES 53551730
DELISSES 53551730
DELISSEZ 23551730
DELISSIEZ 231551730
DELOGE 390730
DELOGE 390730
DELOGEE 3390730
DELOGEES 53390730
DELOGES 5390730
DELOGES 5390730
DELOGEZ 2390730
DELOGIEZ 23190730
DES 530
DES 530
DES 530
DESOBEI 1380530
DESOBEIE 31380530
DESOBEIES 531380530
DESOBEIS 51380530
DESOBEISSE 3551380530
DESOBEISSES 53551380530
DESOBEISSEZ 23551380530
DESOBEISSIEZ 231551380530
DESOBLIGE 391780530
DESOBLIGE 391780530
DESOBLIGEE 3391780530
DESOBLIGEES 53391780530
DESOBLIGES 5391780530
DESOBLIGES 5391780530
DESOBLIGEZ 2391780530
DESOBLIGIEZ 23191780530
DESOLE 370530
DESOLE 370530
DESOLEE 3370530
DESOLEES 53370530
DESOLES 5370530
DESOLES 5370530
DESOLEZ 2370530
DESOLIEZ 23170530
DESOSSE 3550530
DESOSSE 3550530
DESOSSEE 33550530
DESOSSEES 533550530
DESOSSES 53550530
DESOSSES 53550530
DESOSSEZ 23550530
DESOSSIEZ 231550530
DESSELLE 37735530
DESSELLE 37735530
DESSELLEE 337735530
DESSELLEES 5337735530
DESSELLES 537735530
DESSELLES 537735530
DESSELLEZ 237735530
DESSELLIEZ 2317735530
DESSILLE 37715530
DESSILLE 37715530
DESSILLEE 337715530
DESSILLEES 5337715530
DESSILLES 537715530
DESSILLES 537715530
DESSILLEZ 237715530
DESSILLIEZ 2317715530
DESSOLE 3705530
DESSOLE 3705530
DESSOLEE 33705530
DESSOLEES 533705530
DESSOLES 53705530
DESSOLES 53705530
DESSOLEZ 23705530
DESSOLIEZ 231705530
DG 90
DIESE 35310
DIESEL 735310
DIESELS 5735310
DIESES 535310
DIODE 30010
DIODES 530010
DIS 510
DISE 3510
DISES 53510
DISIEZ 231510
DISSE 35510
DISSES 535510
DISSIEZ 2315510
DL 70
DO 00
DODO 0000
DODOS 50000
DOGE 3900
DOGES 53900
DOIS 5100
DOL 700
DOLE 3700
DOLE 3700
DOLEE 33700
DOLEES 533700
DOLES 53700
DOLES 53700
DOLEZ 23700
DOLIEZ 231700
DOLS 5700
DOS 500
DOSE 3500
DOSE 3500
DOSEE 33500
DOSEES 533500
DOSES 53500
DOSES 53500
DOSEZ 23500
DOSIEZ 231500
DOSSE 35500
DOSSES 535500
EBISELE 3735183
EBISELE 3735183
EBISELEE 33735183
EBISELEES 533735183
EBISELES 53735183
EBISELES 53735183
EBISELEZ 23735183
EBISELIEZ 231735183
EBOSSE 355083
EBOSSE 355083
EBOSSEE 3355083
EBOSSEES 53355083
EBOSSES 5355083
EBOSSES 5355083
EBOSSEZ 2355083
EBOSSIEZ 23155083
EDILE 37103
EDILES 537103
EGIDE 30193
EGIDES 530193
EGLISE 351793
EGLISES 5351793
EGO 093
EGOSILLE 37715093
EGOSILLEE 337715093
EGOSILLEES 5337715093
EGOSILLES 537715093
EGOSILLEZ 237715093
EGOSILLIEZ 2317715093
EH 43
ELEGI 19373
ELEGIE 319373
ELEGIES 5319373
ELEGIS 519373
ELEGISSEZ 235519373
ELEGISSIEZ 2315519373
ELEIS 51373
ELIDE 30173
ELIDE 30173
ELIDEE 330173
ELIDEES 5330173
ELIDES 530173
ELIDES 530173
ELIDEZ 230173
ELIDIEZ 2310173
ELIGIBLE 37819173
ELIGIBLES 537819173
ELIS 5173
ELISE 35173
ELISES 535173
ELISEZ 235173
ELISIEZ 2315173
ELLE 3773
ELLES 53773
ELODEE 330073
ELODEES 5330073
ELOGE 39073
ELOGES 539073
ES 53
ES 53
ESSE 3553
ESSES 53553
GEL 739
GELE 3739
GELE 3739
GELEE 33739
GELEES 533739
GELES 53739
GELES 53739
GELEZ 23739
GELIEZ 231739
GELOSE 350739
GELOSES 5350739
GELS 5739
GEODE 30039
GEODES 530039
GEODESIE 31530039
GEODESIES 531530039
GEOIDE 301039
GEOIDES 5301039
GEOLE 37039
GEOLES 537039
GEOLOGIE 31907039
GEOLOGIES 531907039
GESSE 35539
GESSES 535539
GHILDE 307149
GHILDES 5307149
GIBOIE 310819
GIBOIES 5310819
GIGOLO 070919
GIGOLOS 5070919
GILDE 30719
GILDES 530719
GILLE 37719
GILLES 537719
GIS 519
GISEZ 23519
GISIEZ 231519
GLEBE 38379
GLEBES 538379
GLISSE 355179
GLISSE 355179
GLISSEE 3355179
GLISSEES 53355179
GLISSES 5355179
GLISSES 5355179
GLISSEZ 2355179
GLISSIEZ 23155179
GLOBE 38079
GLOBES 538079
GLOSE 35079
GLOSE 35079
GLOSEE 335079
GLOSEES 5335079
GLOSES 535079
GLOSES 535079
GLOSEZ 235079
GLOSIEZ 2315079
GO 09
GOBE 3809
GOBE 3809
GOBEE 33809
GOBEES 533809
GOBES 53809
GOBES 53809
GOBEZ 23809
GOBIE 31809
GOBIES 531809
GOBIEZ 231809
GODE 3009
GODE 3009
GODES 53009
GODEZ 23009
GODIEZ 231009
GODILLE 3771009
GODILLE 3771009
GODILLES 53771009
GODILLEZ 23771009
GODILLIEZ 231771009
GOGO 0909
GOGOS 50909
GOI 109
GOSSE 35509
GOSSES 535509
HE 34
HELE 3734
HELE 3734
HELEE 33734
HELEES 533734
HELES 53734
HELES 53734
HELEZ 23734
HELIEZ 231734
HELLO 07734
HELODEE 3300734
HELODEES 53300734
HI 14
HIE 314
HIEBLE 378314
HIEBLES 5378314
HIES 5314
HISSE 35514
HISSE 35514
HISSEE 335514
HISSEES 5335514
HISSES 535514
HISSES 535514
HISSEZ 235514
HISSIEZ 2315514
HO 04
HOBBIES 5318804
HOLOSIDE 30150704
HOLOSIDES 530150704
IBIS 5181
IDE 301
IDEE 3301
IDEEL 73301
IDEELLE 3773301
IDEELLES 53773301
IDEELS 573301
IDEES 53301
IDEOLOGIE 319070301
IDEOLOGIES 5319070301
IDEOLOGISE 3519070301
IDEOLOGISE 3519070301
IDEOLOGISEE 33519070301
IDEOLOGISEES 533519070301
IDEOLOGISES 53519070301
IDEOLOGISES 53519070301
IDEOLOGISEZ 23519070301
IDEOLOGISIEZ 231519070301
IDES 5301
IDOLE 37001
IDOLES 537001
IGLOO 00791
IGLOOS 500791
IL 71
ILE 371
ILES 5371
ILLISIBLE 378151771
ILLISIBLES 5378151771
ILS 571
IODE 3001
IODE 3001
IODEE 33001
IODEES 533001
IODES 53001
IODES 53001
IODEZ 23001
IODIEZ 231001
IODLE 37001
IODLE 37001
IODLEE 337001
IODLEES 5337001
IODLES 537001
IODLES 537001
IODLEZ 237001
IODLIEZ 2317001
ISOGLOSSE 355079051
ISOGLOSSES 5355079051
ISOLE 37051
ISOLE 37051
ISOLEE 337051
ISOLEES 5337051
ISOLES 537051
ISOLES 537051
ISOLEZ 237051
ISOLIEZ 2317051
LE 37
LEBEL 73837
LEBELS 573837
LEGE 3937
LEGES 53937
LEGS 5937
LEI 137
LES 537
LES 537
LESE 3537
LESE 3537
LESEE 33537
LESEES 533537
LESES 53537
LESES 53537
LESEZ 23537
LESIEZ 231537
LI 17
LIBELLE 3773817
LIBELLE 3773817
LIBELLEE 33773817
LIBELLEES 533773817
LIBELLES 53773817
LIBELLES 53773817
LIBELLEZ 23773817
LIBELLIEZ 231773817
LIBIDO 001817
LIBIDOS 5001817
LIDO 0017
LIDOS 50017
LIE 317
LIE 317
LIED 0317
LIEDS 50317
LIEE 3317
LIEES 53317
LIEGE 39317
LIEGE 39317
LIEGEE 339317
LIEGEES 5339317
LIEGEOIS 51039317
LIEGEOISE 351039317
LIEGEOISES 5351039317
LIEGES 539317
LIEGES 539317
LIEGEZ 239317
LIEGIEZ 2319317
LIES 5317
LIES 5317
LIESSE 355317
LIESSES 5355317
LIEZ 2317
LIGE 3917
LIGES 53917
LIGIE 31917
LIGIES 531917
LIIEZ 23117
LIS 517
LISE 3517
LISES 53517
LISEZ 23517
LISIBLE 3781517
LISIBLES 53781517
LISIEZ 231517
LISSE 35517
LISSE 35517
LISSEE 335517
LISSEES 5335517
LISSES 535517
LISSES 535517
LISSEZ 235517
LISSIEZ 2315517
LOB 807
LOBBIES 5318807
LOBE 3807
LOBE 3807
LOBEE 33807
LOBEES 533807
LOBELIE 3173807
LOBELIES 53173807
LOBES 53807
LOBES 53807
LOBEZ 23807
LOBIEZ 231807
LOBS 5807
LODS 5007
LOESS 55307
LOGE 3907
LOGE 3907
LOGEE 33907
LOGEES 533907
LOGES 53907
LOGES 53907
LOGEZ 23907
LOGIEZ 231907
LOGIS 51907
LOGO 0907
LOGOS 50907
LOI 107
LOIS 5107
LOISIBLE 37815107
LOISIBLES 537815107
LOLO 0707
LOLOS 50707
OBEI 1380
OBEIS 51380
OBEISSE 3551380
OBEISSES 53551380
OBEISSEZ 23551380
OBEISSIEZ 231551380
OBEL 7380
OBELE 37380
OBELES 537380
OBELS 57380
OBESE 35380
OBESES 535380
OBLIGE 391780
OBLIGE 391780
OBLIGEE 3391780
OBLIGEES 53391780
OBLIGES 5391780
OBLIGES 5391780
OBLIGEZ 2391780
OBLIGIEZ 23191780
OBOLE 37080
OBOLES 537080
OBSEDE 303580
OBSEDE 303580
OBSEDEE 3303580
OBSEDEES 53303580
OBSEDES 5303580
OBSEDES 5303580
OBSEDEZ 2303580
OBSEDIEZ 23103580
ODE 300
ODES 5300
OEIL 7130
OH 40
OHE 340
OIE 310
OIES 5310
OIL 710
OILLE 37710
OILLES 537710
OIS 510
OISELE 373510
OISELEE 3373510
OISELEES 53373510
OISELES 5373510
OISELEZ 2373510
OISELIEZ 23173510
OISELLE 3773510
OISELLES 53773510
OLE 370
OLLE 3770
OS 50
OSE 350
OSE 350
OSEE 3350
OSEES 53350
OSEILLE 3771350
OSEILLES 53771350
OSES 5350
OSES 5350
OSEZ 2350
OSIDE 30150
OSIDES 530150
OSIEZ 23150
SE 35
SEBILE 371835
SEBILES 5371835
SEIDE 30135
SEIDES 530135
SEIGLE 379135
SEIGLES 5379135
SEILLE 377135
SEILLES 5377135
SEIZE 32135
SEL 735
SELLE 37735
SELLE 37735
SELLEE 337735
SELLEES 5337735
SELLES 537735
SELLES 537735
SELLEZ 237735
SELLIEZ 2317735
SELS 5735
SES 535
SESSILE 3715535
SESSILES 53715535
SI 15
SIED 0315
SIEE 3315
SIEGE 39315
SIEGE 39315
SIEGES 539315
SIEGEZ 239315
SIEGIEZ 2319315
SIGILLE 3771915
SIGILLEE 33771915
SIGILLEES 533771915
SIGILLES 53771915
SIGISBEE 33851915
SIGISBEES 533851915
SIGLE 37915
SIGLES 537915
SIL 715
SILO 0715
SILOS 50715
SILS 5715
SIS 515
SISE 3515
SISES 53515
SODE 3005
SODEE 33005
SODEES 533005
SODES 53005
SOI 105
SOIE 3105
SOIES 53105
SOIS 5105
SOL 705
SOLDE 30705
SOLDE 30705
SOLDEE 330705
SOLDEES 5330705
SOLDES 530705
SOLDES 530705
SOLDEZ 230705
SOLDIEZ 2310705
SOLE 3705
SOLEIL 713705
SOLEILS 5713705
SOLES 53705
SOLIDE 301705
SOLIDES 5301705
SOLO 0705
SOLOS 50705
SOLS 5705
SOSIE 31505
SOSIES 531505
ZEE 332
ZEES 5332
ZELE 3732
ZELE 3732
ZELEE 33732
ZELEES 533732
ZELES 53732
ZELES 53732
ZELLIGE 3917732
ZELLIGES 53917732
ZIBE 3812
ZIBE 3812
ZIBEE 33812
ZIBEES 533812
ZIBES 53812
ZIBES 53812
ZIBEZ 23812
ZIBIEZ 231812
ZIG 912
ZIGS 5912
ZIZI 1212
ZIZIS 51212
ZOILE 37102
ZOILES 537102
ZOO 002
ZOOGLEE 3379002
ZOOGLEES 53379002
ZOOIDE 301002
ZOOIDES 5301002
ZOOLOGIE 31907002
ZOOLOGIES 531907002
ZOOS 5002
ZOZO 0202
ZOZOS 50202
In [6]:
# Exercice 2 : Scrabble
# On lit le dictionnaire sous forme d'une  liste de lignes, sans le '\n'
ll = [w.rstrip() for w in open('liste.de.mots.francais.frgut.txt').readlines()]

# On se débarasse des lettres accentuées

from string import maketrans
aa = 'àâäéèêëîïôöûüùÿç'.decode('utf8').encode('latin1')
bb = 'aaaeeeeiioouuuyc'.decode('utf8').encode('latin1')
tt = 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]
In [7]:
lookup('ZERXHGVHREAZZRFXH')
Out[7]:
['GRAVEREZ']
In [8]:
lookup('XWRDYTRERASZ')
Out[8]:
['DARTRES', 'RETARDS', 'STEWARD']
In [10]:
# Exercice 3

#Le cours 2 suggère une solution  utilisant des expressions régulières.
#!/usr/bin/env python


import random, re, sys

p = re.compile('(\w)(\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>"
Usage: touille <fichier> <encodage> <encodage>
In [11]:
# Solution pédestre

#!/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)
                ll.extend([mm[0]]+uu+[mm[-1]])
            else:
                ll.extend(mm)
            continue
        else:
            while i<len(s) and not s[i].isalpha():
                ll.append(s[i])
                i+=1
    return ''.join(ll)


if __name__=="__main__":

    import sys
    
    if len(sys.argv)>1:
        s = open(sys.argv[1]).read()
        print blurr(s)
        
    else:
        s = raw_input('texte: ')
        print '--->  ', blurr(s)