Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 01-01-2016 19:01:06

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

python3 : jouer à 'qui_fait_pareil_en_plus_court'

Yep les copains DF,

je débute en python, et je me suis donnée comme but de codé l'algo : "écrire un programme qui affiche le nombre de toutes les lettres identiques et toutes ces lettres identiques ainsi que le nombre de lettres différentes et toutes ces lettres différentes entre deux string entrées par un utilisateur.


# compare_two_strings
# l'algo doit donner le nombre et toutes les lettres identiques ainsi que le nombre et toutes les lettres différentes de deux string entrées par l'utilisateur

s1 = input("entrer un premier mot : \n")
s2 =  input("entrer un deuxième mot : \n")

liste1 = []  # la 'liste1' servira a contenir sous forme de liste les lettres de la string 's1'
liste2 = []  # la 'liste2' servira a contenir sous forme de liste les lettres de la string 's2'
liste3 = []  # la 'liste3' servira a contenir sous forme de liste les lettres de la string 's1' et les lettres de la string 's2'

i = 0
max1 = len(s1)
max2 = len(s2)

# On copie s1 dans liste1 et dans liste2
while i< max1:
    liste1.append(s1[i])
    liste3.append(s1[i])
    i +=1

#print("s1 est :",  liste1)                                            # pour remplacer le debug

i = 0

# On copie s2 dans 'liste2' et 'liste3'
while i< max2:
    liste2.append(s2[i])
    liste3.append(s2[i])
    i +=1

#print("s2 est : ",  liste2)                                           # pour remplacer le debug

#print("Liste3 (les lettres de s1 et s2) : ", liste3)            # pour remplacer le debug

i = 0

# On enlève les doublons de 'liste3', ce qui permet d'obtenir toutes les lettres de s1 et de s2 sans doublon
ssDoublon = set(liste3)
ssD = []
for l in ssDoublon:
    ssD.append(l)
#print("la liste sans doublon est : ", ssD)                          # pour remplacer le debug

# On cherche toutes les lettres identiques entre s1 et s2 et on ajoute à la liste 'listeID' toutes les lettres identiques de s1 et s2 sont copiées
tailleS1 = len(s1)
tailleS2 = len(s2)
tailleS3 = len(liste3)
tailleSsd = len(ssD)
i =0
listeID = []
listeDiff= []
while i < tailleSsd:
    lettre = ssD[i]
    for l in s1:
        for L in s2:
            if lettre == l and lettre == L:
                listeID.append(l)
    i += 1

#print("identiques : ", listeID)                                           # pour remplacer le debug
listeIdTrillee = set(listeID)
nblisteIdTrillee = len(set(listeID))

#print("nbre de lettres identiques", nblisteIdTrillee)               # pour remplacer le debug
print("Les mots ",  s1,  "et",  s2,  "ont",  nblisteIdTrillee, "lettre(s) identique(s) :", listeIdTrillee )


# On s'occupe des lettres différentes entre s1 et s2
i = 0
if nblisteIdTrillee > 0:    # s'il y a au moins une lettre identique entre les deux strings, alors je me sers de la liste des lettres identiques
    while i < nblisteIdTrillee:
        lettre = listeID[i]
        for l in ssD:
            if lettre != l:
                listeDiff.append(l)
        i += 1
    listeDiffTrillee = set(listeDiff)
    nblisteDiffTrillee = len(listeDiffTrillee)
    print("Les mots ",  s1,  "et",  s2,  "ont",  nblisteDiffTrillee,  "lettre(s) différente(s) :", listeDiffTrillee )
if nblisteIdTrillee == 0:   # Si toutes les lettres sont différentes alors la liste des lettres différentes == s1 + s2
                                 #  ou encore à la liste des lettres différentes sans doublon
    print("Les mots ",  s1,  "et",  s2,  "ont",  tailleS3,  "lettre(s) différente(s) :", liste3)




 



pour qui veut jouer à "Qui fait pareil en plus court" :P

Hors ligne

#2 01-01-2016 19:07:57

paskal
autobahn
Lieu : ailleurs
Inscription : 14-06-2011
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Yohoho  smile

Plus court, vraiment mais précise : en longueur de code ? en temps d'exécution ? ...

I'd love to change the world
But I don't know what to do
So I'll leave it up to you...

logo-sur-fond.png

Hors ligne

