Количество вопросов Django/Python
Количество вопросов:
Попробуйте создать новую игру из 20 вопросов средней сложности (MEDIUM) в категории Искусство.
Он вел себя странно, так?
Это определенно нежелательная ситуация. Из этого следует, что в Open Trivia DB не хватает вопросов из данной категории с данным уровнем сложности, поэтому она возвращает нам ошибку. И мы поступаем неразумно:
try:
question = quiz.get_question()
quiz.save(request)
return render(request, 'game.html', vars(question))
except IndexError as x:
return redirect('/finish')
Потому что мы предполагаем, что конец вопросов = конец игры. Что имеет смысл, если API имеет нужное количество вопросов ...
Код ответа от сайта Open Trivia в данном случае равен 1. Обратившись к документации (https://opentdb.com/api_category.php), мы выясним, что означает каждый код:
Подсказка
Нам нужно подумать, как решить эту проблему. Было бы здорово, если бы ответ, кроме кода ошибки, включал все возможные задания для данной категории и уровня сложности - но, к сожалению, это не так. Нам приходится приспосабливаться к существующему API, изменить что-либо в нем - выше наших сил.
У нас есть три возможных решения:
- или мы предоставим пользователю столько вопросов, сколько сможем (а не столько, сколько просят)
- мы сообщим пользователю, что у него не так много вопросов, как он просит, и попросим его выбрать другое значение .
- или мы дополним вопросы вопросами "соседнего" уровня сложности. Например, если у нас есть 10 вопросов на уровне сложности HARD, а пользователь хотел получить 15 вопросов HARD - мы добавим к упомянутым 10 вопросам еще 5 вопросов из категории MEDIUM.
Первый шаг является общим для всех подходов - нам нужно определить, сколько вопросов мы можем получить из Open Trivia DB. К счастью, нам не придется выяснять это методом проб и ошибок. В документации есть информация о дополнительной конечной точке:
Для категории искусство (Art, id = 25) ответ из https://opentdb.com/api_count.php?category=25 следующий:
{
"category_id":25,
"category_question_count":{
"total_question_count":26,
"total_easy_question_count":8,
"total_medium_question_count":10,
"total_hard_question_count":8
}
}
Первый и второй варианты просты - достаточно, чтобы до момента построения списка категорий мы еще подтянули вышеупомянутые данные и в первом случае заменили выбранное пользователем количество вопросов на имеющееся, а во втором - вывели красивую ошибку. Третий вариант сложнее, так как требует от нас решить, сколько вопросов с какого уровня сложности мы должны загрузить. Например, если у нас есть 10 вопросов на сложном уровне сложности, а пользователь хотел 15 сложных вопросов - мы добавим к указанным 10 вопросам еще 5 вопросов из средней категории
В то время как легко сказать, какой уровень сложности является "соседним" для hard или easy (это будет medium), в обратном случае - для соседнего medium это будет easy или hard? Представляется справедливым добавить "половину" вопросов из обоих уровней сложности. Мы также должны защитить себя от ситуации, как в категории "Искусство" - если мы хотим сыграть в викторину, состоящую из 20 сложных вопросов, мы должны предоставить 8 сложных, 10 средних и 2 легких вопроса из нашего приложения, чтобы всего их было 20.
Если вы остановитесь на самом сложном решении, вам придется написать функцию, которая будет "выбирать" вопросы из других уровней сложности. Я советую вам в самом начале проверить, что желаемое количество вопросов не превышает максимальное количество вопросов для всех уровней. Когда вы закончите с этим, функция должна выглядеть как цикл while, который будет вращаться столько раз, сколько нет вопросов, и в каждом своем цикле выбирать один вопрос из пула, подготовленного для пользователя
Другая идея состоит в том, чтобы построить на примере категории "Искусство" - где если мы хотим сыграть в викторину, состоящую из 20 сложных вопросов, мы должны предоставить 8 сложных, 6 средних и 6 легких вопросов из нашего приложения, так что всего их будет 20, код типа:
lvls = ['easy', 'medium', 'hard']
requested_questions = request.POST['quantity']
requested_difficulty = request.POST['difficulty']
question_deficiency = requested_questions - total_hard_question_count
question_deficiency_per_lvl = question_deficiency / 2
questions_for_user = get_questions_for_lvl(requested_difficulty, requested_questions)
lvls.remove(requested_difficulty)
for level in lvls
questions_for_user.extend(get_questions_for_lvl(level, question_deficiency_per_lvl))
<
- в легком будет 2
- в сложном будет 10
- в среднем будет 10
согласно этому коду мы сможем взять 10 средних, 5 трудных и 5 легких, но .... в легких только 2 вопроса.
Однако, я предлагаю цикл :), возможно, творческий подход к этому решению :)
Код: https://github.com/Mar3eczek17/ProjektPlusPython/tree/master/pythonplussources/sdaquiz