I wanted to try and learn multi-threading, so I thought it would be good to make a small program normally first and make it multi-threaded, so I made this prime finder.
from time import sleep
def prime_finder(num: int) -> bool:
"""Checks to see if a number is prime"""
if num == 2:
return True
divider = 2
while True:
if (num % divider) == 0:
return False
elif (divider + 1) >= (
num / divider): # I don't know how to explain this, but it prevents checking multiples twice
return True
divider += 1
num = 1
pause = 0 # A delay that makes each prime number more readable
print(f"The prime numbers starting from {num} are:")
while True:
if prime_finder(num):
print(num, end=", ")
sleep(pause)
num += 1
Before I added the multi-threading I wanted to make sure that there was nothing fundamentally wrong with it. As well I wanted it to be pretty quick from the start, and so any optimization (other than multi-threading obviously) would be appreciated. I also wanted it to be easy to build on, and so if there are any ways to make it easier to add stuff, specifically multi-threading, please let me know.
1 Answer 1
So, I am assuming that you are aware that a more efficient algorithm for finding prime numbers can be written, so we'll ignore this aspect.
Comments to the prime_finder
method
If we pass
num=1
to the method, will it return what you expect? Do you consider 1 a prime number?But even more important, the name of the method is misleading. The method does not really find prime numbers as the name suggests, it checks if a number is prime. It is very important to name methods properly, especially when other people have to read your code. If the name is bad, and a developer cannot understand what the method is doing, they might spend a lot of extra time reading the code. Even worse, if the method doesn't do what the name says it does, it might not be used properly and nasty bugs could be made.
If you rename the method, you don't even need a comment explaining what it is doing:
def is_prime(num: int) -> bool:
You will then also see that the statement below will make more sense:
while True:
if is_prime(num):
...
Comments to the rest of the code
In the code that goes after, you mix the logic of finding the next prime number and printing numbers. What if you want to reuse your code that finds prime numbers somewhere else but don't need to print them?
I would create a separate method that returns the next prime number using the concept of generator:
def next_prime_number() -> int:
num = 1
while True:
if is_prime(num):
yield num
num += 1
Then, if you need, you can print them:
for prime_number in next_prime_number():
print(prime_number)
You can also add waiting, obviously.
Now, if you want to add multithreading, you will have to modify the next_prime_number
method, and you won't have problems with printing in multiple threads.
num
, you can just look at the smaller primes. You also appear to be building up a new list of lower primes for every number investigated, which is quite the overhead compared to just keeping track of the previous ones. [1]: en.wikipedia.org/wiki/Sieve_of_Eratosthenes \$\endgroup\$