Breaking a number to primes - Why does this code never stop? - python

def breaktoprimes(x):
primefactors = []
if x==1:
primefactors.append(1)
y=1
while y<=x or x!=1:
if(x%y==0):
primefactors.append(y)
x=x/y
y=1
else:
y=y+1
return primefactors
So basically what i am trying to do with this, is to fill the list "primefactors" with the prime factors of x. However, no matter what i enter, the code just runs and runs, and after some time, returns with this error:
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
breaktoprimes(15)
File "<pyshell#35>", line 8, in breaktoprimes
primefactors.append(y)
MemoryError
Basically what i intended the code to do is:
While y is smaller or equal to x and while x is not equal to one, which it should always apply to unless you enter a smaller number than 1 or x got divided by itself, in either case we are finished, we go on
test if the division of x by y results in the remainder of 0. If it does, y is sure to be a prime factor of x since y is not bigger than x and, y can't be a multiplication of a prime since we have tested the smaller numbers already.
If that didin't work, we add 1 to the value of y and try again
I have searched the web, but the solutions to this problem i have found are very different, so i haven't found any help in them. I have no idea where the problem in this code lies. I am a beginner in python with c# background and have coded for about a year now.
Thanks for reading!

All numbers are divisible by 1. Choosing 1 as an initival value for y is not good choice.
Reset y to 1 should be gone (same reason for 1)
def breaktoprimes(x):
primefactors = []
if x == 1:
primefactors.append(1)
y = 2
while y <= x or x != 1:
if x % y == 0:
primefactors.append(y)
x = x / y
else:
y = y + 1
return primefactors

If x=1 and y=1 then y<=x or x!=1 is true, and x=x/y sets x to 1, so both x and y will continue to be 1 and the loop will run forever.

In this part of the code:
y=1
while y<=x or x!=1:
if(x%y==0):
primefactors.append(y)
x=x/y
y=1
x%y is 0. Then y becomes 1 again. So the loop continues.

The problem is your x and y values are always remaining the same. So due to this your code runs in infinite loop.

Related

Python While Loop Square

I am a beginner at Python and I'm trying to use a while loop to sum up all of the squared n values in a given n value range.
Code:
def problem2(n):
x = 0
y = 0
while x < n:
y = (n**2)+y
x+=1
return y
For some reason, this equation returns the input number cubed.
Can someone explain why this happens and how to fix it?
You need to perform the ** on x, the value that is being incremented:
def problem2(n):
x = 0
count = 0
while x < n:
count += pow(x, 2)
x += 1
return count
You keep squaring the same number n, instead of the one being incremented x.
def sum_of_squares(n):
sum = 0
for x in range(0, n):
sum += x*x
return sum
You also don't really need the while loop, avoiding having to manually keep track of which variable is the counting variable and which one is the result variable (which is what you are confusing, as explained e.g. by #Ajax1234 in their answer).
It is a lot more Pythonic to use the built-in function sum, a generator expression and range:
def problem2(n):
return sum(x**2 for x in range(n))
This would be a lot more readable and better (unless of course you are being forced to use while).
Looks good. You're almost there.
It makes it the cube root because you add y to (n**2) everytime. Because you code runs until x !< n it runs n times. That means that you add n**2 to n**2*n.
That means that it gives 1(n**2)*(n-1)(n**2) which equals n(n**2) = n**3
Hope this was clear enough.

Python program Query

