Python IF Else and For loop workflow - python-3.x

I am trying to write a function that returns the number of prime numbers that exist up to and including a given number.
Initially this was my code:
def count_primes(num):
prime = [2]
x = 3
if num < 2:
return 0
while x <= num:
for y in prime:
if x%y == 0:
print('not prime')
x+=2
break
else:
prime.append(x)
x += 2
return len(prime)
How ever I realise this code will run forever because of the following line of code:
for y in prime:
if x%y == 0:
print('not prime')
x+=2
break
else:
prime.append(x)
x += 2
Can anyone help to explain to me why will this end up with an infinite loop compared to the following code?
for y in prime:
if x%y == 0:
print('not prime')
x+=2
break
else:
prime.append(x)
x += 2

Related

PYTHON: projecteuler 60

I have some trouble about project euler problem 60.
The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.
Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.
The code that I created is too slow to see the correct answer. And I don't even see that is it work correctly or not. The code is:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Aug 27 21:18:10 2022
#author: burak
"""
def is_prime(n, check_list_for_primes): #checks if value is prime
if check_list_for_primes.count(n) > 0: #checks if valu calculated before. if it were, it avoid loop.
return True
else:
if n == 1:
return False
if n == 2 or n == 3:
return True
i = 2
while i * i <= n:
if n % i == 0:
return False
exit(0)
i += 1
check_list_for_primes.append(n) # if it never calculated, stores the value to avoid loop at the beginning of function.
return True
def check_1(i, j): # checks the concanated calues if they are primes.
if is_prime(int(str(i)+str(j)), check_list_for_primes) == True and is_prime(int(str(j)+str(i)), check_list_for_primes) == True:
return True
else:
return False
def check_2(temp_list, n): # checks the final list that obtain the minimum summation.
if temp_list.count(n) == 0:
temp_list.append(n)
for i in temp_list:
for j in temp_list:
if len(temp_list) == 1:
return check_1(i, j)
elif i == j:
continue
elif len(temp_list) == 1:
return True
break
elif check_1(i, j) == False:
return False
return True
def func_(prime_list): # creates a dictionary summation of the five prime numbers in order to problem.
temp_list = []
result_dic = {}
k = 0
t = 0
for i in prime_list:
if i == 5:
continue
while k == 0:
t = k
for j in prime_list:
if i == j or j == 5:
continue
elif j < i:
continue
else:
temp_list.append(j)
if check_2(temp_list, i) == True:
continue
else:
temp_list.remove(j)
if t > 0 and len(temp_list) > 1:
t -= 1
temp_list.remove(max(temp_list))
continue
if len(temp_list) == 5:
result_dic[sum(temp_list)] = temp_list
elif len(temp_list) < 5:
k +=1
temp_list = []
return result_dic
if __name__ == "__main__":
dic_ = {}
prime_list = []
check_list_for_primes = []
for i in range(3, 9000, 1): #creates prime list between given range
if is_prime(i, check_list_for_primes) == True:
prime_list.append(i)
check_list_for_primes = prime_list.copy() #pseudo prime list to avoid calculating if the number is prime.
dic_ = func_(prime_list) #final dictionary to obtain minimum summation of five prime numbers.
x = min(list(dic_.keys()))
print(str(x) + " : " + str(dic_[x]))
I tried to type the examination of calculating order.
The main problem is at "func_" function. The for loop of "j" must be manipulated if the code not to get required list lenght. The "j" loop must be restart again after remove second element of "temp_list" and it must be start after shift to removed element of "prime_list".
Could you help me to see where I made mistakes and how can I improve calculation speed. Thanks so much.
I solved it. while loop changed and the "j" for loop determined by a list. The final code is;
def is_prime(n, check_list_for_primes): #checks if value is prime
if check_list_for_primes.count(n) > 0: #checks if valu calculated before. if it were, it avoid loop.
return True
else:
if n == 1:
return False
if n == 2 or n == 3:
return True
i = 2
while i * i <= n:
if n % i == 0:
return False
exit(0)
i += 1
check_list_for_primes.append(n) # if it never calculated, stores the value to avoid loop at the beginning of function.
return True
def check_1(i, j): # checks the concanated values if they are primes.
if is_prime(int(str(i)+str(j)), check_list_for_primes) == True and is_prime(int(str(j)+str(i)), check_list_for_primes) == True:
return True
else:
return False
def check_2(temp_list): # checks the final list that obtain the minimum summation.
for i in temp_list:
for j in temp_list:
if len(temp_list) == 1:
return check_1(i, j)
elif i == j:
continue
elif len(temp_list) == 1:
return True
break
elif check_1(i, j) == False:
return False
return True
def func_(prime_list): # creates a dictionary summation of the five prime numbers in order to problem.
prime_list.remove(5)
temp_list = []
result_dic = {}
# k = 0
copy_primes = prime_list.copy()
for i in prime_list:
for z in prime_list:
if z <= i:
copy_primes.remove(z)
else:
break
if i == max(prime_list):
break
elif i == 5:
continue
# for z in range(len(prime_list) - 1, 0, -1):
# if check_1(i,prime_list[z]) == True:
# max_prime_of_i = prime_list[z]
# break
while len(temp_list) < 5:
# if temp_list[1] == max_prime_of_i:
# break
if len(temp_list) == 1:
break
if len(copy_primes) == 0 and len(temp_list) > 1:
copy_primes = prime_list.copy()
for z in prime_list:
if z <= temp_list[1]:
copy_primes.remove(z)
else:
break
temp_list = []
for j in prime_list:
if len(copy_primes) > 0:
j = copy_primes[0]
copy_primes.remove(j)
else:
break
if temp_list.count(i) == 0:
temp_list.append(i)
continue
temp_list.append(j)
temp_list.sort()
if check_2(temp_list) == True and len(temp_list) > 1:
continue
elif check_2(temp_list) == False and len(temp_list) > 1:
temp_list.remove(j)
print(i)
print(temp_list)
if len(temp_list) < 5 and len(copy_primes) == 0:
continue
elif len(temp_list) == 5:
break
copy_primes = prime_list.copy()
if len(temp_list) == 5:
result_dic[sum(temp_list)] = temp_list
print(str(min(list(result_dic.keys()))) + " : " + str(result_dic[min(list(result_dic.keys()))]))
weight_ = 0
check_weight = 0
for p in temp_list:
weight_ = weight_ + len(str(p))
if weight_ < check_weight or check_weight == 0:
check_weight = weight_
elif check_weight < weight_ and len(temp_list) == 5:
return result_dic
temp_list = []
return result_dic
if __name__ == "__main__":
dic_ = {}
prime_list = []
check_list_for_primes = []
for i in range(3, 9000, 1): #creates prime list between given range
if is_prime(i, check_list_for_primes) == True:
prime_list.append(i)
check_list_for_primes = prime_list.copy() #pseudo prime list to avoid calculating if the number is prime.
dic_ = func_(prime_list) #final dictionary to obtain minimum summation of five prime numbers.
x = min(list(dic_.keys()))
print(str(x) + " : " + str(dic_[x]))

Recursively calling a second function inside a function

I have this code that counts up -3, -2, -1. I have also written another that counts down 3, 2, 1. If the condition is true for another after an input, the program should stop. For Example, The input i enter -3 for negatives it gives -3, -2, -1, if i enter positive number like 3, the result should be 3, 2, 1 in a single combined code.
I have tried to put a function into an if statement of the first function but fails with "NameError: name 'countdown' is not defined" for count down but count up works.
print('+=+=+=+=+=+=+=+=+=+=+=+=+ F1')
#count up
def countup(n):
if (n >= 0):
print('Hello')
if n==0:
print('Blastoff!')
else:
print(n)
countdown(n-1)
else:
print(n)
nth = n + 1
countup(nth)
result = int(input('Enter Number: '))
countup(result)
Have you tried replacing the second else with elif? And fixing the indenting? The resulting code should be this:
print('+=+=+=+=+=+=+=+=+=+=+=+=+ F1')
#count up
def countup(n):
if (n >= 0):
print('Hello')
if n==0:
print('Blastoff!')
elif (condition):
print(n)
countdown(n-1)
else:
print(n)
nth = n + 1
countup(nth)
result = int(input('Enter Number: '))
countup(result)
I solve the problem by doing this code below:
def countup(n):
if (n >= 0):
print('Blastoff 1')
else:
print(n)
nth = n + 1
return countup(nth);
def zero(n):
if (n==0):
print('You have erntered 0 program exiting')
exit()
def countdown(n):
if (n <= 0):
print('explode 2')
else:
print(n)
nth = n - 1
return (countdown(nth))
num = int(input("Enter number: "));
if (num <= 0):
print(countup(num))
elif num == 0:
print(zero(num))
else:
print(countdown(num))
The output is either negative or positive, regardless of what integer you fuse in

Finding the logical error in my code to get first 50 primes

I'm trying to write my own formula to find a prime number, but it does not completely work and I cannot find the flaw in my logic. Bare in mind I have taken a look around but cannot find an algorithm that I find similar to mine.
My code:
#Challenge 7
prime = []
num = 0
found = False
while found == False:
if num == 0 or num == 1:
num+=1
else:
for value in range(2, num+1):
if len(prime) == 50:
print('Found all')
found = True
break
if num % value == 0:
num+=1
else:
if num not in prime:
prime.append(num)
else:
pass
print(prime)
This code works for first few primes (3, 5, 7...)
but it also gives incorrect values like 10, and I don't understand why. If someone could explain it to me so that I can understand where the logical mistake is, I'd appreciate it.
The error comes from this part
if num % value == 0:
num+=1
else:
if num not in prime:
prime.append(num)
else:
pass
You assume that the integer is a prime as soon as we find the first occurence of a non-divisor. But the def for primes is that every integer in the interval [2..prime] is a non-divisor. How do we check if any number does not have any divisors?
def isPrime(x):
for v in range(2, x):
if (x % v == 0):
return False;
return True;
Something like this would work to check if any given number is a prime or not. And since we now have taken the isPrime part out of the main loop, we no longer need a for loop inside the while. Something like this would do
def isPrime(x):
for v in range(2, x):
if (x % v == 0):
return False;
return True;
prime = [}
num = 2
found = False
while found == False:
if len(prime) == 50:
print("found all")
found = True
break
if(isPrime(num)):
print(num)
prime.append(num)
num+=1
else:
num+=1
If you set a breakpoint for when num == 10 you will see the problem clearly.
When you start doing you division check inside of for value in range(2, num + 1): the second number is 3, so num (10) modulo value (3) is 1, which is your test for determining a prime. What your test should be is that it not divisible by any number less than it (less than half is actually sufficient since you check with 2 anyway).
So, consider instead:
else:
is_indivisible = True
# loop through all numbers less than it not including itself
# (because x % x == 0)
for value in range(2, num - 1):
# it is only indivisible if it was previously indivisible
# And the check is same as before, modulo != 0
is_indivisible = is_indivisible and (num % value != 0)
if not is_indivisible:
break
# if it is indivisible and it doesn't exist in prime list yet
if is_indivisible and num not in prime:
prime.append(num)
# move on to the next number
num += 1

Logic to find out the prime factors of a number

I have created the below script to find out the prime factors of a number :
def check_if_no_is_prime(n):
if n <= 3:
return True
else:
limit = int(math.sqrt(n))
for i in range(2,limit + 1):
if n % i == 0:
return False
return True
def find_prime_factors(x):
prime_factors = []
if check_if_no_is_prime(x):
prime_factors.append(1)
prime_factors.append(x)
else:
while x % 2 == 0 and x > 1:
prime_factors.append(2)
x = x // 2
for i in range(3,x+1,2):
while x % i == 0 and x > 1:
if check_if_no_is_prime(i):
prime_factors.append(i)
x = x // i
if x <= 1:
return prime_factors
return prime_factors
no = int(input())
check = find_prime_factors(no)
print (check)
I am not sure whether this is the best and efficient way to do this ?
Can someone please point out any better way to do this ?
using sieve of erathnostanes to get all prime numbers from 2 to whatever limit inputted
def sieve(N):
from math import floor,sqrt
A=[1 for x in range(N+1)]
for count in range(2):
A[count]=0
for i in range(floor(sqrt(N))+1):
if A[i]==1:
for k in range(i*i,N+1,i):
A[k]=0
ans=list(enumerate(A))
res=[]
for (i,j) in ans:
if j==1:
res+=[i]
return res
print(sieve(100))
#my code

Python: TypeError: 'int' object is not iterable

I'm tackling this following question:
Write a function is_fib(n) that returns True if n is a Fibonacci number, and False otherwise.
This is my code:
def is_fib(n):
def fib(x):
if x == 0:
return 0
elif x == 1:
return 1
else:
return fib(x-1) + fib(x-2)
for a in n:
if fib(a) == n:
result = True
break
else:
result = False
return result
Running this give rise to:
TypeError: 'int' object is not iterable.
I have been staring at the code for half an hour. Any help is greatly appreciated.
I think you mean
for a in range(n)
not
for a in n
As jozefg said you are missing range(n)
also notice that you need range(n+2) to cover all cases
def is_fib(n):
def fib(x):
if x == 0:
return 0
elif x == 1:
return 1
else:
return fib(x-1) + fib(x-2)
for a in range(n+2):
if fib(a) == n:
return True
return False
print(is_fib(3))
Firstly thanks to the two guys that helped me.
However, for Yoav's edition, python will run into an error when n is a really big number.
This is my new and improved version.
def is_fib(n):
if n < 0:
return False
else:
fib_0 = 0
fib_1 = 1
if n == fib_0 or n == fib_1:
return True
else:
for a in range(2,n+2):
fib = fib_0 + fib_1
fib_0,fib_1 = fib_1,fib
if fib >= n:
break
return fib == n

Resources