Skip to content

Commit a06bd51

Browse files
Add prime utilities: is_prime, next_prime, generate_primes
Refactor prime number functions for clarity and correctness.
1 parent e2a78d4 commit a06bd51

File tree

1 file changed

+71
-20
lines changed

1 file changed

+71
-20
lines changed
Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22
"""
3-
module to operations with prime numbers
3+
Module for prime number operations
44
"""
55

66
import math
@@ -21,8 +21,6 @@ def is_prime(number: int) -> bool:
2121
True
2222
>>> is_prime(27)
2323
False
24-
>>> is_prime(87)
25-
False
2624
>>> is_prime(563)
2725
True
2826
>>> is_prime(2999)
@@ -31,29 +29,82 @@ def is_prime(number: int) -> bool:
3129
False
3230
"""
3331

34-
# precondition
35-
assert isinstance(number, int) and (number >= 0), (
36-
"'number' must been an int and positive"
37-
)
32+
if not isinstance(number, int) or number < 0:
33+
raise ValueError("'number' must be a non-negative integer")
3834

39-
if 1 < number < 4:
40-
# 2 and 3 are primes
35+
if number < 2:
36+
return False
37+
if number in (2, 3):
4138
return True
42-
elif number < 2 or not number % 2:
43-
# Negatives, 0, 1 and all even numbers are not primes
39+
if number % 2 == 0:
4440
return False
4541

46-
odd_numbers = range(3, int(math.sqrt(number) + 1), 2)
47-
return not any(not number % i for i in odd_numbers)
42+
for i in range(3, int(math.isqrt(number)) + 1, 2):
43+
if number % i == 0:
44+
return False
45+
return True
46+
47+
48+
def next_prime(value: int, factor: int = 1, **kwargs) -> int:
49+
"""
50+
Returns the next prime number after (factor * value).
51+
If desc=True, returns the previous smaller prime number.
52+
53+
>>> next_prime(5)
54+
7
55+
>>> next_prime(10)
56+
11
57+
>>> next_prime(7, desc=True)
58+
5
59+
>>> next_prime(2, desc=True)
60+
Traceback (most recent call last):
61+
...
62+
ValueError: No smaller prime exists below 2.
63+
"""
4864

65+
if not isinstance(value, int) or value < 0:
66+
raise ValueError("'value' must be a non-negative integer")
4967

50-
def next_prime(value, factor=1, **kwargs):
51-
value = factor * value
52-
first_value_val = value
68+
value *= factor
69+
descending = kwargs.get("desc", False)
5370

54-
while not is_prime(value):
55-
value += 1 if not ("desc" in kwargs and kwargs["desc"] is True) else -1
71+
if descending:
72+
if value <= 2:
73+
raise ValueError("No smaller prime exists below 2.")
74+
value -= 1
75+
while value > 1 and not is_prime(value):
76+
value -= 1
77+
else:
78+
value += 1
79+
while not is_prime(value):
80+
value += 1
5681

57-
if value == first_value_val:
58-
return next_prime(value + 1, **kwargs)
5982
return value
83+
84+
85+
def generate_primes(limit: int) -> list[int]:
86+
"""
87+
Generate all prime numbers up to the given limit (inclusive).
88+
89+
>>> generate_primes(10)
90+
[2, 3, 5, 7]
91+
>>> generate_primes(1)
92+
[]
93+
>>> generate_primes(20)
94+
[2, 3, 5, 7, 11, 13, 17, 19]
95+
"""
96+
if not isinstance(limit, int) or limit < 0:
97+
raise ValueError("'limit' must be a non-negative integer")
98+
99+
primes = []
100+
for num in range(2, limit + 1):
101+
if is_prime(num):
102+
primes.append(num)
103+
return primes
104+
105+
106+
if __name__ == "__main__":
107+
import doctest
108+
109+
doctest.testmod()
110+
print("All doctests passed ✅")

0 commit comments

Comments
 (0)