Я пытаюсь создать викторину с несколькими вариантами ответов, используя python. У меня есть внешний файл .txt с 20 вопросами, и я хочу, чтобы он выбрал 10 случайных вопросов из этого файла, что он и делает в настоящее время. Файл имеет макет:
1. Кто был первым человеком, ступившим на Луну?, А. Майкл Джексон, Б. Базз Лайтер, К. Нил Армстронг, Д. Никто, С.
У меня проблема в том, что я не хочу, чтобы один и тот же вопрос печатался дважды.
Единственный способ, которым я могу решить эту проблему, - добавить подробность [0], которая является номером вопроса, в список, определенный в python, а затем проверить в этом списке, чтобы убедиться, что номер вопроса не дублируется.
import random
qno = []
def quiz():
i = 0
global score #makes the score variable global so it can be used outside of the function
score=0 #defines the score variable as '0'
for i in range (1,11): #creates a loop that makes the program print 10 questions
quiz=open('space_quiz_test.txt').read().splitlines() #opens the file containing the questions, reads it and then splits the lines to make them seperate entities
question=random.choice(quiz)
detail = question.split(",")
print(detail[0],detail[1],detail[2],detail[3],detail[4],detail[5])
print(" ")
qno.append(detail[0])
print(qno)
if detail[0] in qno is False:
continue
qno.append(detail[0])
print(qno)
elif detail[0] in qno is True:
if detail[0] not in qno == True:
print(detail[0],detail[1],detail[2],detail[3],detail[4],detail[5])
print(" ")
qno.append(detail[0])
print(qno)
while True:
answer=input("Answer: ")
if answer.upper() not in ('A','B','C','D'):
print("Answer not valid, try again")
else:
break
if answer.upper() == detail[6]:
print("Well done, that's correct!")
score=score + 1
print(score)
continue
elif answer.upper() != detail[6]:
print("Incorrect, the correct answer is ",detail[6])
print(score)
continue
quiz()
Когда я запускаю этот код, я ожидаю, что ни один вопрос не будет повторяться дважды, но кажется, что это всегда так, я изо всех сил пытаюсь придумать способ сделать это. Буду признателен за любую помощь, Спасибо!
Использовать этот:
questions = random.sample(quiz, 10)
Он выберет случайный подсписок длиной 10 из списка викторин.
Также:
Вы должны прочитать файл и сделать список вопросов вне цикла, а затем просто перебрать вопросы:
with open('space_quiz_test.txt') as f:
quiz = f.readlines()
questions = random.sample(quiz, 10)
for question in questions:
...
вау... зачем я все время указывал k=
... работает без
Привет, спасибо за ответ, он не дает мне повторяющихся вопросов, и это хорошо. Проблема сейчас в том, что он говорит, что ответ неверен, хотя это не так. Он знает, что ответ детализирован [6], потому что он говорит, что это правильный ответ, но, похоже, он просто не проверяет введенный ответ на него?
@MilanLad Я бы посоветовал вам реализовать эти исправления, а затем задать для этого новый вопрос. Трудно понять, что не так, потому что мы не можем видеть внесенные вами изменения.
@MilanLad нет проблем! Не стесняйтесь отмечать мой ответ как принятый, если считаете, что он ответил на ваш вопрос :)
Вместо того, чтобы открывать файл 10 раз, возьмите из него 10 вопросов и циклически задавайте их:
def get_questions(fn, number):
with open(fn) as f:
# remove empty lines and string the \n from it - else you get
# A\n as last split-value - and your comparisons wont work
# because A\n != A
q = [x.strip() for x in f.readlines() if x.strip()]
random.shuffle(q)
return q[:number]
def quiz():
i = 0
global score # makes the score variable global so it can be used outside of the function
score=0 # defines the score variable as '0'
q = get_questions('space_quiz_test.txt', 10) # gets 10 random questions
for question in q:
detail = question.split(",")
print(detail[0],detail[1],detail[2],detail[3],detail[4],detail[5])
print(" ")
# etc ....
Доку:
random.shuffle
Есть еще несколько вещей, которые нужно исправить:
# global score # not needed, simply return the score from quiz():
my_score = quiz() # now my_score holds the score that you returned in quiz()
...
# logic errors - but that part can be deleted anyway:
elif detail[0] in qno is True: # why `is True`? `elif detail[0] in qno:` is enough
if detail[0] not in qno == True: # you just made sure that `detail[0]` is in it
...
while True:
answer=input("Answer: ").upper() # make it upper once here
if answer not in ('A','B','C','D'): # and remove the .upper() downstream
print("Answer not valid, try again")
else:
break
Вы можете добиться этого, рисуя вопросы сразу с выбором без замены, а затем перебирая их.
import numpy as np
quiz=open('space_quiz_test.txt').read().splitlines() #opens the file containing the questions, reads it and then splits the lines to make them seperate entities
questions=np.random.choice(quiz, size=10, replace=False)
for question in quesions: #creates a loop that makes the program print 10 questions
#rest of your code
Упс, я обычно использую numpy. Отредактировано.
Спасибо. Я не думал об этом. Обычно я могу позволить себе роскошь работать с довольно короткими и быстрыми сценариями. Должен ли я измениться на from numpy import random
? в таком случае? Или даже from numpy.random import choice
?
Прочитайте все вопросы:
with open('space_quiz_test.txt') as f:
quiz = f.readlines()
Перемешайте список вопросов на месте:
random.shuffle(quiz)
Цикл по перетасованному списку:
for question in quiz:
print(question)
Это потому, что random.choice
может давать один и тот же результат более одного раза. Вместо использования random.choice попробуйте
random.shuffle(list)
, а затем выбрав первые 10 записей из перемешанного списка.
quiz=open('space_quiz_test.txt').read().splitlines()
random.shuffle(quiz)
for question in quiz[1:11]:
detail = question.split(",")
print(detail[0],detail[1],detail[2],detail[3],detail[4],detail[5])
Привет, Милан, возможно, вы не знакомы с [минимальным, полным и проверяемым] аспектом задавания вопросов, поскольку вы новичок, но ваш вопрос довольно хорош. Часть промахов является «минимальной». Весь ваш код действительно необходим, чтобы задать вопрос, который у вас был.