【问题标题】:How can I create a quiz in Python using a dictionary rather than a large number of if/else statements?如何使用字典而不是大量 if/else 语句在 Python 中创建测验?
【发布时间】:2016-04-15 22:54:58
【问题描述】:

我正在做一个是/否问题的测验,根据问题回答是/否会奖励不同数量的积分,这些积分将在每个问题之后添加到总分中并显示在最后。

但是,测验中有大约 50 个问题,这意味着 if/else 语句堆积如山。有没有办法可以使用字典和循环或类似的东西来显着减少程序的长度?

edit 这种重复多次是我试图避免的。我正在考虑添加一个变量 i 并在每个问题之后为其添加 1,并查找下一个问题的索引。但这只能通过列表实现吗?

print "The following are y/n questions."
total = 0 

q1 = raw_input("Do you exercise daily? ")
if q1 == "y":
    total += 1
else:
    total = total

print total

【问题讨论】:

  • 请向我们展示您到目前为止所做的尝试!
  • 你在哪里设想这个庞大的 if/else 语句?示例代码在这里会有所帮助
  • 请添加一些代码来改进您的问题。你有什么想法?你在想什么样的结构?你是从什么开始的?
  • 该问题中有很多与字典相关的解决方案;基本上是一样的。

标签: python python-2.7 loops dictionary


【解决方案1】:

创建一个字典列表。每个元素都是一个问题,是和否的点。然后,您可以轻松地遍历列表。

qa = [{"question": "Do you exercise?", "yes": 10, "no": 0},
       "question": "Do you smoke?", "yes": -10, "no": 0},
       ...
     ]
for item in qa.items():
    answer = raw_input("Do you exercise daily? ")
    score = item.get(answer)
    total = total + score

当然,您需要添加一些额外的代码来处理用户没有按字面意思回答“是”或“否”的情况,但这不会影响此解决方案。关键是,您创建一个代表问题的对象,以及带有分数的可能答案,然后遍历这些对象的列表。

您甚至可以更进一步,创建一个自定义类。你可以这样做,例如:

class Question(object):
    def __init__(self, question, yes=0, no=0):
        self.question = question
        self.yes = yes
        self.no = no

questions = [Question("Do you exercise?", yes=10, no=0),
             Question("Do you smoke?", yes=0, no=-10),
             ...
            ]

for question in questions:
    answer = raw_input(question.question)
    ...

【讨论】:

    【解决方案2】:

    在最低级别,对于你给定的例子,你真正需要的只是一个要问的问题列表,然后循环遍历这个

    print "The following are y/n questions."
    total = 0 
    
    questions = ["Do you exercise daily? ", "Is this a second question?"]
    
    for question in questions:
        q1 = raw_input(question)
        if q1 == "y":
            total += 1
    
    print total
    

    当然,这可以扩展为包括适当的对象类等等..

    我正在考虑使用这种方法,但是,如何将不同的分值与每个问题联系起来?一个问题可能值六,而另一个问题可能值四。我可以制作第二个包含点值的列表吗?

    您创建一个问题类,然后将列表列出这些答案

    class Question()
        def __init__(self, text, correct_answer_value)
            this.text = text
            this.value = correct_answer_value
    
    print "The following are y/n questions."
    total = 0 
    
    questions = [Question("Do you exercise daily? ",1), Question("Is this a second question?",2)]
    
    for question in questions:
        q1 = raw_input(question.text)
        if q1 == "y":
            total += question.value
    
    print total
    

    【讨论】:

    • 我正在考虑使用这种方法,但是,如何将不同的点值与每个问题联系起来?一个问题可能值六,而另一个问题可能值四。我可以制作第二个包含点值的列表吗?
    • @RyanWerner - 我已经扩展了我的答案
    • 我遇到了一个奇怪的错误。就是说 init 正好有两个参数,但给出了三个。但是给出了两个论点。
    • @RyanWerner - 我忘了在这里包含self,已修复!
    【解决方案3】:
    # Firstly, declare your questions. Create it with their answer and associated score.
    questions = {}
    questions[1] = {}
    questions[1]["question"] = "Is the sky blue? Y/N"
    questions[1]["answer"] = True
    questions[1]["score"] = 50
    
    # We can add more questions
    questions[2] = {}
    questions[2]["question"] = "Is Python a programming language? Y/N"
    questions[2]["answer"] = True
    questions[2]["score"] = 150
    
    # Set the initial score at 0
    score = 0
    
    # Loop over the questions
    for key in questions:
        user_answer = None
    
        # We ask the question till the user answer Yes or Not
        while user_answer not in ["Y","N"]:
            user_answer = raw_input(questions[key]["question"])
    
        # If the user said Yes we keep True, if he said No we keep False
        user_answer = True if user_answer == "Y" else False 
    
        # We increment the score if the answer is the same that it's stored in your dictionary
        score += questions[key]["score"] if user_answer == questions[key]["answer"] else 0
    
    print "Final score {0}".format(score)
    

    【讨论】:

    • 考虑到他提出的问题数量 (50),使用函数创建字典条目会更容易,而不是单独声明每个条目。那是假设您要保留当前的 ​​4 行/问题格式。否则,您只需要为问题声明查看 200 行代码。
    • @disflux 我同意你的看法。我已经写了最简单的解决方案,但不是声明问题的最佳方式。如果您认为可以改进我的帖子,我们邀请您编辑它!
    【解决方案4】:

    一些设置代码,比如

    def get_yesno(prompt):
        while True:
            response = raw_input(prompt).strip().lower()
            if response in {'y', 'yes'}:
                return True
            elif response in {'n', 'no'}:
                return False
            else:
                print("Please respond with yes or no.")
    
    class YesNo:
        __slots__ = ('question', 'yes_points', 'no_points')
    
        def __init__(self, question, yes_points=1, no_points=0):
            self.question = question
            self.yes_points = yes_points
            self.no_points = no_points
    
        def ask(self):
            if get_yesno(self.question):
                return self.yes_points
            else:
                return self.no_points
    

    意味着您可以轻松定义问题,例如

    questions = [
        YesNo("Do you exercise daily? "),
        YesNo("Do you have more than 3 drinks a week? ", -5, 2)
    ]
    

    然后你的主程序就变成了

    def main():
        score = sum(q.ask() for q in questions)
        print("Your score was {}".format(score))
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

      【解决方案5】:

      将您的问题添加到列表中。 (Lists)

      然后简单地使用:

      for question in questionList:
          q1 = raw_input(question)
          if q1 == "y":
              total += 1
          else:
              total = total
      print total
      

      【讨论】:

        【解决方案6】:

        您特别提到您想使用字典,因此此答案将提供有关如何执行此操作的解决方案。

        如果您只期望答案是“是”/“否”,那么您可以按如下方式设置您的字典:

        test_dict = {'question1': {'yes': 100, 'no': 50}, 
                     'question2': {'yes': 75, 'no': 25}}
        

        然后,您可以提出问题,获取他们的答案,然后通过字典来累积他们的分数。

        question1_ans = raw_input("Is your favorite animal a Rhino?").lower()
        
        num_points += test_dict['question1'][question1_ans]
        

        在这种情况下,如果您回答“是”,那么 num_points 将为 100。否则,回答“否”将导致 num_points 为 50。

        显然,这不会阻止他们回答类似“FOO”的问题,而不是“是”/“否”,这会导致 KeyError。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-13
          • 1970-01-01
          • 2016-09-15
          • 2020-10-29
          • 2019-08-28
          • 2020-10-02
          • 1970-01-01
          • 2018-01-27
          相关资源
          最近更新 更多