Class "super" variable - python

There is a class as following:
class N:
def __init__(self, node_id):
self.id = node_id # id (as an integer for example)
self.super = 0
self.color = 0
It is about creating a node. As you can see, there is an attribute, super. I want to call the color of the supernode.
I tried to implement:
node.color = node.super.color
but, it was wrong implementation. Do you have any idea how to get the information of other node?

You need to explicitly pass the parent node -or at least its color, to the class init function
- there is no way a simplist node class can "guess" how it is connected with other node objects.
One way to go is:
class N(object):
def __init__(self, node_id, parent_node):
self.id = node_ide
self.parent = parent_node
self.color = 0
# and you canget parentnode color with self.node.color

Related

UML diagrams in python?

I just got started learning about UML and I am currently trying to implement functionality for this diagram using python.
I have wrote the inheritance part, but I don't know yet how to deal with the association part of it. Could anyone give me some pointers on how to do this? Especially the circular reference.
My implementation so far:
class RailCar():
def __init__(self, name):
if len(name) >= 2:
self.__name = name
self.locomotive = None
else:
raise Exception("Name length of", type(self), " object must be at least 2 characters long.")
class PassengerCar(RailCar):
def __init__(self, capacity):
super().__init__(self, name)
self.__capacity = capacity
class RestaurantCar(RailCar):
def __init__(self, first):
super().__init__(self, name)
self.__first = first
class Locomotive():
def __init__(self, railCar):
self.railCar = railCar
rc01 = RailCar('01')
rc01.locomotive = "It works!!"
print(rc01.locomotive)
Supposedly the self reference is a doppelganger of the private next attribute. It should rather be written with the role name next to the association like so:
Anyhow, you would code it with self._next holding a reference to a RailCar instance. The getter/setter would then reference this private property.
class RailCar():
def __init__(self, name):
# as above
self._next = None
def setNext(self, next):
self._next = next
# you might check if the instance is RailCar.
#property
def getNext(self):
return self._next
P.S. The Locomotive-RailCar relation would be similar (with the same modeling issue). Just a self._first in Locomotive.

Graph and Dijkstra in python

As another homework I have to do a Dijsktra's algorithm, but I'm not sure how to create a graph and if my implementation is right.
I have to use a given pattern that look like this:
class Vertex:
def __init__(self, id, name):
self.id = id
self.name = name
self.minDistance = None
self.previousVertex = None
self.edges = []
class Edge:
def __init__(self, source, target, weight):
self.source = source
self.target = target
self.weight = weight
class Dijkstra:
def __init__(self):
self.vertexes = Vertex
def createGraph(self, vertexes, edgesToVertexes):
pass
def getVertexes(self):
pass
def computePath(self, sourceId):
pass
def getShortestPathTo(self, targetId):
pass
def resetDijkstra(self):
pass
While calling a createGraph function it gives me two arrays: vertexes & edgesToVertexes containing Vertexes and Edges.
So how do I exactly extract data from these arrays and Initialize them as objects into both classes?

comunication between parent and child class python

Does anyone know how i can get the name of an object with a class function?
I want to use this because i have a class that is supposed to have multiple players in a list, and get their cordinates
object that wants to give their cordinates:
import math
class Pixel:
"""Represents a posision in a grid with a x posistion, a y position and
a character, the x and y position are saved in one tuple"""`
def __init__(self, char='#', pos=(0, 0)):
assert type(char) == str
assert type(pos[0]) == int and type(pos[1]) == int
self.pos = pos
self.x = self.pos[0]
self.y = self.pos[1]
self.char = char
def __str__(self):
return self.char
def __repr__(self):
return self.char
# possible debug repr 'Pixel object with
# char = ' + str(self.char) + ' and pos = ' + str(self.pos)`
class TestObject(Pixel):
def __str__(self, parent):
return '+'
The parent object wants to know what self.pos is from theTestObject (the parent has a list with different testObjects) is there a way for me to give the TestObject the name of the parent object when i am creating it so that he can push that information (parent.funcname(position)) I need it for a function that doesn't return values.
if anyone knows another way to get TestObject.pos to my parent object please tell too, thanks in advance
You could give your instances of TestObject a reference to the parent. This could be done via the __init__ method of TestObject. This way however, the parent has to be known at the time of the instance's construction. I would make it an optional (keyword) parameter and implement a setter method. For example:
class Pixel:
def __init__(self, char='#', pos=(0, 0), parent=None):
assert type(char) == str
assert type(pos[0]) == int and type(pos[1]) == int
self.pos = pos
self.x = self.pos[0]
self.y = self.pos[1]
self.char = char
self._parent = parent
def set_parent(self, parent):
self._parent = parent
class TestObject(Pixel):
def somemethod(self):
position = 0
# do what ever you need to do here
if isinstance(self._parent, Pixel):
self._parent.set_value(self)
When you add an instance obj of TestObject to the list in the parent object, the parent object should call obj.set_parent(self) to set itself as the object's parent.
Here is an example for a parent class:
class PixelList:
def __init__(self):
self._pixels = []
def add_pixel(self, pixel):
self._pixels.append(pixel)
pixel.set_parent(self)
def set_value(self, pixel):
# do stuff here
position = pixel.pos
If you then call obj.somemethod, your parent object's set_value method is called with the pixel as argument. In the set_value method you can thus access any information of the pixel you like (e.g. pixel.pos).

Python - inner class is not defined?

