I'm relatively new to Python and I decided to try and code a relatively simple collatz conjecture where the user enters a number (integer). The code is just a simple function that calls itself. i is a list that should have every number that the function calculates appended to it. I'm new to executing Python scripts and I have tried using the IDLE shell to run the code. It asks me what number I want but when I enter a number nothing is printed? I'm sure I just need to edit a small bit of this code (or maybe it's all wrong yikes) but does anybody have any idea why my script returns nothing? Sorry about this and thanks.
Here's the code:
l = input("Enter a number: ")
l = int(l)
i = []
def collatz(n):
if n==1:
return i
if n%2 == 0:
n = n/2
i.append(n)
return collatz(n)
else:
n = ((n*3) + 1) / 2
i.append(n)
return collatz(n)
print(i)
collatz(l)
There are three returns before your print and one of them is inside an else statement, which means that at least one of them will be executed, so your print won't even be reached to be executed, you should move it right after the function definition to see something:
def collatz(n):
print(i) # <= print here
if n==1:
....
See more about the return statement. A snippet:
return leaves the current function call with the expression list (or None) as return value.
As others have mentioned, all of the execution paths in your function end in a return statement, so that print call is unreachable. So if you want each value of n or i to be printed you need to move the call to somewhere that it will be reachable. ;)
Also, there's a little bit of redundancy in that code. You don't need
i.append(n)
return collatz(n)
in both the if and else branches, you can move them outside the if...else block.
Here's a modified version of your code. I've also changed the / operators to // so that the results of the divisions will be integers.
i = []
def collatz(n):
print(n)
if n==1:
return i
if n%2 == 0:
n = n // 2
else:
n = ((n*3) + 1) // 2
i.append(n)
return collatz(n)
# Test
print(collatz(12))
output
12
6
3
5
8
4
2
1
[6, 3, 5, 8, 4, 2, 1]
Related
def main():
n = int(input().strip())
a = list(map(int, input().rstrip().split()))
b = list(map(int, input().rstrip().split()))
a.sort()
b.sort()
total=0
i=0
j=0
while i!=len(a):
while j!=len(b):
# print('a[i]', a[i],'b[j]',b[j])
if a[i]<b[j]:
# print('in a[i]<b[j]')
i+=1
break
if a[i]==b[j]:
total+=1
i+=1
j+=1
# print('total is ',total)
break
else:
# print('in else')
j+=1
if total==n:
print(n)
else:
print(total+1)
main()
Input:
4
1 2 3 4
1 2 3 3
The program keeps asking for input even after i press the "enter" button on my keyboard. while for other types of input it works perfectly fine
Your program is not taking any more inputs, it just runs in an infinite loop in your while statement because of the last digits of a and b namely 4 and 3.
For the first 3 digits 1 2 3, the value of i and j are both 3.
Then while comparing the last digits 4 and 3, it isn't True for this
if a[i]<b[j]:
Nor this
if a[i]==b[j]:
Thus it executed else which only increments j making i=3 and j=4.
Now you're stuck because it will never go inside the inner while loop (since j is already 4) which means it will never increment i again thus will never reach the length of 4.
while i!=len(a):
while j!=len(b):
Want proof? switch your inputs for a and b
1
1 2 3 3
1 2 3 4
def getInput(n): #another method.
a = list()
for x in range(n):
a.append(input().rstrip().split())
return a
def main():
n = int(input().strip())
a = getInput(n)
b = getInput(n)
a.sort()
b.sort()
total=0
i=0
j=0
while i!=len(a):
while j!=len(b):
# print('a[i]', a[i],'b[j]',b[j])
if a[i]<b[j]:
# print('in a[i]<b[j]')
i+=1
break
if a[i]==b[j]:
total+=1
i+=1
j+=1
# print('total is ',total)
break
else:
# print('in else')
j+=1
if total==n:
print(n)
else:
print(total+1)
main()
The first problem is that your question is quite imprecise. You've said it stops taking input but have also expressed the idea that it runs infinitely. These cannot both be true given what we have here.
The problem with getting input was that you called map() with int and list().rstrip().split(), as 1st and 2nd arguments when the Python library states that the function requires the method you want to call as 1st arg and the 2nd must be an iterable, or a collection as per:
https://docs.python.org/3/library/functions.html#map
So if you wanted to use map() you also needed to have a list full of items because map() uses the provided function on each value in the given list. in other words: you needed data to run map() on prior to calling it.
I am assuming that you're implementing an algorithm and the print()'s executed properly when I ran it with them uncommented. My solution above should at least allow you to get back to developing your algorithm.
I simply deferred the call to a method defined called getInput() which takes the number of values to take (n) and returns the list of them retrieved from the input.
I am trying to write code to find whether a given number is odd or even using recursion in Python.
When I execute my code, the recursive function descends down to 0 correctly but then doesn't halt, and keeps going with negative values. I expect it to stop when it reaches 0.
How to make sure the function returns after it reaches zero?
My code:
def odeven(n):
if n%2 == 0:
print("even no. : ",n)
elif n%2 != 0:
print("odd no. : ",n)
elif (n == 0):
return 0
return odeven(n-1)
result = odeven(10)
print("result odd ={}".format(result))
Fixing the most obvious mistake
Your main issue is that the branch elif (n == 0): will never be reached because 0 is even, so 0 gets caught in the first branch if n%2 == 0:
You can fix it by changing the order of the branches:
def odeven(n):
if (n == 0):
return 0
elif n%2 == 0:
print("even no. : ",n)
else: # n%2 != 0
print("odd no. : ",n)
return odeven(n-1)
result = odeven(10)
print("result odd ={}".format(result))
Output:
even no. : 10
odd no. : 9
even no. : 8
odd no. : 7
even no. : 6
odd no. : 5
even no. : 4
odd no. : 3
even no. : 2
odd no. : 1
result odd =0
Further improvements
You can figure out whether a number n is odd or even simply by checking the value of n % 2. There is no need for recursion here.
Presumably this is an exercise that was given by a teacher who wants you to use recursion to figure out whether n is odd or even without using %. This is terribly inefficient and has no use in practice, and is purely an exercise to learn about recursion. In that case, do not use %. Operator % solves the whole problem by itself so if you use it, you don't need to use recursion. It defeats the purpose of the exercise.
Compare the two following functions:
def oddeven_direct(n):
if (n % 2 == 0):
return 'even'
else:
return 'odd'
def oddeven_recursive(n):
if (n == 0):
return 'even'
elif (n == 1):
return 'odd'
elif (n > 1):
return oddeven_recursive(n-2)
elif (n < 0):
return oddeven_recursive(-n)
print(oddeven_direct(10))
print(oddeven_recursive(10))
Note that I did not call function print inside the function. The function returns a result, which is 'even' or 'odd', and doesn't print anything. This is more consistent. If the user calling the function wants to print something, they can call print themselves.
A variation
Notice how the recursive call jumped from n to n-2? This is because I know that n and n-2 will have the same parity (both odd or both even); and we have two base cases, 0 and 1, to which we're guaranteed to arrive when jumping 2 by 2.
If we had jumped from n to n-1 instead, we'd have run into an issue because n and n-1 have different parity (odd and even or even and odd), so we need some way to keep track of this change of parity during the recursion.
This can be achieved by implementing two distinct functions, is_odd and is_even, and using the recursion to express the facts "n is odd if n-1 is even" and "n is even if n-1 is odd".
Since those functions have names that sound like yes/no question, or true/false question, we will make them return True or False, which are called boolean values.
def is_odd(n):
if n == 0:
return False
else:
return is_even(n-1)
def is_even(n):
if n == 0:
return True
else:
return is_odd(n-1)
print('10 is even? {}'.format(is_even(10)))
print('10 is odd? {}'.format(is_odd(10)))
Note that python knows boolean values very well and we can make the code shorter using the two lazy logic operators and and or:
def is_odd(n):
return n != 0 and is_even(n-1)
def is_even(n):
return n == 0 or is_odd(n-1)
print('10 is even? {}'.format(is_even(10)))
print('10 is odd? {}'.format(is_odd(10)))
You get an error, because you call the function inside the function and never stop that function call so it recurses over and over again. Python allows recursion but only until a defined end is reached
To change this limit:
https://www.geeksforgeeks.org/python-handling-recursion-limit/
Also your recursion gets into minus, because you call your function attribute (= (n)) allways one number lower than the function call before:
Your function is now called with
odeven(9)
and so on until it reaches -985, which is in your case the maximum recursion depth which results in:
[Previous line repeated 992 more times]
File "/python/test.py", line 5, in odeven
print("odd no. : ",n)
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
I am trying to create a simple program to apply the statement of the Collatz Conjecture to an integer that the user can enter, I have:
def collatz(n):
print n,
if n % 2 ==0:
n = n / 2
elif n == 0:
Print "Collatz Conjecture true for" , 'n'
else:
n = n *3 + 1
input("\n\nInsert a positive integer:")
def collatz(n)
However it is saying there is a syntax error in the line:
Print "Collatz Conjecture true for" , 'n'
I can't see what mistake ther is in this line.
Also as I haven't been able to test it yet, does this look as though it will work ok?
Python is case sensitive. Use "print" not "Print".
Well, your syntax error is that python is case-sensitive, so you need print rather than Print.
But you've got more problems:
'n' prints the string n. I think what you want is n to print the value of the variable (or if not, then you can just make a single string "... true for n").
Finally (I think), in order to run the function collatz, you don't need the def; that's just for the definition.
More problems:
The stopping condition should be n == 1, not n == 0.
You have to recur or iterate, as is you're only making one step.
Check the input, make sure it really is a positive number.
def collatz_steps(n):
steps=0
if n==1:
return 0
else:
while n!=1:
if n%2==0:
n=n/2
steps+=1
else:
n = 3*n+1
steps+=1
return steps
I'm having trouble getting my list to return in my code. Instead of returning the list, it keeps returning None, but if I replace the return with print in the elif statement, it prints the list just fine. How can I repair this?
def makeChange2(amount, coinDenomination, listofcoins = None):
#makes a list of coins from an amount given by using a greedy algorithm
coinDenomination.sort()
#reverse the list to make the largest position 0 at all times
coinDenomination.reverse()
#assigns list
if listofcoins is None:
listofcoins = []
if amount >= coinDenomination[0]:
listofcoins = listofcoins + [coinDenomination[0]]
makeChange2((amount - coinDenomination[0]), coinDenomination, listofcoins)
elif amount == 0:
return listofcoins
else:
makeChange2(amount, coinDenomination[1:], listofcoins)
You're not returning the value of the recursive calls to makeChange2.
Once control reaches either of those calls to makeChange2 and completes the call, the program continues to the next statement, which is the end of the function; thus, it returns None.
If that concept is still giving you trouble, try running this simple factorial program with and without the return keyword in the return n*factorial(n-1) line:
def factorial(n):
if n == 0 or n == 1:
return 1
return n * factorial(n-1)
print factorial(3)
Manually walking through the code should help elucidate what was wrong in your original program.