#3 01-01-2016 20:09:43

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

ouais en longueur de code tongue

Hors ligne

#4 01-01-2016 20:23:47

paskal
autobahn
Lieu : ailleurs
Inscription : 14-06-2011
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Ok  smile

C'est que mon neurone risque de faire fusible ... mais je chercherais bien du côté des fonctions et récurrences ...  smile

I'd love to change the world
But I don't know what to do
So I'll leave it up to you...

logo-sur-fond.png

Hors ligne

#5 01-01-2016 20:28:45

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

oups, pas encore fait le chapitre...

je vais regarder smile

merci !!!

Hors ligne

#6 01-01-2016 20:41:10

paskal
autobahn
Lieu : ailleurs
Inscription : 14-06-2011
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Il existe sans doute d'autres pistes ...  smile

I'd love to change the world
But I don't know what to do
So I'll leave it up to you...

logo-sur-fond.png

Hors ligne

#7 01-01-2016 20:42:59

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Salut smile

Est-il nécessaire de déclarer les listes liste1 et liste2. Il me semble que les chaînes sont déjà des listes. Du coup, tu peur travailler directement avec s1 et s2, et tu gagne déjà une 15aine de ligne wink

Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#8 02-01-2016 10:19:52

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Salut

Voilà mon résultat. En fait, savoir si une variable est déjà contenu dans une liste, c'est simple avec le mot in

# compare_two_strings
# l'algo doit donner le nombre et toutes les lettres identiques ainsi que le nombre et toutes les lettres différentes de deux string entrées par l'utilisateur

#Saisie des mots de façon insensible à la casse. Sinon, "Truc" et "truc" sont différents
s1 = str.lower(input("entrer un premier mot : \n"))
s2 =  str.lower(input("entrer un deuxième mot : \n"))

#Création des 2 liste contenant les lettres communes et différentes. C'est fait en une ligne ;)
lettreCommunes,lettreDifferentes=[],[]

#Tout ce qui est dans s1 et s2 est commun, le reste non
for i in s1:
    if i in s2:
        lettreCommunes.append(i)
    else:
        lettreDifferentes.append(i)

#Il peut rester des lettres de s2 non présente dans s1. Dans ce cas les rajouter aux lettres différentes
for i in s2:
    if not i in lettreDifferentes and not i in lettreCommunes:
        lettreDifferentes.append(i)

#Tri des listes. Attention, ça modifie les listes d'origine
lettreCommunes.sort()
lettreDifferentes.sort()

#Sortie des liste et de leur nombre. On peut éviter les variables intermédiaires en utilisant directement des fonctions dans print
print("Les mots ",  s1,  "et",  s2,  "ont",  len(lettreCommunes),  "lettre(s) différente(s) :", lettreCommunes)
print("Les mots ",  s1,  "et",  s2,  "ont",  len(lettreDifferentes),  "lettre(s) différente(s) :", lettreDifferentes)
 


Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#9 02-01-2016 11:45:53

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Coucou,

en cherchant à suivre le conseil de bendia, et les encouragements de paskal, j'ai sensiblement réduit la partie "afficher les lettres identiques et leur nombre".

Par contre, le premier script était faux pour le morceau "trouver les lettres différentes et leur nombre" dès qu'il y avait répétition de lettres différentes.

Fonctionnait :
s1 = abcd
s2 = cdef

Mais ne fonctionnait pas  :

s1 = abcdabcd
s2 = cdefcdef

J'ai donc corrigé et tous les tests semblent fonctionner maintenant.

Mais j'ai dû garder le copiage des strings en listes pour pouvoir utiliser la fonction liste.remove...

ça donne cela maintenant :


# amélioration du code pour les lettres identiques
#correction_bug_lettres différentes

s1 = input("entrer un premier mot : \n")
s2 =  input("entrer un deuxième mot : \n")

####  ####    Je m'occupe des lettres identiques   ####  ####

## Je compare s1 avec s2 et je copie dans la liste 'listeID' les lettres identiques

i = 0
listeID = []

while i < len(s1):
    lettre = s1[i]
    for l in s2:
        if lettre == l:
            listeID.append(l)
    i += 1

## J'enlève les doublons de la liste des lettres identiques
listeIDSansDoublon = []
listeIDSansDoublon = set(listeID)

