这是带有CLI的简单的摩尔斯电码解释器。这是一个幼稚的表查询实现,并使用my-py进行类型检查。它会自动检测输入(英语或摩尔斯)并进行相应的转换。它具有我能想到的最简单的CLI。这里有一个git repo。

我不经常写Python;我在业余时间写Ruby来上班,并写Clojure,但我确实喜欢Python,并且对Python有一些经验。我欢迎有关如何编写更多“ Pythonic”代码,更简单的代码或接口或如何使代码更强大的建议。理想情况下,我希望它“正常工作”并能够接收甚至格式错误的数据。不幸的是,我认为我需要在命令行中将msg参数保留在引号中,否则shell会将单点或双点解释为当前目录或父目录。

我正在考虑使用Boyer-Moore算法而不是查找表,但我不确定是否值得。

 import re
import argparse
from typing import Dict


eng = {
    "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" : "--..",
    " " : "/",
    "0" : "-----",
    "1" : ".----",
    "2" : "..---",
    "3" : "...--",
    "4" : "....-",
    "5" : ".....",
    "6" : "-....",
    "7" : "--...",
    "8" : "---..",
    "9" : "----.",
    "," : ",",
    "." : ".",
    "!" : "!",
    "?" : "?",
} # type: Dict[str, str]


morse = {v: k for k, v in eng.items()} # type: Dict[str, str]


def morsep(msg: str) -> bool:
    if msg[0][0] in ['.', '-', '/']:
        return True
    else:
        return False


def morse_to_eng(msg: str) -> str:
    out = "" # type: str
    split_msg = re.split(" ", msg) # type: list
    filtered_msg = [e for e in split_msg if e] # type: list
    for char in filtered_msg:
        c = morse[char] # type: str
        out += c
    return("".join(out))


def eng_to_morse(msg: str) -> str:
    out = "" # type: str
    for char in msg:
        c = eng[char] # type: str
        out += "{} ".format(c)
    return("".join(out))


def decode(msg: str) -> str:
    "Main control flow."
    if morsep(msg) == True:
        return(morse_to_eng(msg))
    else:
        return(eng_to_morse(msg))


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Translate English to Morse code, and vice versa.')
    parser.add_argument('-v', '--version', help='Show the version.', action='version', version='Morse 0.1')
    parser.add_argument('msg', type=str, nargs=1,
                        help='The message to be decoded. Input type will be automatically detected and converted. \
                        Must be wrapped in quotes.')

    args = parser.parse_args()
    out = decode(args.msg[0]) # type: str
    print("{}".format(out))
 


#1 楼

总体而言,此代码非常简单且易于遵循。我只是指出了一些建议。


函数语法

def func_name(param_name: type) -> return_type:


是Python 3中的新功能。但是,在Python中使用它并不是很常见的事情,而且我认为它看起来不是非常pythonic。

您的代码在不创建此类函数的情况下也可以正常工作,因此我建议您坚持使用通常的语法:

def func_name(param_name):



这个笨拙的声明:

if msg[0][0] in ['.', '-', '/']:
    return True
else:
    return False


可以简化为更Python化和更干净的版本:

return msg[0][0] in ['.', '-', '/']



类似的评论:

# type: list


确实没有必要,只需在代码中添加噪音即可。只需阅读代码,审查它的人就应该能够确定每个变量的类型。


您需要进行更多的错误捕获。

例如,假设您要将莫尔斯电码的字符串翻译成英语。如果您遇到的字符不是有效的摩尔斯字符怎么办?您的程序将在此处引发错误:

for char in msg:
    c = eng[char] # <======
    out += "{} ".format(c)


因此,这是您应该执行的操作:


一个try/except
except中,抛出一个自定义的InvalidMorseLetter异常。
退出

我的意思是:

try:
    c = eng[char] # type: str
except KeyError:
    raise(InvalidMorseLetter)

<
其中InvalidMorseLetter是:

class InvalidMorseLetter(Exception):
    pass


在这里和这里阅读。

在代码中,我写了一个KeyError,因为那是

您应该使用一个自定义异常,因为它专门描述您的特定代码出了什么问题,而不仅仅是一般的KeyError

将英语翻译为莫尔斯电码时,应该做与此类似的事情。


感谢Zenohm的帮助。

翻译功能,您不应该在每次迭代中不断修改单个字符串:

c = morse[char] # type: str
out += c # <======================


原因:python字符串是不可变的。因此,通过不断更改字符串,实际上您每次都在创建一个新字符串。这是非常低效的。

如Zenohm在评论中所述,您应该按照以下方式进行操作:

return ''.join("{} ".format(eng[char]) for char in msg))



尽管修改单个字符串并没有什么坏习惯,并且
在这里并不是真正的问题,但我认为,如果他开始避免马上修改不可变对象,那会很好。蝙蝠。
返回''.join(“ {}” .format(eng [char])for msg中的char)可以用于
代替他的原始字符串修改,这将有助于
/>鼓励将来更好地实践。


评论


\ $ \ begingroup \ $
谢谢!我做了您在git repo中建议的更改。我包括类型注释和注释,因为我使用的是mypy。我试图学习更好,更明确地使用类型,因此(希望)在学习Haskell时会更容易。因此,我暂时将其保留。
\ $ \ endgroup \ $
– bsima
15年7月13日在1:38



\ $ \ begingroup \ $
完成!但是,您的意思是除了在最后两个代码块中捕获而不是捕获?
\ $ \ endgroup \ $
– bsima
15年7月13日在2:09

\ $ \ begingroup \ $
@BenSima啊,是的!抱歉,在编写答案时,我非常努力地忘记了这一点。我已经修复了。
\ $ \ endgroup \ $
– SirPython
15年7月13日在2:13

\ $ \ begingroup \ $
@BenSima mypy仅从函数定义中推断类型,您可以删除注释类型。
\ $ \ endgroup \ $
– Caridorc
15年7月13日在11:26

\ $ \ begingroup \ $
@SirPython虽然修改单个字符串并不是一个坏习惯,而且在这里并不是真正的问题,但我认为,如果他立即避免修改不可变对象,那将是很好的。返回''.join(“ {}” .format(eng [char])for msg中的char)可以代替他原来的字符串修改,并且将来会鼓励更好的实践。
\ $ \ endgroup \ $
–千欧姆
15年7月13日在15:26