[Tutor] Need a solution.

David david at abbottdavid.com
Sat Jun 13 18:01:46 CEST 2009


Alan Gauld wrote:
> "David" <david at abbottdavid.com> wrote
>>> class GuessError(Exception): pass
>>> class GuessedNumber:
>>>     def __init__(self,tries=None,limits=None):...
>>>     def generate(self, limits=None):...
>>>     def __cmp__(self, aNumber):
>>>           if self.count >= self.tries: raise GuessError
>> Thanks always for the feedback, i came up with this, not sure if it is 
>> much better but I am learning as I prod along :)
> 
> The big problem from an OO point of view is that you are not making the 
> objects do any work. You are extracting the data from inside them and 
> you are doing all the work in your main function. In OOP we should be 
> trying to make the objects do everything and the main function just does 
> some high level coordination.
> 
> If you make your GuessedNumber class have comparison methods you can 
> avoid much of that. And if you put the counting code inside the 
> comparison that could save a lot of effort in main too. Remember that in 
> theory you shold not know what data is inside the object. You should 
> only interact with objects via their published operations.
> 
>> #!/usr/bin/python
>> from random import randrange
>> from sys import exit
>>
>> class GuessedNumber:
>>     def __init__(self, attempts=None):
>>         self.attempts = attempts
>>         self.number = randrange(1,99)
> 
> Any time you have a class that just has an __init__ it means its not 
> doing anything. And that's a bad sign. Classes are there to *do* things 
> not just store data. We can use a tuple or dictionary to do that.
> 
>> class Counter:
>>     def __init__(self):
>>         self.value = 0
>>     def step(self):
>>         self.value += 1
>>     def current(self):
>>         return self.value
> 
> Whilst this is OK,, because it does something, its a lot of code to wrap 
> an integer. I personally wouldn't bother. But at least it is doing 
> things :-)
> 
>> def play():
>>     c = Counter()
>>     guessit = GuessedNumber(attempts=5)
>>     target_number = guessit.number
>>     attempts = guessit.attempts
> 
> See, here is the problem, you create an object then immediately extract 
> all the data and then just ignore the object. You might as well just 
> assign the values to variables
> 
> 
>>     guess = int(raw_input('Guess-> '))
>>     c.step()
>>     while c.current() < attempts:
> 
> So why not
>         while c.current() < guessit.attempts
> 
> use the object, thats why its there
> 
>>         try:
>>             if guess == target_number:
> 
> Whereas this could have been
>               if guess == guessIt
> 
>>                 print "Well Done"
>>                 play_again()
>>             elif guess < target_number:
> 
> and         elif guess < guessit
> 
>>                 print 'Higher ... '
>>                 guess = int(raw_input('Guess Again-> '))
>>                 c.step()
>>             elif guess > target_number:
>>                 print 'Lower ... '
>>                 guess = int(raw_input('Guess Again-> '))
>>                 c.step()
>>
>>         except ValueError:
>>             print 'You must enter a number'
>>             pass
>>
>>     print 'Too many attempts, the number was', target_number
>>     play_again()
>> def play_again():
>>     answer = raw_input('Do you want to try again? y/n ')
>>     answer = answer.lower()
>>     if answer == 'y':
>>         play()
>>     else:
>>         exit()
> 
> This recursive approach will work most of the time but remember that 
> Python does limit recursion to 1000 levels so if your player was very 
> keen you could run out of levels. A normal loop would be safer.
> 
> HTH,
> 
> Alan G.
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 
> 
Ok, I think I am getting somewhere now :)

#!/usr/bin/python
from random import randrange
from sys import exit

class GuessedNumber:
     def __init__(self, count=0, attempts=None):
         self.attempts = attempts
         self.number = randrange(1,99)
         self.count = count
     def step(self):
         self.count += 1
     def current(self):
         return self.count

def play():
     guessit = GuessedNumber(attempts=5)
     guess = int(raw_input('Guess-> '))
     guessit.step()
     while guessit.current() < guessit.attempts:
         try:
             if guess == guessit.number:
                 print "Well Done"
                 play_again()
             elif guess < guessit.number:
                 print 'Higher ... '
                 guess = int(raw_input('Guess Again-> '))
                 guessit.step()
             elif guess > guessit.number:
                 print 'Lower ... '
                 guess = int(raw_input('Guess Again-> '))
                 guessit.step()

         except ValueError:
             print 'You must enter a number'
             pass

     print 'Too many attempts, the number was', guessit.number
     play_again()
def play_again():
     answer = raw_input('Do you want to try again? y/n ')
     answer = answer.lower()
     if answer == 'y':
         play()
     else:
         exit()

if __name__ == "__main__":
     play()

-- 
Powered by Gentoo GNU/Linux
http://linuxcrazy.com


More information about the Tutor mailing list