Skip to content

Commit ee428bb

Browse files
author
fkromer
committed
merge with faif/master
2 parents 070c2cf + ad59bd5 commit ee428bb

17 files changed

+783
-74
lines changed

builder.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ def __init__(self):
3131
def new_building(self):
3232
self.building = Building()
3333

34+
def build_floor(self):
35+
raise NotImplementedError
36+
37+
def build_size(self):
38+
raise NotImplementedError
3439

3540
# Concrete Builder
3641
class BuilderHouse(Builder):

catalog.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def _instance_method_2(self):
7575

7676
def main_method(self):
7777
"""
78-
will execute either _instance_method_1 or _instance_method_1
78+
will execute either _instance_method_1 or _instance_method_2
7979
depending on self.param value
8080
"""
8181
self._instance_method_choices[self.param].__get__(self)()
@@ -111,7 +111,7 @@ def _class_method_2(cls):
111111

112112
def main_method(self):
113113
"""
114-
will execute either _instance_method_1 or _instance_method_1
114+
will execute either _class_method_1 or _class_method_2
115115
depending on self.param value
116116
"""
117117
self._class_method_choices[self.param].__get__(None, self.__class__)()
@@ -143,7 +143,7 @@ def _static_method_2():
143143

144144
def main_method(self):
145145
"""
146-
will execute either _instance_method_1 or _instance_method_1
146+
will execute either _static_method_1 or _static_method_2
147147
depending on self.param value
148148
"""
149149
self._static_method_choices[self.param].__get__(None, self.__class__)()

chain.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33

4-
"""http://www.testingperspective.com/wiki/doku.php/collaboration/chetan/designpatternsinpython/chain-of-responsibilitypattern"""
54
"""http://www.dabeaz.com/coroutines/"""
65

76
import time