This is a question from John Guttag's book Introduction to Computation and Programming Using Python
Write a program that prints out the greatest odd number out of three numbers and an alternate error message if none of the numbers are odd.
This is my program. Is it correct? Does it cover all possibilities? I tried thinking it this way - exhaust all possibilities for the 3 statements - x is the largest, y is the largest and z is the largest - one by one. Is it the correct approach? Anyway, this is my program.
if ((x>y and x>z) or (x>y and x<z and z%2==0) or (x>z and x<y and
y%2==0) or (x<z and x<y and y%2==0 and z%2==0)) and x%2!=0:
print(x)
elif (y>z and y%2!=0) or (y<z and z%2==0)
print(y)
elif z%2!=0:
print(z)
else:
print('None of the numbers are odd')
Three simple steps:
Filter the list
Check if empty
Get max
filtered_list = filter(lambda x:x%2!=0, [x, y, z])
if filtered_list:
print max(filtered_list)
else:
print "No Odd number given"
It's almost correct
You are very close but you've forgotten a condition for when x is not printed and y and z are both even. Try the example of (4,2,6) for (x,y,z). Your exhaustive reasoning makes sense, but it is hard to program like this. I want to walk through your current logic then show how your code can be simplified, but your approach is clear using only if-else and indentation.
Your logic
In your logic you check all possibilities where you would ever print x which is if any following are true so long as x is odd:
x is the largest of x, y, and z
x is bigger than y when z is even
x is bigger than z when y is even
y and z are even
Then in the first elif you test whether to print y and make the correct decision to no longer check x at all since the first if handled all the cases where you would want to print x.
This is where your mistake is, however, since you should keep the same logical structure as your if statement for x:
elif ((y>z) or (y<z and z%2==0)) and y%2!=0:
You do the same for z in the last elif and then use else if all are even.
Simplifying your logic
We can simplify the first if statement where you check for x. One small note is that it is better to check that x is odd before doing all the or checks, since if x is even the computer doesn't have to look at all the or logic (short-circuiting):
if x%2 != 0 and ((x>y and x>z) or (x>y and x<z and z%2==0) or (x>z and x<y and
y%2==0) or (x<z and x<y and y%2==0 and z%2==0)):
Next the or logic can be simplified to:
if x%2 != 0 and ((x>=y and x>=z) or (x>=y and z%2==0) or (x>=z and
y%2==0) or (y%2==0 and z%2==0)):
All the simplifications came from the idea that if y or z is even we don't need to compare it to x since we'd want to print x regardless. I've also changed the > to >= or you would have had errors if some of the variables had the same values.
With the same reasoning we can simplify the first elif to:
elif ((y>=z) or (z%2==0)) and y%2!=0:
Bonus
If we know x, y, and z are not negative you can do this little trick. Try to work it out, leave a comment if you have questions or figure out how to make it work with negatives.
x = x*(x%2)
y = y*(y%2)
z = z*(z%2)
if x+y+z == 0:
print('None of the numbers are odd')
elif x >= y and x >= z:
print(x)
elif y >= x and y >= z:
print(y)
elif z >= x and z >= y:
print(z)
This is the Efficient code for finding whether the given number is odd or not.
Here I used '&' (and bitwise operator) which do bitwise and with one .
let the number 5(00000101)
when we do 5 & 1 then it will do (00000101) & (00000001) = (00000001).
This will happen with all other odd numbers.
ip = []
ip = map(int,raw_input().split())
odds = filter(lambda x : x & 1 != 0 , ip)
if len(odds) > 0 :
print (max(odds))
else :
print ("None of the numbers are odd")

How can I fix this algorithm?

I am trying to create a function in Python. This function should be able to create a list of whole numbers less than or equal to the number provided. I've created an empty list, a variable called y and a while loop. In this while loop, as long as y <= x, the results of the subsequent equations are appended to the empty list, and y increments by 1. However, when I call this function, I get a list with only one element. How can I fix this?
def fff(x):
numbers = []
y = 2
while(y <= x):
x = x - (x - y)
numbers.append(x)
y += 1
return numbers
>>> fff(10)
[2]
That function already exists, more or less.
Python 2
def fff(x):
return range(1,x+1)
Python 3
def fff(x):
return list(range(1,x+1))
If you look at this line x = x - (x - y) and think of your inputs, you will see the problem. if x initially equals 10, then x - (x - y) equals 2, and y will equal 3, therefore breaking out of your loop.
If you are trying to mimic the range function then this is how you would do it:
def fff(x):
numbers = []
y = 1
while(y <= x):
numbers.append(y)
y += 1
return numbers

Python: List all prime numbers that exist before an input number [duplicate]

