2

this is my first question so I hope I won't throw too much stuff at once.. I'm implementing four different algorithms for a Vacuum Cleaner World problem. So far I made four different working .py files but I thought I would make it fancier since a lot of code is repeated and implement it all in one file with a nice class hierarchy. So at first I had a Node class which looked a bit like this and was a bit different for each algorithm (breadth-first, A*, greedy and random):

class Node(object):
def __init__(self, parent, depth, cost, plan):
    plana = copy.deepcopy(plan)
    self.parent = parent
    self.succsor = []
    self.depth = depth
    self.cost = cost
    self.position = []
    self.plansza = plana
# 'plansza' is an object which is a representation of state - e.g. board with marked uncleaned rooms
    self.action = ''
def printa(self):
    return [self.action]
def isFirst(self):
    res = (self.plansza.side/2)
    self.position = [res,res]
def clean(self):
    n = Node(self, self.depth+1, self.cost+1, self.plansza)
    n.position = self.position
    no = n.plansza.board
    no[n.position[0]][n.position[1]] = '.'  
    n.action = 'clean'  
    self.succsor.append(n)
def up(self):
    # // self.action = 'up'
    n = Node(self,self.depth+1,self.cost+1, self.plansza)
    n.position = [self.position[0]-1, self.position[1]]
    n.action = 'up'
    self.succsor.append(n)

#couple of other move methods...

def expand(self):
    pos = self.position 
    self.none()
    if (pos[0]>0):
        self.up()
    if (pos[1]>0):
        self.left()         
    if (pos[1] + 1 < self.plansza.side):
        self.right()
    if (pos[0] + 1 < self.plansza.side):
        self.down()
    if self.plansza.board[pos[0]][pos[1]] == 'x':
        self.clean()
    return self.succsor

Now I'm trying to use super() function in defining a subclass of Node named NodeStar (for A* implementation):

class NodeStar(Node):
def __init__(self, parent, depth, cost, plan):
    super(NodeStar,self).__init__(parent, depth, cost, plan)
    self.heur = self.funH()
    self.prior = self.cost + self.heur
def expand(self):
super(NodeStar,self).expand()

Where 'self.heur', 'self.funH()' and 'self.prior' are attributes nad function which the Node class doesn't have. This code doesn't work. I got an error:

line 211, in treeSearch
for item in exp:
TypeError: 'NoneType' object is not iterable

(Notion on the side:) I don't know why I have to use arguments in super() function even though I installed python 3.4.3 on my computer (I work in Sublime Text 3 with Anaconda)

I see that the problem is somehow related with the TreeSearch function where an expand() function was called on the first Node of the fringe.

But my main concern is -- is it a good direction? And if so, how I am suppose to use the super() function? For example can I find super() helpful if I need same method but with a different return? Or should I, in such case, override entire thing? Or perhaps should I instead of overwriting the methods (doesn't save much of a code) try to make some boolean attributes in the Node class that will change the type of Node?

I hope that this isn't too long. Will be very grateful for any thoughts and ideas

tadek
  • 100
  • 7
  • i'm not sure you saw my (updated) answer, so i add this comment, i think it answers all your questions and issues – Nikos M. May 19 '15 at 12:28

1 Answers1

0

you have to return the result of expand:

def expand(self):
    return super(NodeStar,self).expand()

If the expand method of the NodeStar class is exactly the same as that of the Node class there is no need to re-define the method in the NodeStar class (this is the inheritance part of object-oriented programming). However if the NodeStar expand method can do some additional functionality along with the functionality of the original expand method then you can re-define it and call the super.expand as needed if needed (this is the polymorphism part of object-oriented programming)

As regards you other questions:

Object-Oriented programming offers some basic concepts like:

  1. Inheritance / Extension (DRY, dont-repeat-yourself)
  2. Polymorphism (similar interface for many-faceted fuinctionality)
  3. Encapsulation (make only interface visible while underlying implementation can change as needed)

So these principles can certainly be helpful in many situations. The OO pattern you try to implement with your code is a variation of what is refered as Composite pattern, look it up for further information and examples

Effectively the composite design pattern is a way to handle both single items and compounds of items in a uniform way. This is what you (try to) do with the Node class (single item) and NodeStar class (compound item, sequence of Node items)

Nikos M.
  • 8,033
  • 4
  • 36
  • 43