Comment ne pas répéter des portions de code ?
Résolu
Louis-Fiacre
-
Louis-Fiacre Messages postés 2 Date d'inscription Statut Membre Dernière intervention -
Louis-Fiacre Messages postés 2 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
Je suis débutant en python et j'aimerais avoir une relecture critique de mon petit script. J'ai trois problèmes : je déclare des variables globales mais je ne sais pas si dans mon script c'est nécessaire où si je peux faire d'une autre manière. Je répète du code dans ma fonction decode() mais là aussi je ne sais pas comment simplifier la tache, je n'est même pas le début d'une idée. Et enfin ma gestion des arguments optionnels de la ligne de commande dans main() me paraissent pas pro. Je mets le code complet à la fin de mon poste. Je vous remercie du temps que vous me consacrerez. Et j'ai vraiment envie d'apprendre de vos remarques et explications.
Bien cordialement,
Louis-Fiacre
Je suis débutant en python et j'aimerais avoir une relecture critique de mon petit script. J'ai trois problèmes : je déclare des variables globales mais je ne sais pas si dans mon script c'est nécessaire où si je peux faire d'une autre manière. Je répète du code dans ma fonction decode() mais là aussi je ne sais pas comment simplifier la tache, je n'est même pas le début d'une idée. Et enfin ma gestion des arguments optionnels de la ligne de commande dans main() me paraissent pas pro. Je mets le code complet à la fin de mon poste. Je vous remercie du temps que vous me consacrerez. Et j'ai vraiment envie d'apprendre de vos remarques et explications.
Bien cordialement,
Louis-Fiacre
# -*- coding: utf-8 -*-
from collections import Counter
import sys, getopt
global ordered_french_dico
french_dico = dict() # issu de https://www.apprendre-en-ligne.net/crypto/stat/francais.html
french_dico = {'a': 8.15, 'b': 0.97, 'c': 3.15, 'd': 3.73, 'e': 17.39, 'f': 1.12, 'g': 0.97, 'h': 0.85, 'i': 7.31, 'j': 0.45, 'k': 0.02, 'l': 5.69, 'm': 2.87, 'n': 7.12, 'o': 5.28, 'p': 2.80, 'q': 1.21, 'r': 6.64, 's': 8.14, 't': 7.22, 'u': 6.38, 'v': 1.64, 'w': 0.03, 'x': 0.41, 'y': 0.28, 'z': 0.15,}
ordered_french_dico = sorted(french_dico.items(), key=lambda x: x[1], reverse = True) #valeurs décroissantes
global ordered_english_dico
english_dico = dict() # issu de https://www.apprendre-en-ligne.net/crypto/stat/anglais.html
english_dico = {'a': 8.08, 'b': 1.67, 'c': 3.18, 'd': 3.99, 'e': 12.56, 'f': 2.17, 'g': 1.80, 'h': 5.27, 'i': 7.24, 'j': 0.14, 'k': 0.63, 'l': 4.04, 'm': 2.60, 'n': 7.38, 'o': 7.47, 'p': 1.91, 'q': 0.09, 'r': 6.42, 's': 6.59, 't': 9.15, 'u': 2.79, 'v': 1.00, 'w': 1.89, 'x': 0.21, 'y': 1.65, 'z': 0.07,}
ordered_english_dico = sorted(english_dico.items(), key=lambda x: x[1], reverse = True) #valeurs décroissantes
global ordered_italian_dico
italian_dico = dict() # issu de https://fr.sttmedia.com/frequences-de-lettres-italien
italian_dico = {'a': 11.00, 'b': 1.05, 'c': 4.30, 'd': 3.39, 'e': 11.97, 'f': 1.01, 'g': 1.65, 'h': 1.43, 'i': 10.27, 'j': 0.00, 'k': 0.00, 'l': 5.70, 'm': 2.87, 'n': 7.02, 'o': 10.08, 'p': 2.96, 'q': 0.45, 'r': 6.19, 's': 5.48, 't': 6.97, 'u': 3.28, 'v': 1.75, 'w': 0.00, 'x': 0.00, 'y': 0.00, 'z': 0.85,}
ordered_italian_dico = sorted(italian_dico.items(), key=lambda x: x[1], reverse = True) #valeurs décroissantes
global freq
freq = dict()
global alpha
alpha = ['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']
def sorti(src_in, decal): #fonction de substitution des caractères
list_decal = []
for car in src_in:
upper = False
if car not in alpha:
if car.isupper() == False:
car_decal = car
if car.isupper() == True:
car = car.lower()
upper = True
if car in alpha:
ide = (alpha.index(car) + decal)
while ide >= len(alpha):
ide = ide - len(alpha)
car_decal = alpha[ide]
if upper == True:
car_decal = car_decal.upper()
list_decal.append(car_decal)
text_decal = "".join(list_decal)
print("[!] Texte sorti : \n",text_decal)
return text_decal
def taux(a, b): #donne taux de différence entre frequence des caractères de la source et d'un dictionnaire de référence
somme_score = 0
score = []
for i in range(0,len(a)):
taux = (a[i][1] - b[i][1])
if taux < 0:
taux = taux * (-1)
score.append(taux)
somme_score = sum(score)/len(score)
return somme_score
def pretraitement(text_0):
text = text_0.lower()
text = text.replace(",", "")
text = text.replace("'", "")
text = text.replace(" ", "")
text = text.replace("\n", "")
return text
def read(src_in): #extrait la source et renvoie une chaine de caractère
try:
source = open(src_in, "r")
text_0 = "".join(source.readlines())# passe d'une list à une chaine de caracrère
print("[!] Texte source :\n",text_0)
finally:
source.close()
return text_0
def write(src_out, text_decal): # ecrit le text de sorti dans un nouveau fichier
try:
source = open(src_out, "a")
source.write(text_decal)
print("[!] Texte de sorti dans: ", src_out)
finally:
source.close
return True
def code(src_in, decal, src_out = ""):
decal = int(decal)
text_0 = read(src_in)
print("[!] Substitution par ",decal," lettres")
text_out = sorti(text_0, decal)
if src_out != "":
write(src_out, text_out)
def decode(src_in, src_out = ""):
text_0 = read(src_in)
text = pretraitement(text_0)
length_text = len(text) #longueur du texte
occur = Counter(text) # occurence de chaque caractère
for (key, value) in occur.items():
pourcent = round((value / length_text)*100, 2)
freq[key] = pourcent # frequence de pourcentage des occurences
alpha_freq = sorted(freq.items(), key=lambda x: x[0]) #alphabétique
value_freq = sorted(freq.items(), key=lambda x: x[1], reverse = True) #valeurs décroissantes
FR = taux(value_freq, ordered_french_dico)
ANG = taux(value_freq, ordered_english_dico)
IT = taux(value_freq, ordered_italian_dico)
if FR < ANG and FR < IT:
print("[!] Texte source de ",length_text,"caractères en français")
decal = alpha.index(ordered_french_dico[0][0]) - alpha.index(value_freq[0][0])
print("[!] Lettre ",value_freq[0][0],"=",ordered_french_dico[0][0],"Substitution par ",decal," lettres")
elif ANG < FR and ANG < IT:
print("[!] Texte source de ",length_text,"caractères en anglais")
decal = alpha.index(ordered_english_dico[0][0]) - alpha.index(value_freq[0][0])
print("[!] Lettre ",value_freq[0][0],"=",ordered_english_dico[0][0],"Substitution par ",decal," lettres")
elif IT < FR and IT < ANG:
print("[!] Texte source de ",length_text,"caractères en italien")
decal = alpha.index(ordered_italian_dico[0][0]) - alpha.index(value_freq[0][0])
print("[!] Lettre ",value_freq[0][0],"=",ordered_italian_dico[0][0],"Substitution par ",decal," lettres")
text_out = sorti(text_0, decal)
if src_out != "":
print(text_out)
write(src_out, text_out)
def usage():
print("[!] Script pour coder et decoder un texte par substitution de lettre\n",
" --decode ou -d attend un argument obligatoire [fichier_source.txt] et un argument optionnel [fichier_out.txt]\n",
" --code ou -c attend deux arguments obligatoires [fichier_source.txt] [integer] et un argument optionnel [fichier_out.txt]\n",
" --help ou -h Affiche les commandes possibles")
def main(argv):
try:
opts, args = getopt.getopt(argv, "hdc",["help", "decode","code"])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
print(opt, arg)
if opt in ("-h", "--help"):
print(arg)
usage()
sys.exit()
elif opt in ("-d", "--decode"):
try: src_out = argv[2]
except: src_out = ""
decode(argv[1],src_out)
elif opt in ("-c", "--code"):
try: src_out = argv[3]
except: src_out = ""
code(argv[1], argv[2], src_out)
if __name__ == "__main__":
main(sys.argv[1:])
A voir également:
- Comment ne pas répéter des portions de code ?
- Code ascii - Guide
- Comment déverrouiller un téléphone quand on a oublié le code - Guide
- Code puk bloqué - Guide
- Code activation windows 10 - Guide
- Code blocks - Télécharger - Langages
1 réponse
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
bonjour,
il est utile de préciser le langage quand tu utilises les balises de code. explications ici: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
à propos de decode():
1) ne manque t'il pas un else? que doit faire le programme si aucune des trois conditions n'ait satisfaite?
2) comment simplifier et éviter de recopier du code: commence par identifier clairement ce qui change et ce qui ne change pas.
il est utile de préciser le langage quand tu utilises les balises de code. explications ici: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
à propos de decode():
1) ne manque t'il pas un else? que doit faire le programme si aucune des trois conditions n'ait satisfaite?
2) comment simplifier et éviter de recopier du code: commence par identifier clairement ce qui change et ce qui ne change pas.
Oui merci, je rajoute un else pour proprement dire qu'il ne reconnait pas la langue d'origine et mettre fin au script même si avec les conditions actuels il y aura toujours un des trois selectionnés.
Alors c'est là où je sèche. J'ai bien compris ce qui est récurrent, et donc j'ai deux infos FR et ordered_french_dico[0][0] et leur variantes dans les autres langues mais dois-je faire une boucle for avec un dico ['FR':'0.23','ANG':'0.52', etc] et un dico ['FR':'ordered_french_dico',etc] ? Je vous remercie du temps que vous m'accordez.
il me semble indispensable d'avoir un else, pour éviter des erreurs dans la suite du code.
commence par écrire ce que tu as compris qui était récurrent.
à titre d'exemple, voilà comment je montrerais ce qui est récurrent tout au début du programme, où tu fais également trois fois plus ou moins la même chose:
global <gras>ordered_french_dico
dico = dict()
dico = {'a': 8.15, 'b': 0.97, 'c': 3.15, 'd': 3.73, 'e': 17.39, 'f': 1.12, 'g': 0.97, 'h': 0.85, 'i': 7.31, 'j': 0.45, 'k': 0.02, 'l': 5.69, 'm': 2.87, 'n': 7.12, 'o': 5.28, 'p': 2.80, 'q': 1.21, 'r': 6.64, 's': 8.14, 't': 7.22, 'u': 6.38, 'v': 1.64, 'w': 0.03, 'x': 0.41, 'y': 0.28, 'z': 0.15,}
ordered_french_dico = sorted(dico.items(), key=lambda x: x[1], reverse = True)
ainsi, on peut voir clairement ce qui change et ce qu'il faut traiter si on veut simplifier.
fais de même pour les instructions simplifiables dans decode().
if FR < ANG and FR < IT:
print("[!] Texte source de ",length_text,"caractères en français")
decal = alpha.index(ordered_french_dico[0][0]) - alpha.index(value_freq[0][0])
print("[!] Lettre ",value_freq[0][0],"=",ordered_french_dico[0][0],"Substitution par ",decal," lettres")
Mais si je fais une fonction decal comme :
Je n'ai pas l'impression de simplifier tant que ca et simplifier plus haut avec me paraît hors de ma portée. Je ne vois pas comment créer un lien entre FR ANG IT, avec un liste ? Je vous remercie de toutes vos explications
tu parles de simplifier. tant que tu n'as que trois langues, ce c'est pas très utile. moi j'essaierais de généraliser, afin, si nécessaire, de pouvoir gérer un plus grand nombre de langues.
si tu veux faire cela, il me semble nécessaire de commencer par utiliser des noms de variables génériques, donc supprimer les noms spécifiques tels que ordered_french_dico et FR.
Où alors dois-je me tourner vers une déclaration de classe définie par un nom de langue, un dictionnaire et une variable de taux ?