This question already has answers here:
Fastest way to list all primes below N
(39 answers)
Closed 9 years ago.
n= int(raw_input("Number? "))
for x in range (2, n+1):
for y in range (2, x+1):
if x < n+1 and x % 2.0 > 0 and x % 3.0 > 0 and x%y > 0:
print x
x = x + 1
Hello there. I need to create a SIMPLE python program, which lists all the prime numbers up to and inclusive of the input number. For example, if you input 10, it would produce 2, 3, 5 ,7
I'd prefer to keep it simple, and do not use more advanced functions such as def, break. Nested loops are PREFERED.
The code above does NOT work, it contains non-primes such as 25 and 91.
Please help!
Your code concludes that a number x is prime if it's not divisible by at least one y, whereas it needs to check that it's not divisible by all y.
You also need to carefully check the bounds of the y loop.
On a side note, I suggest you get rid of the floating-point calculations (e.g. x % 2.0) and stick to integer maths. It probably doesn't matter here, but has the potential of opening a large can of worms.
You must reverse your thinking. Your code reports a number as soon as it is a non-multiple of some y. Instead, you should non-report a number as soon as it is a multiple of some y.
n= int(raw_input("Number? "))
for x in range (2, n + 1):
prime= True
for y in range (2, x):
if x % y == 0:
prime= False
if prime:
print x

Can't figure out how to use all() to work in my "code"

m = range(1, 2000000, 2)
sum1 = 2
for x in xrange(1, 2000000, 2):
for y in m:
if x != y:
if x%y == 0:
m.remove(x)
if all(x%y != 0):
sum1 += x
That's what I've written. It's about a problem, trying to add all the primes bellow two million. My problem is in the all() statement. What I want to happen is to check if x is a prime; that is true only if every x%y gives a remainder.
Also if I use a can I use a statement (break?) to stop the loop if y > x/3 like so:
m = range(1, 2000000, 2)
sum1 = 2
for x in xrange(1, 2000000, 2):
for y in m:
if y > x/3:
break
else:
if x != y:
if x%y == 0:
m.remove(x)
if all(x%y != 0):
sum1 += x
You have to pass a sequence or iterable to all -- it just tests whether or not all the items passed to it evaluate as true. Here's the right way to use all:
>>> all([True, True, True])
True
>>> all([True, False, True])
False
>>> all([x > 5 for x in range(10)])
False
>>> all([x > 5 for x in range(6, 10)])
True
>>> all(x > 5 for x in range(6, 10))
True
That last one is the best, because it takes advantage of short-circuiting.
However, your call to all in your code is pointless. The idea behind your code, it seems to me, is to go through all the values in m and remove those that are divisible by any number between 2 and 2000000. Once you've done that, m will contain only prime numbers.
Of course, your code still won't work if you remove all. That's because you're actually testing whether each number in m is divisible by the numbers [1, 3, 5, 7...1999999]. (That's the sequence signified by xrange(1, 2000000, 2). Because you start at 1, and everything is divisible by 1, your code will count nothing as prime. And then, once you remove 1 from that sequence, anything divisible by 2 will be counted as prime by your code! You should think more carefully about which numbers you actually have to test in your inner loop.
Finally, you should think about how many loops this code will complete. Even once you have this working, it will take a very long time to generate a result. You should test it on smaller numbers first; and then, you should think about how to reduce the number of loops. (And -- only after you've thought about it a bit -- read this.)
But once you have this working, all you have to do is call sum on your list of primes.
Your use of all is incorrect, if you look at the documentation for it, it takes an iterable.
What you may be trying to do is use a generator expression, something of the form:
sum(x**2 for x in range(10))
which is very similar to the list comprehension
[x**2 for x in range(10)]
However, use of all in this manner wouldn't suddenly stop the generator expression, if it found a divisor. Use of any and checking for x == 0 would stop sooner, but as the code is currently formatted, would check for many divisors before deeming something prime.
This would be more appropriate:
primes = []
MAX = 2000000
number = 2
while number < MAX:
for prime in primes:
if number % prime == 0:
number += 1
continue
primes.append(number)
number += 1
total = sum(primes)
all() takes an iterable for an argument. In your situation, you would use it like this:
all(x%y for y in m)
where x%y for y in m is a generator expression.
If I have an iterable
[item1, item2, item3, item4...]
all(iterable) is equivalent to:
item1 and item2 and item3 and item4...'

Categories

Resources