1
\$\begingroup\$

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I'm not sure what you're looking for here, since you mention speed but you have included a pause. You would get really good speed improvements from making a [sieve][1], but I'm sure there are even smarter algorithms. You don't really need to look at all numbers up to 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\$
    – ades
    Apr 1, 2020 at 19:57
  • \$\begingroup\$ @ades The pause is just there to make it so once a prime number is found, it can pause so the user can see that it has found a prime number. I want the code that finds the primes itself to be fast, with easy addition of multi-threading in mind. \$\endgroup\$
    – user211881
    Apr 1, 2020 at 20:00

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.