Here's the code:
a = input()
b = map(int, raw_input().split())
maxcnt=1
for k in range(0,a):
cnt=1
j=k+1
while b[k]%b[j] == 0 or b[j]%b[k] == 0 :
cnt += 1
if maxcnt < cnt:
maxcnt = cnt
print maxcnt
While giving the list values, after giving the values separated with spaces, I press enter and it still keeps getting the input. What's the issue?
The statement b = map(int, raw_input().split()) is perfectly okay. The problem is that you are encountering an infinite loop in the later while part of your code. There should be some issue with the logic.
So, you are taking modulo of consecutive numbers in the list b ? So, an input like this:
b = [1,2,3,4]
will cause an infinite loop, since 1%2 == 0 or 2%1 ==0 => True. It is clearly an input dependent scenario.
Your code shows a while statement which does not change it's conditions while looping:
while (b[s] % b[j]) == 0 or
(b[j] % b[s]) == 0:
cnt += 1
As you can see here, cnt is not in the condition (b[s] % b[j]) == 0 or (b[j] % b[s]) == 0, therefore, it will just keep on incrementing cnt and will not stop.
What you see is an empty console (which you then thought meant it was asking for more input) which was actually just the while loop running continuously.
Related
We've been given a challenge to write a program that prints prime factors of an input number. We're given an outline: the program checks for factors of the original number; each such factor gets one point. Then, if that factor is prime, it gets another point. Each factor with two points gets printed.
Here's what I have so far.
print('Please enter a number')
x = int(input('Number:'))
a = int(0)
b = int(0)
c = int(1)
d = int(0)
counter = int(0)
while (a < x-1):
a = a + 1
counter = 0
if (x / a % 1 == 0):
b = a
counter = counter + 1
while(c < b - 1):
c = c + 1
if((b / c) % 1 != 0):
d = b
counter = counter + 1
if(counter == 2):
print(d)
With input of 15, I get 3 and 5, but also 15 (wrong). With 24, I get 3, 4, 6, 8, and 12; several of these are not prime.
I believe the issue lies somewhere in the innermost loop, but I can't pinpoint the problem.
At first the issue was I wasn't resetting the "counter", so future factors would exceed 2 "points" and nothing would print. I fixed that by resetting it before it enters the innermost loop, but sadly, that didn't fix the problem.
I've also tried getting rid of 'b' and 'd' and just using two variables to see if I was somehow overcomplicating it, but that didn't help either.
EDIT: Edited slightly for clarity.
Your first sentence was enough of a clue for me to unravel the rest of your posting. Your main problems are loop handling and logic of determining a prime factor.
In general, I see your program design as
Input target number
Find each factor of the number
For each factor, determine whether the factor is prime. If so, print it.
Now, let's look at the innermost loop:
while(c < b - 1):
c = c + 1
if((b / c) % 1 != 0):
d = b
counter = counter + 1
if(counter == 2):
print(d)
As a styling note, please explain why you are building for logic from while loops; this makes your program harder to read. Variable d does nothing for you. Also, your handling of counter is an extra complication: any time you determine that b is a prime number, then simply print it.
The main problem is your logical decision point: you look for factors of b. However, rather than waiting until you know b is prime, you print it as soon as you discover any smaller number that doesn't divide b. Since b-1 is rarely a factor of b (only when b=2), then you will erroneously identify any b value as a prime number.
Instead, you have to wait until you have tried all possible factors. Something like this:
is_prime = True
for c in range(2, b):
if b % c == 0:
is_prime = False
break
if is_prime:
print(b)
There are more "Pythonic" ways to do this, but I think that this is more within your current programming sophistication. If it's necessary to fulfill your assignment, you can add a point only when you've found no factors, and then check the count after you leave the for loop.
Can you take it from there?
I'm not entirely sure I follow you're problem description, but here is my attempt at interpreting it as best I can:
import math
def is_factor(n,m):
return m % n == 0
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))
def assign_points(n):
for i in range(1,n+1):
if is_factor(i,n) and is_prime(i):
print('two points for: ', i)
elif is_factor(i,n):
print('one point for: ', i)
print(assign_points(15))
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
def fibonacci(n):
first = 0
second = 1
count = 0
while count <= n:
if (second % 2 == 0):
first, second = second, first + second
count += 1
return first, second
print (fibonacci(4000000))
Can somebody please explain what is wrong with this code? In IDLE the page restarts but returns no answer. By the way, I'm a beginner programmer, only just finished the CodeAcademy course.
Since this is for Problem 2 of Project Euler, you're computing the wrong values. It asks for the sum of all even Fibonacci numbers up to a value of four million, not the four millionth value. That would be too large.
Since we want to keep generating values, we'll use a generator and combine it with itertools.takewhile(). Then we'll filter() it down to the even values, and find the sum().
import itertools
def fibonacci_gen():
first = 0
second = 1
while 1:
first, second = second, first + second
yield second
>>> a = fibonacci_gen()
>>> sum(filter(lambda y: not y%2, itertools.takewhile(lambda x: x<=4e6, a)))
4613732
For a solution that doesn't use these features:
def fibonacci_4m():
result = 0
first = 0
second = 1
while second <= 4e6:
first, second = second, first + second
if not second%2:
result += second
return result
>>> fibonacci_4m()
4613732
second % 2 starts off as 1, which is not odd. Consequently your while loop doesn't run anything in the body, so the loop runs forever.
You probably want to always compute the next Fibonacci number, but only increment the count if the second is even.
Your problem is that you have your count variable inside the if statement. You have created an infinite while loop. Move it outside of the if statement:
if(second % 2 == 0):
first, second = second, first + second
count +=1
Also you will have to add more code to make this work properly.
In your while loop, nothing changes when the if statement fails to execute its conditional code. Try the following instead:
def main():
for index in range(1, 41):
print('even_fibonacci({}) = {}'.format(index, even_fibonacci(index)))
def even_fibonacci(index):
for number in all_fibonacci():
if not number & 1:
index -= 1
if not index:
return number
def all_fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
if __name__ == '__main__':
main()
I know I'm missing something really simple here....but I cannot put my finger on it.
My code is trying to find divisors for the items in "numbers". When count reaches 10 I know I have found the first item in numbers which has 10 divisors...but I cannot see to exit the loop. It just keeps printing the items in numbers that have 10 or more divisors.
I thought it was the indent, but no. I then moved the counter inside the first for loop to see if that was it, and still nothing.
numbers = []
numbers = [i for i in range(1, 100)]
for i in range(1, 100):
test = sum(numbers[0:i])
count = 0
for j in range(1, test+1):
if test % j == 0:
count +=1
if count == 10:
print test
break
Suggestions?
break breaks only the inner-most for loop. You need to check for count == 10 after that as well:
for i in range(1, 100):
test = sum(numbers[0:i])
count = 0
for j in range(1, test+1):
if test % j == 0:
count +=1
if count == 10:
print test
break # Breaks for j but not for i
if count == 10:
break # Breaks for i
You have to exit both for loops. There are two options:
1) Put the code in a function and use return instead of break
def process_something():
for a in items:
for b in other_items:
if some_condition:
return
2) Use a helper variable to detect that the outer loop should break too:
for a in items:
done = False
for b in other_items:
if some_condition:
done = True
break
if done:
break
In your case, you can use if count == 10: instead of if done: but I don't like duplicating "application logic" (DRY principle), so count == 10 should be in code only once. But this is a matter of taste.
3) Wrap the outer loop in a try:/catch ...: and raise exception instead of break, but please don't do this.
I've been learning python for about a week now, and I tried my hand at creating the binary search function:
def bin_srch(a, b, c, d):
l_c = map(int, c.split(" "))
l_d = map(int, d.split(" "))
for n in l_d:
if n <= l_c[a/2]:
for j in l_c[0:(a/2)+1]:
if j == n:
print l_c.index(j)+1,
elif n not in l_c[0:(a/2)+1]:
print -1,
elif n > l_c[a/2]:
for j in l_c[a/2:a]:
if j == n:
print l_c.index(j)+1,
elif n not in l_c[a/2:a]:
print -1,
However, when I test the function with some input:
bin_srch(5,6,
"10 30 50 60 70",
"60 10 50 10 5")
yields 4 1 3 1 -1 -1 -1 instead of 4 1 3 1 -1. Can anybody explain this?
While I don't really understand what you're code is supposed to be doing, I'm pretty sure I know the problem:
for j in l_c[0:(a/2)+1]:
if j == n:
print l_c.index(j)+1,
elif n not in l_c[0:(a/2)+1]:
print -1,
So, for each value, if it's a match, print the match (and keep looking); otherwise, check it against of the same values you're already looping over (and are going to continue to loop over) and if it's not found, print -1. So, if something isn't a match, you're going to print -1 multiple times.
What you probably want is:
for j in l_c[0:(a/2)+1]:
if j == n:
print l_c.index(j)+1,
break
else:
print -1,
At least this gives the desired output for this example. Why?
Well, the break means that as soon as you find a match, you stop going through the inner loop. The else—notice that it's attached to the for, not the if—runs if you finished the loop without ever break-ing. So, instead of checking for a match 3 times and printing -1 each time, you just check for a match 3 times and print -1 at the end, if you never found one.
(Actually, it looks like you could replace this whole loop with a list.index call, but I'll leave that up to you.)
Of course you have to make the same fix in the elif branch of your top-level if, because you have the same problem there.
Also, as a side note, if you write if n <= l_c[a/2]:, you don't need elif n > l_c[a/2]: Just use else; you already know that it's not true that n <= l_c[a/2] or you wouldn't have gotten here, therefore it must be true that n < l_c[a/2], so you don't need to check it.