Posts: 201
Threads: 37
Joined: Dec 2021
Hello,
Its probably the wrong way to do this, but i am trying to print my list and because of the if statement to get rid of the false returned, i ended up with doubles in my list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
prime = []
def is_prime_v1(n):
if n = = 1 :
return False
for d in range ( 2 , n):
if n % d = = 0 :
return False
prime.append(n)
return n
for n in range ( 1 , 21 ):
if is_prime_v1(n) ! = False :
print (is_prime_v1(n))
print (prime)
|
Output: 2
3
5
7
11
13
17
19
[2, 2, 3, 3, 5, 5, 7, 7, 11, 11, 13, 13, 17, 17, 19, 19]
>
print(prime) seems to be prisonner of the for indent. It cause the numbers to repeat twice.
How to avoid this?
Of course the Sieve of Eratosthenes is more efficent. The question is just about controling the return and indentation.
Thank you
Posts: 379
Threads: 2
Joined: Jan 2021
On line 15 you are calling is_prime_v1(n) a second time. Try it like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
prime = []
def is_prime_v1(n):
if n = = 1 :
return False
for d in range ( 2 , n):
if n % d = = 0 :
return False
prime.append(n)
return n
for n in range ( 1 , 21 ):
prime_number = is_prime_v1(n)
if prime_number ! = False :
print (prime_number)
print (prime)
|
Posts: 201
Threads: 37
Joined: Dec 2021
Wonder what is the principle idea behind the scene to be force to create a new variable to escape the indent.
Thanks!
Posts: 7,324
Threads: 123
Joined: Sep 2016
Also it's not necessary to append to a list.
When have done if check in function then it's not needed to add != False: outside.
1 2 3 4 5 6 7 8 9 10 11 |
def is_prime_v1(n):
if n = = 1 :
return False
for d in range ( 2 , n):
if n % d = = 0 :
return False
return True
for i in range ( 1 , 21 ):
if is_prime_v1(i):
print (i)
|
Output: 2
3
5
7
11
13
17
19
Frankduc and BashBedlam like this post
Posts: 201
Threads: 37
Joined: Dec 2021
I agree with you. My goal was to print the result with and without a list.
At first i wanted to print without a list but ended up with False and True. Removing false or true get you a none.
Than i returned n to only get the primes. But true is in output. I tried for fun Ruby language. I like the idea to not have to return something (return is automatic). In python you have to return otherwise nothing comes out.
In the end your solution is what i was looking for. Just that was enough:
1 2 3 4 5 |
for n in range ( 1 , 21 ):
if is_prime_v1(n):
print (n)
print (prime)
|
Again a logic problem i suppose.
Posts: 4,801
Threads: 77
Joined: Jan 2018
Frankduc Wrote:Wonder what is the principle idea behind the scene to be force to create a new variable to escape the indent. Your design is wrong from the start because the role of function is_prime_v1() is not well defined. It tells whether n is prime by returning a boolean, and at the same time, it appends items to the prime list and returns the value of n . These are too many tasks for a single function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def is_prime_v1(n):
if n = = 1 :
return False
for d in range ( 2 , n):
if n % d = = 0 :
return False
return True
prime = []
for n in range ( 1 , 21 ):
if is_prime_v1(n):
prime.append(n)
print (prime)
|
Output: [2, 3, 5, 7, 11, 13, 17, 19]
Frankduc and BashBedlam like this post
Posts: 201
Threads: 37
Joined: Dec 2021
It maybe the right way to do this. The difference in compiling is small.
My version: Time required 0.00012230873107910156
Yours: 0.0001380443572998047
That if i timed it correctly with an online compiler.
Posts: 6,809
Threads: 20
Joined: Feb 2020
Worry about being correct first, then worry about speed. Your design was incorrect. It did not create a list you wanted. This has nothing to do with indenting and all to do with writing the wrong code.
Posts: 201
Threads: 37
Joined: Dec 2021
Got influenced by this code:
1 2 3 4 5 6 7 8 9 |
def primes(n):
prime, sieve = [], set ()
for q in range ( 2 , n + 1 ):
if q not in sieve:
prime.append(q)
sieve.update( range (q * q, n + 1 , q))
return prime
print (primes( 20 ))
|
list and set are inside the function. I learned in c# that list must be close the for loop just above. But it depends what return you are expecting. In this case its a function.
Posts: 6,809
Threads: 20
Joined: Feb 2020
In the Sieve of Eratosthenes example the prime list and sieve set are generated fresh each time the function is called. The user wants a list of prime numbers up to and including "n". The algorithm depends on generating a set of non-prime numbers. But even if you don't want a list there are lots of things you can do with a list. Sometimes creating a list may be the most efficient way to accomplish your goal.
Looking at your code it is unclear what you want to accomplish. If you just want to print the prime number in the range 0..20 the Sieve of Eratosthenes may be the most efficient way to do that.
1 2 3 4 5 6 7 8 9 10 |
def primes(n):
prime, sieve = [], set ()
for q in range ( 2 , n + 1 ):
if q not in sieve:
prime.append(q)
sieve.update( range (q * q, n + 1 , q))
return prime
for prime in primes( 20 ):
print (prime)
|
The code is very efficient because it doesn't do any division or much math at all, far more efficient than using the modulo operator. This would be seen if n=1000000 instead of 20.
If you really hate the idea of having a list, even as a temporary holder for your values, you could rewrite this as a generator.
1 2 3 4 5 6 7 8 9 10 |
def primes(n):
sieve = set ()
for q in range ( 2 , n + 1 ):
if q not in sieve:
yield q
sieve.update( range (q * q, n + 1 , q))
return prime
for prime in primes( 20 ):
print (prime)
|
Now primes() returns a number, not a list of numbers. It doesn't make much sense writing something like Sieve of Eratosthenes as a generator. The algorithm needs an ending point and making the ending point arbitrarily large makes the algorithm run very slow. But for many kinds of calculations or operations a generator is the way to go. You don't have to wait for it to compute every result, and it doesn't use a lot of storage to save results.
|