## J'affiche le résultat pour les lettres identiques
print("Les mots ",  s1,  "et",  s2,  "ont",  len(listeIDSansDoublon), "lettre(s) identique(s) :", listeIDSansDoublon )

####  #### Je m'occupe des lettres différentes.  ####  ####
## Il faut supprimer dans une liste correspondante à s1, les lettres qui sont les mêmes que celles de la liste correspondante à s2, et vis-versa

## Je crée liste1 et liste2 à partir de s1 et s2 pour pouvoir utiliser la fonction liste.remove(x) qu'on ne peut pas utiliser avec les strings
## Je crée liste3 pour avoir les lettres en commun et leur nombre ( utile pour supprimer avec une boucle qui tourne
## autant de fois en supprimant qu'il y a de lettres différentes (nbLettreDifferente = nbLettreEnCommun - nbLettreIdentique)

liste3 = []

i = 0
liste1 = []
while i< len(s1):
    liste1.append(s1[i])
    liste3.append(s1[i])
    i +=1

#print("liste1 = s1 :",  liste1)

i = 0
liste2 = []
while i< len(s2):
    liste2.append(s2[i])
    liste3.append(s2[i])
    i +=1

#print(" liste2 = s2 :",  liste2)
#print(" liste3  :",  liste3)

## je cherche le nombre de lettres en commun pour créer le nbre maxDiff
## maxDiff c'est le nbre de lettre en commun sans doublon - le nbre de lettres identiques
## maxDiff va servir à boucler pour supprimer dans liste1 ce qu'il y a de commun avec liste2, et cela tant qu'il reste des lettres

LettreEnCommun = []
LettreEnCommun = set(liste3)
#print(" LettreEnCommun (sans doublon) :",len(LettreEnCommun),   LettreEnCommun)
maxDiff = len(LettreEnCommun) - len(listeIDSansDoublon)
#print("maxDiff = ",  maxDiff)

## Je nettoie liste1 de ce qu'elle a en commun avec liste2
x = 0
while x < maxDiff:
    i = 0
    while i < len(s2):
        lettre = s2[i]
        for l in liste1:
            if l == lettre:
                liste1.remove(l)
        i += 1
    x += 1

## je nettoie liste2 de ce qu'elle a en commun avec liste 1
x = 0
while x < maxDiff:
    i =0
    while i < len(s1):
        lettre = s1[i]
        for l in liste2:
            if l == lettre:
                liste2.remove(l)
        i += 1
    x += 1

#print("la liste un est maintenant :",  liste1)
#print("la liste deux est maintenant :",  liste2)

## enfin on ajoute dans une nlle liste qui contiendra les lettres différentes de s1 et s2 (i.e. liste1 et liste2).
listeDiff = []
for l in liste1:
    listeDiff.append(l)
for l in liste2:
    listeDiff.append(l)
## On affiche le résultat pour les lettres différentes :
print("Les mots ",  s1,  "et",  s2,  "ont",  len(listeDiff), "lettre(s) différente(s) :", listeDiff )
 



On doit surement pouvoir faire mieux pour la jointure des lettres différentes, puisqu'en fait récupérer les lettres différentes, revient à  filtrer un ensemble d'ensembles en ne conservant que ceux qui sont totalement disjoints...

Dommage que ce ne sont pas des nombres roll

Merci à vous smile

Dernière modification par Hypathie (02-01-2016 11:46:49)

Hors ligne

#10 02-01-2016 12:37:51

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

hé bé !

set, ça fait un tableau \o/

en six lignes big_smile


txt1 = set(input("Entrez un premier mot \n"))
txt2  = set(input("Entrez un deuxième mot \n"))
print("lettre(s) identique(s) :")
print(txt1 & txt2, "\n")
print("lettre(s) diffirente(s) ) :")
print( (txt1 | txt2) -  (txt1 & txt2), "\n")
 



Merci à un copain pour la remarque.

Génial le python smile

Hors ligne

#11 02-01-2016 12:59:05

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Tu peux encore ganger 3 lignes wink

txt1 = set(input("Entrez un premier mot \n"))
txt2  = set(input("Entrez un deuxième mot \n"))
print("\nlettre(s) identique(s) : ", txt1 & txt2, "soit, ",len(txt1 & txt2)," lettre(s).\n" "lettre(s) diffirente(s) ) : ", (txt1 | txt2) -  (txt1 & txt2), "soit, ", len((txt1 | txt2) -  (txt1 & txt2)), " lettres(s).")
 


Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#12 02-01-2016 13:54:50

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

