Traducteur de code Morse Python
Je m'enseigne moi-même sur Python ces dernières semaines, je m'intéresse à la cryptographie, aux codes, etc. donc j'ai pensé que démarrer un traducteur de code Morse serait un bon projet. Je sais que mes noms de variables peuvent être différents, il ne s'agit pas vraiment de chiffrer, de déchiffrer, etc. Je cherche surtout des conseils sur la façon dont je peux rendre le code plus propre et où je peux être plus efficace.
Je pense que mon plus gros problème n'est pas vraiment de savoir comment gérer les entrées dans une boucle while comme je le ferais habituellement. Le problème que j'ai eu était que je ne pouvais pas vérifier si l'entrée était «e» ou «d», donc ça devenait vraiment bancal.
Domaines que je sais que je pourrais améliorer:
- Ajouter une boucle d'entrée
- Le if, elif, else pour l'action
- Faire de 'son' une valeur booléenne réelle
- Trouvez le temps sonore réel pour le dit and dah mais ce n'est pas vraiment un problème de code
# Started: 08/17/2020
# Finished: 08/17/2020
# Takes an input message and outputs the message in morse code
# Keys taken from 'https://en.wikipedia.org/wiki/Morse_code'
from playsound import playsound
import time
# Dictionary that holds each letter and it's corresponding value
dict = {'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': '--..',
'1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----',
' ': '/', '.': '.-.-.-', ',': '.-.-', '?': '..--..', "'": '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-',
':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.', '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.'}
outputMessage = "" # Holds our output message
# Sounds
sound = 'False'
dit = 'dit.wav'
dah = 'dah.wav'
def Encrypt(message):
output = ''
for char in message:
if char in dict:
output = output + dict[char]
output = output + ' '
return output
def Get_Key(val):
for key, value in dict.items():
if val == value:
return key
def Decrypt(message):
output = ''
letters = message.split(' ')
for letter in letters:
temp = Get_Key(letter)
output = output + temp
return output
def Get_Inputs():
# Get Inputs
inputString = input('Enter a message to start.\n')
action = input('(E)ncrypt or (D)ecrypt?\n')
# Format Inputs
message = inputString.lower().strip()
action = action.lower().strip()
return message, action
def Play_Sound(message):
for char in message:
if char == '.':
playsound(dit)
elif char == '-':
playsound(dah)
elif char == ' ':
time.sleep(0.15)
elif char == '/':
time.sleep(0.30)
message, action = Get_Inputs()
if action == 'e' or action == 'encrypt':
outputMessage = Encrypt(message)
elif action == 'd' or action == 'decrypt':
outputMessage = Decrypt(message)
else:
print('Error!')
print(outputMessage)
print('')
sound = input('Play sound? (T)rue / (F)alse\n')
if sound.lower().strip() == 't' or sound.lower().strip() == 'true':
Play_Sound(outputMessage)
Réponses
Style général
Votre traduction dict
utilise un mot-clé et des lettres minuscules. Envisagez d'écrire des constantes avec des lettres majuscules et de leur donner des noms expressifs comme MORSE_CODES = {...}
.
Selon PEP 8 , les fonctions doivent être nommées en utilisant snake_case
. CamelCase
est réservé aux classes: outputMessage
→ output_message
, def Encrypt(...)
→ def encrypt(...)
, etc.
Performance
L'utilisation de la Get_Key
fonction n'est pas très performante, car elle effectue une recherche linéaire du dict. Inversez simplement le dictionnaire de traduction une fois, puis utilisez-le:
MORSE_ENCODING = {
'a': '.-',
'b': '-...',
...
}
MORSE_DECODING = {value: key for key, value in MORSE_ENCODING.items()}
...
temp = MORSE_DECODING[letter]
Gestion des erreurs
Actuellement, la Encrypt
fonction ignore silencieusement tous les caractères non traduisibles. Envisagez ValueError()
plutôt de lancer un pour indiquer qu'une entrée non valide a été fournie:
def encode(message):
"""Encodes a string into morse code."""
code = ''
for index, char in enumerate(message):
try:
code += MORSE_ENCODING[char.lower()]
except KeyError:
raise ValueError(f'Char "{char}" at {index} cannot be encoded.')
code += ' '
return code[:-1] # Remove trailing space.
def decode(morse_code):
"""Decodes morse code."""
message = ''
for index, sequence in enumerate(morse_code.split()):
try:
message += MORSE_DECODING[sequence]
except KeyError:
raise ValueError(f'Cannot decode code "{sequence}" at {index}.')
return message
Exactitude
Votre Encrypt
fonction renvoie actuellement toujours un espace de fin. Vous pouvez éviter cela en revenant output[:-1]
.
Terminologie
La conversion du code morse en texte dans les deux sens n'est pas vraiment un cryptage dans son sens. Vous voudrez peut-être reformuler {en,de}crypt
avec {en,de}code
.
Globales
L'utilisation de variables globales comme outputMessage
peut avoir des effets secondaires désagréables lorsque le programme est utilisé comme bibliothèque. Tout le code sous la def Play_Sound
fonction doit entrer dans une def main()
fonction que vous pouvez appeler via
if __name__ == '__main__':
main()
Au bas de l'appareil.