Kevin Leimkuhler
Kevin Leimkuhler

Reputation: 51

Can't seem to get my 'while True' loop to keep looping

I'm making a little guess a number game and I have a 'while True' loop that I want to keep looping until the user guesses the correct number. Right now I have the number displayed for ease of testing. Whether I guess the correct number or not though, I get an error " 'Nonetype' object has no attribute 'Guess'." Im confused why the 'while True' has no error the first time it loops but an error is brought up after that.

Tracker.py

from Number import *

class Runner(object):
def __init__(self, start):
    self.start = start
    print Integer.__doc__
    print Integer.code

def play(self):
    next_guess = self.start

    while True:
        next_guess = next_guess.Guess()

        if next_guess == Integer.code:
            print "Good!"
            exit(0)

        else:
            print "Try again!"

Integer = Random_Integer()

Game = Runner(Integer)

Game.play()

Number.py

from random import randint

class Random_Integer(object):

"""Welcome to the guessing game! You have unlimited attempts
to guess the 3 random numbers, thats pretty much it."""

def __init__(self):
    self.code = "%d%d%d" % (randint(1,9), randint(1,9), randint(1,9))
    self.prompt = '> '

def Guess(self):
    guess_code = raw_input(self.prompt)

Thanks!

Upvotes: 2

Views: 119

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122092

Your .Guess() method doesn't return anything:

def Guess(self):
    guess_code = raw_input(self.prompt)

You need to add a return statement there:

def Guess(self):
    guess_code = raw_input(self.prompt)
    return guess_code

When a function doesn't have an explicit return statement, it's return value is always None. Thus, the line:

next_guess = next_guess.Guess()

sets next_guess to None.

However, even if .Guess() does return it's raw_input() result, you now have replaced next_guess with a string result, and your next iteration through the loop will now fail because string objects do not have a .Guess() method.

You are also referring to a global Integer value everywhere, after passing it in as an argument to your Runner() instance, storing it as self.start there. Don't rely on globals, you already have self.start:

class Runner(object):
    def __init__(self, start):
        self.start = start
        print start.__doc__
        print start.code

    def play(self):        
        while True:
            next_guess = self.start.Guess()

            if next_guess == self.start.code:
                print "Good!"
                exit(0)

            else:
                print "Try again!"

In the above code we dispense with accessing the Integer global, instead using self.start. The next_guess variable is strictly used to hold the current guess, and we use self.start.Guess() instead.

Upvotes: 8

Related Questions