2

I am trying to create a function called "odd_even" which takes my already created list (named "nums") and determines the number of odd and even numbers, and then returns the variables to me. However when I run this code I get:

NameError: name 'odd' is not defined

How do I fix this? If you can give me any useful pointers on the "return" function that would also be greatly appreciated.

import random

def main():

     nums = []

     for x in range(10):

     nums.append(random.randrange(1,26))

     def odd_even(given_list):
         odd = 0
         even = 0
         for x in given_list:
             if x % 2 == 0:
                 even += 1
             else:
                 odd += 1

         return odd
         return even

     odd_even(nums)

     print("List had ", odd, "odds and ", even, "evens.")

 main()

2 Answers2

1

You are doing 2 things wrong.

First, you are trying to return two values but on different lines. You cant do this, to do this, do so as a tuple:

def odd_even(given_list):
     odd = 0
     even = 0
     for x in given_list:
         if x % 2 == 0:
             even += 1
         else:
             odd += 1

     return odd, even

Second, you call the function but dont store the value(s) of return. So you need change:

odd_even(nums) to odd, even = odd_even(nums)

By trying to execute:

print("List had ", odd, "odds and ", even, "evens.")

The main() is looking for variables odd and even, but they dont exist in main(), they exist locally in odd_even() (hence why you are calling return as to return them to the calling function. The reason you only see an error with respect to odd is because it is the first variable in that print() that the interpreter encounters an error on.

The only way around this without correct use of return is to declare them as global. But that is a bad idea so don't do that, keep things local on the stack!

pstatix
  • 3,611
  • 4
  • 18
  • 40
0

You have some syntactic errors. Python...unlike many programming languages is whitespace conscious. This means you need to be careful with your indentation and spacing. More traditional languages like Java and C use brackets {} to define a scope, and semicolons ; to figure out line termination.

Perhaps you copied it poorly, but from what I see, it appears as though you are defining the function odd_even() within the function main(). That is, the definition of odd_even() is tabbed to the right, which means that its definition is within the function main. I assume that you want main to call the function odd_even(). Thus, you must tab it back over to the left so that it is at the same indentation level as main().

For this reason I use horizontal lines (see below) to clearly outline the scope of functions. This is good for me when I write in Python because otherwise it can be very unclear where one function ends, and where another begins.

Also, it appears as though you have 2 return statements. If you want to return 2 values, you should encompass it within an object. To get around this, there are two simple solutions that come to mind. You can make the odd_even() function access global variables (not recommended)...or you can return an array (any number of values back) or a tuple (exactly 2, but this is python specific).

Below is an implementation of both:

import random

# Declare global variables outside the scope of any function
odd = 0
even = 0

#-------------------------------------------------------------------------------

def main():

    nums = [1,2,3,4,5,6,7,8,9,10]

    return_value = odd_even(nums)

    # Get the individual values back
    o = return_value[0]
    e = return_value[1]

    # You can use the global variables
    print("List had ", odd, "odds and ", even, "evens.")


    # Or you can get the array back
    print("List had ", o, "odds and ", e, "evens.")


#-------------------------------------------------------------------------------

def odd_even(given_list):

    # This means we are referencing the variables odd and even that are global
    global odd
    global even

    # Loop through the array
    for x in given_list:
        if x % 2 == 0:
            even += 1
        else:
            odd += 1

    return [odd, even]
#-------------------------------------------------------------------------------


main()
  • This is all incorrect information. Python supports a user defined `main()` unlike C/C++/Java which have a `main`. Python also supports the return of multiple values (as a `tuple`) as has done so for many versions. Beyond that, declaring variables as `global` should be seldom done; especially where there is a way to do so locally, which there is here. – pstatix Oct 02 '17 at 00:12
  • 1
    I am not saying anything about main...I am saying that they cannot define a function odd_even() WITHIN the function main(). So provided that the function odd_even() is tabbed over...the python interpreter is finding a function definition (hence the keyword def) within another function main()... I did mention tuples as an option... "... or a tuple (exactly 2, but this is python specific)." –  Oct 02 '17 at 00:13
  • To say "not permitted" but then provide a valid use of the language is a contradiction. You should update your post accordingly. – pstatix Oct 02 '17 at 00:14
  • You can absolutely define a nested function as to not take up space in global definitions. – pstatix Oct 02 '17 at 14:30
  • Well, you probably know better than I do. Thanks for the insight –  Oct 02 '17 at 22:07