A plugin to add positions to the nodes.
Place
and Transition
are added an optional argument for the
constructor pos=(x,y)
to set their position. Moreover, these classes
are added an attribute pos
that holds a pair of numbers with
attributes x
and y
and methods shift(dx, dy)
and moveto(x, y)
.
So, when the plugin is loaded, we can specify and retreive nodes
positions:
>>> import snakes.plugins >>> snakes.plugins.load('pos', 'snakes.nets', 'nets') <module ...> >>> from nets import PetriNet, Place, Transition >>> n = PetriNet('N') >>> n.add_place(Place('p00')) >>> t10 = Transition('t10', pos=(1, 0)) >>> n.add_transition(t10) >>> n.add_place(Place('p11', pos=(1, 1))) >>> n.add_transition(Transition('t01', pos=(0, 1))) >>> t10.pos Position(1, 0) >>> t10.pos.x 1 >>> t10.pos.y 0 >>> t10.pos() (1, 0)
Nodes positions is immutable, we must use method moveto
to change
positions:
>>> t10.pos.y = 1 Traceback (most recent call last): ... AttributeError: readonly attribute >>> t10.pos.moveto(t10.pos.x, 1) >>> t10.pos Position(1, 1)
Petri nets are added methods bbox()
that returns a pair of extrema
((xmin, ymin), (xmax, ymax))
, a method shift(dx, dy)
that shift
all the nodes, and a method transpose()
that rotates the net in such
a way that the top-down direction becomes left-right:
>>> n.bbox() ((0, 0), (1, 1)) >>> n.shift(1, 2) >>> n.bbox() ((1, 2), (2, 3)) >>> n.node('t01').copy().pos Position(1, 3) >>> n.transpose() >>> n.node('t01').pos Position(-3, 1)
Class Position
class Position (object) :
The position of a node
Method Position.__init__
def __init__ (self, x, y) :
Constructor expects the Cartesian coordinates of the node,
they can be provided as float
or int
.
Call API
float x
: horizontal positionfloat y
: vertical position
Method Position.moveto
def moveto (self, x, y) :
Change current coordinates to the specified position
Call API
float x
: horizontal positionfloat y
: vertical position
Method Position.shift
def shift (self, dx, dy) :
Shift current coordinates by the specified amount.
Call API
float dx
: horizontal shiftfloat dy
: vertical shift
Method Position.__getitem__
def __getitem__ (self, index) :
Access coordinates by index
>>> Position(1, 2)[0] 1 >>> Position(1, 2)[1] 2 >>> Position(1, 2)[42] Traceback (most recent call last): ... IndexError: Position index out of range
Call API
int index
: 0 forx
coordinate, 1 fory
Exceptions
IndexError
: whenindex not in {0, 1}
Method Position.__iter__
def __iter__ (self) :
Successively yield x
and y
coordinates
>>> list(Position(1, 2)) [1, 2]
Method Position.__call__
def __call__ (self) :
Return the position as a pair of values
>>> Position(1, 2.0)() (1, 2.0)
Call API
return tuple
: the pair of coordinates(x, y)
Extensions
Class Place
class Place (module.Place) :
Method Place.__init__
def __init__ (self, name, tokens=[], check=None, **args) :
If no position is given (0, 0)
is chosen
>>> Place('p').pos Position(0, 0) >>> Place('p', pos=(1,2)).pos Position(1, 2)
Call API
object name
object tokens
object check
object args
- keyword
pos
: the position of the new place
Class Transition
class Transition (module.Transition) :
Method Transition.__init__
def __init__ (self, name, guard=None, **args) :
If no position is given (0, 0)
is chosen
>>> Transition('t').pos Position(0, 0) >>> Transition('t', pos=(1,2)).pos Position(1, 2)
Call API
object name
object guard
object args
- keyword
pos
: the position of the new transition
Class PetriNet
class PetriNet (module.PetriNet) :
Method PetriNet.add_place
def add_place (self, place, **args) :
Position can be set also when a place is added to the net.
>>> n = PetriNet('n') >>> n.add_place(Place('a', pos=(1, 2))) >>> n.node('a').pos Position(1, 2) >>> n.add_place(Place('b'), pos=(3,4)) >>> n.node('b').pos Position(3, 4) >>> n.add_place(Place('c', pos=(42, 42)), pos=(5, 6)) >>> n.node('c').pos Position(5, 6)
Call API
object place
object args
- keyword
pos
: the position of the added place
Method PetriNet.add_transition
def add_transition (self, trans, **args) :
Position can be set also when a transitions is added to
the net. See method add_place
above.
Call API
object trans
object args
- keyword
pos
: the position of the added transition
Method PetriNet.merge_places
def merge_places (self, target, sources, **args) :
When places are merged, the position of the new place
is the barycentre of the positions of the merged nodes.
Optionally, position can be specified in the call the
merge_places
.
>>> n = PetriNet('n') >>> n.add_place(Place('a', pos=(1,2))) >>> n.add_place(Place('b', pos=(3,4))) >>> n.merge_places('c', ['a', 'b']) >>> n.node('c').pos Position(2.0, 3.0) >>> n.merge_places('d', ['a', 'b'], pos=(0, 0)) >>> n.node('d').pos Position(0, 0)
Call API
object target
object sources
object args
- keyword
pos
: the position of the added transition
Method PetriNet.merge_transitions
def merge_transitions (self, target, sources, **args) :
See method merge_places
above.
Method PetriNet.bbox
def bbox (self) :
The bounding box of the net, that is, the smallest rectangle that contains all nodes coordinates.
Call API
return tuple
: rectangle coordinates as((xmin, ymin), (xmax, ymax))
Method PetriNet.shift
def shift (self, dx, dy) :
Shift every node by (dx, dy)
Call API
float dx
: horizontal shiftfloat dy
: vertical shift
Method PetriNet.transpose
def transpose (self) :
Perform a clockwise 90 degrees rotation of node coordinates, ie,
change every position (x, y)
to (-y, x)