T'as gagné bendia cool

Hors ligne

#13 02-01-2016 15:28:43

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Non, je te laisses les points choco, c'est ton algo le meilleur. Pour ma part, j'ai juste un peu mieux concaténé la chaîne de réponse wink

Par contre au niveau des spécification, tu voulais éviter les doublon ou non, je n'ai pas bien compris ?

Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#14 02-01-2016 19:16:03

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

coucou smile

je voulais juste afficher ça

1451754643.png


J'avoue, je ne sais pas ce que c'est qu'une spécification... big_smile

Hors ligne

#15 02-01-2016 19:18:45

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Hypathie a écrit :

J'avoue, je ne sais pas ce que c'est qu'une spécification...

C'est le cahier des charges de ton script. Faut-il que les lettres en double n'apparaisse qu'une seule fois ou pas. En fait, je n'ai pas bien compris ce que tu disais dans ton post #9

Hypathie a écrit :

Par contre, le premier script était faux pour le morceau "trouver les lettres différentes et leur nombre" dès qu'il y avait répétition de lettres différentes.

Fonctionnait :
s1 = abcd
s2 = cdef

Mais ne fonctionnait pas  :

s1 = abcdabcd
s2 = cdefcdef


Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#16 02-01-2016 19:20:42

Hypathie
Membre
Lieu : Chambéry _ Montréal
Distrib. : Jessie
Noyau : Linux debian 3.16.0-4-586
(G)UI : Cinnamon Mate Xfce
Inscription : 28-12-2013

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

merci smile

Hors ligne

#17 02-01-2016 19:44:21

Thuban
Modérateur
Distrib. : OpenBSD
Noyau : current
(G)UI : xfce ou dwm
Inscription : 09-01-2009
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Wow, j'étais parti sur une compréhension de liste. Mais c'est génial la solution avec les opérateurs & et | smile


# compare_two_strings
# l'algo doit donner le nombre et toutes les lettres identiques ainsi que le nombre et toutes les lettres différentes de deux string entrées par l'utilisateur

#Saisie des mots de façon insensible à la casse. Sinon, "Truc" et "truc" sont différents
s1 = str.lower(input("entrer un premier mot : \n"))
s2 =  str.lower(input("entrer un deuxième mot : \n"))

#Tout ce qui est dans s1 et s2 est commun, le reste non
lettreCommunes = [ car for car in s1 if car in s2 ]
lettreDifferentes = [ car for car in s1 if not car in s2 ] + [ car for car in s2 if not car in s1 ]

#Tri des listes. Attention, ça modifie les listes d'origine
lettreCommunes.sort()
lettreDifferentes.sort()

#Sortie des liste et de leur nombre. On peut éviter les variables intermédiaires en utilisant directement des fonctions dans print
print("Les mots ",  s1,  "et",  s2,  "ont",  len(lettreCommunes),  "lettre(s) communes(s) :", lettreCommunes)
print("Les mots ",  s1,  "et",  s2,  "ont",  len(lettreDifferentes),  "lettre(s) différente(s) :", lettreDifferentes)

 



edit à bendia : parce-qu'un joli sucre syntaxique comme ça, ça mérite une belle cloration syntaxique big_smile


YA3HGA-H

Hors ligne

#18 02-01-2016 19:58:14

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Super Thuban smile

Je cherchais un truc comme ça en écrivant mon algo, mais je ne maitrise pas assez la compréhension de liste.

Pour info, il y a un nouveau tuto sur Zeste de Savoir, concernant les notions de Python avancées. Le tuto pour débutant sur Python, n'est pas très vieux non plus d'ailleurs wink

Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#19 02-01-2016 20:02:58

Thuban
Modérateur
Distrib. : OpenBSD
Noyau : current
(G)UI : xfce ou dwm
Inscription : 09-01-2009
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

J'avoue que les compréhensions de listes, ça m'a longtemps freiné. Puis j'ai du trouver des façons d'accélérer le code en écrivant le handysoft. J'ai donc pris le temps de bien comprendre comment ça fonctionnait, et une fois qu'on a le truc c'est tout bête. En plus, la vitesse d'éxécution est nettement améliorée!

En gros, ça donne :