I have to do an unrolled linked list for one of my classes. I'm new to python, but not to programming, and for some reason I cannot get around this little problem!
I have a class Node that is to be the node object used within the unrolled linked list. The unrolled linked list class performs all the operations on the Node class.
class UnrolledLinkedList(object):
""" INNER NODE CLASS """
class Node(object):
def __init__(self):
self.array = []
self.next_node = None
""" END NODE CLASS """
def __init__(self, max_node_capacity=16):
self.max_node_capacity = max_node_capacity
self.head = Node()
""" OTHER FUNCTIONS OF UNROLLEDLINKEDLIST CLASS """
The problem comes at the last line of the UnrolledLinkedList class' init function: "global name Node is not defined". I double checked my indentation and looked all over the internet for examples of something like this, but couldn't find any. Would someone mind explaining to me what's wrong?
Methods do not include their class as a scope to be searched. If you want this to work then you will need to use either UnrolledLinkedList.Node or self.Node instead.
The inner class Node is a member of the class UnrolledLinkedList and can only be accessed via self.
def __init__(self, max_node_capacity=16):
self.max_node_capacity = max_node_capacity
self.head = self.Node()
Use:
self.head = self.Node()
and it works.
A class does not create its own name space. Using self.Node(), Python first searches all attributes of the instances. Since it does not find the name Node there, it it searches the class UnrolledLinkedList for Node.
Alternatively, you can use the class name directly:
UnrolledLinkedList.Node()
You can achieve the same without nesting the class Node:
class Node(object):
def __init__(self):
self.array = []
self.next_node = None
class UnrolledLinkedList(object):
def __init__(self, max_node_capacity=16):
self.max_node_capacity = max_node_capacity
self.head = Node()
Qualify Node() with self:
class UnrolledLinkedList(object):
class Node(object):
def __init__(self):
self.array = []
self.next_node = None
def __init__(self, max_node_capacity=16):
self.max_node_capacity = max_node_capacity
self.head = self.Node()
Python needs to qualify references to things. In this case, you could either say UnrolledLinkedList.Node() or self.Node().

python parent child relationship class

I've written up a class as seen below. I want to add the attribute of 'parent' to my base class Node. I was wondering if someone could show me how to properly do this. I've been given guidance on how to do it but I'm not entire sure how to write it syntax wise. Here is the suggested way to do it...
generally I would hide the parent attribute behind a property so when
its set, the children array of the previous parent can be modified so
if you say n.parent = x, it actually remove node n from it's parent
and set the parent value
class Node(object):
def __init__(self, name, attributes, children):
self.name = name
self.attributes = attributes if attributes is not None else {}
self.children = children if children is not None else []
class Camera(Node):
def __init__(self, name="", attributes=None, children=None, enabled=True):
super(Camera, self).__init__(name=name, attributes=attributes, children=children)
self.enabled = enabled
updated
import weakref
class Node(object):
_parent = None
def __init__(self, name, attributes, children, parent):
self.name = name
self.attributes = attributes if attributes is not None else {}
self.children = children if children is not None else []
self.parent = parent
for child in children:
child.parent = self
#property
def parent(self):
return self._parent() if self._parent is not None else None
#parent.setter
def parent(self, newparent):
oldparent = self.parent
if newparent is oldparent:
return
if oldparent is not None:
oldparent.children.remove(self)
if self not in newparent.children:
newparent.children.append(self)
self._parent = weakref.ref(newparent) if newparent is not None else None
class Camera(Node):
def __init__(self, name="", attributes=None, children=None, enabled=True, parent=None):
super(Camera, self).__init__(name=name, attributes=attributes, children=children, parent=parent)
self.enabled = enabled
Camera()
Example code, incorporating weakref to avoid reference cycles that can delay cleanup (or prevent it entirely in some cases, particularly on Python 3.3 and earlier):
import weakref
class Node:
# If this is Python 2, you need to explicitly inherit from object to
# be a new-style class with descriptor support (which allows properties), so
# the class line would be:
# class Node(object):
# On Py3, it's implicit and can be omitted
# Ensure attribute readable so getter/setter don't need to use has/getattr
# Will be allocated per-instance when self.parent is assigned in __init__
# So on Py3.3+, it will still get the compact key-sharing dicts for attributes
_parent = None
# Adding defaults for all values matching Camera for simplicity
def __init__(self, name='', attributes=None, children=None, parent=None):
self.name = name
self.attributes = attributes if attributes is not None else {}
self.children = children if children is not None else []
self.parent = parent
for child in children:
child.parent = self
#property
def parent(self):
return self._parent() if self._parent is not None else None
#parent.setter
def parent(self, newparent):
oldparent = self.parent
# If setting to existing parent, then no-op
# Remove this check and early-out if you want to be able to move
# a node to the end of its parent's children by reassigning the same parent
if newparent is oldparent:
return
if oldparent is not None:
oldparent.children.remove(self)
if self not in newparent.children:
newparent.children.append(self)
self._parent = weakref.ref(newparent) if newparent is not None else None
Typically, to avoid issues with changing parent class prototypes, I put additional parameters to child class __init__ methods first, not last. Because I gave __init__ defaults on Camera, this makes Camera very simple:
class Camera(Node):
def __init__(self, enabled=True, *args, **kwargs):
super().__init__(*args, **kwargs)
# On Py2, super isn't magic, so you need to be explicit unlike Py3:
# super(Camera, self).__init__(*args, **kwargs)
self.enabled = enabled
As you can see, by moving the Camera unique __init__ param to the front, Camera can stop paying attention to changes in the Node __init__; the new Camera works with the original Node or the new Node (that accepts parent and assigns self.parent) just fine, because it's less tightly coupled to the exact parameter ordering. Note that this does mean that if enabled is not passed positionally, then all arguments must be passed by keyword.
Please comment if I made any mistakes, but that should be close to correct. In general, I had the Node class use the parent accessor to simplify the code by removing the difficulty with handling None properly (None is not weak referencable).

Categories

Resources