【问题标题】:Quiz Web app error: Function to generate 10 random questions sometimes generates 9 or 11 questions insteadQuiz Web 应用程序错误:生成 10 个随机问题的功能有时会生成 9 或 11 个问题
【发布时间】:2019-04-16 06:27:22
【问题描述】:

我正在使用烧瓶在 pythonanywhere 上编写一个测验应用程序。这是我第一次在任何地方使用 flask 或 pythonanywhere,所以我还在学习。下面的函数抛出了一个奇怪的错误,有时它会生成 11 或 9 个字典条目而不是 10 个,即使 Qnum 参数永远不会改变。

我认为这个问题可能与别名有关(因为该函数会删除一个条目),所以我尝试通过遍历字典键和值来创建单独的列表。当我直接在我的主应用程序文件中编写代码时,它运行良好,但是一旦我将它抽象为一个辅助函数,它就开始发挥作用了。

来自辅助函数文件:

  def create_answer_dict(Dict, Qnum):
        import random
        Qdict={}
        for i in range(Qnum):
            #Choose random word to test
            Qkeys=[]
            for key in Dict.keys():
                Qkeys.append(key)
            Qword=random.choice(Qkeys)

            #Get correct answer from dictionary
            correctAnswer = Dict[Qword]

            #Generate wrong answer options
            wrongAnswers=[]
            for value in Dict.values():
                wrongAnswers.append(value)
            del wrongAnswers[wrongAnswers.index(correctAnswer)]
            wrongAnswers = random.sample(wrongAnswers, 3)
            answerOptions = wrongAnswers + [correctAnswer]
            random.shuffle(answerOptions)
            Qdict[Qword]=answerOptions
        return Qdict

来自主应用文件:

@app.route("/", methods=["GET","POST"])
def index():
    Qdict=create_answer_dict(questions, total)
    if request.method == "GET":
        return render_template('main.html', q = Qdict, keys=Qdict.keys())
    elif request.method == 'POST':
        score=0
        for i in Qdict.keys():
            answered=request.form[i]
            if original_questions[i]==answered:
                score+=1
    return render_template("results.html", score=score, total=total)

从 html 视图:

<form action='/' method='POST'>
    <ol>
        {% for i in keys %}
            <li>What is the French for <u>{{i}}</u> ?  </li>
            {% for j in q[i] %}
                <input type='radio' value='{{j}}' name='{{i}}'      style="margin-right: 5"/>{{j}}
                <br></br>
            {% endfor %}
        {% endfor %}
    </ol>
    <input type="submit" value="submit" />
</form>

它应该如何工作:

可能的问题和答案存储在字典对象中。

在我的主应用程序文件中,我使用我的问答字典和变量 total 作为参数从辅助函数文件中调用此函数。总计设置为 10。

函数选择Qnum问题,找到对应的答案,随机选择3个不正确的答案。

它将这些作为字典返回,格式如下:

{Question1:[CorrectAnswer, IncorrectAnswer1,IncorrectAnswer2, IncorrectAnswer3],
Question2:[CorrectAnswer, IncorrectAnswer1,IncorrectAnswer2, IncorrectAnswer3], 
etc.}

一切都会返回而不会引发错误,只是有时字典中的条目比预期的少一个或多一个。

【问题讨论】:

  • 9 是可解释的(一个键覆盖了字典中已经存在的相同键),11 不是。
  • 是的。而且我现在已经看到它在相同的代码上产生了 7 到 11 个条目。我只是刷新页面并观察行为。
  • 无法重现您的问题。我一直在Qdict 中获得Qnum 或少于Qnum 的条目,永远不会更多。在return Qdict前添加print(len(Qdict)),多次运行脚本后查看输出。
  • 编辑:当我 11 岁时,我可能有 Qnum+1。非一错误让我认为我有一个零索引错误。在控制台中重复调用函数的结果: >>> check=create_answer_dict(questions, total) >>> len(check) 10 10 9 10 8 9 10 9 9 9 10 9 10 7 9 10 9
  • 您应该可以在此处访问实际站点:hapaxhypatia.pythonanywhere.com/

标签: python for-loop flask pythonanywhere


【解决方案1】:

您不能期望通过从另一个字典中随机选择 n 条目来获得长度为 n 的字典,因为总是有可能选择重复的条目(并且由于字典键是唯一的,因此重复的条目将被覆盖在结果字典中)。

在字典中选择固定数量的随机键 n 的更好方法是简单地从字典键创建一个列表,打乱该列表,然后对该列表进行切片以仅保留第一个 n 元素.

在您的代码中,它看起来像这样:

def create_answer_dict(Dict, Qnum):
    import random
    Qdict={}

    possibleQuestions = list(Dict.keys())
    random.shuffle(possibleQuestions)
    possibleQuestions = possibleQuestions[:Qnum]

    for Qword in possibleQuestions:
        #Get correct answer from dictionary
        correctAnswer = Dict[Qword]

        #Generate wrong answer options
        wrongAnswers = list(Dict.values())
        del wrongAnswers[wrongAnswers.index(correctAnswer)]
        wrongAnswers = random.sample(wrongAnswers, 3)
        answerOptions = wrongAnswers + [correctAnswer]
        random.shuffle(answerOptions)
        Qdict[Qword] = answerOptions
    return Qdict

这将保证生成Qnum 独特的问题。

编辑:另外,在index() 中,如果用户没有回答所有问题,为了避免 KeyErrors,请替换

for i in Qdict.keys():
        answered=request.form[i]
        ...

for i in request.form:
        answered=request.form[i]
        ...

工作演示:https://repl.it/@glhr/55701832

【讨论】:

    猜你喜欢
    • 2022-06-11
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-26
    • 2013-06-03
    • 1970-01-01
    • 2011-11-17
    相关资源
    最近更新 更多