0

I have this function in Python that helps me to find the sum of a number's digits:

def sum01(n):
    if n < 9 and n > 0:
        return n
    elif n > 9:
        s = sum01((n%10)+(n//10))
        return s
    else:
        return "ERROR, only natural numbers (N)!"

    print(sum01(22224))

The results this function give are:

3

However, the results I wish to see are:

12

I want to get this answer using a recursive function without the use of while or for loops and no lists, however, I have been failing in doing so.

Thanks!

I couldn't add the solution I have been searching for as an answer so here it is in the question.

`def sum01(n):
   x = 0
   if n < 9 and n > 0:
       return n
   elif n > 9:
       x = (n%10) + x
       s = sum01(n//10)
       return s + x
   else:
       return "ERROR, only natural numbers (N)!"`
Majed Saaeddin
  • 81
  • 2
  • 10
  • 1
    Why do you expect 12? 2+2+2+2+4 -> 12, but then 1+2 -> 3. – jonrsharpe Sep 23 '20 at 09:31
  • I am not expecting 12, I know the function I have written gives me a 3, however, I am failing in writing a function that gives me a 12 instead of a 3 and thus want to make changes into the one that I have already written. @jonrsharpe – Majed Saaeddin Sep 23 '20 at 09:32
  • 1
    In your own words, how do you think the function works? Why, specifically, do you think it gives you 3 instead of 12? Did you try to trace through its logic by hand? If you did, you might find a point where there is a `12` computed. Maybe just... stop there? I notice you tagged the question with `recursion`. Is there a specific reason why you expect to need recursion to solve the problem? Why? How would you solve the problem by hand? Does your solution involve breaking the problem up into smaller ones? – Karl Knechtel Sep 23 '20 at 09:34
  • 1
    The parentheses are wrong on this line: `s = sum01((n%10)+(n//10))`. It should rather be: `s = sum01(n//10) + (n%10)`. Explanation: `n%10` is the value of the units digit. `n//10` is the number "without its unit digits". You want to add the value of the units digit with the sum of the remaining digits. For instance if `n = 8964`, then `n%10 == 4` and `n//10 == 896`. In this case the recursive call should be `sum01(8964) = sum01(896) + 4` and not `sum01(8964) = sum01(4 + 896)`. – Stef Sep 23 '20 at 09:39
  • Karl, I appreciate your answer that involves many questions that will help me learn more about programming logic. To my understanding, the function starts by checking the input I have given it `22224` in this case, it checks if it is between nine and zero and if not, then it is bigger. Thus, it performs the process `s` several times until it reaches a number that is less than nine, in this case `3` and thus print out `3`. This is what I understand. @KarlKnechtel – Majed Saaeddin Sep 23 '20 at 09:44
  • `def sum01(n): return n if n < 10 else sum01(n//10) + (n % 10)`. – ekhumoro Sep 23 '20 at 10:01
  • 1
    "I am searching for a way where there is a recursive function with no for or while loops." If the goal is to learn recursion for the sake of learning recursion, as a way of replacing a loop: the trick is to pass two parameters, so that you keep the "sum so far" separate from the "digits remaining", and avoid "processing" the sum once it exceeds 9. – Karl Knechtel Sep 23 '20 at 21:15
  • 1
    Try putting `how to think recursively` into a search engine; there is a lot of good material out there. – Karl Knechtel Sep 23 '20 at 21:16
  • @KarlKnechtel I have not thought of that, thanks for the advice, I will sure do! – Majed Saaeddin Sep 24 '20 at 18:41

1 Answers1

3

This is not the best or most performant solution, but its rather short if you just need it done quick:

sum_of_digits = 0
for digit in str(22224):
  sum_of_digits += int(digit)

You can also use this "one liner" if you want to impress someone:

from functools import reduce
reduce(lambda a, b: int(a) + int(b), str(22224))

But @ekhumoro solution is even better (see comments).

Anyways, this would kinda mimic the reduce recursivly, no loop involved:

def sum_of_digits(sum, digits):
    sum += int(digits.pop())
    if len(digits) == 0:
        return sum
    return sum_of_digits(sum, digits)

print(sum_of_digits(0, list(str(22224))))

I guess this is a little cleaner:

def sum_of_digits(sum, number):
    if number == "":
        return sum
    digits = str(number)
    return sum_of_digits(sum + int(digits[0]), digits[1:])

print(sum_of_digits(0, 22224))
Markus
  • 309
  • 2
  • 11
  • 5
    don't use `sum` as variable name, it's a built-in function. – buran Sep 23 '20 at 09:32
  • I am searching for a way where there is a recursive function with no `for` or `while` loops. Thanks! – Majed Saaeddin Sep 23 '20 at 09:35
  • 1
    @MajedSaaeddin No loops: `sum(map(int, str(22224)))`. – ekhumoro Sep 23 '20 at 09:44
  • @buran you are totally right. I changed it. Thanks for pointing that out. – Markus Sep 23 '20 at 09:59
  • I have read everyone's comments and came up with the soultion I have been searching for. Everyone's comments have helped me a lot. However, I cannot post the solution here as an answer. So I will just paste into the question itself as pasting it here did not work. – Majed Saaeddin Sep 23 '20 at 10:09