delegation_pattern.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Reference: https://en.wikipedia.org/wiki/Delegation_pattern
6+
Author: https://github.com/IuryAlves
7+
"""
8+
9+
10+
class Delegator(object):
11+
"""
12+
>>> delegator = Delegator(Delegate())
13+
>>> delegator.do_something("nothing")
14+
'Doing nothing'
15+
>>> delegator.do_anything()
16+
17+
"""
18+
def __init__(self, delegate):
19+
self.delegate = delegate
20+
21+
def __getattr__(self, name):
22+
def wrapper(*args, **kwargs):
23+
if hasattr(self.delegate, name):
24+
attr = getattr(self.delegate, name)
25+
if callable(attr):
26+
return attr(*args, **kwargs)
27+
return wrapper
28+
29+
30+
class Delegate(object):
31+
32+
def do_something(self, something):
33+
return "Doing %s" % something
34+
35+
36+
if __name__ == '__main__':
37+
import doctest
38+
doctest.testmod()

facade.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def __init__(self):
5656
self.tc1 = TC1()
5757
self.tc2 = TC2()
5858
self.tc3 = TC3()
59-
self.tests = [i for i in (self.tc1, self.tc2, self.tc3)]
59+
self.tests = [self.tc1, self.tc2, self.tc3]
6060

6161
def runAll(self):
6262
[i.run() for i in self.tests]

hsm.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
"""
2+
Implementation of the HSM (hierachrical state machine) or
3+
NFSM (nested finite state machine) C++ example from
4+
http://www.eventhelix.com/RealtimeMantra/HierarchicalStateMachine.htm#.VwqLVEL950w
5+
in Python
6+
7+
- single source 'message type' for state transition changes
8+
- message type considered, messages (comment) not considered to avoid complexity
9+
"""
10+
11+
12+
class UnsupportedMessageType(BaseException):
13+
pass
14+
15+
16+
class UnsupportedState(BaseException):
17+
pass
18+
19+
20+
class UnsupportedTransition(BaseException):
21+
pass
22+
23+
24+
class HierachicalStateMachine(object):
25+
26+
def __init__(self):
27+
self._active_state = Active(self) # Unit.Inservice.Active()
28+
self._standby_state = Standby(self) # Unit.Inservice.Standby()
29+
self._suspect_state = Suspect(self) # Unit.OutOfService.Suspect()
30+
self._failed_state = Failed(self) # Unit.OutOfService.Failed()
31+
self._current_state = self._standby_state
32+
self.states = {'active': self._active_state,
33+
'standby': self._standby_state,
34+
'suspect': self._suspect_state,
35+
'failed': self._failed_state}
36+
self.message_types = {'fault trigger': self._current_state.on_fault_trigger,
37+
'switchover': self._current_state.on_switchover,
38+
'diagnostics passed': self._current_state.on_diagnostics_passed,
39+
'diagnostics failed': self._current_state.on_diagnostics_failed,
40+
'operator inservice': self._current_state.on_operator_inservice}
41+
42+
def _next_state(self, state):
43+
try:
44+
self._current_state = self.states[state]
45+
except KeyError:
46+
raise UnsupportedState
47+
48+
def _send_diagnostics_request(self):
49+
return 'send diagnostic request'
50+
51+
def _raise_alarm(self):
52+
return 'raise alarm'
53+
54+
def _clear_alarm(self):
55+
return 'clear alarm'
56+
57+
def _perform_switchover(self):
58+
return 'perform switchover'
59+
60+
def _send_switchover_response(self):
61+
return 'send switchover response'
62+
63+
def _send_operator_inservice_response(self):
64+
return 'send operator inservice response'
65+
66+
def _send_diagnostics_failure_report(self):
67+
return 'send diagnostics failure report'
68+
69+
def _send_diagnostics_pass_report(self):
70+
return 'send diagnostics pass report'
71+
72+
def _abort_diagnostics(self):
73+
return 'abort diagnostics'
74+
75+
def _check_mate_status(self):
76+
return 'check mate status'
77+
78+
def on_message(self, message_type): # message ignored
79+
if message_type in self.message_types.keys():
80+
self.message_types[message_type]()
81+
else:
82+
raise UnsupportedMessageType
83+
84+
85+
class Unit(object):
86+
87+
def __init__(self, HierachicalStateMachine):
88+
self.hsm = HierachicalStateMachine
89+
90+
def on_switchover(self):
91+
raise UnsupportedTransition
92+
93+
def on_fault_trigger(self):
94+
raise UnsupportedTransition
95+
96+
def on_diagnostics_failed(self):
97+
raise UnsupportedTransition
98+
99+
def on_diagnostics_passed(self):
100+
raise UnsupportedTransition
101+
102+
def on_operator_inservice(self):
103+
raise UnsupportedTransition
104+
105+
106+
class Inservice(Unit):
107+
108+
def __init__(self, HierachicalStateMachine):
109+
self._hsm = HierachicalStateMachine
110+
111+
def on_fault_trigger(self):
112+
self._hsm._next_state('suspect')
113+
self._hsm._send_diagnostics_request()
114+
self._hsm._raise_alarm()
115+
116+
def on_switchover(self):
117+
self._hsm._perform_switchover()
118+
self._hsm._check_mate_status()
119+
self._hsm._send_switchover_response()
120+
121+
122+
class Active(Inservice):
123+
124+
def __init__(self, HierachicalStateMachine):
125+
self._hsm = HierachicalStateMachine
126+
127+
def on_fault_trigger(self):
128+
super(Active, self).perform_switchover()
129+
super(Active, self).on_fault_trigger()
130+
131+
def on_switchover(self):
132+
self._hsm.on_switchover() # message ignored
133+
self._hsm.next_state('standby')
134+
135+
136+
class Standby(Inservice):
137+
138+
def __init__(self, HierachicalStateMachine):
139+
self._hsm = HierachicalStateMachine
140+
141+
def on_switchover(self):
142+
super(Standby, self).on_switchover() #message ignored
143+
self._hsm._next_state('active')
144+
145+
146+
class OutOfService(Unit):
147+
148+
def __init__(self, HierachicalStateMachine):
149+
self._hsm = HierachicalStateMachine
150+
151+
def on_operator_inservice(self):
152+
self._hsm.on_switchover() # message ignored
153+
self._hsm.send_operator_inservice_response()
154+
self._hsm.next_state('suspect')
155+
156+
157+
class Suspect(OutOfService):
158+
159+
def __init__(self, HierachicalStateMachine):
160+
self._hsm = HierachicalStateMachine
161+
162+
def on_diagnostics_failed(self):
163+
super(Suspect, self).send_diagnostics_failure_report()
164+
super(Suspect, self).next_state('failed')
165+
166+
def on_diagnostics_passed(self):
167+
super(Suspect, self).send_diagnostics_pass_report()
168+
super(Suspect, self).clear_alarm() # loss of redundancy alarm
169+
super(Suspect, self).next_state('standby')
170+
171+
def on_operator_inservice(self):
172+
super(Suspect, self).abort_diagnostics()
173+
super(Suspect, self).on_operator_inservice() # message ignored
174+
175+
176+
class Failed(OutOfService):
177+
'''No need to override any method.'''
178+
179+
def __init__(self, HierachicalStateMachine):
180+
self._hsm = HierachicalStateMachine
181+

0 commit comments

Comments
 (0)