Removing dictionary item that has been picked through random.choice

Question:

This is a small quiz game. I have a class that creates two text files: the first one contains a dictionary of questions and the latter a dictionary of answers. These are then utilized in the following code snippet to pick ten random questions, register the answers and give the player points based on whether their answer is right or not.

The issue is that the same question can be picked multiple times. I’m therefore looking for a way of removing the dictionary item/key or value from the question dictionary after it’s been used.

with open("question.txt", "r") as questions:
    qdic = ast.literal_eval(questions.read())

with open("answers.txt", "r") as answers:
    adic = ast.literal_eval(answers.read())


print("Welcome to my quiz!")

answer = input("Are you ready to play the quiz? (yes/no) :")
name = input(f"nWhat's your name? ")
points = 0
total_questions = 10

while total_questions <= 10:
    if answer.lower() == "yes":
        question = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        for i in range(len(question)):
            answers = input(f"Question " + str(question[i]) + ": " + random.choice(list(qdic.values())))
            givenAnswer = answers
            if givenAnswer.lower() in adic.values():
                points += 1
                print("Correct!")

            else:
                print("Wrong answer =(")
            i += 1


    total_questions += 1

EDIT! Here are the dicts:

import json

questions = {"1": "What year did man land on the moon?",
             "2": "Which Indonesian island shares a name with a programming language? ",
             "3": "What is the formula for water? ",
             "4": "The UV in UV rays stand for what? ",
             "5": "Which currency was used in italy prior to the Euro? ",
             "6": "Where was the croissant invented? ",
             "7": "Which movie won the first Oscar for best picture? ",
             "8": "What musical piece was Mozart's last? ",
             "9": "What country was Stalin born? ",
             "10": "Who separated the red sea in the old testament? "}


with open("question.txt", "w") as question_file:
    question_file.write(json.dumps(questions))

answers = {"1": "1969",
           "2": "java",
           "3": "h20",
           "4": "ultraviolet",
           "5": "lira",
           "6": "austria",
           "7": "wings",
           "8": "requiem",
           "9": "georgia",
           "10": "moses"
           }

with open("answers.txt", "w") as answers_file:
    answers_file.write(json.dumps(answers))


Asked By: Nozdub

||

Answers:

You can use dict_name.pop('key') to remove keys from a dictionary. Here is an article on the pop() function.

Answered By: mpp

You’re really looking for something like this:

# Bind questions to answers
questions = [(qdic.get(str(n)), adic.get(str(n)) for n in range(len(qdic))]
questions.shuffle()

points = 0

for question, answer in questions[:10]:
    response = input(f"Question: {question}")
    if answer.lower() == response.lower():
        points += 1
        print("Correct!")
    else:
        print("Incorrect!")

You don’t show the form of your input data (generally a good idea when asking a question), so it’s hard to entirely predict – but assuming you have a list of questions (qdic) and answers (adic), you can pair them and create a much simpler loop. (Note, your ‘while’ loop is misnomered – it’s not looking for less than ten questions, it’s asking to play the game ten times.)

With a list of question/answer pairs (which can be the dict.items() of an actual dictionary), you just shuffle it and take the first ten. Then you iterate through those until you’re done. If you want to number them, you can use enumerate().

That said, having separate question and answer files is complicating what you need to do. If you have a dictionary, and can structure it like this:

dx = {
  "What is the capital of Rhode Island?": "Providence",
  "How many letters are used to represent numbers over ten in hexadecimal?": "6"
}

Then it makes handling the loop real simple, and you don’t have to match up question and answer ahead of time:

 qas = dx.items()
 qas.shuffle()
 for idx, qa in enumerate(qas[:10]):
     question, answer = qa
     response = input(f"Question {idx}: {question}")
     ... etc.
Answered By: Nathaniel Ford

In this case I would probably use the function random.sample, which given a list (or tuple, etc.), returns a random subset as specified.
For example-

in:  random.sample(range(100), 10)
Out: [99, 28, 69, 29, 49, 34, 4, 66, 23, 40]

So in your case I would choose the 10 questions in the beginning

random.sample(questions, 10)

Then look at the answer depending on the question.

Another option would run it on a list of tuples which are the questions and the answers
[(question1, answer1), (question2, answer2), ...]

Answered By: Guy

Given your question and answer files, you should try this.

I shuffle the question numbers, iterate over them, picking out the questions and answers:

import random
import ast

with open("question.txt", "r") as questions:
    qdic = ast.literal_eval(questions.read())

with open("answers.txt", "r") as answers:
    adic = ast.literal_eval(answers.read())


print("Welcome to my quiz!")

answer = input("Are you ready to play the quiz? (yes/no) :")
if answer.lower() == "yes":
    name = input(f"nWhat's your name? ")
    points = 0

    question_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    random.shuffle(question_numbers)

    for i,q in enumerate(question_numbers):
        question = qdic[str(q)]
        response = input(f"Question {i+1}: {question}").lower()
        answer = adic[str(q)].lower()
        if response == answer:
            points += 1
            print("Correct!")
        else:
            print("Wrong answer =(")
    print(f'Your total is {points} points.')
Answered By: quamrana
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.