patternpythonMinor
Digital root computation with benchmarking
Viewed 0 times
computationwithdigitalrootbenchmarking
Problem
I've read this question about computing the digital root of some integer, and wondered how it would look like in Python.
As a reminder,
"If you take the digits of any number and add them together, and then add the digits of the resulting number together, and continue doing that until you get a single digit, that single digit is the digital root of the original number."
This is not much about the algorithm performance itself, since it was shown in this answer that instead of summing the digits, you could do a simple division by 9 to get the same result. The question is more about the readability, elegance, and pythonicity (if this word exists) of my code. I checked its correctness with a tool from Thonky.
More, I'd be interested in knowing your opinion on the way I deal with
Finally, is it OK to use the
Any suggestion would be highly appreciated. Thanks.
digitalroot.py
```
# -- encoding: utf-8 --
import time
import random
import sys
def request_user_number():
while True:
try:
nb = int(raw_input('Enter a number\n'))
return nb
except (ValueError, NameError):
print 'This is not a number. Try again.'
def request_user_again():
while True:
try:
ans = str(raw_input('New computation? (y/n)\n')).lower()
if ans[0] == 'n':
again = False
print 'Bye !'
break
elif ans[0] == 'y':
again = True
break
else:
print 'Did not understand. Try again.'
except IndexError:
print 'Say something.'
return again
def digits_generator(nb):
tmp = nb
while tmp != 0:
yield tmp % 10
tmp /= 10
def digital_root(nb):
if nb ', dr, '(time :', end_time-start_tim
As a reminder,
"If you take the digits of any number and add them together, and then add the digits of the resulting number together, and continue doing that until you get a single digit, that single digit is the digital root of the original number."
This is not much about the algorithm performance itself, since it was shown in this answer that instead of summing the digits, you could do a simple division by 9 to get the same result. The question is more about the readability, elegance, and pythonicity (if this word exists) of my code. I checked its correctness with a tool from Thonky.
More, I'd be interested in knowing your opinion on the way I deal with
sys.argv, the user interaction, and the benchmarking.Finally, is it OK to use the
int type for such long numbers? It seems to work fine even with 1000-digit numbers, but intuitively it shouldn't...Any suggestion would be highly appreciated. Thanks.
digitalroot.py
```
# -- encoding: utf-8 --
import time
import random
import sys
def request_user_number():
while True:
try:
nb = int(raw_input('Enter a number\n'))
return nb
except (ValueError, NameError):
print 'This is not a number. Try again.'
def request_user_again():
while True:
try:
ans = str(raw_input('New computation? (y/n)\n')).lower()
if ans[0] == 'n':
again = False
print 'Bye !'
break
elif ans[0] == 'y':
again = True
break
else:
print 'Did not understand. Try again.'
except IndexError:
print 'Say something.'
return again
def digits_generator(nb):
tmp = nb
while tmp != 0:
yield tmp % 10
tmp /= 10
def digital_root(nb):
if nb ', dr, '(time :', end_time-start_tim
Solution
I think your algorithmic part is exceedingly verbose. One of the nicenesses of Python is how it can lead to code that reads almost like English. And for this particular problem, even leaving performance considerations aside, I think iteration is clearer than recursion. So I would rewrite things as:
I'm pretty sure my 6 year old daughter could make sense of that last function with very little help.
def digits_of(number):
"""Yields the digits of an integer."""
while number > 0:
yield number % 10
number //= 10
def digital_root(number):
"""Computes the digital root of an integer."""
while number > 9:
number = sum(digits_of(number))
return numberI'm pretty sure my 6 year old daughter could make sense of that last function with very little help.
Code Snippets
def digits_of(number):
"""Yields the digits of an integer."""
while number > 0:
yield number % 10
number //= 10
def digital_root(number):
"""Computes the digital root of an integer."""
while number > 9:
number = sum(digits_of(number))
return numberContext
StackExchange Code Review Q#135488, answer score: 7
Revisions (0)
No revisions yet.