首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >构建一个madlib生成器

构建一个madlib生成器
EN

Code Review用户
提问于 2021-02-11 21:37:44
回答 1查看 90关注 0票数 3

我正在学习Python,我正在构建一个基本的madlib生成器。下面的代码按预期工作。我只是想知道它是否使用了最佳实践/是否可以做得更好。

代码语言:javascript
复制
def intro():
    print("Welcome to our madlib generator!")
    print("We'll ask you for a serious of words, you'll give us the words, and "
          "we'll make a dope ass story out of it!")
    print("Let's get some info from you first.")
    print("Select the type of madlib you want. ")
    madlib_type = input("1. Short Story\n2. Poem\n")
    return madlib_type


def user_input():
    name = input("Enter a name: ")
    color = input("Enter a color: ")
    animal = input("Enter an animal: ")
    food = input("Enter a food: ")
    item = input("Enter an item: ")
    adjective = input("Enter an adjective: ")
    noun1 = input("Enter a plural noun: ")
    noun2 = input("Enter any noun: ")
    return [name, color, animal, food, item, adjective, noun1, noun2]


class MadlibGenerator:
    def __init__(self, *args):
        self.name = args[0].title()
        self.color = args[1]
        self.animal = args[2]
        self.food = args[3]
        self.item = args[4]
        self.adjective = args[5]
        self.noun1 = args[6]
        self.noun2 = args[7]

    def short_story_generator(self):
        print(f"There once was a person named {self.name}. {self.name} LOVED "
              f"{self.animal}s. They were {self.name}'s favorite animal.")
        print(f"One day, {self.name} was walking down the street wearing "
              f"{self.color} pants and a {self.color} shirt. In fact, all of "
              f"{self.name}'s ")
        print(f"clothes were {self.color}! In one of {self.name}'s hand, "
              f"there was a bright green {self.item}. In the other, there was "
              f"a big {self.food} that {self.name} was waiting to eat!")

    def poem_generator(self):
        print(f"Roses are {self.adjective}")
        print(f"{self.noun1} are blue")
        print(f"I can't start my day without {self.noun2}")


madlib_type = intro()
madlib_input = user_input()
madlib = MadlibGenerator(madlib_input[0], madlib_input[1], madlib_input[2],
                         madlib_input[3], madlib_input[4], madlib_input[5],
                         madlib_input[6], madlib_input[7])
if madlib_type == "1":
    madlib.short_story_generator()
if madlib_type == "2":
    madlib.poem_generator()
EN

回答 1

Code Review用户

回答已采纳

发布于 2021-02-12 02:16:38

你想要很多你不用的词。最好只向用户询问相关的单词。也许user_input不需要使用任何参数,而是可以列出一些像user_input(["a name", "a color", "a different color"])这样的描述,并在此基础上进行询问?

我不明白为什么这两个故事生成器像那样生活在同一个类里。将相同的数据传递给多个生成器可能不是很有用。函数可以与参数本身一样容易地接受这些词。这并不使MadlibsGenerator类的思想不合适,但这两个函数属于不同的生成器,函数的输入根本不需要直接绑定到生成器。

这些生成器还各自做两件不同的事情--它们都生成故事并打印它们。通常情况下,最好是分开做,以防你也想用故事做其他的事情。

在选择使用哪个生成器时,不检查用户是否提供了有效的输入。如果我被要求选择1或2并输入3,我可能会期待一条错误消息,也许还有机会再试一次。取而代之的是,这个节目像往常一样继续进行,只是我最后没有得到一个有趣的故事。

有一天,其他人可能会想要使用这些函数(或者您可能希望将它们用于其他功能)。他们可能会尝试将您的文件作为一个模块导入。当他们这样做的时候,整个文件就会运行,现在这意味着整个madlibs程序。这可能不是他们想要的。您可以通过将程序逻辑放置在if __name__ == "__main__":块中来防止这种情况发生,这样在导入文件时它就不会执行。

在字符串上分支,找出要使用哪个生成器有点难看。只要能在字典中查到,那就好了,也可能让我们更容易添加新的词典,因为我们只需要更新一个地方,而不必担心introifs的同步。

但是,如果我们不想每次想出一个新的生成器时更新intro,我们仍然有一个问题--当告诉我们我们的选项是什么时,我们需要知道如何调用所有不同的生成器。我们可以把它放在我前面提到的字典中,或者如果我们已经将内容放入生成器对象中,我们也可以在其中添加一个name字段。后者可能更整洁。

把所有的东西加在一起,我们可能会得到

代码语言:javascript
复制
class MadlibsGenerator:
    def __init__(self, name, descriptions, generator):
        self.name = name
        self.descriptions = descriptions
        self.generator = generator
    
    def __call__(self, *args, **kwargs):
        return self.generator(*args, **kwargs)

def intro(generators):
    print("Welcome to our madlib generator!")
    print("We'll ask you for a serious of words, you'll give us the words, and "
          "we'll make a dope ass story out of it!")
    print("Let's get some info from you first.")
    print("Select the type of madlib you want. ")

    for key in generators:
        print(f"{key}. {generators[key].name}")

    while True:
        selection = input()
        if selection in generators:
            break
        else:
            print(f"No generator \"{selection}\", please try again.")

    return generators[selection]

def user_input(descriptions):
    words = []
    for description in descriptions:
        words.append(input(f"Enter {description}: "))

    return words


def generate_short_story(name, animal, color, item, food):
    return (f"There once was a person named {name}. {name} LOVED "
        f"{animal}s. They were {name}'s favorite animal.\n"
        f"One day, {name} was walking down the street wearing "
        f"{color} pants and a {color} shirt. In fact, all of "
        f"{name}'s\n"
        f"clothes were {color}! In one of {name}'s hand, "
        f"there was a bright green {item}. In the other, there was "
        f"a big {food} that {name} was waiting to eat!")



def generate_poem(adjective, noun1, noun2):
    return (f"Roses are {adjective}\n"
        f"{noun1} are blue\n"
        f"I can't start my day without {noun2}")


if __name__ == "__main__":
    generators = {
        "1": MadlibsGenerator("Short Story",
            ["a name", "an animal", "a color", "an item", "a food"],
            generate_short_story),
        "2": MadlibsGenerator("Poem",
            ["an adjective", "a plural noun", "any noun"],
            generate_poem)
    }

    generator = intro(generators)
    madlib_input = user_input(generator.descriptions)
    print(generator(*madlib_input))

更新

此时,您可能会开始想:“等等,每个生成器函数只是将字符串放入另一个字符串--每当我们想要创建一个函数时,创建一个函数似乎很笨拙”。你说得有道理。虽然f-字符串很好,但是还有其他可用的选项可以让我们在一个地方指定模板,然后在另一个地方使用它。例如,字符串已经有了一个format方法。我们可以利用这一点,用字符串替换生成器函数,如

代码语言:javascript
复制
poem_template = """
Roses are {0}
{1} are blue
I can't start my day without {2}
"""

而不是让我们的生成器调用这些函数,我们可以让它们在这些字符串上调用.format,例如

代码语言:javascript
复制
class MadlibsGenerator:
    def __init__(self, name, descriptions, template):
        self.name = name
        self.descriptions = descriptions
        self.template = template.strip()

    def __call__(self, *args):
        return self.template.format(*args)

现在,如果我们愿意的话,我们可以创建类似greeting_generator = MadlibsGenerator("Greeting", ["a name"], "Hi there, {0}!")的生成器。整洁!

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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