[Tutor] Converting integers into digit sum (Python 3.3.0)

Wolfgang Maier wolfgang.maier at biologie.uni-freiburg.de
Tue Dec 10 13:39:34 CET 2013


Steven D'Aprano <steve <at> pearwood.info> writes:

> 
> On Tue, Dec 10, 2013 at 10:39:34AM +0100, Rafael Knuth wrote:
> 
> > def DigSum (integer):
> >     s = 0
> >     while integer != 0:
> >         integer, remainder = divmod(integer, 10)
> >         s += remainder
> >     print(s)
> 
> A thought comes to mind... an very important lesson is to learn the 
> difference between return and print, and to prefer return.
> 
> You have written a function that calculates the digit sum. But it is not 
> *reusable* in other functions, since it cannot do anything but *print* 
> the digit sum. What if you want to store the result in a variable, and 
> print it later? Or print it twice? Or put it in a list? Or add one to 
> it? You're screwed, the function is no use to you at all.
> 
> This is because the function does *two things*, when it should do one. 
> First it calculates the digit sum, and then it prints it.
> 
> My advice is, (nearly) always use return, not print, inside functions. 
> Once you return a result, it is easy to print it if you so desire:
> 
> print(digit_sum(23))
> 
> Or do anything else:
> 
> x = digit_sum(42952)
> y = digit_sum(1032897) + digit_sum(8234)
> z = [1, 2, digit_sum(99742), 3]
> 
> but you can't do anything *but* print if your function automatically 
> calls print.
> 

A very valuable lesson for sure.
Along the same lines: if you look very closely, you will see that
digit_sum() still performs two tasks. It breaks down an integer into digits
*and* it calculates the sum of these digits.
A more atomic function would return just the digits, but leave it up to the
caller what to do with them. E.g., you might decide to multiply them instead
of adding them.
Asokan split the functionality exactly like that in one of the first replies
here, but using the int -> str -> int method.
>From his post:

def num2Digits(n):
      return [int(ch) for ch in str(n)]
def digitSum(n):
     return sum(num2Digits(n))

For the number approach, using a generator function, this could look like:

def digits(n):
    """Generator that breaks down an integer into digits from right to left."""
    while n>0:
        yield n % 10
        n //= 10

with it you can do things like:

sum(digits(819))
list(digits(819))
sorted(digits(819))

from functools import reduce
reduce(lambda x, y: x*y, digits(99))

Best,
Wolfgang 



More information about the Tutor mailing list