Digit_sum using (recursive?) function


#1



https://www.codecademy.com/courses/python-intermediate-en-rCQKw/0/4?curriculum_id=4f89dab3d788890003000096


ERROR: Oops, try again. Your function fails on digitsum(434). It returns 22 when it should return 11.


EDIT : Writing this function in the terminal on my mac returns the correct sum, so I'm thinking it's a code academy bug

I decided to take on the extra challenge of not converting the number to a string and then back to an int. Took me a couple days, but I figured out how to set it up.

However, I am running into a problem.

So when I run my recursive (possibly using wrong term here) function, it does print out the correct sum. However, CodeAcademy sees it as a different number for some reason. In the case of 434, it sees it as 22, not 11, even though my function returns 11.

Can someone give me some insight on what I might be doing wrong? Or is this an error on codeacademy's part?


temp_number = []

def digit_sum(n):
    
    remove_last_digit = n//10 
    temp_int = remove_last_digit
    temp_number.append(n%10)
    
    #print temp_int, temp_int % 10, temp_number
    if temp_int != 0:
        return digit_sum(temp_int)
    
    print sum(temp_number)
    return sum(temp_number)
    
digit_sum(434)


#2

Hi @rejor11,

To fully test your digit_sum function, display the value that it returns by calling it, rather than only displaying it from inside the function. In fact, let's comment this line out ...

   print sum(temp_number)

... and change this ...

    digit_sum(434)

... to this ...

    print digit_sum(434)

The output is ...

11

At first it may appear that the function works correctly. However, to continue the testing, call the function several times in the same program, as Codecademy does after you submit your code. Let's try this ...

print digit_sum(434)
print digit_sum(24)
print digit_sum(1)
print digit_sum(1)

Output ...

11
17
18
19

Since only the first result is correct, there must be a problem. What do you think it might be?

You can successfully write a recursive digit_sum function in just a few lines of code. As with any recursion, begin by clearly describing ...

  • the base case(s)
  • the recursive case(s)

Once you have done that, think about what condition you can use in an if block header to distinguish between the base and recursive cases. That will help you write a concise recursive digit_sum function.


#3

Hey mate,

So I've tried a few things, but the first thing that came to mind was that I needed to clear the list somehow. Unfortunately I couldn't really figure out how to do so without throwing a "referenced before assigned" error.

So I read more on recursive functions and, frankly, it is kind of confusing (still)

I did come upon an example that showed something similar to how a recursive function for this type of problem should work. After thinking about it, I came up with this code:

def digit_sum(n):
    
    if n == 0: #or if n < 10? which is better?
        return n
    
    else:    
        numbers_before_last = n//10
        last = n%10
        return digit_sum(numbers_before_last) + last
   
    
print digit_sum(432)

I just can't decide which is better: "if n == 0" or "if n < 10"


#4

That is a nice recursive solution. You could simplify the else block by replacing the three statements that it contains with this single line ...

        return digit_sum(n // 10) + n % 10

That depends, in part, upon which one you feel is clearer from a conceptual perspective. In my opinion, this is pretty clear ...

  • the base case: n contains only one digit -> the sum of the digits is n
  • the recursive case: n contains more than one digit -> the sum of the digits is (the sum of the digits in n without the final digit) + (the final digit).

Accordingly, I would opt for ...

    if n < 10:

However, if you come up with a concise statement in support of this ...

    if n == 0:

... I can become convinced. :smile:


#5

Ok, I understand that, and why would you choose n< 10 over n == 0.

One question though. I am still not completely clear as to why this function works.

Keep in mind I've only been programming for about a year in Javascript, so perhaps my education in logic isn't that great. (I've been teachign myself so far, never went to college for Comp Sci)

The way I think of it:

On the first pass, n = 432. It is more than 10, so it goes tot he ELSE statement.

There, it calls on itself again, this time as digit_sum(43) + 2.

Here 's my first problem. Does the function now look like digit_sum(43): <code in here> + 2?

On this second pass, since 43 is still over 10, it goes thorugh the ELSE statement again. Now it calls on itself again, this time as digit_sum(4) + 2 + 3 or perhaps as digit_sum(4) + 5

Since it IS less than ten, it returns n, which is 4. The whole sum is 4 + 5, which equals 9. Therefore, it returns 9.

Is my brain-logic correct? Or is there something else going on?


#6

Try Checking this Out.

def digit_sum(n):
    n = str(n)
    x = []
    for i in n:
       i = int(i)
       x.append(i)
      
    return sum(x)
       
    
print digit_sum(345)

#7

@rejor11,

Yes, with the recursion, more than one copy of the function can in the process of execution at the same time, each with its own copy of the variable, n. Each of those copies of n has its own value.

When the function calls itself, it waits for that call to return a value, then uses that value to complete its own execution, as you have described above.


#8

@appylpye

Awesome. I've been studying Javascript by myself for the past year through freecodecamp and other sources, and this is the first time I feel like I've really understood how recursion works.

Of course my logic still is kinda meh, but I still learned quite a bit. Thanks mate.


#9