首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Reddit挑战#380 Python

Reddit挑战#380 Python
EN

Code Review用户
提问于 2020-03-02 09:38:36
回答 1查看 184关注 0票数 5

我完成了Reddit挑战#380 (来源)。

以下是一个简短的描述:

通常情况下,莫尔斯码,您将指示一个字母的结尾和下一个字母的开头位置,例如,在字母代码之间有一个空格,但是对于这个问题,只需将所有编码的字母合并成一个字符串,其中只有破折号和点。这个系统的一个明显的问题是解码不明确。例如,bitsthree都编码为相同的字符串,因此在没有更多信息的情况下,您无法判断您将解码到哪个字符串。

我已经尽了我最大的努力,但是我想要一些我能做的更好的见解。

代码是Reddit挑战的解决方案。在主方法中,初始化类,然后打印出每个解决方案。请注意,主要挑战和可选挑战1-4包括在内。我没有包括可选的挑战5。类的初始化转换和分组的单词从一个文件'wordlist.txt‘,是来源于reddit的帖子。我不会在这里包含这个文件,因为它很长,但是这里是来源。请确保将文件重命名为“wordlist.txt”。

非正统选择

  1. morse_alphabet变量PyLint将其突出显示为“行太长”的异常。我禁用了它,因为缩短变量名不会有帮助,但我不确定是否应该分割行。我把它保存在那里,因为它比为每个单独的字母打字容易,但也许最好是分开字母?
  2. count_longest_dash_run函数它似乎是一个非正统的解决方案,也许有一种方法可以做到这一点而不作比较?
  3. 在可选的挑战性print(key+":"+str(value))中重复的行,我应该把它分割成一个函数,还是会过分呢?
  4. 文档--我不确定文档,通常人们会输入返回类型或参数信息,但我不确定它应该是什么样子,或者我正在做的事情是否正确。
  5. 静态方法和类方法应该包括所有函数的@typemethod,还是特定于某些特定情况,例如静态方法?

Python代码

代码语言:javascript
复制
"""
    This module is a solution the the programming exercise found on reddit.
    Exercise:
        https://www.reddit.com/r/dailyprogrammer/comments/cmd1hb/20190805_challenge_380_easy_smooshed_morse_code_1/
    This solution is not posted in the reddit thread.
    This solution completes the challenge and the optional challenges 1-4.
    On running this script, you should see the results with the console.
    Each set of results will be labeled with which challenge they refer to.
"""
class Morsecoder:
    """
        This class handles generating the morse code for all of the words listed in the wordlist.txt
        and storing them. It also handles generating the result for each challenge.
    """
    def __init__(self):
        """ Create a list of words and its morse code.
        Also creates a dict compiling the words with the same more code together. """
        # pylint: disable=line-too-long
        morse_alphabet = ".- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --.."
        self.morse_characters = morse_alphabet.split(" ")
        self.words = []
        self.encoded_words = {}
        self.encode_word_list()
        self.find_matching_codes()

    def get_morse_character(self, char):
        """ Retrieves the morse character of the character.
        Return none is the character int is not int the lower case range. """
        char_int = ord(char)-97
        if char_int >= len(self.morse_characters) or char_int < 0:
            return None
        return self.morse_characters[char_int]

    def encode_string(self, string):
        """ Encodes the entire string into the morse code.
        Raises an Exception if the string is not a lowercase alphabet only string. """
        if string.islower() and string.isalpha():
            morsecode = ''
            for char in string:
                morsecode += self.get_morse_character(char)
            return morsecode
        ex = "'"+string+"' could not be converted."
        ex += "The string must only contain lowercase alphabet characters"
        raise Exception(ex)

    def encode_word_list(self):
        """ Reads the wordlist.txt file and encodes each line into morse code.
        The original word and the morse code is stored within the words variables. """
        with open("wordlist.txt", 'r') as file:
            content = file.readlines()
        content = [x.strip() for x in content]

        for word in content:
            encoded = self.encode_string(word)
            self.words.append([word, encoded])

    def find_matching_codes(self):
        """ Find morse codes that are the same and groups the words under the morse code. """
        for word, encoded in self.words:
            if encoded in self.encoded_words:
                self.encoded_words[encoded].append(word)
            else:
                self.encoded_words[encoded] = [word]

    @staticmethod
    def count_longest_dash_run(string):
        """ static method that count the number of '-' in a row and retrieved the
        number of the longest '-' in a row within the string. """
        dashruns = string.split('.')
        longest_dash_run = 0
        for dashrun in dashruns:
            length = len(dashrun)
            if length > longest_dash_run:
                longest_dash_run = length
        return longest_dash_run

    @staticmethod
    def is_palindrome(word):
        """ static method that checks if the word is a palindrome. """
        return word == word[::-1]

    def challenge(self):
        """ prints out the result of the challenge. """
        print("Challenge Result:")
        print(self.encode_string("sos"))
        print(self.encode_string("daily"))
        print(self.encode_string("programmer"))
        print(self.encode_string("bits"))
        print(self.encode_string("three"))

    def optional_challenge_one(self):
        """ prints out the result of the first optional challenge. """
        print("Optional Challenge One Result:")
        for key in self.encoded_words:
            value = self.encoded_words[key]
            if len(value) >= 13:
                print(key+":"+str(value))

    def optional_challenge_two(self):
        """ prints out the result of the second optional challenge. """
        print("Optional Challenge Two Result:")
        for key in self.encoded_words:
            value = self.encoded_words[key]
            if self.count_longest_dash_run(key) == 15:
                print(key+":"+str(value))

    def optional_challenge_three(self):
        """ prints out the result of the third optional challenge. """
        print("Optional Challenge Three Result:")
        selected = {}
        for pair in self.words:
            word = pair[0]
            encoded = pair[1]
            if len(word) == 21:
                selected[encoded] = word

        for key in selected:
            if key.count('.') == key.count('-'):
                value = selected[key]
                print(key+":"+str(value))

    def optional_challenge_four(self):
        """ prints out the result of the fourth optional challenge. """
        print("Optional Challenge Four Result:")
        for pair in self.words:
            key = pair[0]
            value = pair[1]
            if len(key) == 13:
                if self.is_palindrome(value):
                    print(str(value)+":"+key)

if __name__ == "__main__":
    CODER = Morsecoder()
    CODER.challenge()
    CODER.optional_challenge_one()
    CODER.optional_challenge_two()
    CODER.optional_challenge_three()
    CODER.optional_challenge_four()
EN

回答 1

Code Review用户

回答已采纳

发布于 2020-03-03 23:20:53

  1. 太长的线可以通过包裹长字符串来固定.至少有两种明显的方法可以做到这一点。首先,使用三重引号字符串。这使得字符串包含跨多行。一个可能的问题是,字符串现在包括第二行和第三行开头的额外空格。但是,对split()的调用将删除这些内容。morse_alphabet =“”--.-.- -.。……。。-。第二种可能性是利用解释器连接相邻字符串。morse_alphabet =(“,--.-.- -.。……。。. -。在这两种情况下,morse_alphabet = morse_alphabet.split()将分割空格字符上的字符串,并返回莫尔斯代码的列表。
  2. 需要在某个地方进行比较,以找到最长的“-”S。它可以是显式的,如您的代码。也可以是隐式的,如内置的max()函数。代码可以通过使用生成器表达式来计算破折号的长度来简化。def count_longest_dash_run(代码):返回最大(code.split(‘.’.‘)中的dashrun (Dashrun))
  3. 对于这样的小程序来说,将print(...)提取到一个单独的函数中可能是过分的。但是使用f字符串或str.format()或者比使用'+‘串接字符串更好。打印(f“{key}:{value}")或打印(”{}:{}“.format(键,值))
  4. 关于文件。我发现类型提示不必要地搅乱了这样的小型程序的代码。对于较大的项目,它们可以帮助记录预期的类型。Docstring应该告诉某人如何使用被记录的东西(类、函数、模块、方法等)。它们应该是完整的和正确的。在这里,encode_string()的docstring表示“将整个字符串编码到morse代码中”,这是不正确的。它将字符串编码为morse代码,字母之间没有空格。challenge()的docstring表示“打印出挑战的结果”。但没有人会记得下周/月/年的挑战是什么。同样也适用于可选的挑战。
  5. 我不知道你在问什么。

其他的东西。

您可以迭代一个包含两个元组的列表,如下所示:

代码语言:javascript
复制
for key, value in self.words:
    ...

编码可以使用str.maktrans()str.translate()完成。

使用collections.defaultdict,您可以跳过在字典中没有键时执行特殊情况。例如,如果__init__self.encoded_words = defaultdict(list),那么

代码语言:javascript
复制
def find_matching_codes(self):
    for word, encoded in self.words:
        self.encoded_words[encoded].append(word)
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/238227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档