J'écris beaucoup de petits programmes en Python mais le code produit n'est pas très propre / efficace. Par exemple, sur ce petit programme, j'aimerais avoir vos avis sur la manière de l'optimiser et de rendre le code plus propre.
#!/usr/bin/env python3
# rot13.py - ROT13 encoder/decoder written in Python.
from sys import argv
from os.path import basename
def rot13(txt):
"""Encoder / décoder la chaine txt."""
A2Z = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
MAX = len(A2Z)
MOY = MAX // 2
res, tmp = str(), str()
pos = int()
for car in txt:
if car.islower():
tmp = car.capitalize()
else:
tmp = car
if A2Z.count(tmp):
pos = A2Z.index(tmp)
pos += MOY
if pos >= MAX:
pos -= MAX
tmp = A2Z[pos]
if car.islower():
tmp = tmp.lower()
res += tmp
return(res)
if len(argv) > 1:
for arg in argv[1:len(argv)]:
print(rot13(arg))
else:
print("Usage: {0} <chaine1> <chaine2>".format(basename(argv[0])))
Merci d'avance pour vos conseils !
# Quelques pistes
Posté par GuieA_7 (site web personnel) . Évalué à 6.
Lire le code des autres est très formateur :
http://stackoverflow.com/questions/3269686/short-rot13-function
Il serait intéressant de pour toi de comparer le temps d'exécution de ta version avec ceux de ces versions. On y trouve des choses intéressantes en terme de concision et de performances (même si je serais incapable de dire laquelle est la plus rapide) :
in
(voire pire unhas_key()
) puis un[key]
, donc 2 recherches au lieu d'une.Sinon sur ton code en particulier, à part la boucle
for
qu'il faut revoir, j'aurais des petites trucs en plus :''
est plus rapide questr()
(dans le 2ème cas l'interpréteur doit faire une recherche du symbole "str", qui peut être surchargé). La différence est évidemment infime, mais c'est toujours bon à savoir.0
est plus rapide que int() (même raison).list()
vs[]
oudict()
vs{}
)res, tmp = str(), str()
=> c'est plus efficace (et plus lisible je trouve) de le faire en 2 lignes, car là l'interpréteur doit construire un tuple temporaire en plus et faire l'unpacking. L'unpacking c'est génial dans bien des cas mais pas là.Amuses toi bien :)
[^] # Re: Quelques pistes
Posté par JPEC . Évalué à 2.
Merci pour tes explications qui sont intéressantes. Je vais mettre ça en application !
# j'aime bien le titre "avis sur un algo python"
Posté par francoisp31 . Évalué à 1.
par définition un algo est adaptable quelque soit le langage ;) dans les limites des spécificités de celui ci.
donc soit l'algo est bon et fonctionne dans tous les langages d'une même famille/d'un meme type ou style
soit il ne marche pas.
L'optimisation du code…ça c'est autre chose :D
# Essai
Posté par Strash . Évalué à 4.
Je suis loin d'être un pro niveau optimisation, je suis un peu dans le même cas que toi, j'ai juste essayé de diminuer le nombre de lignes. Aucune idée si ça a une influence sur la rapidité d'exécution.
sinon une version plus bourrin en une ligne (list comprehension), je peux détailler si tu le souhaites :
[^] # Re: Essai
Posté par Strash . Évalué à 6.
Bon, j'ai un peu de temps alors je décompose :
1 - La base est une list comprehension, outil très puissant que j'utilise très souvent en lieu et place des boucles for qui permet de construire une liste à partir d'une (ou plusieurs) autre liste :
est équivalent à :
2 - A cette list comprehension j'y ai ajouté un ternary operator afin d'ajouter une condition if
est équivalent à :
3 - la fonction appliquée
A partir du code simplifié, la fonction est assez simple, j'ai simplement supprimé la variable intermédiaire pos.
Donc chaque caractère inclus dans la liste se voient appliquer cette "fonction" qui renvoie le caractère (majuscule ou minuscule) converti par rot13 (grâce à la liste initiale modifiée pour ajouter les minuscules) :
4 - join
''.join() doit être appliqué à la liste car la sortie de la list comprenhsion est une liste de caractères, et non une chaine.
[^] # Re: Essai
Posté par Xavier Combelle (site web personnel) . Évalué à 1.
à la place de
je ferais un
# gagner du temps
Posté par NeoX . Évalué à 2.
pourquoi tester chaque caractere pour le mettre en majuscule si necessaire
il doit bien y avoir une fonction qui met tout en majuscule en une seule fois.
tu n'as alors plus qu'a faire tes rot13 sur les caracteres de la chaine, sans avoir à les tester un par un.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.