0

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))
Stef
  • 13,242
  • 2
  • 17
  • 28
  • I'm sorry, but I don't see any code. Please update your question with the text of your code. – quamrana Dec 01 '20 at 10:10
  • please include a [minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) which isnt a picture – an inconspicuous semicolon Dec 01 '20 at 10:12
  • i have added the code plz help – ashish sony Dec 01 '20 at 10:14
  • What's the question? You posted some code. OK. What's wrong with this code? What do you need help with? Is there an error? What's the error? Please include all the relevant information in the question. – Stef Dec 01 '20 at 10:15
  • 4
    Note 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:`. – Stef Dec 01 '20 at 10:16
  • Also please update your question with some sample inputs and the expected outputs. – quamrana Dec 01 '20 at 10:18

2 Answers2

1

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)))
Stef
  • 13,242
  • 2
  • 17
  • 28
  • Thank you for the solution . now i got the desired output – ashish sony Dec 01 '20 at 10:58
  • i tried with break instead of return 0 to come out of the loop , but i get and error "SyntaxError: 'break' outside loop" if (n == 0): break – ashish sony Dec 01 '20 at 15:01
  • @ashishsony The keyword `break` is used to interrupt `for`-loops and `while`-loops. These loops are easily recognized by the use of the keywords `for` or `while`. Your code doesn't contain such a loop. What you want is to *return from a function*, not to *break out of a `while`/`for`-loop*. – Stef Dec 01 '20 at 15:06
-1

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)
majortobi
  • 3
  • 3