Getting started with python, cannot get iterator working - python

I have the following code, and I am trying to find the largest prime factor of the number that is square rooted in variable a. When I do some print testing, it doesn't seem my iterator is increasing. The code just runs infinitely it seems. Any tips? Am I missing a point where this becomes an infinite loop?
import math
a = math.sqrt(600851475143)
primefactors = [0]
i=1
while i<=a:
if a%i == 0:
if i%2 != 0 and i%3 != 0 and i%4 != 0 and i%5 != 0 and i%6 != 0 and i%7 != 0 and i%8 != 0 and i%9 != 0:
primefactors.append(i)
print(primefactors)
i=i+1
edit: just realized my mistake of using a as both upper-bound and the test value. Thank you for all the answers!

a is 775146.099225, so a%i==0 is never true, so even if your iterator worked (and it is working for me), you won't get anything added to prime factors.

The first thing I would try is printing out your i variable at the end of the loop after you increment and make sure it increments.
Your programs should loop 775146 times. This could possible take some time. I would try it with a smaller number first and then see what happens.

Related

Need help properly executing a "break" statement in python

I have some code which gives me the answer I want, but I'm having trouble stopping it once I get the
answer I want.
Here's my code:
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
This is an attempt at solving problem 5 of Project Euler. Essentially, I'm supposed to get the smallest multiple of all the digits within a given range.
Now, when i run the above code using the example given (1-10 should yield 2520 as the smallest multiple), i get the answer right. However, the code continues to run infinitely and print the answer without breaking. Also, the moment I add the break statement to the end like so:
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
break
The code just keeps spamming the number 30. Any ideas why this is happening. For the record, I'm not really looking for an alternative solution to this question (the goal is to learn after all), but those are welcome. What I want to know most of all is where I went wrong.
You never break out of your while loop. The for is the entire while body. break interrupts only the innermost loop; you have no mechanism to leave the while loop. Note that your continue doesn't do anything; it applies to the for loop, which is about to continue, anyway, since that's the last statement in the loop (in that control flow).
I can't really suggest a repair for this, since it's not clear how you expect this to solve the stated problem. In general, though, I think that you're a little confused: you use one loop to control n and the other to step through divisors, but you haven't properly tracked your algorithm to your code.
One way to deal with this is to have an exception. At best a custom one.
multiples = range(1,10)
n = 1
class MyBreak(Exception):
pass
while n>0:
try:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
raise MyBreak()
except MyBreak:
# now you are free :)
break
With this brake you stop only for loop, to exit whole cycle you should create trigger variable, for example:
multiples = range(1,10)
n = 1
tg = 0
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
tg = 1
break
if tg != 0:
break
Or it'll be better to use a function and stop a cycle by return:
def func():
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
return n

Can you tell me how to use a for loop in my code?

def get_odds(first=0, stop=10, step=1):
number = first
while number % 2 == 1:
yield number
number += step
for i in range(1,10):
third_value = get_odds[4]
number = third_value
print(third_value)
I want to return the odd numbers from range(10), so that's why I coded like this. But now, I want to know 'How to use for loop to find and print the third value returned'.
Use list-comprehension
odd_list = [x for x in range(0,11) if x%2 != 0]
or use recursion,
or use a state machine (just kidding,but it can be done)
best suggestion?
google it.
If your aim is to use a generator function to find the odd numbers in the range from 0 to 10 and you need to use a 'for' statement in it, and you need to be able to state the third odd value, then I think this is what you are after. But none of the answers given by me or the Stack Overflow respondents will do you any good until you understand why they work. (Comprehension is its own thing, and is not the same thing as a generator function.) This is a great opportunity to learn. Study them all until you know why they work, how to write your own, -and- why your code did not work. Good luck with this Hojin. And have fun!
def get_odds(first=0, stop=10, step=1):
number = first
for x in range(first, stop, step):
number += step
if number %2:
yield number
numbers = []
print("The odd numbers in the range from 0 to 10 are:")
for num in get_odds():
print(num)
numbers.append(num)
print("-"*25)
print("The third odd number is "+str(numbers[2])+".\n") #(Computers count from 0)
list comprehension is your best bet
>>> [ i for i in range(10) if i%2 !=0][4]
9
This expression returns the 3rd element in a list between the numbers 0 and 10 that are not divisible by 2.
My Answer : [ i for i in range(1,10) if i%2 !=0][4]

Finding fault in this recursive list addition in python

