Hey awesome python people,
Warning: I am new to coding. Ok, now that you have been warned...
I am trying to write a python file that finds the largest prime number of a variable I declare inside the code.
Here is my thought process:
Step 1:Find Factors of X
Step 2:Put factors of X in an array a
Step 3:Analyze last element of array a
Step 4:Check if last element of array a is Prime
Step 5: if last element of array a is prime print "found the largest prime" along with the number itself, else, analyze second to last element in array a, and so on until at a[1]
Step 6: if no prime numbers in array, print "no primes found"
The issue is somewhere in the last else statement, when dealing with x=28 and its factors in an array:
[1, 2, 4, 7, 14] my code thinks 7 is not a prime...
My steps are listed in-line:
#find factors, put them in an array a
#1.Find factors of X
#2.Put factors of X in an array a
x=28
i=1
a=[]
length = 0
while i<x:
if x%i == 0: #checks to see if X is divisible by anything between 1 and X-1
a.append(i) #adds factor to array a
i = i+1
print "your factors are: ", "\n", a
print "\n"
#3. Analyze the last element in array a
# Before loop below, a = [1, 2, 4, 7, 14] and length = 5
length = 0
length = len(a)
n=a[length-1]-1
print "checking for primes in your array now...", "\n"
while len(a) > 2:
if a[length-1]%n != 0:
n=n-1
if n == 1:
print "PRIME TIME"
break
else:
print a[length-1], "is not a prime" #added
del a[-1]
length = len(a)
print "length = ",length
if length == 2:
print "NO Primes"
A few questions:
How would you re-assign variables like x, i a[], and n to make the code more readable
In the second loop, after the first iteration, when analyzing 7 why does the code not recognize that it is a prime number?
Thanks so much for any constructive feedback!!
Ok, I would do it like this:
def primes(n):
primfac = []
d = 2
while d*d <= n:
while (n % d) == 0:
primfac.append(d)
n /= d
d += 1
if n > 1:
primfac.append(n)
return primfac
print "Factors: ", primes(28)
print "The largest is: ", max(primes(28))
First use the primes function which I took from here. It returns an array containing all prime factors.
Then, simply aply the max-function, which gives you the largest element of the array.
The output is as follows:
Factors: [2, 2, 7]
The largest is: 7
I hope this helps.
Related
sample.py
y = [2,3,4,5,6,7,8,9] # array
Function is created below
def _div(a): # Needed to create a function
z = 0 # constant
for x in range(1 , a +1): # To check for all the numbers within the range of a
while z < 8:
if x % y[z] != 0 : # To check if the value of x is divisible by any of the value in the array
j = [x]
Print (j[0])
z += 1
Calling function
div(15) # not showing any result on Python
end Python
Loop over all values in the range from 1 to the given number. For each value check if the modulo operation gives a value other than 0 for all divisors. If yes, add the value to the list.
Now we can write that down in Python code.
def _div(number, divisors):
result = []
for value in range(1, number + 1):
if all(value % divisor != 0 for divisor in divisors):
result.append(value)
return result
y = [2, 3, 4, 5, 6, 7, 8, 9]
print(_div(15, y))
This will give you [1, 11, 13].
There is a possible optimization. Instead of checking if the current value is not divisible by all divisors we can check if the value is divisible by any divisor. This will end the check (shortcut) when a matching divisor is found.
So replace
if all(value % divisor != 0 for divisor in divisors):
result.append(value)
with
if not any(value % divisor == 0 for divisor in divisors):
result.append(value)
I replaced the variable names in the function by more meaningful ones. The function itself would deserve a better name too. At least I added the list of divisors as a parameter because it's a bad idea to work with global states in a function.
With a list comprehension you could even make a one-liner out of this but I prefer the more readable multiline version.
def _div(number, divisors):
return [value for value in range(1, number + 1) if not any(value % divisor == 0 for divisor in divisors)]
def not_dividable_by(factor, quotient_list, unique_output=True):
"""
Args:
factor(int): All numbers from 0-factor are calculated
quotient_list(list): List of to test if factor is divisable with
unique_output(bool): Numbers may occur multiple times if False
Returns:
list: with integers of numbers not divisable by any of 0-factor
"""
result = []
for i in range(0, factor + 1):
for x in quotient_list:
if i % x:
if x not in result or not unique_output:
result.append(x)
return sorted(result) if unique_output else result
print(not_dividable_by(15, [2,3,4,5,6,7,8,9]))
But most of the times the output will be all numbers in the list.
I am trying to find the largest prime number in a list (ascending order). I created a while-loop which checks if a number in the list is prime by dividing it by each number less than itself and 'breaking' the loop when it finds a number that has no factor less than itself (greater than 1). This loop is nested in another while-loop which iterates backward through the list.
When I run the code, it keeps returning the number 8 (which is obviously not prime).
I have tried going through the code step-by-step on paper, inserting the variable values and doing the math. I must be miscalculating something.
factors = [2, 3, 4, 6, 8]
b = 1
y = len(factors) - 1
x = factors[y]
z = x - b
while y >= 0:
while b < x:
if x % z == 0:
break
else:
if b == x-1:
print(f'The number {x} is the largest prime in the list')
break #need to end the outer loop here
else:
b +=1
y -= 1
b = 1
print('There were no prime numbers in the list')
I expect the code to return 'The number 3 is the largest prime in the list'
What it actually returns:
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
A few main problems with your code:
You are not updating the values of x (outer loop) and z (inner loop) on each iteration. You will want to add for z:
else:
b += 1
z = x - b
and for x:
y -= 1
x = factors[y]
b = 1
The fact that you are having that many variables for that task makes it hard to read and understand. You could for example get rid of z all together and simply start b from 2 and go up.
Since both loops iterate over a known range (outer on the list, inner until x) it would be better to use for loops instead of while. That will also arrange your variables better. For example:
factors = [2, 3, 4, 6, 8]
for number in factors[::-1]:
for b in range(2, number):
if number % b == 0:
break
elif b == number-1:
print(f'The number {number} is the largest prime in the list')
break # you should put this whole code in a function and return here
print('There were no prime numbers in the list')
Notice that we don't use any other variables except the ones defined by the loops. That makes the code more readable.
The factors[::-1] means we are looping over the list in reverse order.
A nice little python feature is adding an else clause on a loop. This else will be executed only if the loop is exhausted without meeting any break statement. Which is perfect in our case because if the inner loop is exhausted, then the number is a prime for sure. So it can be:
factors = [2, 3, 4, 6, 8]
for number in factors[::-1]:
for b in range(2, number):
if number % b == 0:
break
else:
print(f'The number {number} is the largest prime in the list')
break # This now breaks the outer loop
else:
print('There were no prime numbers in the list')
Note the use of that same technique also in the outer-loop, as if the inner loop exhausted without hitting the break in the else block, it means no prime was found so we want to print the no-found message.
Can you check the below codes please?
def prime_numbers(numbers):
for i in numbers:
for j in range(2, i):
if i % j == 0:
break
else:
yield i
try:
print(f"{max(prime_numbers([2, 3, 5, 6, 8]))} is the largest prime number.")
except ValueError:
print("There are no prime numbers in the list.")
I have to write a function factor, which takes an integer parameter n, and returns the least number from 2 through n-1 that divides n. If no such number exists, it returns -1.
I was able to create the function to find the factors, but am unsure on how to refine it to return the correct result.
def factors(n):
i = n
lst=[]
while i > 0:
if n % i == 0:
lst.append(i)
i -= 1
print(lst)
result=[i for i in lst if i > 2 and i < n-1]
print(result[1])
def main():
n=int(input("Enter n:"))
factors(n)
main()
You can use list comprehension to find the factors of a number. Also, to optimize your solution, you only need to run until half of the number.
e.g. for 12, the maximum factor of 12 can be 6.
A number greater than half of that number can't be its factor. So, you do not require to run your loop until n-1.
>>> [n for n in range(2, number/2+1) if number % n == 0]
In the above line, we will run a loop from 2 to (number/2 + 1) and check if the number is divisible by n, then add it to the list.
Your factor function should look from the smallest value first, then start increasing
def factor(n):
i = 2
while i < n:
if n % i == 0:
return i
i += 1
return -1
>>> factor(6)
2
>>> factor(21)
3
>>> factor(49)
7
>>> factor(13)
-1
Then factors can call that
def factors(n):
values = [1]
while n > 1:
f = factor(n)
if f > -1:
values.append(f)
n //= f
else:
values.append(n)
break
return values
>>> factors(21)
[1, 3, 7]
You're doing a lot of unnecessary work here: you find all factors, instead of just the smallest. However, you do have a correct answer at your fingertips: you print the second element as the lowest factor, but your list is in the opposite order. Try
print lst[-2]
That said you really should not bother with all of that. Instead, start at 2 and work upward, looking for the smallest factor. If you get to sqrt(n) without finding any, return a result of -1.
Here is optimized way for finding factor of a number in between 2 or n-1:
def factor(n):
i=2
a=[]
while i*i<=n:
if n%i==0:
if i!=n/i:
a.append(i)
a.append(n/i)
else:
a.append(i)
i+=1
a.sort()
print a
n=int(input())
factor(n)
I'm having trouble with my code. The question is:
"By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10 001st prime number?"
This is what it looks like:
div = 10001
i = 2
count = 0
prime = 0
now = []
while count < div:
for x in range (2,i+1):
if len(now) ==2:
break
elif i%x == 0:
now.append(x)
if len(now)==1:
prime = i
count += 1
now = []
i+=1
print(prime)
I have tried div up to 1000 and it seems to work fine(for div 1000 I receive 7919). However, when I try div = 10001 I get nothing, not even errors. If someone would help me out I would really appreciate it.
Thank you.
# 7 10001st prime
import itertools
def is_prime(n):
for i in range(2, n//2 + 1):
if n % i == 0:
return False
else:
continue
return True
p = 0
for x in itertools.count(1):
if is_prime(x):
if p == 10001:
print(x)
break
p += 1
Try this code:
prime_list = lambda x:[i for i in xrange(2, x+1) if all([i%x for x in xrange(2, int(i**0.5+1))])][10000]
print prime_list(120000)
Lambda in Python defines an anonymous function and xrange is similar to range, defining a range of integer numbers. The code uses list comprehension and goes through the numbers twice up to the square root of the final number (thus i**0.5). Each number gets eliminated if it is a multiple of the number that's in the range count. You are left with a list of prime numbers in order. So, you just have to print out the number with the right index.
With just some simple modifications (and simplifications) to your code, you can compute the number you're looking for in 1/3 of a second. First, we only check up to the square root as #Hashman suggests. Next, we only test and divide by odd numbers, dealing with 2 as a special case up front. Finally, we toss the whole now array length logic and simply take advantage of Python's break logic:
limit = 10001
i = 3
count = 1
prime = 2
while count < limit:
for x in range(3, int(i ** 0.5) + 1, 2):
if i % x == 0:
break
else: # no break
prime = i
count += 1
i += 2
print(prime)
As before, this gives us 7919 for a limit of 1000 and it gives us 104743 for a limit of 10001. But this still is not as fast as a sieve.
m=0
n=None
s=1
while s<=10001:
for i in range(1,m):
if m%i==0:n=i
if n==1:print(m,'is prime',s);s+=1
m+=1
I am attempting to do Project Euler problem #2. Which is:
Each new term in the Fibonacci sequence is generated by adding the previous two
terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed
four million, find the sum of the even-valued terms.
However the terminal window hangs when I use the following code with 4000000. Smaller numbers run ok. Is there something about this code that is really inefficient, hence the lagginess?
n = int(raw_input("Enter the start number: "))
def fib_generator():
a, b = 0, 1
yield 0
while True:
a, b = b, a + b
yield a
def even_sum(fib_seq):
seq = []
seq = [next(fib_seq) for number in range(n)]
seq = [number for number in seq if number % 2 == 0]
return sum(seq)
def start():
fib = fib_generator()
even_sum = even_sum(fib)
print even_sum
start()
You have a bug. You're generating the first 4,000,000 Fibonacci numbers, but the problem statement only asks for those Fibonacci numbers whose values are not more than 4,000,000.
Since the Fibonacci numbers grow exponentially (Fn ~ 1.618n), you're generating some numbers with a very large number of digits (log10 Fn ~ n / 5) and that will take an immense amount of time.
Fix the bug, and you'll be okay.
You just need to add logic to stop when the next fibonacci number exceeds 4000000.
Also, I spy a potential problem with this line:
def start():
fib = fib_generator()
even_sum = even_sum(fib) #<--- right here
print even_sum
It isn't good to have a variable name the same as the function name.
Yes, there is something inefficient in your code, you load a very long list into memory twice, with your two seq = ... statements. Why not try one generator expression rather than two list comprehensions? Also, you could alter your Fibonacci generator to stop at a certain number:
def fib_generator(n):
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
def even_sum(fib_seq):
seq = (number for number in fib_seq if not number % 2)
return sum(seq)
def start():
n = int(raw_input('Enter max constraint: '))
fib_seq = fib_generator(n)
even_sum1 = even_sum(fib_seq)
print even_sum1
start()
This ran pretty fast for me
lst = []
num1 = 1
num2 = 2
sum = 0
jump = 0
next = 0
while next<4000000:
next = num1 + num2
if next<4000000:
if jump ==0:
num1 = next
jump = 1
else:
num2 = next
jump = 0
if next%2 == 0:
lst.append(next)
for item in lst:
sum+=item
print ''
print "Sum: ",
print sum