#python #python-3.x
#python #python-3.x
Вопрос:
Я пытаюсь создать тест с несколькими вариантами ответов, используя Python. У меня есть внешний txt-файл, в котором содержится 20 вопросов, и я хочу, чтобы он выбрал 10 случайных вопросов из этого файла, что он и делает в данный момент. Файл имеет макет:
1, Кто был первым человеком, ступившим на Луну?, А.Майкл Джексон, Б. Базз Лайтер, К.Нил Армстронг, Д.Никто, С
Проблема, с которой я сталкиваюсь, заключается в том, что я не хочу, чтобы он печатал один и тот же вопрос дважды.
Единственный способ, который я могу придумать, чтобы решить эту проблему, — добавить detail [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()
Когда я запускаю этот код, я ожидаю, что ни один вопрос не повторяется дважды, но, похоже, это всегда происходит, я изо всех сил пытаюсь придумать способ сделать это. Буду признателен за любую помощь, спасибо!
Комментарии:
1. Привет, Милан, возможно, ты не знаком с [Минимальным, полным и поддающимся проверке] аспектом примера задаваемых вопросов, поскольку ты новичок, но твой вопрос довольно хорош. Часть пропусков «минимальна». Весь ваш код действительно необходим, чтобы задать возникший у вас вопрос.
Ответ №1:
Используйте это:
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:
...
Комментарии:
1. вау … почему я все время указывал
k=
… это работает без2. Привет, спасибо за ответ, он не дает мне никаких повторяющихся вопросов, что хорошо. Проблема сейчас в том, что он говорит, что ответ неверен, хотя это не так. Он знает, что ответ — detail[6], потому что он говорит, что это правильный ответ, но, похоже, он просто не проверяет введенный ответ на него?
3. @MilanLad Я бы посоветовал вам внедрить эти исправления, а затем задать новый вопрос по этому поводу. Трудно понять, что не так, потому что мы не можем видеть внесенные вами изменения.
4. @MilanLad нет проблем! Не стесняйтесь отметить мой ответ как принятый, если вы чувствуете, что он ответил на ваш вопрос 🙂
Ответ №2:
Прочитайте все вопросы:
with open('space_quiz_test.txt') as f:
quiz = f.readlines()
Перетасуйте список вопросов по месту:
random.shuffle(quiz)
Цикл по перетасованному списку:
for question in quiz:
print(question)
Ответ №3:
Это связано с тем, что 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])
Ответ №4:
Вы можете добиться этого, нарисовав все вопросы сразу с помощью choice без замены, а затем выполнив итерацию по ним.
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
Комментарии:
1. Напротив, я обычно использую numpy. Отредактировано.
2. Спасибо. Я об этом не подумал. Обычно я могу позволить себе роскошь работать с довольно короткими и быстрыми скриптами. Должен ли я изменить на
from numpy import random
? в таком случае? Или дажеfrom numpy.random import choice
?
Ответ №5:
Вместо того, чтобы открывать файл 10 раз, извлеките из него 10 вопросов и повторяйте их в цикле:
def get_questions(fn, number):
with open(fn) as f:
# remove empty lines and string the n from it - else you get
# An as last split-value - and your comparisons wont work
# because An != 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 ....
Doku:
Есть несколько других вещей, которые нужно исправить:
# 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