Here is some code I have been working on to find a list of prime numbers (bear in mind I am fairly new and I know this will seem over complex)
prime_list=[2,3,5,7,11,13]
prime_list=[2,3,5,7,11,13]
a=1
length=len(prime_list)
last=prime_list[length-1]
true=True
while last < last**2 and a <30:
last= last+1
a=a+1
for number in prime_list:
if (last)%number == 0:
true = False
else:
pass
if true == True:
prime_list.append(last)
else:
print("n")
pass
print(prime_list)
The essence of the problem is this, all I get is ns. As in, the true variable is always made false. For some reason the remainder function isn't working. I would really appreciate some help. (For the specific section involved look at the if last%number == 0:
I would go for something like this if you are a beginner:
def isPrime(x): # define a function that will check if 'x' is prime
if x == 2:
return True
i = 2
while i * i <= x: # this will loop from i = 2 to sqrt(x)
if x % i == 0: # check if 'i' can divide 'x'
return False
i += 1 # this will increase 'i' by 1
return True
n = 100 # every prime number in 'list' will be below 'n'
list = []
for k in range(1, n):
if isPrime(k): # let see if 'k' is a prime number
list.append(k) # if 'k' is a prime number add it to the list
print(list)
For a more efficient algorithm I would use Sieve of Eratosthenes
The reason that last is not working in your code is that it needs to be defined outside of the while loop. Here is a simple way to do it. Notice that the prime list, and nextNum (my equivalent to your last) are defined globally. Because they are defined outside the while loop, they will persist from iteration to iteration.
primes = []
nextNum = 2
while nextNum < 100 :
tester = 0 # 0 at the end means nextNum is prime
for p in primes :
if nextNum%p == 0 :
tester += 1
if tester == 0 :
primes.append(nextNum)
print nextNum
nextNum += 1
You're never resetting true (which really is a bad name for this variable) to True after it gets set to False once.
Move true = True into your while loop before the for loop.
The first number you are testing (14) is not primary, so the flag (variable named true) is set to False. So far so good. The bad thing is that the flag never changes since then, and remains False for all subsequent numbers: there is nothing that could reset it to True.
You need to set the flag variable to True for each number you test, before you start iterating over potential dividers.
That is, the operator true=True (I hate writing this) should be inside while, not before it.
P.S. Operator % works as intended.
What martijnn replied is perhaps the best example for a beginner. If we want to apply his example to a particular list you have made, like you did in your original code (just so you can see a difference from a mandatory 100 loop, and you can learn more about lists and loops):
original_list=[2,3,5,6,7,11,13]
prime_list = []
def isPrime(x): # define a function that will check if 'x' is prime
if x == 2:
return True
i = 2
while i * i <= x: # this will loop from i = 2 to sqrt(x)
if x % i == 0: # check if 'i' can divide 'x'
return False
i += 1 # this will increase 'i' by 1
return True
for k in original_list:
if isPrime(k):
prime_list.append(k)
print prime_list
Related
The script is supposed to take in three whole numbers from the user(who will input the numbers) and
determine whether one of them is divisible by ten.
determine whether two of the numbers can add up to the remaining number.
I believe the first one is done, but the second one puzzled me for a bit. first I did "trial and error" which worked but took up too many lines for my taste, then I tried this:
num_list = [num_1, num_2, num_3]
for i in num_list:
a = num_list.index(i)
if i % 10 == 0:
is_div_by_10 = True
if i == num_list[a-1] + num_list[a-2]:
addsUpToNumber = True
sure my phrasing isn't great, but I cant find a way to use lesser lines of code to get the same result.
Without changing too much, I think you were pretty close. I'd split it up into two separate loops though:
is_divisible = False
is_summable = False
num_list = [1, 2, 3]
for num in num_list:
if num % 10 == 0:
is_divisible = True
break # we don't need to check the other numbers.
for i, num in enumerate(num_list):
if num == num_list[i-1] + num_list[i-2]:
is_summable = True
break # we don't need to check the other numbers.
Alternatively:
is_divisible = any(num % 10 == 0 for num in num_list)
is_summable = any(num == num_list[i-1] + num_list[i-2] for i, num in enumerate(num_list))
For context, I am trying to solve Project Euler problem 3 using Python:
What is the largest prime factor of the number 600851475143?
As a first step to this, I am trying to write a function that returns whether or not a number is prime as a Boolean. I made a first attempt, and checked out how this has been written previously. I have ended up with the following code:
def isprime(x):
limit = x**0.5
i = 2
if x < 2:
return False
elif x == 2:
return True
else:
while i <= limit:
if x%i == 0:
return False
i = i + 1
else:
return True
For some reason, the code above does not work perfectly. For example, isprime(99) would return True.
Please, can someone help me understand why this isn't working? I am trying to avoid just copying and pasting someone else's code, as I want to understand exactly what is going on here.
To me, it looks like the issue is with the final else statement. I say this because the logic reads "in the event that x%i == 0, this number is not prime" but it doesn't explicitly say what to do in the event that no x%i iterations == 0.
Any help on this would be appreciated! I'm not necessarily looking for the cleanest, neatest way of doing this, but more just trying to first make this code work.
Just to show an alternative, what you could do is checking from number 2 to your number if the operation (x % i) is equal to zero. If it never happend, it will be a prime.
def isprime(x):
# check for factors
for i in range(2,x):
if (x % i) == 0:
return False
else:
return True
print(isprime(99))
Try this :
def isprime(x):
limit = x**0.5
i = 2
if x <= 2:
return False
while i <= limit:
if x%i == 0:
return False
i = i + 1
return True
I've changed many things. have this point in your mind that there is no need to else clauses when you return at the end of if block.
you need to tell what happens when x%i==0 condition not met and the value of i remain constant and also need to see when all conditions not met, then it is a prime
# your code goes here
def isprime(x):
limit = x**0.5
i = 2
if x < 2:
return False
elif x == 2:
return True
else:
while i <= limit:
if x%i == 0:
return False
i+=1
return True
print(isprime(144)) # false
print(isprime(99)) # false
print(isprime(131)) # true
I am pretty new to Python and just got started in Leet and I am doing the Happy Number question, only half of the test cases have been passed. I would appreciate any help. Thanks
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
My test cases were 19, 100 where it output True correctly but when I do 7, it is wrong
def isHappy(self, n: int) -> bool:
if (n == 1):
return True
sum = 0
flag = False
for j in range(1,100):
x = str(n)
a = list(x)
for i in range(0,len(a)):
sum += int(a[i])*int(a[i])
if sum == 1:
return True
break
else:
x = sum
return False
Here is an implementation using a set to keep track of numbers that we have already seen. (I've removed the self argument here for sake of something that can be run outside of your test class.)
def isHappy(n: int) -> bool:
seen = set()
while True:
if n == 1:
return True
if n in seen:
return False
seen.add(n)
n = sum(int(c) ** 2 for c in str(n))
Your code has various issues aside from the fact that the number 100 is arbitrary.
Mainly that you never update n in your loop. Also you do not wait for the completion of the for loop before testing sum (in fact your break is never reached), you initialise sum only once, and you return False prematurely. Here is a minimally corrected version of your code, although still subject to the fact that there is no rule about 100 maximum iterations.
def isHappy(n: int) -> bool:
if (n == 1):
return True
for j in range(1,100):
x = str(n)
a = list(x)
sum = 0
for i in range(0,len(a)):
sum += int(a[i])*int(a[i])
if sum == 1:
return True
else:
n = sum
return False
The following code returns the summation of the values in list "A" that exist before the first even value in the list.
Example:
if list A = [1,3,5,4] the result would return 1 + 3 + 5 = 9
if list A = [1,2,5,4] the result would return 1
def for_version(L):
found_even = False
total = 0
for num in L:
if num % 2 != 0 and not found_even:
total = total + num
else:
found_even = True
return total
A = [1,3,5,9]
for_version(A)
I don't understand how, after the first iteration, we don't lose the 1st integer in the list. In other words, here's how I imagine the code is working.
Starts at the first value in the list "A" and prepares to move through all values one at a time:
for num in L:
Checks the first iteration of the if statement:
if num % 2 != 0 and not found_even:
Although the first number in the list IS ODD, because found_even was set to False originally the code should move to the else statement:
else:
found_even = True
I imagine that the if statement has now been completed on the first value of the list and all that occurred was that the found_even bool was changed to True.
I assumed that the code would then move on; that the if statements would then be tested on the NEXT value in the list. This, however appears incorrect. If my thinking were right, in the example above, it would mean that the first value in the list "1" would be ignored when completing the summation, and we would end up with 3 + 5 = 8 NOT 1 + 3 + 5 = 9.
I obviously don't understand something very foundational about how the
for num in L:
line works... It's as if it did not, in fact, move to the next integer in the list and reruns the code on the first integer in the list. Can someone please explain why this is.
Although the first number in the list IS ODD, because found_even was set to False originally the code should move to the else statement[.]
You got your logic wrong right there. not False is true, so the if statement test tests true and the else suite is not executed.
You can test this yourself:
>>> num = 1 # odd
>>> found_even = False
>>> num % 2
1
>>> num % 2 != 0
True
>>> not found_even
True
>>> num % 2 != 0 and not found_even
True
The code itself is overly complicated; just return early. There is no need to iterate on, or use a flag; return ends a function and iteration:
def for_version(L):
total = 0
for num in L:
if num % 2 == 0:
return total
total += num
Alternatively, use break to stop the loop, and return afterwards.
The Python standard library has a helpful tool in the itertools library for this, called itertools.takewhile(); it'll give you all elements of an iterable until the given test fails. It then just stops iterating:
from itertools import takewhile
sum(takewhile(lambda x: x % 2, A))
I removed the != 0 test there; % 2 only results in 0 or 1, and 0 is considered a false value in a boolean test. I also used the sum() function to add up all the numbers that takewhile does pass through.
You don't need to keep track if you found or not the first even number, just break and leave the for loop when you find it:
for num in L:
if num % 2 != 0:
total = total + num
else:
break
I was trying to make a program which would check a number for its greatest prime factor. I was almost done when this error message came up. list index out of range.
What does this mean and what is wrong with my code?
Here is my code.
def is_prime(n):
for i in range(3, n):
if n % i == 0:
return False
return True
def Problem3():
x = 144
n = 2
not_a_factor = []
z = []
prime = []
not_a_prime = []
while n < x:
if x%n == 0:
z.append(n)
else:
not_a_factor.append(n)
n = n + 1
for i in z:
if is_prime(z[i]) == True:
prime.append(z[i])
else:
not_a_prime.append(z[i])
print(prime)
Problem3()
You're just a bit off. for-loops in Python iterate an object and return it's entities, not a pointer/ index.
So just use the thing you get from each iteration of 'z'
(Side note: might want to check out this post, it'll help you make your is_prime function more performant)
def is_prime(n):
for i in range(3, n):
if n % i == 0:
return False
return True
def Problem3():
x = 144
n = 2
not_a_factor = []
z = []
prime = []
not_a_prime = []
while n < x:
if x%n == 0:
z.append(n)
else:
not_a_factor.append(n)
n =+ 1 # Python version of n++
for i in z: # Python for-loop is more like a say "for each", no need for the indexing
if is_prime(i): # no need for '=='; Python will 'truthify' your object
prime.append(i)
else:
not_a_prime.append(i)
print(prime)
Problem3()
"list index out of range - what does this mean?"
The message list index out of range refers to an IndexError. Basically, this means that you are attempting to refer to an index in a list that doesn't exist.
Using your code as an example: you generate a list, z, containing the factors of the number 144. You then iterate through each element in this list (for i in z:). This means that for the:
1st iteration: i is the 1st element in z, which is 2;
2nd iteration: i is the 2nd element in z, which is 3;
and so on.
Then, you attempt if isprime(z[i]) == True:. So, as written, your program works like this:
1st iteration: if isprime(z[2]) == True:;
2nd iteration: if isprime(z[3]) == True:;
...
8th iteration: if isprime(z[16]) == True:
At this point, your code prompts an IndexError, because there are only 13 elements in z.
"what is wrong with my code?"
One way to get the result that you want is to iterate through range(len(z)) instead of each element of z. So, adjust the line for i in z to for i in range(len(z)).
Additionally, since prime is a list, and you want to return the greatest prime factor, change print(prime) to print(max(prime)).
These two changes will give you the result you are looking for.
Additional Learnings
Overall, your program could be written much more efficiently. If you want a simple algorithm to determine the greatest prime factor of a number, here is one possibility:
def greatest_prime_factor(n):
greatest_prime = 1
for i in range(n + 1):
# iterate through range(n). We skip index 0.
if i == 0:
continue
# determine if the number i is a factor of n.
if n % i == 0:
# determine if the number i is prime.
for i_ in range(2,i):
if i % i_ == 0:
break
else:
# update greatest_prime.
greatest_prime = max(greatest_prime, i)
return greatest_prime
print (greatest_prime_factor(144))
This algorithm saves a lot of memory space when compared with your original program by not initializing lists to store numbers that are primes, that aren't primes, etc. If you want to store those values, that's up to you; there are just far more efficient possibilities for what you appear to want to achieve.
Check this link for some more info on algorithmic efficiency and how to think about time and space complexity.