0

My homework is simple, declare a function named printPrimeNumbersTo with a single argument named to

I created the skeleton of the code itself, however, I needed some help from the net. GeeksforGeeks was the site where I "borrowed" a line of code, which I don't completely understand. (Site: https://www.geeksforgeeks.org/python-program-to-print-all-prime-numbers-in-an-interval/)

My code looks like this (I have comments on nearly every line, describing what I think that the line of code does):

def printPrimeNumbersTo(to):
   x = 0
   prime_list = [] # This was a string, however, I changed it to a list so I won't have to convert the numbers to a string every time I wanted to append it to the list
   for i in range(x, to + 1): # Create a for loop, using the function range an starting the loop at number 0. Add 1 to 'to', because range excludes the end integer
      if i == 0 or i == 1:
         continue
      else:
         for j in range(2, i // 2 + 1): # <--
            if i % j == 0: # If 'j' is divided by any number in the list and remainder is 0, then the number is not a prime number, which means I can break the loop
               break
            else:
               prime_list.append(i) # Append the prime number to the list
   return str(prime_list)[1:-1] # Returns '[2,3,5,7..]', I use the square brackets the get rid of the brackets themselves


print(printPrimeNumbersTo(7)) # >>> 2, 3, 5, 7

The one line I don't understand is marked with an arrow, it's the 8th line of the code. Why am I dividing the number by 2? And then making it an integer? When I do the calculations, it works, but... where is the logic? Anybody help?

tripleee
  • 175,061
  • 34
  • 275
  • 318
Aakuho
  • 33
  • 4
  • That is a terribly inefficient implementation with a failed optimization attempt. You can't learn by copying, in particular if you copy from geeksforgeeks, which is an awful place worth staying far away from. – molbdnilo Mar 16 '22 at 17:26
  • A successful optimization would loop up to the square root, by the way. It is worth spending a few minutes on figuring out why. – molbdnilo Mar 16 '22 at 17:40
  • Thanks @molbdnilo for the reply, however this does not answer my question. I am simply asking for someone to explain the logic to me. If I wanted to make the code more efficient, then sure, I would look into this deeper and possibly rewrite it. But this is just a **school project**, nothing that will be a part of some different code. There is no need for optimization. Maybe it would be a good exercise to write the functions optimized right away, so I will look into your solution. If you have a felicitous answer for the question I asked, then I would be glad, if you could share it with me. Ty! – Aakuho Mar 16 '22 at 18:23
  • That's why they posted a comment, not an answer. – tripleee Mar 16 '22 at 18:29
  • Perhaps, I joined Stack Overflow moments ago, so I do not understand the value of the comment itself. – Aakuho Mar 16 '22 at 18:45
  • @Aakuho I attempted to provide value by inviting you to think about the problem instead of cheating. – molbdnilo Mar 16 '22 at 18:51
  • A good learning exercise would be to try to condense the code as much as possible too, here is a one-line version for studying purposes: `printPrimeNumbersTo(to): return [n for n in range(1, to+1) if not any(n%i == 0 for i in range(2, n)) and n > 1]` – Eli Harold Mar 16 '22 at 19:19
  • @molbdnilo Yes, I appreciate it. Of course, everyone can copy paste, so I thank you for your answer and trying to help me instead of well.. help me. dw about it though! The answer maybe came out wrong and more aggressive than it should have been. – Aakuho Mar 16 '22 at 21:56

3 Answers3

0

Dividing the number by 2 is done to reduce the number of iterations. For example, the number 12 you can divide it without a remainder by 1,2,3,4,6. Notice that there is no number bigger than (6) which is 12 / 2. And this goes on with all of the numbers.

 16   --->  1,2,8      no number bigger than its half (8)
ouflak
  • 2,458
  • 10
  • 44
  • 49
Mo Hesham
  • 1
  • 1
0

There are two points to note:

  1. the code needs to be indented correctly, in Python indentation matters as it forms the code blocks.

  2. aside from this and specifically adressing the question: the range function that you refer to requires integers otherwise it would throw an typeerror like this: 'float' object cannot be interpreted as an integer .

# this will throw an error
for i in range(1,  10.5):
    print(i)

# this will work
for i in range(1,  10):
    print(i)

So the reason why the line of code you queried was written like that was to ensure that the upper bound of the range was an integer.

You should also note that the // has a meaning, for example try this:

x = 5//2
print(x)


y = 5/2
print(y)

x is the integer part only (x=2)

y is the full number (y=2.5)

In terms of implementaiton, there are a number of methods that would be better (suggested here):

Print series of prime numbers in python

tripleee
  • 175,061
  • 34
  • 275
  • 318
D.L
  • 4,339
  • 5
  • 22
  • 45
  • The code was shifted due to a copy paste, I edited it and now it should be okay. Now, I understand that I cannot put a float into the range function, however, that does not answer my question. I am unsure about this `i // 2 + 1` part. Mo Hesham said that this was made for performance boost, yet, when I delete the part and just keep it as `i + 1`, the code breaks. – Aakuho Mar 16 '22 at 18:17
  • Thank you for correcting the indentation. Now running the code (in the modded question), i see that it does not find primes. The output that is returned with the code in the question is `5, 7, 7`.... – D.L Mar 16 '22 at 18:23
  • That is correct, I was unsure why does that happen – Aakuho Mar 16 '22 at 18:25
0

The biggest number which could possibly be an even factor of a number is the half of that number. The integer division operator // produces this number as an integer.

Because of how range works, the ending index needs to be the desired number plus one.

tripleee
  • 175,061
  • 34
  • 275
  • 318