"Where is the Duck?"¶
This notebook illustrates how context-aware components can be developed in PyGX.
In this example, Duck is a symbolic class which subscribes the on_sym_parent_change and on_sym_path_change events. Therefore, when the containing context of a Duck object is changed, it can respond to such changes.
In [ ]:
Copied!
!pip install pygx
!pip install pygx
In [2]:
Copied!
import pygx as pg
import pygx as pg
In [4]:
Copied!
@pg.members([
('occupied_by', pg.typing.Any())
])
class Venue(pg.Object):
pass
@pg.members([
('size', pg.typing.Enum('small', ['small', 'large'])),
('color', pg.typing.Enum('green', ['green', 'blue', 'black']))
], init_arg_list=['occupied_by', 'size', 'color'])
class Pool(Venue):
def __str__(self):
return f'a {self.size} {self.color} pool'
@pg.members([], init_arg_list=['occupied_by'])
class Cage(Venue):
def __str__(self):
return f'a small cold cage'
def free(self):
self.sym_rebind(occupied_by=None)
class Duck(pg.Object):
def on_sym_parent_change(self, old_parent, new_parent):
super().on_sym_parent_change(old_parent, new_parent)
def venue(parent):
if isinstance(parent, Venue):
return str(parent)
return 'nowhere'
print(f'I am moving from {venue(old_parent)} '
f'to {venue(new_parent)}')
def on_sym_path_change(self, old_path, new_path):
super().on_sym_path_change(old_path, new_path)
print(f'I am now identified by path "{new_path}"')
def who_am_i(self):
if isinstance(self.sym_parent, Pool):
message = f'I am a happy duck swimming in {str(self.sym_parent)}.'
elif isinstance(self.sym_parent, Cage):
message = f'I am a sad duck wandering in {str(self.sym_parent)}.'
else:
message = f'I am just a duck.'
print(message)
@pg.members([
('occupied_by', pg.typing.Any())
])
class Venue(pg.Object):
pass
@pg.members([
('size', pg.typing.Enum('small', ['small', 'large'])),
('color', pg.typing.Enum('green', ['green', 'blue', 'black']))
], init_arg_list=['occupied_by', 'size', 'color'])
class Pool(Venue):
def __str__(self):
return f'a {self.size} {self.color} pool'
@pg.members([], init_arg_list=['occupied_by'])
class Cage(Venue):
def __str__(self):
return f'a small cold cage'
def free(self):
self.sym_rebind(occupied_by=None)
class Duck(pg.Object):
def on_sym_parent_change(self, old_parent, new_parent):
super().on_sym_parent_change(old_parent, new_parent)
def venue(parent):
if isinstance(parent, Venue):
return str(parent)
return 'nowhere'
print(f'I am moving from {venue(old_parent)} '
f'to {venue(new_parent)}')
def on_sym_path_change(self, old_path, new_path):
super().on_sym_path_change(old_path, new_path)
print(f'I am now identified by path "{new_path}"')
def who_am_i(self):
if isinstance(self.sym_parent, Pool):
message = f'I am a happy duck swimming in {str(self.sym_parent)}.'
elif isinstance(self.sym_parent, Cage):
message = f'I am a sad duck wandering in {str(self.sym_parent)}.'
else:
message = f'I am just a duck.'
print(message)
In [5]:
Copied!
duck = Duck()
duck.who_am_i()
duck = Duck()
duck.who_am_i()
I am just a duck.
In [6]:
Copied!
cage = Cage(duck)
duck.who_am_i()
cage = Cage(duck)
duck.who_am_i()
I am now identified by path "occupied_by" I am moving from nowhere to a small cold cage I am a sad duck wandering in a small cold cage.
In [7]:
Copied!
cage.free()
cage.free()
I am moving from a small cold cage to nowhere I am now identified by path ""
In [8]:
Copied!
pool = Pool(duck)
duck.who_am_i()
pool = Pool(duck)
duck.who_am_i()
I am now identified by path "occupied_by" I am moving from nowhere to a small green pool I am a happy duck swimming in a small green pool.