2013-03-29

Sum of Digits

While playing around and taking online classes in Python, I came across an exercise that I hadn't encountered before (in any language). The goal of the exercise was to write a function that took in an integer as an argument and returned the sum of the digits of the integer.

Because this exercise was nestled in a section of Codecademy that showcased looping strategies, for loops in particular, I starting trying to figure out a way to write a Python for loop to solve this problem. That maent I needed to figure out how to iterate over the digits of the int I received and add them up.

I had lots of wrong ideas. (Well, not "wrong," per se, but definitely "bad.") My first thought was to convert the int to a string, then iterate over the length of the string, taking each character and converting that back to an int to be added to a total (and then returned later). I didn't like this approach because it seemed clunky and inefficient. I have always felt that using strings to solve any arithmetic problem is probably among the worst ways to do it. It certainly didn't seem like the best approach here.

After a few moments of thought, I realized I could get the value of the last (rightmost) digit of any integer by taking the modulo (remainder) x % 10. Attempting to extrapolate this, I got caught up in my excitement and tried to add the values of x % 10^1, x % 10^2, ... x % 10^n, because this would translate somewhat easily to a for loop. This was sort of close to a good answer, and ultimately led me to a good answer.

I finally solved the problem by iterating through my integer x, adding x % 10 to my total and then dividing x by 10 with each iteration. This method gives each of x's original digits a turn in the ones' place, to be hit with % 10. I used a while loop instead of a for loop, and iterated through the integer dividing by 10 until my integer was 0 (rounded down). It worked like a charm ...

... until I tried a negative number! Python doesn't currently have native support for toward / away from infinity / negative infinity. When using modulo (%), Python always rounds down toward negative infinity. This meant that for any negative, single-digit number x % 10, Python would give me -1 as a result. So, my while loop would never equal 0 and would never exit!

My first thought was to write a needlessly complex snippet to catch negative numbers and use math.ceil() to ensure Python would round up in these cases. But that is more complex than it needs to be, since the remainder of any integer x / 10 will be the same (in real life) whether x is positive or negative. I fixed this by simply setting x = abs(x) (taking the absolute value of my integer) at the beginning of the function. Perfect!

Here is the code, in its beautiful simplicity (my first Python post!):