Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Dates and Times in Python (2014) Let's Build a Timed Quiz App Taking The Quiz

Don't understand random.choice(question_types)(num1, num2)

I understand how the class works, and what the methods (init) does within each respective (Add, Multiply) class, but I don't necessarily understand how quiz.py, specifically question = random.choice(question_types)(num1, num2) works.

What does it look like behind the scenes? How does it know to do 1 x 1 vs 1 + 1? This is stumping me in completing the challenge :( -- I can't conceptualize what it's doing

Matthew Rigdon
Matthew Rigdon
8,223 Points

Can you post the question and link it please?

Oh shoot. Sorry. Ok, so, you have a class:

class Question:
    answer = None
    text = None


class Add(Question):
    def __init__(self, num1, num2):
        self.text = '{} + {}'.format(num1, num2)
        self.answer = num1 + num2


class Multiply(Question):
    def __init__(self, num1, num2):
        self.text = '{} x {}'.format(num1, num2)
        self.answer = num1 * num2

Which is then called from within a Method, in another Class Quiz(Question)

 def __init__(self):
        question_types = (Add, Multiply)
        # generate 10 random questions with numbers from 1 to 10
        for _ in range(10):
            num1 = random.randint(1, 10)
            num2 = random.randint(1, 10)
            question = random.choice(question_types)(num1, num2)
            # add these questions into self.questions
            self.questions.append(question)

What specifically does question = random.choice(question_types)(num1, num2) do, and how does that look like in the background? The teacher kind of just grazed over it and carried on with the rest of the code.

Matthew Rigdon
Matthew Rigdon
8,223 Points

To answer the "what does question = random.choice(question_types)(num1, num2) do." It is making a random choice between your tuple "question_types" which you said can either be the Add or Subtract class. In the Python simulator, it always makes the same choice, but if you ran it in the Workspace or somewhere else, it would randomly make a choice between Add or Multiply. If you wanted to know which one it was using, you could have a "print" line in both Add and Multiply that could say something like, "I am using the Add/Multiply function" so you can see.

1 Answer

Matthew Rigdon
Matthew Rigdon
8,223 Points

I find it is best to visualize code. Try this website and post in the code I wrote:

import random

class Question:
    answer = None
    text = None


class Add(Question):
    def __init__(self, num1, num2):
        self.text = '{} + {}'.format(num1, num2)
        self.answer = num1 + num2


class Multiply(Question):
    def __init__(self, num1, num2):
        self.text = '{} x {}'.format(num1, num2)
        self.answer = num1 * num2

class Quiz(Question):        
    def __init__(self):
        question_types = (Add, Multiply)
        # generate 10 random questions with numbers from 1 to 10
        for _ in range(10):
            num1 = random.randint(1, 10)
            num2 = random.randint(1, 10)
            question = random.choice(question_types)(num1, num2)
            # add these questions into self.questions
            self.questions.append(question)

Quiz()

This will let you see what is happening with the question = portion. Let me know if you still have questions.

I ran the code, but it didn't produce anything in the terminal. I think i may know what's going on. Is this known as Lamda? Basically, since everything in Python is an object, this is like saying, questions.Add(num1, num2). If we provided random.choice(Add()) it would error out, since it's expecting parameters. But, if you strip away the (), eg., print(Add), you'll get its footprint in memory. If you add () afterwards, you then explicitly call the class with num1 and num2... Right?

I think i'm getting it.

Matthew Rigdon
Matthew Rigdon
8,223 Points

Run this on Python Tutor instead: Pythontutor.com . I don't believe your code works at the minute since your last line:

self.questions.append(question)

Refers to self.questions, but question is not setup anywhere.

You cannot run random.choice(Add(num1, num2)). The random.choice is supposed to pick between two options, but here you only give it Add. The num1 and num2 are two random numbers selected in the lines previous to this step. If you call Add() it would simply run your function, but it wouldn't actually work. If you look at the Add() function, it requires you to have num1 and num2 assigned, but that doesn't happen until you run Quiz(). Also, more on the random.choice portion in case you missed my post above:

To answer the "what does question = random.choice(question_types)(num1, num2) do." It is making a random choice between your tuple "question_types" which you said can either be the Add or Subtract class. In the Python simulator, it always makes the same choice, but if you ran it in the Workspace or somewhere else, it would randomly make a choice between Add or Multiply. If you wanted to know which one it was using, you could have a "print" line in both Add and Multiply that could say something like, "I am using the Add/Multiply function" so you can see.

OH! That just blew my mind. Thank you for this web site. Definitely bookmarking this. As soon as I saw it, and your explanation (basically it's randomly selecting Add(num1,num2) or Multiply(num1,num2)) it clicked.

Awesome. Totally get it :)