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)