Skip to content

Commit 9716b36

Browse files
Fix num_digits functions: correct doctests and improve benchmark
1 parent 33aef9e commit 9716b36

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

maths/number_of_digits.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import math
22
from timeit import timeit
3+
from typing import Callable
34

45

56
def num_digits(n: int) -> int:
67
"""
7-
Find the number of digits in a number.
8+
Find the number of digits in an integer.
89
910
>>> num_digits(12345)
1011
5
@@ -21,7 +22,6 @@ def num_digits(n: int) -> int:
2122
...
2223
TypeError: Input must be an integer
2324
"""
24-
2525
if not isinstance(n, int):
2626
raise TypeError("Input must be an integer")
2727

@@ -37,8 +37,7 @@ def num_digits(n: int) -> int:
3737

3838
def num_digits_fast(n: int) -> int:
3939
"""
40-
Find the number of digits in a number.
41-
abs() is used as logarithm for negative numbers is not defined.
40+
Find the number of digits using logarithm.
4241
4342
>>> num_digits_fast(12345)
4443
5
@@ -50,22 +49,19 @@ def num_digits_fast(n: int) -> int:
5049
1
5150
>>> num_digits_fast(-123456)
5251
6
53-
>>> num_digits('123') # Raises a TypeError for non-integer input
52+
>>> num_digits_fast('123') # Raises a TypeError for non-integer input
5453
Traceback (most recent call last):
5554
...
5655
TypeError: Input must be an integer
5756
"""
58-
5957
if not isinstance(n, int):
6058
raise TypeError("Input must be an integer")
61-
62-
return 1 if n == 0 else math.floor(math.log(abs(n), 10) + 1)
59+
return 1 if n == 0 else math.floor(math.log10(abs(n)) + 1)
6360

6461

6562
def num_digits_faster(n: int) -> int:
6663
"""
67-
Find the number of digits in a number.
68-
abs() is used for negative numbers
64+
Find the number of digits using string conversion.
6965
7066
>>> num_digits_faster(12345)
7167
5
@@ -77,30 +73,32 @@ def num_digits_faster(n: int) -> int:
7773
1
7874
>>> num_digits_faster(-123456)
7975
6
80-
>>> num_digits('123') # Raises a TypeError for non-integer input
76+
>>> num_digits_faster('123') # Raises a TypeError for non-integer input
8177
Traceback (most recent call last):
8278
...
8379
TypeError: Input must be an integer
8480
"""
85-
8681
if not isinstance(n, int):
8782
raise TypeError("Input must be an integer")
88-
8983
return len(str(abs(n)))
9084

9185

9286
def benchmark() -> None:
9387
"""
94-
Benchmark multiple functions, with three different length int values.
88+
Benchmark multiple functions with three different length integers.
9589
"""
96-
from collections.abc import Callable
97-
9890
def benchmark_a_function(func: Callable, value: int) -> None:
9991
call = f"{func.__name__}({value})"
100-
timing = timeit(f"__main__.{call}", setup="import __main__")
101-
print(f"{call}: {func(value)} -- {timing} seconds")
92+
timing = timeit(f"__main__.{call}", setup="import __main__", number=10000)
93+
print(f"{call}: Result={func(value)}, Time={timing:.6f} sec")
10294

103-
for value in (262144, 1125899906842624, 1267650600228229401496703205376):
95+
test_values = [
96+
262144,
97+
1125899906842624,
98+
1267650600228229401496703205376,
99+
]
100+
101+
for value in test_values:
104102
for func in (num_digits, num_digits_fast, num_digits_faster):
105103
benchmark_a_function(func, value)
106104
print()
@@ -111,3 +109,4 @@ def benchmark_a_function(func: Callable, value: int) -> None:
111109

112110
doctest.testmod()
113111
benchmark()
112+

0 commit comments

Comments
 (0)