Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Code Reviews

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

75%
+4 −0
Code Reviews A state machine in Python

I think you've got an architectural error. A state machine (SM) determines it's own actions based on it's state and the messages it may receive. The calling code may send messages (information) t...

posted 2y ago by Nick Alexeev‭  ·  edited 2y ago by Nick Alexeev‭

Answer
#2: Post edited by user avatar Nick Alexeev‭ · 2022-05-30T23:22:45Z (almost 2 years ago)
  • I've written a dozen state machines, and I think there's an architectural error. A state machine (SM) determines it's own actions based on it's state and the messages it may receive. The calling code may send messages (information) to a SM. But the calling code shouldn't send actions (imperative commands) to a SM.
  • A SM should be able to ignore a message which it doesn't know how to react to. Maybe in some states the SM reacts to the message, in other states it doesn't react, and the SM happens to be in a state in which it doesn't react. Maybe the SM never reacts to that message in a any state. In these cases, the SM should ignore the message if doesn't know how to react to it. The SM shouldn't raise an exception, because this situation is normal. The calling code which sends the message shouldn't know the state of the SM. It should pump messages to the SM, and let the SM take care of itself.
  • ```python
  • def next_state(self, state_machine: "StateMachine", action: str) -> "State":
  • """
  • return the new state caused by the action
  • """
  • if not action in self._action_map:
  • raise ValueError(f"State {self} does not support action {action}")
  • new_state = state_machine.get_state(self._action_map[action])
  • return new_state
  • ```
  • I think you've got an architectural error. A state machine (SM) determines it's own actions based on it's state and the messages it may receive. The calling code may send messages (information) to a SM. But the calling code shouldn't send actions (imperative commands) to a SM.
  • A SM should be able to ignore a message which it doesn't know how to react to. Maybe in some states the SM reacts to the message, in other states it doesn't react, and the SM happens to be in a state in which it doesn't react. Maybe the SM never reacts to that message in a any state. In these cases, the SM should ignore the message if doesn't know how to react to it. The SM shouldn't raise an exception, because this situation is normal. The calling code which sends the message shouldn't know the state of the SM. It should pump messages to the SM, and let the SM take care of itself.
  • ```python
  • def next_state(self, state_machine: "StateMachine", action: str) -> "State":
  • """
  • return the new state caused by the action
  • """
  • if not action in self._action_map:
  • raise ValueError(f"State {self} does not support action {action}")
  • new_state = state_machine.get_state(self._action_map[action])
  • return new_state
  • ```
#1: Initial revision by user avatar Nick Alexeev‭ · 2022-05-30T20:16:51Z (almost 2 years ago)
I've written a dozen state machines, and I think there's an architectural error.  A state machine (SM) determines it's own actions based on it's state and the messages it may receive.  The calling code may send messages (information) to a SM.  But the calling code shouldn't send actions (imperative commands) to a SM.

A SM should be able to ignore a message which it doesn't know how to react to.  Maybe in some states the SM reacts to the message, in other states it doesn't react, and the SM happens to be in a state in which it doesn't react.  Maybe the SM never reacts to that message in a any state.  In these cases, the SM should ignore the message if doesn't know how to react to it.  The SM shouldn't raise an exception, because this situation is normal.  The calling code which sends the message shouldn't know the state of the SM.  It should pump messages to the SM, and let the SM take care of itself.

```python
def next_state(self, state_machine: "StateMachine", action: str) -> "State":
    """
    return the new state caused by the action
    """
    if not action in self._action_map:
        raise ValueError(f"State {self} does not support action {action}")
    new_state = state_machine.get_state(self._action_map[action])

    return new_state
```