Louis-Fiacre
-
22 mars 2021 à 16:13
Louis-Fiacre
Messages postés2Date d'inscriptionmardi 23 mars 2021StatutMembreDernière intervention24 mars 2021
-
24 mars 2021 à 10:02
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,
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()
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 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)
à 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.
Merci pour vos remarques, oui j'ai vu qu'on pouvais choisir le langage pour les balises dans un menu déroulant, j'ai été trop vite.
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.
yg_be
Messages postés22730Date d'inscriptionlundi 9 juin 2008StatutContributeurDernière intervention26 avril 20241 477
>
Louis-Fiacre
Modifié le 22 mars 2021 à 17:46
dans decode, il s'agit bien du else dans le cas où aucune des conditions n'est remplie:
FR < ANG and FR < IT:
ANG < FR and ANG < IT:
IT < FR and IT < ANG:
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().
Louis-Fiacre
>
yg_be
Messages postés22730Date d'inscriptionlundi 9 juin 2008StatutContributeurDernière intervention26 avril 2024 Modifié le 22 mars 2021 à 18:28
Je vous suis alors pour :
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")
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 :
def decal(dico, lang)
print("[!] Texte source de ",length_text,"caractères en ", lang)
decal = alpha.index(dico[0][0]) - alpha.index(value_freq[0][0])
print("[!] Lettre ",value_freq[0][0],"=",dico[0][0],"Substitution par ",decal," lettres")
Je n'ai pas l'impression de simplifier tant que ca et simplifier plus haut avec
if FR < ANG and FR < IT:
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
yg_be
Messages postés22730Date d'inscriptionlundi 9 juin 2008StatutContributeurDernière intervention26 avril 20241 477
>
Louis-Fiacre
Modifié le 22 mars 2021 à 18:48
tu ne montres pas comment tu proposes d'utiliser la fonction decal().
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.
Louis-Fiacre
>
yg_be
Messages postés22730Date d'inscriptionlundi 9 juin 2008StatutContributeurDernière intervention26 avril 2024 Modifié le 22 mars 2021 à 19:04
Oui je crois que j'atteins une limite dans ma compréhension de python. J'aimerais justement généraliser comme tu dis pour un nombre x de langue. Mais je ne vois pas comment faire dès la déclaration des différents dictionnaires. Si je fais un fichier texte avec un nom de langue, un dictionnaire et une variable de taux par ligne ca serait une solution ?
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 ?
Modifié le 22 mars 2021 à 17:20
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.
Modifié le 22 mars 2021 à 17:46
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().
Modifié le 22 mars 2021 à 18:28
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
Modifié le 22 mars 2021 à 18:48
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.
Modifié le 22 mars 2021 à 19:04
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 ?