I have a prime_factorize
function that returns a dictionary mapping from prime divisors to their powers. E.g., 50 = 2^1 * 5^2, so prime_factorize(50)
returns {2 : 1开发者_StackOverflow社区, 5 : 2}
.
Assuming this is the documented behavior, what would be the least surprising way to signal an error if called 0, 1, or a negative number? Throw ValueError
? Return something that looks like correct output (e.g., prime_factorize(-5) -> {-1: 1, 5: 1}
)? return an empty dict?
And if you have a better format for returning a prime factorization, I'd love to hear that too.
In prime_factorize(n)
:
if n < 2 or not isinstance(n, numbers.Integral):
raise ValueError("Number to factor can't be less than 2")
else:
# normal behavior
That way users a.) get meaningful info about what went wrong and b.) can handle the exception in a try...except
block.
I definitely wouldn't turn incorrect data or an empty dict, because that will lead to some tricky debugging the first time someone passes an improper value. Raise exceptions, that's what they're there for!
Not sure why you're using a dictionary here. Wouldn't a list of 2-tuples work as well? I.e., have prime_factor(50)
return [(2,1), ((5,2)]
.
Use of a dictionary presupposes that you know the key and want to look up it's value, which doesn't seem to be the case for the prime factors of an arbitrary number.
More to do with the concept of prime factorization than anything to do with python; factorization should raise an exception for all x < 2 or non integer.
Math functions in the standard library may be a good reference to take as the least surprising behaviour. Let's check math.sqrt
for example: it returns a ValueError
on domain error (here n < 1) and a TypeError
on unexpected type (here if you send a non-integer). So I'd write.
if is not isinstance(n, numbers.Integral):
raise TypeError("an integer is required")
elif n < 1:
raise ValueError("number to factor can't be less than 1")
...
And I agree with Piotr Findeisen, a factorization of 1 as an empty dictionary seems perfectly sound.
精彩评论