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

Yet isn't clear one thing again in quiz.py second part! below, I post my code, help me please again

This is the questions.py

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

** Instead here thre is a file quiz.py**

import datetime
import random

from questions import Add, Multiply


class Quiz:
    questions = []
    answers = []

    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)


    def take_quiz(self):
        # log the start time
        self.start_time = datetime.datetime.now()

        # ask all of the questions
        for question in self.questions:
            # log if they got the question right
            self.answers.append(self.ask(question))
        else:
            # log the end time
            self.end_time = datetime.datetime.now()

        # show a summary
        return self.summary()


    def ask(self, question):
        correct = False

        # log the start time
        question_start = datetime.datetime.now()

        # capture the answer
        answer = input(question.text + ' = ')

        # check the answer
        if answer == str(question.answer):
            correct = True

        # log the end time
        question_end = datetime.datetime.now()

        # if the answer's right, send back True
        # otherwise, send back False
        # send back the elapsed time, too
        return correct, question_end - question_start

    def total_correct(self):
        # return the total # of correct answers
        total = 0

        for answer in self.answers:
            if answer[0]:
                total += 1
        return total

    def summary(self):
        # print how many you got right and the total # of questions. 5/10
        print("You got {} out of {} right.".format(
                self.total_correct(), len(self.questions)
        ))
        # print the total time for the quiz: 30 seconds!
        print("It took you {} seconds total.".format(
                (self.end_time-self.start_time).seconds
        ))


Quiz().take_quiz()

Hence, is more correct if I say that self refers to the attributes of an instance of the class itself, but in the code above if I want get the attributes start_time and end_time go back me message that says: AttributeError: 'Quiz' object has no attribute 'start_time'.

The same thing happen though I refer them after that (take_quiz()) it has been run . Still ,because ** summary() sees them**?

Chris Freeman
Chris Freeman
Treehouse Moderator 68,468 Points

Not sure what the question is. Your code works for me as is. Under what conditions are you seeing the AttributeError?

2 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,468 Points

All of the methods, such as take_quiz(), ask(), summary(), etc. are all passed a reference to the current instance through the self parameter.

Printing the "directory" of self would show all of the attributes of the current instance. By inserting the line:

print(dir(self))

just before the return statement of take_quiz, it prints out the following:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'answers', 'ask', 'end_time', 'questions', 'start_time', 'summary', 'take_quiz', 'total_correct']

This shows all of the objects (methods and attributes) of the Quiz() instance. This can be thought of as the namespace of the instance. Here, you can see the 'end_time and start_time attributes added by the take_quiz() method. All methods have access to this namespace through the self reference. This is why the self.summary() reference works within the take_quiz method and why the self.start_time reference works within the summary method. It all goes through the namespace

To see a list of the attributes of self, add the print(self.__dict__) this will show the attributes and their values:

{'end_time': datetime.datetime(2016, 4, 15, 3, 17, 36, 992210), 'start_time': datetime.datetime(2016, 4, 15, 3, 17, 33, 315770)}

Don't worry about the __var__ methods. Those are inherited from the base class object.

This is getting to more advanced aspects of Python. It worth coming back to this discussion after you've progressed further in the language. It all will make sense soon enough.

very good

Yet isn't clear one thing again in quiz.py second part! below, I post my code, help me please again

Of course , it works fine why is the code of Kenneth Love teacher but I'm not sure about how the variables work (start time) and (end _time). I don't understand hpw them work. why summary() method can print them, how can see them also if them stay within a function and moreover they haven't been give to summary() as argument