1

I have a list called all_questions:

all_questions={
{
    'question': "Mac and Pc share which of the following things:",
    'answer1': "They are both expensive",
    'answer2': "They are both Touch Screen",
    'answer3': "Intel is now inside both computers",
    'answer4': "They both have good security",
    'correct_answer': 3,
  },
  {
    'question': "Who was the other person that co-founded Microsoft:",
    'answer1': "Bill Gates",
    'answer2': "Nathan Myhrvold",
    'answer3': "Paul Allen",
    'answer4': "Richard Rashid",
    'correct_answer': 3,
  },
  {
    'question': "When did Windows 10 come out:",
    'answer1': "July 29,2015",
    'answer2': "July 30,2015",
    'answer3': "July 28,2015",
    'answer4': "It was not released in July",
    'correct_answer': 1,
  }
    }

The list has questions and answer. I am trying to make a hint button that removes random buttons with taking out the right answer. The code for the hint button is:

def hint_btn():
    choices=[choice1,choice2,choice3,choice4]
    q = all_questions[current_question]
    h = [('correct_answer', 1), ('correct_answer', 2), ('correct_answer', 3), ('correct_answer', 4)]
    f = all_questions.popitem()
    h = choices.pop(choices.index(f))    
    false_answer = random.choice(choices)
    false_answer2 = random.choice(choices)

    if (random.random() > 0.5):
        hint1 = choices[q['correct_answer']]
        hint1.pack()
        hint_btn()
        hint2 = choices[false_answer]
        hint2.pack_forget()
        hint3 = choices[false_answer2]
        hint3.pack_forget()
        choices.append(h)

But, I get an error saying:

TypeError: unhashable type: 'dict' for 'correct_answer': 1
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • if u want my full code i will send u the link –  Jan 13 '16 at 19:01
  • "but had error with it so idk what do now". First things first, edit your question and add the error message. – Dimitris Fasarakis Hilliard Jan 13 '16 at 19:04
  • In which line getting error. Can u send the link for your full code ? – Rahul K P Jan 13 '16 at 19:15
  • yes ill give me a min –  Jan 13 '16 at 19:17
  • http://pastebin.com/MgU2iR7E –  Jan 13 '16 at 19:17
  • actually that message points to a syntax error. You are using all_questions as an array and as such you must use [ ] signs instead of { }. i.e: `all_questions = [{'question': 'When did...'},{...}]` – user1040495 Jan 13 '16 at 19:38
  • for arrays it is just pop(), but for h it wont work well, because they are completely different data types (radiobutton vs dict). Still i have one last suggestion: maybe you are limiting so much when using fixed named variables answer1, answer2 and such. it could be a lot more flexible to introduce an array within your question definition called _answers_ with a list of answers. See example http://pastebin.com/8hfALikx and work from that. Just remember that arrays in Python start from zero. – user1040495 Jan 13 '16 at 20:04

1 Answers1

3

The error means you're doing something like this:

dictionary[key]

... where key is an "unhashable type". The key to a dictionary must be "hashable" (essentially, something that can't change -- ie: a string, tuple, number, etc.).

In your case, you're trying to create a dictionary (all_questions) with dictionaries as keys. A simple solution might be to make all_questions a list rather than a dictionary (notice the use of square brackets rather than curly brackets):

all_questions = [
    {
        'question': "Mac and Pc share which of the following things:",
        'answer1': "They are both expensive",
        'answer2': "They are both Touch Screen",
        ...
    },
    {
        ...
    },
    ...
]

For more information on what "hashable type" means, see this question: Hashable, immutable


You seem to be struggling with this problem, I've seen two or three questions all dealing with the same data structure. I'd like to suggest that you rethink your data structure. If you're having difficulty trying to do something with some data, sometimes the solution is to change the data so that it's easier to manipulate.

You want to have a question, a correct answer, and some incorrect answers, so that you can present them on the screen. You also want to be able to randomly remove incorrect answers at some point in time. Correct? To me that means your correct and incorrect answers should be stored as separate entities.

Alternate solution one

You might want to consider putting your incorrect answers in a list, and keeping the correct answer separately. For example:

all_questions = [
    {
        "question": "Mac and Pc share which of the following things:",
        "correct answer": "Intel is now inside both computers",
        "incorrect answers": [
            "They are both expensive",
            "They are both Touch Screen",
            "They both have good security",
        ],
    },
    ...
]

To create a list of all answers for the first question you can do this:

q = all_questions[0]
answers = q["incorrect answers"]
answers.append(q["correct answer"])
random.shuffle(answers)

With the above, answers is now a list of all possible answers, but in random order.

To remove two random incorrect answers so that you have one correct and two incorrect answers, again in random order, you would do it like this:

answers = random.sample(q["incorrect answers"], 2)
answers.append(q["correct answer"])
random.shuffle(answers)

In either case, when the user picks an answer you can easily compare it to the correct answer:

if user_answer == q["correct answer"]:
    print "correct!"
else
    print "incorrect"

Alternate solution 2

Note that the above isn't necessarily the best way to do it. There are many alternatives. For example, the questions could be the dictionary keys, and the value could be a list of answers with the correct one always first. For example:

all_questions = {
    "Mac and Pc share which of the following things": [
        "They both have intel inside",
        "They are both expensive",
        "They are both Touch Screen",
        "They both have good security"
    ]
}

With that, to remove two random items you start by removing the correct answer and saving it to a variable. You then remove two items at random and combine them with the correct answer.

Data structures are important

The point is, data structures are important. Think about how you need to access the data, and structure the data so that is easy. In your case you need to be able to easily get the correct answer, and you need to be able to easily remove random items from the list of incorrect answers. Define your structure to make that easy.

Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685