I need to create a program that takes in an array of numbers, check if each number is greater than the sum of all previous numbers, and output true if the condition is met, and false, if not. My trial is presented below:
import fileinput
a0 = [int(i) for i in fileinput.input()]
a = a0[1:]
b=[]
for i in range(1, a0[0]+1):
b.append(a[i])
if (a[i+1] > sum(b)):
print("true")
break
else:
print ("false")
break
My program works for half of the test cases but fails for the other test. Could you please help me figure out what i am doing wrongly. Many thanks for your assistance.
You are breaking too early in the true case. Only because the first element checks, doesn't mean all others will, too:
for i in range(1, a0[0]+1):
b.append(a[i])
if (a[i+1] <= sum(b)):
print ("false")
break
else: # for-else: else is executed only if loop isn't `break`ed out of
print("true")
Only once the loop has finished without finding a counter example, you can be sure that it holds for the entire list.
A more concise of writing this, would be:
import fileinput
_, *a = (int(i) for i in fileinput.input())
s = 0 # just keep track of total
for num in a:
if (num <= s):
print("false")
break
s += num
else:
print("true")

Why does my code return 1 when the given number has more zeroes?

If you have another method that can help me I will appreciate your help, I tried my best to write a code that calculates the number of zeroes in a given number.
Here's the code I tried:
def zrc(n):
count=0
while n%10==0 and n!=0:
n=n%10
count=count+1
return count
print(zrc(2500))
it just gives 1 as output of the code, while it must print 2, but for numbers like 36, it gives 0 as output, what is the problem? I know there must be a problem with that while...
If n%10 is zero, n is zero in the next step, so the condition is always fulfilled after the first loop. You probably want to use // instead of %:
def zrc(n):
count = 0
while n%10 == 0 and n != 0:
n //= 10
count += 1
return count
while n%10==0 and n!=0:
n=n%10
See the above lines. If the condition in the while loop is true, n=n%10 line will be executed.
This line will make your n=0 no matter what. For example,
2500%10 = 0
25000%10 = 0
250000%10 = 0
So, there is no chance that your loop condition will be True during the second iteration, so no chance of increment count variable more than once.
So, no matter what is your n is, you always get the output 1.
In your code, Change this:
n=n%10
To this:
n=n/10
An alternative way, might help you.
from collections import Counter
def zrc(n):
valDict=Counter(str(n))
return valDict['0']
print(zrc(2500))

Printing primes less than 100?

I am new to programming and trying to write a program that prints primes less than 100. When I run my program I get an output that has most of the prime numbers, but I also have even numbers and random odd numbers. Here is my code:
a=1
while a<100:
if a%2 == 0:
a+=1
else:
for i in range(2,int(a**.5)+1):
if a%i != 0:
print a
a+=1
else:
a+=1
The first part of my code is meant to eliminate all even numbers (doesn't seem to fully work). I also don't fully understand the part of my code (for i in).
What exactly does the "for i in" part of the code do? What is 'i'?
How can I modify my code that it does accurately find all of the primes from 1-100?
Thanks in advance.
See the comments on your post to find out why your code doesn't work. I'm just here to fix your code.
First of all, make use of functions. They make code so much more readable. In this case, a function to check if a number is a prime would be a good idea.
from math import sqrt
def is_prime(number):
return all(number%i for i in range(2, int(sqrt(number))+1))
There isn't much left to do now - all you need is to count how many primes you've found, and a number that keeps growing:
primes= 0
number= 1
while primes<100:
if is_prime(number):
print number
primes+= 1
number+= 1 # or += 2 for more speed.
Suddenly it's very easy to read and debug, is it not?
I'm going to try to guide you without giving you any code to help you learn, you should probably start from scratch I think and make sure you know how each part of your code works.
Some things about primes, 1 isn't prime and 2 is so you should start with a=3 and print 2 immediately if you want to eliminate even numbers.
By doing that, you will then be able to just increment a by 2 rather than 1 as you're doing now and just skip over even numbers.
As you loop a to be less than 100, you need to check if each value of a is prime by making another loop with another variable that loops downward through all numbers that could possibly divide a (less than or equal to a's square root). If that variable divides a, then exit the inner loop and increment a, but if it makes it all the way to 1, then a is prime and you should print it, then increment a.
There's several things wrong with what you're doing here:
You don't find the first 100 primes, you find the primes less than 100 with while a < 100
You print a every time a is evenly divisble by i, and then increment a. But you've gotten ahead of yourself! a is prime only if it is not divisble by any value i, but you fail to keep track of whether it's failed for any i.
You add +1 to the range up to the square root of the number - but that's not necessary. The square root of the number is the largest number that could possibly be the smaller of two factors. You don't need to add 1 because that number is _bigger than the sqare root - in other words, if a is evenly divisble by sqrt(a)+1 , then a / (sqrt(a)+1) will be smaller than sqrt(a)+1 and therfore would have already been found.
You never print the list of primes you found; you print a every time you find a number that is not a factor ( primes have no factors other than one and themselves, so you're not printing prime numbers at all!)
This might get you thinking in the right direction:
a=0
primes = []
while len(primes) < 100:
a = a + 1
prime=True
maxfactor = int(a ** .5)
for i in primes:
if i == 1:
continue
if i > maxfactor:
break
if a % i == 0:
print a, " is not prime because it is evenly divisble by ", i
prime=False
break
if prime:
print "Prime number: ", a
primes.append(a)
for p in primes:
print p

Categories

Resources