11#!/usr/bin/env python3
22"""
3- module to operations with prime numbers
3+ Module for prime number operations
44"""
55
66import 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