Penerjemah Kode Python Morse

Aug 18 2020

Saya telah belajar sendiri Python selama beberapa minggu terakhir, saya memiliki minat dalam kriptografi, kode, dll. Jadi saya pikir memulai penerjemah kode Morse akan menjadi proyek yang bagus. Saya tahu nama variabel saya bisa berbeda, tidak benar-benar mengenkripsi, mendekripsi, dll. Saya kebanyakan mencari saran tentang bagaimana saya bisa membuat kode lebih bersih dan di mana saya bisa lebih efisien.

Saya pikir masalah terbesar saya tidak benar-benar mengetahui bagaimana menangani input dalam loop sementara seperti yang biasanya saya lakukan. Masalah yang saya hadapi adalah saya tidak dapat memeriksa apakah inputnya adalah 'e' atau 'd' jadi itu benar-benar miring.

Area yang saya tahu bisa saya tingkatkan:

  • Tambahkan loop masukan
  • If, elif, else untuk aksinya
  • Buat 'suara' menjadi nilai boolean yang sebenarnya
  • Temukan waktu suara sebenarnya untuk dit dan dah tapi itu bukan masalah kode
# 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)

Jawaban

6 RichardNeumann Aug 18 2020 at 19:25

Gaya Umum

Terjemahan Anda dictmenggunakan kata kunci dan huruf kecil. Pertimbangkan untuk menulis konstanta dengan huruf besar dan memberinya nama ekspresif seperti MORSE_CODES = {...}.

Menurut PEP 8 , fungsi harus diberi nama menggunakan snake_case. CamelCasedisediakan untuk kelas: outputMessageoutput_message, def Encrypt(...)def encrypt(...), dll.

Performa

Menggunakan Get_Keyfungsi ini tidak terlalu berkinerja, karena melakukan pencarian linier dari dict. Balikkan perintah terjemahan satu kali, lalu gunakan:

MORSE_ENCODING = {
    'a': '.-',
    'b': '-...',
    ...
}
MORSE_DECODING = {value: key for key, value in MORSE_ENCODING.items()}

...

        temp = MORSE_DECODING[letter]

Penanganan kesalahan

Saat ini Encryptfungsi tersebut mengabaikan semua karakter yang tidak dapat diterjemahkan secara diam-diam. Pertimbangkan untuk Melempar a ValueError()sebagai gantinya untuk menunjukkan, bahwa masukan yang tidak valid telah diberikan:

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

Ketepatan

EncryptFungsi Anda saat ini selalu mengembalikan spasi tambahan. Anda dapat menghindarinya dengan kembali output[:-1].

Terminologi

Mengonversi dari kode morse ke teks bolak-balik sebenarnya bukanlah enkripsi dalam artiannya. Anda mungkin ingin mengulanginya {en,de}cryptdengan {en,de}code.

Globals

Menggunakan variabel global seperti outputMessagedapat memiliki efek samping yang buruk ketika program digunakan sebagai perpustakaan. Semua kode di bawah def Play_Soundfungsi tersebut harus masuk ke dalam def main()fungsi yang dapat Anda panggil

if __name__ == '__main__':
    main()

Di bagian bawah unit.