views:

59

answers:

4

I'm trying to set a function to do something like this

   def __binaryTreeInsert(self, toInsert, currentNode=getRoot(), parentNode=None):

where current node starts as root, and then we change it to a different node in the method and recursivly call it again.

However, i cannot get the 'currentNode=getRoot()' to work. If i try calling the funcion getRoot() (as above) it says im not giving it all the required variables, but if i try to call self.getRoot() it complains that self is an undefined variable. Is there a way i can do this without having to specify the root while calling this method?

EDIT: The base case of this method is already

if currentNode == None:

so using that to set the root wouldn't work

A: 

You can do

def __binaryTreeInsert(self, toInsert, currentNode=None, parentNode=None):
   if currentNode is None:
      currentNode = self.getRoot()

...
Alexander Gessler
I thought of that, but the problem is the base case of the recursion is 'if curentNode is None:'so it wouldn't work with the rest of the method
kyeana
@user, You are going to give more info then. If you look at this you can still check afterwards if it is `None` or not.
voyager
`None` is just a sentinel value here, you can use an arbitrary object instead of it if the `currentNode is None` case does already have a meaning … you can use, for example, `False` or `True`.
Alexander Gessler
@voyager, i am adding an item to a binary tree as part of building a red black tree. What this method is going to do is go to the left or right child of the current node every recursion (depending on the data), and if that same left or right child node is none, then that is where this new node is going to be added. The reason doing 2 checks wouldn't work is that if there was ever an empty node, it would set it back to root first, and never add the child node
kyeana
@Alexander, smart thinking, thanks :). Coming from a java background i keep forgetting that variables aren't strong typed.
kyeana
@user272689, Python is strongly typed; objects have a strong type. Python variables do not have types, strong or otherwise.
Mike Graham
A: 
def __binaryTreeInsert(self, toInsert, currentNode=0, parentNode=None):
    if not currentNode: 
        currentNode = self.getRoot()
voyager
+1  A: 

While arg=None is the idiomatic Python sentinel value for an non-supplied argument, it doesn't have to be None. In Lua, for instance, the idiomatic non-supplied argument is an empty table. We can actually apply that to this case:

class Foo:
    sentinel = {}
    def bar(self, arg=sentinel):
        if arg is self.sentinel:
            print "You didn't supply an argument!"
        else:
            print "The argument was", arg

f = Foo()
f.bar(123)
f.bar()
f.bar(None)
f.bar({})

Output:

The argument was 123
You didn't supply an argument!
The argument was None
The argument was {}

This works for any case except explicitly passing Foo.sentinel, because Foo.sentinel is guaranteed to have a unique address -- meaning, x is Foo.sentinel is only true when x is Foo.sentinel :) Thus, due to the closure we've created around Foo.sentinel, there is only one object that can create an ambiguous situation, and it will never be used by accident.

Mark Rushakoff
What i was looking for. I partially want to do this for further abstraction, but mostly i was just curious if/how it could be done.
kyeana
Always inherit `object` rather than nothing so that you are using new-style classes.
Mike Graham
@Mike the class that this method is hosted in inherits from object
kyeana
A: 

When a function or method is defined, the def line is evaluated immediately, including any keyword arguments. For this reason, things like function calls and mutable objects are usually not appropriate for default arguments.

The solution is instead to use a sentinel value. None is most common, but for the cases that None would be a valid value, you can use another sentinel, for example:

not_provided = object()
def _binaryTreeInsert(self, toInsert, currentNode=not_provided, parentNode=None):
    if currentNode is not_provided:
        currentNode = self.getRoot()
Mike Graham