Как не печатать повторяющиеся строки из внешнего текстового файла?

#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