[ l'expression pour avoir au final une liste ]
( l'expression pour avoir à la fin un tuple )
 


Exemple :


[ i+1 for i in maliste if i > 0 ]
 



- "i +1" : on met la variable trouvée dans la suite et on la met dans la liste après lui avoir ajouté 1
- for i in maliste : comme d'hab
- if i > 0 : on prend que les valeurs de maliste qui sont supérieures à 0


YA3HGA-H

Hors ligne

#20 02-01-2016 20:17:31

enicar
Membre
Lieu : Grenoble
Distrib. : debian/sid
Noyau : Linux 4.8.10
(G)UI : openbox
Inscription : 26-08-2010

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Remarquez que les lettres qui sont différentes, en terme ensembliste, ça s'appelle la différence
symétrique. Et python sait faire cela :


diff_sym=s1 ^ s2
 


Voir cela dans la doc officielle :
https://docs.python.org/3/library/stdty … -frozenset

EDIT:
Pour le dire plus clairement, c'est la même chose que :


diff_sym = (s1 & s2) - (s1 | s2)
 


Voilà wink

Dernière modification par enicar (02-01-2016 20:43:32)


La machine, c'est dépassé ! On va tout remplacer par des humains big_smile

Hors ligne

#21 02-01-2016 20:48:17

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Merci enicar et hypathie aussi, pour m'avoir fait découvrir ce type de données que je ne connaissais pas smile

L dernière ligne devient donc un truc nettement plus lisible

print("\nlettre(s) identique(s) : ", txt1 & txt2, "soit, ",len(txt1 & txt2)," lettre(s).\n" "lettre(s) diffirente(s) ) : ", txt1 ^ txt2, "soit, ", len(txt1 ^ txt2), " lettres(s).")


Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#22 03-01-2016 19:20:48

bendia
Admin stagiaire
Distrib. : Jessie
Noyau : 3.16.0-4-amd64
(G)UI : Gnome + XFCE + Console
Inscription : 20-03-2012
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Salut smile

Désolé d'avance pour le pavé hmm

Ce petit jeu m'amusant et voulant rebondir sur la remarque très pertinente de Paskal dans le post #2

Le très pertinent Paskal a écrit :

Plus court, vraiment mais précise : en longueur de code ? en temps d'exécution ? ...



Je me suis donc posé la question du temps d’exécution des différents algo avec le code ci en-bas (je le met après parce que c'est long quand même). Il serait largement améliorable pour en sortir des résultats chiffrés, je ne vais donc vous livrer ici que mes premières constatation, et donner des axes d'amélioration du code si ça intéresse quelqu'un wink

J'ai donc mis les algo suivants :

  • hypathie1 : celui avec les intersections d'ensembles et les 6 print à suivre pour l'affichage des résultats

  • hypathie2 : le même avec un seul print

  • bendia : le miens avec les boucles for

  • thuban : celui de thuban avec les listes en compréhension

  • enicar : avec la différence symétrique

  • variable1 : identique à enicar en stockant l'intersection d'ensemble et la différence symétrique dans des variables

  • variables2 : identique à hypathie2, mais en stockant également les calculs d'ensemble dans des variables



Je me suis dit en premier lieu que plus le mot allait être long, plus la différence serait appréciable. J'ai donc pondu un petit algo pour générer un 2 mots aléatoires de longueur réglable et j'ai fait plusieurs tirages en modifiant ce nombre de lettres.

  • Première constatation, l'algo de Thuban et le mien n'ont pas le comportement attendus, puisqu'il laisse apparaître les doublons dans la liste des lettres différentes. Conclusion, dès que le nombre de lettre du mot augmente, le temps d'exécution s'envole. On constate cependant que l'algo de Thuban avec les listes en compréhension est plus rapide que le miens. Su un faible nombre de lettre, il est même plus rapide que hypathie2.

  • Les différences de temps d'exécution pour les autres algo semble s'écraser lorsque le nombre de lettre augmente. Cela serait à vérifier par des calculs statistiques, mais je présume que le temps d’exécution de l'instruction set devient prépondérant par rapport à l'intersection et différence symétrique d'ensembles.

  • L'appel à print consomme un temps important. Il suffit pour cela de comparer l'algo d'hypathie avec plusieurs print (je l'ai  nommé hypathie) et celui avec un seul print nommé hypathie2.

  • L'utilisation de la différence symétrique indiqué par enicar (j'ai donc nomé la fonction enicar) apporte un gain de vitesse.

  • Je me suis dit que réaliser plusieurs fois ces intersection et différences symétrique (une fois pour la liste, une fois pour la longueur de cette liste) devait être coûteux. J'ai donc réalisé ses opération une seule fois en les stockant dans des variables. Il semble qu'on observe là aussi effectivement un gain de temps, alors que le code est plus long. Preuve que nombre de ligne et performances ne sont pas toujours proportionnel. wink



Ce qui serait bien à améliorer :

  • Automatiser la variation du nombre de lettre des mots

  • Multiplier le nombre de tirage pour pouvoir en tirer des résultats statistiques

  • Pondre un joli graphique avec ces résultats


#! /usr/bin/env python3
# -*- coding: utf-8 -*-

#Script vérifiant les temps d'execution de chaque algorithme
#en tirant aléatoirement 2 séries de lettres assez longues
# constituant les mots

import random
#Génération d'une liste des lettres de l'alphabet
alphabet= [ car for car in map(chr, range(97,123)) ]

#Génération des 2 "mots"

#Nombre de lettres du mot
nbLettres=80
txt1 = ''.join([ alphabet[random.randrange(0,26)] for l in range(0,nbLettres)  ])
txt2 = ''.join([ alphabet[random.randrange(0,26)] for l in range(0,nbLettres)  ])

#print("\n",txt1,"\n",txt2)


def benchmark(func):
    """
    Un décorateur qui affiche le temps qu'une fonction met à s'éxécuter
    """

    import time
    def wrapper(*args, **kwargs):
        t = time.clock()
        res = func(*args, **kwargs)
        print(func.__name__, time.clock()-t)
        return res
    return wrapper

@benchmark
def hypathie(txt1="abcdabcd", txt2="cdefcdef"):
    txt1, txt2 = set(txt1), set(txt2)
    print("lettre(s) identique(s) :")
    print(txt1 & txt2)
    print(len(txt1 & txt2), " lettres(s)")
    print("lettre(s) diffirente(s) ) :")
    print( (txt1 | txt2) -  (txt1 & txt2))
    print(len((txt1 | txt2) -  (txt1 & txt2)), " lettres(s)")

@benchmark
def hypathie2(txt1="abcdabcd",txt2="cdefcdef"):
    txt1, txt2 = set(txt1), set(txt2)
    print("\nlettre(s) identique(s) : ", txt1 & txt2, "soit, ",len(txt1 & txt2)," lettre(s).\n" "lettre(s) diffirente(s) ) : ", (txt1 | txt2) -  (txt1 & txt2), "soit, ", len((txt1 | txt2) -  (txt1 & txt2)), " lettres(s).")

@benchmark
def variable2(txt1="abcdabcd",txt2="cdefcdef"):
    txt1, txt2 = set(txt1), set(txt2)
    intersection = txt1 & txt2
    difference = (txt1 | txt2) -  (txt1 & txt2)
    print("\nlettre(s) identique(s) : ", intersection, "soit, ",len(intersection)," lettre(s).\n" "lettre(s) diffirente(s) ) : ", difference, "soit, ", len(difference), " lettres(s).")

@benchmark
def bendia(txt1="abcdabcd", txt2="cdefcdef"):
   
    lettreCommunes,lettreDifferentes=[],[]
    #txt1,txt2 = set(txt1), set(txt2)
    #Tout ce qui est dans s1 et s2 est commun, le reste non
    for i in txt1:
        if i in txt2:
            lettreCommunes.append(i)
        else:
            lettreDifferentes.append(i)
       
    #Il peut rester des lettres de s2 non présente dans s1. Dans ce cas les rajouter aux lettres différentes
    for i in txt2:
        if not i in lettreDifferentes and not i in lettreCommunes:
            lettreDifferentes.append(i)

    #Tri des listes. Attention, ça modifie les listes d'origine
    #lettreCommunes.sort()
    #lettreDifferentes.sort()

    #Sortie des liste et de leur nombre. On peut éviter les variables intermédiaires en utilisant directement des fonctions dans print
    print("lettre(s) commune(s) :", lettreCommunes, " soit, ",len(lettreCommunes)," lettre(s)" )
    print("lettre(s) différentes(s) :", lettreDifferentes, " soit, ",len(lettreDifferentes)," lettre(s)")

@benchmark
def thuban(txt1="abcdabcd",txt2="cdefcdef"):
    #txt1,txt2 = set(txt1), set(txt2)
    lettreCommunes = [ car for car in txt1 if car in txt2 ]
    lettreDifferentes = [ car for car in txt1 if not car in txt2 ] + [ car for car in txt2 if not car in txt1 ]

    #Tri des listes. Attention, ça modifie les listes d'origine
    #lettreCommunes.sort()
    #lettreDifferentes.sort()

    #Sortie des liste et de leur nombre. On peut éviter les variables intermédiaires en utilisant directement des fonctions dans print
    print("lettre(s) commune(s) :", lettreCommunes, " soit, ",len(lettreCommunes)," lettre(s)" )
    print("lettre(s) différentes(s) :", lettreDifferentes, " soit, ",len(lettreDifferentes)," lettre(s)")


@benchmark
def enicar(txt1="abcdabcd",txt2="cdefcdef"):
    txt1, txt2 = set(txt1), set(txt2)
    print("\nlettre(s) identique(s) : ", txt1 & txt2, "soit, ",len(txt1 & txt2)," lettre(s).\n" "lettre(s) diffirente(s) ) : ", txt1 ^ txt2, "soit, ", len(txt1 ^ txt2), " lettres(s).")

@benchmark
def variable1(txt1="abcdabcd",txt2="cdefcdef"):
    txt1, txt2 = set(txt1), set(txt2)
    intersection = txt1 & txt2
    difference = txt1 ^ txt2
    print("\nlettre(s) identique(s) : ", intersection, "soit, ",len(intersection)," lettre(s).\n" "lettre(s) diffirente(s) ) : ", difference, "soit, ", len(difference), " lettres(s).")

hypathie(txt1,txt2)
hypathie2(txt1,txt2)
bendia(txt1,txt2)
thuban(txt1,txt2)
enicar(txt1,txt2)
variable1(txt1,txt2)
variable2(txt1,txt2)
 


Ben
___________________
La seule question bête, c'est celle qu'on ne pose pas.
file-Re06858991f6f328b4907296ac5cea283

Hors ligne

#23 03-01-2016 19:30:52

enicar
Membre
Lieu : Grenoble
Distrib. : debian/sid
Noyau : Linux 4.8.10
(G)UI : openbox
Inscription : 26-08-2010

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

Haha, il y en a qui s'amuse ! cool
Très bien cette idée de comparer les temps d'exécutions des différentes
solutions dans un seul programme wink On peut aussi faire la même chose
en plusieurs programmes pilotés par le programme de test, mais bon.

La machine, c'est dépassé ! On va tout remplacer par des humains big_smile

Hors ligne

#24 03-01-2016 20:24:11

paskal
autobahn
Lieu : ailleurs
Inscription : 14-06-2011
Site Web

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

bendia a écrit :

"Le très pertinent Paskal a écrit"

Heu ... t'aurais pas un truc à me d'mander, par zazar ?  tongue  lol


I'd love to change the world
But I don't know what to do
So I'll leave it up to you...

logo-sur-fond.png

Hors ligne

#25 03-01-2016 20:40:39

smolski
administrateur quasi...modo
Lieu : AIN
Distrib. : 8 (jessie) 64 bits + backports
Noyau : 4.6.0-0.bpo.1-amd64
(G)UI : gnome 3.14.1
Inscription : 21-10-2008

Re : python3 : jouer à 'qui_fait_pareil_en_plus_court'

paskal a écrit :

bendia a écrit :

"Le très pertinent Paskal a écrit"

Heu ... t'aurais pas un truc à me d'mander, par zazar ?  tongue  lol


Si c'est un point choco df, ça doit obligatoirement passer par la trésorerie df des points chocos... donc aboule bendia ! tongue


"Définition d'eric besson : S'il fallait en chier des tonnes pour devenir ministre, il aurait 2 trous du cul." - JP Douillon
"L'utopie ne signifie pas l'irréalisable, mais l'irréalisée." - T Monod (source :  La zone de Siné)
"Je peux rire de tout mais pas avec n'importe qui." - P Desproges
"saque eud dun" (patois chtimi : fonce dedans)

Hors ligne

Pied de page des forums