Sign in to follow this  
Gixugif

Python, problem returning correct value

Recommended Posts

def countErrors(secret, lettersGuessed, errors):

    if lettersGuessed == "":
         errors = errors + 0  
    else:
         subproblem = lettersGuessed[len(lettersGuessed)-1]
         others = lettersGuessed[0:len(lettersGuessed)-1]
         if subproblem in secret:
             errors = errors + 0
         else:
             errors = errors + 1
             print errors, secret, lettersGuessed, others, subproblem
         countErrors(secret, others, errors)
    return errors        
     
        
        

secret = "guinness"
lettersGuessed = "pnitwzg"
errors = 0
x = countErrors(secret, lettersGuessed, errors)
print x
Here's what it outputs: 0 guinness pnitwzg pnitwz g 1 guinness pnitwz pnitw z 2 guinness pnitw pnit w 3 guinness pnit pni t 3 guinness pni pn i 3 guinness pn p n 4 guinness p p 0 I'm pretty new at this, but this just doesn't seem to make any sense. It does exactly what I want it to, except instead of returning 4, it returns 0. The indentations are correct, I assure you, I just can seem to format it correctly here, so sorry about that. [Edited by - Gixugif on November 12, 2008 3:10:56 AM]

Share this post


Link to post
Share on other sites
You don't assign the result of the recursive function calls anywhere, so the correct value of error only exists as you go deeper into recursion.

BTW, with Python it is mandatory to use code tags, and what's with all the adding 0?

Share this post


Link to post
Share on other sites
Surround your code with [code] or [source] tags to preserve the formatting. :)

Visitor already pointed out your problem, but I'd like to make a few more comments: instead of doing a = b[0:len(b)-1], simply do a = b[0:-1]. Negative indexes simply count from the end of a list. Likewise, c[len(c)-1] does the same as c[-1].

Also, errors = errors + 1 is the same as errors += 1 and errors = errors + 0 can simply be left out.


However, there is no need for recursion here. You want to see how many characters that were entered are not in the secret string, right? How about the following:
errors = 0
for letter in lettersGuessed:
if letter not in secret:
errors += 1
print errors

Share this post


Link to post
Share on other sites
Yeah, I changed all that stuff too.

I know there's no need for recursion, I did it without it first, but it's for a class and we were on recursive functions at the time. I would have just asked my professor but I have a desktop and so couldn't take it to office hours, and apparently I couldn't think of using e-mail until right this second.

Thanks for the pointers and stuff.

Share this post


Link to post
Share on other sites
Pass 1:
- 'errors = errors + 0' obviously doesn't do anything. Note that if blocks do not necessarily require an else; when we want to do something only in what we think of as the "else" case, then we can negate the condition, and do something only in the "if" case.
- Fix the bug by returning the result of the recursive call.
- Fix the subscripts using the techniques others have mentioned.
- Fix error increment to use +=.


def countErrors(secret, lettersGuessed, errors):
if lettersGuessed == "":
return errors
else:
subproblem = lettersGuessed[-1]
others = lettersGuessed[:-1]
if subproblem not in secret:
errors += 1
return countErrors(secret, others, errors)


Pass 2:
- Since 'subproblem' and 'others' are used only once, and those names don't give us much additional information, we can scrap those variables and just use the corresponding expressions in place.
- Instead of passing an error count forward, we can add in the possible error in the current 'subproblem' *after* finding out how many errors are in the rest of the word (recursively). That simplifies the interface. (After all, why would you expect to have to pass 'errors' to something that is supposed to count the errors for you? :) )


def countErrors(secret, lettersGuessed):
if lettersGuessed == "":
return 0
else:
return countErrors(secret, lettersGuessed[:-1]) + (0 if lettersGuessed[-1] in secret else 1)


Note that the 'x if blah else y' construct requires Python 2.5. It could also be used to fold in the initial check for an empty string :)

Pass 3: Skip all of that, and just do it in a natural Pythonic way:


# Yes, it's really this simple
def countErrors(secret, lettersGuessed):
return len(x for x in lettersGuessed if x not in secret)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this