1

I am trying to sum up the nodes in a binary tree:

def average(tree):
   if tree is None:
       return
   total = (tree['data']) + (average(tree['left'])) + (average(tree['right']))
   print(total)

I also tried with "is" and "is not" however it still gave me the following error:

 TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
Andy
  • 13
  • 4
  • 1
    The bare `return` returns `None`, so your check is basically useless. Perhaps return a default _integer_ value such as `0`. Also, it should be `if tree is None:` with `is` rather than `==`. – Christian Dean Aug 12 '17 at 00:27
  • 3
    You also need to `return total`. Also, recommend you don't use `sum` as your function name, it hides python's builtin `sum`. – AChampion Aug 12 '17 at 00:28
  • @Christian Dean why not `==` or even `not`? – t.m.adam Aug 12 '17 at 00:32
  • @t.m.adam _"why not `==` "_ - See [Python None comparison: should I use “is” or ==?](https://stackoverflow.com/questions/14247373/python-none-comparison-should-i-use-is-or). – Christian Dean Aug 12 '17 at 00:34
  • I changed it to: def average(tree): if tree is None: return 0 else: total = tree['data'] + average(tree['left']) + average(tree['right']) But it still doesn't work – Andy Aug 12 '17 at 00:40
  • @Christian Dean it was a nice read, but i don't think it's important for this case. – t.m.adam Aug 12 '17 at 00:41
  • You also need to do what @AChampion said. `return total`. – Christian Dean Aug 12 '17 at 00:43
  • @t.m.adam Why not? The official Python style guide [PEP8 says to do this](https://www.python.org/dev/peps/pep-0008/#programming-recommendations): _"Comparisons to singletons like None should always be done with is or is not, never the equality operators."_. Not that you must always rigidly follow the style guide, but for cases such as this it's best to. Not only is it faster to use `is`, but it's the commonly accepted idiom and thus makes his code more readable to others. – Christian Dean Aug 12 '17 at 00:46

1 Answers1

0

There are two issues here which have to do with taking care to return values once they have been calculated from average.

First, in your code the lone return statement will return the non-numeric None value. This is an issue as when you get any node without two child nodes (e.g. a leaf), tree['left'] or/and tree['right'] will return None. This None is passed to average, which returns None back. The error you are getting is due to subsequenly trying to add this returned value on the 3rd line of the function. To fix this, you can simply return a "base case" value for what should the "average" of a tree that is empty be.

Second, even in the case where average is called recursively on a child node that is not None, average will still return None because as there is no other return statement in the function, and in Python when evaluation reaches the end of a function without a return statement there is an implicit return of None. To fix this simply return the total that you have calculated!

Fixing these two problems might look like the following:

def average(tree):
   if tree is None:
       return 0
   total = tree['data'] + average(tree['left']) + average(tree['right'])
   return total

although I can't say for certain that returning zero in the base case is the best for exactly what you are trying to accomplish.

As a final note, you may want to add a check that tree['data'] is not None to rule out edge cases where nodes have no data!

Jon Deaton
  • 3,943
  • 6
  • 28
  • 41