Extended the documentation to show a few more#340
Conversation
Codecov ReportBase: 100.00% // Head: 100.00% // No change to project coverage 👍
Additional details and impacted files@@ Coverage Diff @@
## develop #340 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 18 18
Lines 862 862
Branches 120 140 +20
=========================================
Hits 862 862
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
| * Single condition: `cond="condition"` | ||
| * Multiple conditions: `cond=["condition1", "condition2"]` |
There was a problem hiding this comment.
praise: Nice way to explain! Thanks!
| unpaid.to(failed, validators="validator", unless="paused") | | ||
| failed.to(paid, cond=["payment_success", "offer_valid"]) |
There was a problem hiding this comment.
praise: Nice that you demonstrated that properties and attributes can be used directly.
suggestion: Maybe we could add an explicit note at dynamic dispatch that this is possible.
| But the good thing is that it implements the ``OR`` operator to combine transitions, | ||
| so you can use the ``|`` syntax to compound a list of transitions and assign | ||
| to the same event. | ||
| You have to declare all transitions for a state in one single line. |
There was a problem hiding this comment.
You have to declare all transitions for a state in one single line.
question: Why do you have added this statement? Can you give me an example?
I think that there's not that blocks someone from writing on multiple lines.
Example
Consider the Guess the number example, someone can write the events like this and it also works:
class GuessTheNumberMachine(StateMachine):
start = State("Start", initial=True)
low = State("Low")
high = State("High")
won = State("Won", final=True)
lose = State("Lose", final=True)
guess = lose.from_(low, high, cond="max_guesses_reached")
guess = guess | won.from_(low, high, cond="guess_is_equal")
guess = guess | low.from_(low, high, start, cond="guess_is_lower")
guess = guess | high.from_(low, high, start, cond="guess_is_higher") Or even the compact form:
class GuessTheNumberMachine(StateMachine):
start = State("Start", initial=True)
low = State("Low")
high = State("High")
won = State("Won", final=True)
lose = State("Lose", final=True)
guess = lose.from_(low, high, cond="max_guesses_reached")
guess |= won.from_(low, high, cond="guess_is_equal")
guess |= low.from_(low, high, start, cond="guess_is_lower")
guess |= high.from_(low, high, start, cond="guess_is_higher")
I personally prefer the "one-liner", but I would not say "have to".
What do you think?
|
Hi @Rosi2143, how are you? Are you still working on this? It's near the point that it can be merged. Please let me know if you need any help. Best regards! |
|
Hi @fgmacedo , I send a reply directly from Thunderbird that somehow didn't make it into this converstation. It's a test that shows - imho - that multiple lines produce a wrong result. Here the copy: Hi, here is my example: """Example of python module statemachine: https://pypi.org/project/python-statemachine/"""
import sys
import os
import logging
import inspect
from statemachine import State
from statemachine import StateMachine
class InvoiceStateMachine(StateMachine):
unpaid = State("unpaid", initial=True)
paid = State("paid")
failed = State("failed")
error = State("error")
paused = False
offer_valid = True
pay = (
unpaid.to(paid, cond="payment_success") |
unpaid.to(paid, cond=["payment_success", "offer_valid"])
)
pay = unpaid.to(failed, unless="paused")
pay = unpaid.to(error)
def payment_success(self):
return True
sm = InvoiceStateMachine()
print(sm.current_state.name)
sm.send("pay")
print(sm.current_state.name)I get: If I start removing lines - from the bottom the state keeps changing - always resulting in the last possible transition: """Example of python module statemachine: https://pypi.org/project/python-statemachine/"""
import sys
import os
import logging
import inspect
from statemachine import State
from statemachine import StateMachine
class InvoiceStateMachine(StateMachine):
unpaid = State("unpaid", initial=True)
paid = State("paid")
failed = State("failed")
# error = State("error")
paused = False
offer_valid = True
pay = (
unpaid.to(paid, cond="payment_success") |
unpaid.to(paid, cond=["payment_success", "offer_valid"])
)
pay = unpaid.to(failed, unless="paused")
# pay = unpaid.to(error)
def payment_success(self):
return True
sm = InvoiceStateMachine()
print(sm.current_state.name)
sm.send("pay")
print(sm.current_state.name)python test.py """Example of python module statemachine: https://pypi.org/project/python-statemachine/"""
import sys
import os
import logging
import inspect
from statemachine import State
from statemachine import StateMachine
class InvoiceStateMachine(StateMachine):
unpaid = State("unpaid", initial=True)
paid = State("paid")
# failed = State("failed")
# error = State("error")
paused = False
offer_valid = True
pay = (
unpaid.to(paid, cond="payment_success") |
unpaid.to(paid, cond=["payment_success", "offer_valid"])
)
# pay = unpaid.to(failed, unless="paused")
# pay = unpaid.to(error)
def payment_success(self):
return True
sm = InvoiceStateMachine()
print(sm.current_state.name)
sm.send("pay")
print(sm.current_state.name)python test.py If I put it all in a single line I get the expected result: """Example of python module statemachine: https://pypi.org/project/python-statemachine/"""
import sys
import os
import logging
import inspect
from statemachine import State
from statemachine import StateMachine
class InvoiceStateMachine(StateMachine):
unpaid = State("unpaid", initial=True)
paid = State("paid")
failed = State("failed")
error = State("error")
paused = False
offer_valid = True
pay = (
unpaid.to(paid, cond="payment_success") |
unpaid.to(paid, cond=["payment_success", "offer_valid"]) |
unpaid.to(failed, unless="paused") |
unpaid.to(error)
)
def payment_success(self):
return True
sm = InvoiceStateMachine()
print(sm.current_state.name)
sm.send("pay")
print(sm.current_state.name)python test.py |
|
Ah, ok, now I see. The difference is that we should think in terms of the assignment of a variable. With this construction, after the first assignment of pay = (
unpaid.to(paid, cond="payment_success") |
unpaid.to(paid, cond=["payment_success", "offer_valid"])
)
pay = unpaid.to(failed, unless="paused")
pay = unpaid.to(error)But this is just regular Python code working as expected, so there's nothing special happening here. Every time you assign a new value to an existing variable, you get the old value out of scope. This is why I think that we don't need to be explicit on the docs. When I say "assign transitions to an event name using multiple lines", I automatically think that for this to work, I need to concatenate to the previous value. This can be done using the previous value: pay = (
unpaid.to(paid, cond="payment_success") |
unpaid.to(paid, cond=["payment_success", "offer_valid"])
)
pay = pay | unpaid.to(failed, unless="paused")
pay = pay | unpaid.to(error)Or using the "in-place OR" operator: pay = (
unpaid.to(paid, cond="payment_success") |
unpaid.to(paid, cond=["payment_success", "offer_valid"])
)
pay |= unpaid.to(failed, unless="paused")
pay |= unpaid.to(error)But I think that this doesn't need to be mentioned in the docs as It's more related to "how Python works" than "how to use the library". What do you think? |
|
Hi @fgmacedo , I'll think of something to rewrite the lines and push a new change. |
usage aéxamples: - list of conditions - how to use validators - possible usage of properties Signed-off-by: Schrotti <Schrott.Micha@web.de>
corrected the description of how to add transitions using multiple lines Signed-off-by: Schrotti <Schrott.Micha@web.de>
cd0560b to
0274159
Compare
|
Kudos, SonarCloud Quality Gate passed!
|
|
|
||
| >>> transitions = draft.to(draft) | producing.to(closed) | ||
|
|
||
| ... and you can append additional transitions for a state to previous definitions. |
|
Hi @Rosi2143 , how are you? Please consider adding yourself to the contributor's list: https://github.com/fgmacedo/python-statemachine/blob/develop/docs/authors.md Best! |








usage aéxamples:
Signed-off-by: Schrotti Schrott.Micha@web.de