简体   繁体   中英

Python function returning correct result but interpreter returning strange error

Python newbie here, so bear with me...

I'm attempting to utilize the often poorly written Codeacademy Python tutorial, wherein the exercise challenge is to:

Write a function called digit_sum that takes a positive integer n as input and returns the sum of all that number's digits.

For example: digit_sum(1234) should return 10 which is 1 + 2 + 3 + 4.

(Assume that the number you are given will always be positive.)

So, my attempt to solve for this challenge was writing the following code:

userInput = raw_input("Please enter your number string here: ")
n = userInput
lst = list(n)
userNumbers = []

def digit_sum(n):
    for i in lst:
        b = int(i)
        userNumbers.append(b)
    numsum = sum(userNumbers)
    return numsum

print "This is your total: %s" % digit_sum(n)

In the console for this exercise, everything seems to work as expected:

Please enter your number string here: 123 This is your total: 6 None

However, the interpreter returns this error (despite the console seeming to work properly):

Oops, try again. Your function fails on digit_sum(434). It returns 18 when it should return 11.

Why in the heck is this error being returned? Can anyone elucidate what's happening here?

Unfortunately, there's no one to ask at Codeacademy, you have to just post a question which only other students read, so not getting any insights there.

You do not understand variable scoping or types. That's the "problem". (It's not really a problem, since you're learning.)

What's expected

The question wants you to provide a function digit_sum that accepts a number, and returns a number. In this case it would accept 434 and return 18 . That is, digit_sum(434) = 18 .

What you're doing

Reading from the keyboard ( raw_input ) and printing ( print ) are not related to the question.

If we remove the non-function parts of your solution, we have:

def digit_sum(n):
    for i in lst:
        b = int(i)
        userNumbers.append(b)
    numsum = sum(userNumbers)
    return numsum

When we try to submit this, some problems become apparent:

  1. lst is not defined.
  2. userNumbers is not defined.
  3. You expect a string ( str ) and not a number ( int )

Addressing the issues

  1. We have to move the definition of userNumbers and lst into the function digit_sum . If they are set at the "top" level, they are not reset each time you call the function, and that's why Codecademy isn't getting the correct answer.

    The code they use to check yours is something like:

     if digit_sum(434) != 18: print "It should have been 18, we got %s" % digit_sum(434) 

    They have many such calls, and each subsequent call does not change the value of lst or userNumbers .

  2. This masks another error: your digit_sum function accepts a string. That is, calling it (after incorporating fixes from #1 above) as digit_sum(434) which is what Codecademy does, will result in an error, since you actually expect it be called as digit_sum("434") .

A possible solution

The following function is based on yours, but is altered with the advice above:

def digit_sum(n):
    lst = list(str(n))
    userNumbers = []
    for i in lst:
        b = int(i)
        userNumbers.append(b)
    numsum = sum(userNumbers)
    return numsum

You'll notice that the other stuff is missing: we can add it back in, but it's unnecessary. You might want to use the following to test while developing:

def digit_sum(n):
    lst = list(str(n))
    userNumbers = []
    for i in lst:
        b = int(i)
        userNumbers.append(b)
    numsum = sum(userNumbers)
    return numsum

print "digit_sum(%s) = %s" % (434, digit_sum(434))
print "digit_sum(%s) = %s" % (123, digit_sum(123))
print "digit_sum(%s) = %s" % (555, digit_sum(555))
print "digit_sum(%s) = %s" % (18, digit_sum(18))
print "digit_sum(%s) = %s" % (1001, digit_sum(1001))

When you run it, this yields:

digit_sum(434) = 11
digit_sum(123) = 6
digit_sum(555) = 15
digit_sum(18) = 9
digit_sum(1001) = 2

The good news is that these results are all correct, so you're off to a good start! One thing you'll learn quickly is that small, tedious details sometimes matter a lot in programming.

A small note

It's not always easy or obvious. So-called experts started at zero, and had to learn and make mistakes as well. Don't be discouraged! There are a lot of disparate concepts that you have to understand to know 100% what's happening. Nobody gets it all at once.

I respect that you're trying to learn and grow tremendously, as well as the fact that you're willing to ask questions. It's never easy, but that little burn that you might be getting in your brain when you try to understand all of this is what learning feels like. Embrace it! Ask questions!

Good luck with your learning!

Other resources

  1. If I may, I recommend Zed Shaw's Learn Python the Hard Way as a quality, free supplement to your learning journey. It's excellent!
  2. I've also found that Udacity's Free Online Courses are a magnificent resource for learning a lot of different things. Specifically, their "Intro"-level CS courses are in Python, and are well worth the time.
  3. Peter Norvig's essay " Teach Yourself Programming in Ten Years " is considered a classic. It's going to be a long journey, enjoy it!

Again, good luck.

You have

n = userinput

while you need

n = userInput

Then it works.

As a followup to Ezra's excellent answer, I propose an implementation that uses the divmod builtin

def digit_sum(n):
    s = 0
    while 1:
        n, d = divmod(n, 10)
        s += d
        if n == 0 : return s

Came up with the solution here, probably not the most elegant but this seems to work (thanks Ezra, gboffi, and user2357112 for pointing my initial oversights in the original code I posted, dumb mistakes..):

n = 1234
def digit_sum(n):
    userNumbers = str(n)
    numList = list(userNumbers)
    dinksList = []
    for i in numList:
        new = int(i)
        dinksList.append(new)
    numSum = sum(dinksList)
    return numSum

print digit_sum(n)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM