add readme, move testing function to lib
This commit is contained in:
parent
2fb8318506
commit
8b3f543bda
5 changed files with 118 additions and 10 deletions
41
README.md
Normal file
41
README.md
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
Starting point for the Statecharts assignment of MoSIS in the academic year 2024-2025.
|
||||||
|
|
||||||
|
Clone this repository, and import the `StartingPoint` directory as an Itemis CREATE project (without copying the files). This way, you can still do a `git pull` in case of a bug fix in the Python code.
|
||||||
|
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
To run the Python scripts, you need the following:
|
||||||
|
|
||||||
|
- **Python 3.?** (tested with 3.12)
|
||||||
|
- **TkInter** library (included in most Python distributions)
|
||||||
|
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
### Exercises
|
||||||
|
|
||||||
|
Files related to the exercises:
|
||||||
|
- **`StartingPoint/exercises/`**: (DO NOT EDIT) directory that contains the exercises. Each exercise is a Statechart model that you can run/debug in ITEMIS.
|
||||||
|
- **`StartingPoint/runner_exercises_tests.py`**: (FEEL FREE TO EDIT) runs automated tests on (generated code from) the exercise models. Feel free to edit and run this file to understand the exercises better.
|
||||||
|
|
||||||
|
### Assignment
|
||||||
|
|
||||||
|
Files related to the assignment:
|
||||||
|
- **`StartingPoint/Statechart.ysc`**: (MUST EDIT THIS) this is the Statechart model.
|
||||||
|
- **`StartingPoint/runner_tests.py`**: (ADD ONE TEST) runs automated tests on your Statechart. It already includes 3 test scenarios, which your solution **must pass**! You are not allowed to modify the existing tests. You must however **add one test** to it.
|
||||||
|
- **`StartingPoint/runner_gui.py`**: (DO NOT EDIT) this script runs a TkInter GUI that allows you to interact with your Statechart.
|
||||||
|
|
||||||
|
When running the GUI, you can pass an additional `time_scale` parameter, as such:
|
||||||
|
```
|
||||||
|
cd StartingPoint
|
||||||
|
python runner_gui.py 0.5
|
||||||
|
```
|
||||||
|
This will run the simulation at half-speed.
|
||||||
|
|
||||||
|
### Background
|
||||||
|
|
||||||
|
Other files:
|
||||||
|
- **`StartingPoint/PythonGenerator.sgen`**: (DO NOT EDIT) specifies how ITEMIS should generate Python code from the models.
|
||||||
|
- **`StartingPoint/srcgen/`**: (DO NOT EDIT BY HAND) This directory contains Python code generated from the models. Each time you change a model, code will be re-generated, overwriting the files in this directory.
|
||||||
|
- **`StartingPoint/lib/`**: (DO NOT EDIT) A Statecharts run-time library, for running the generated code in (scaled) real-time while integrating with TkInter's event loop (for the GUI), and for running the Python tests (simulating as-fast-as-possible).
|
||||||
|
|
@ -134,3 +134,14 @@ def run_scenario(input_trace, expected_output_trace, statechart_class, INITIAL,
|
||||||
elif verbose:
|
elif verbose:
|
||||||
print_diff()
|
print_diff()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def run_scenarios(scenarios, statechart_class, initial, idempotent, verbose=True):
|
||||||
|
ok = True
|
||||||
|
for scenario in scenarios:
|
||||||
|
print(f"Running scenario: {scenario["name"]}")
|
||||||
|
ok = run_scenario(scenario["input_events"], scenario["output_events"], statechart_class, initial, idempotent, verbose=verbose) and ok
|
||||||
|
print("--------")
|
||||||
|
if ok:
|
||||||
|
print("All scenarios passed.")
|
||||||
|
else:
|
||||||
|
print("Some scenarios failed.")
|
||||||
|
|
|
||||||
63
StartingPoint/runner_exercises_tests.py
Normal file
63
StartingPoint/runner_exercises_tests.py
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
from srcgen import a, b, c, d, e
|
||||||
|
from lib.test import run_scenarios
|
||||||
|
|
||||||
|
SCENARIOS_A = [
|
||||||
|
{
|
||||||
|
"name": "A",
|
||||||
|
"input_events": [],
|
||||||
|
"output_events": [
|
||||||
|
(1000000000, "x", None),
|
||||||
|
(2000000000, "x", None),
|
||||||
|
(3000000000, "x", None),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
SCENARIOS_B = [
|
||||||
|
{
|
||||||
|
"name": "B",
|
||||||
|
"input_events": [],
|
||||||
|
"output_events": [
|
||||||
|
(2000000000, "inner", None),
|
||||||
|
(3000000000, "outer", None),
|
||||||
|
(5000000000, "inner", None),
|
||||||
|
(6000000000, "outer", None),
|
||||||
|
(8000000000, "inner", None),
|
||||||
|
(9000000000, "outer", None),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
SCENARIOS_C = [
|
||||||
|
{
|
||||||
|
"name": "C",
|
||||||
|
"input_events": [],
|
||||||
|
"output_events": [],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
SCENARIOS_D = [
|
||||||
|
{
|
||||||
|
"name": "D",
|
||||||
|
"input_events": [],
|
||||||
|
"output_events": [],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
SCENARIOS_E = [
|
||||||
|
{
|
||||||
|
"name": "E",
|
||||||
|
"input_events": [],
|
||||||
|
"output_events": [
|
||||||
|
(1000000000, "x", None),
|
||||||
|
(1000000000, "y", None),
|
||||||
|
(2000000000, "x", None),
|
||||||
|
(2000000000, "y", None),
|
||||||
|
(3000000000, "x", None),
|
||||||
|
(3000000000, "y", None),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run_scenarios(SCENARIOS_A, a.A, [], [], verbose=True)
|
||||||
|
run_scenarios(SCENARIOS_B, b.B, [], [], verbose=True)
|
||||||
|
run_scenarios(SCENARIOS_C, c.C, [], [], verbose=True)
|
||||||
|
run_scenarios(SCENARIOS_D, d.D, [], [], verbose=True)
|
||||||
|
run_scenarios(SCENARIOS_E, e.E, [], [], verbose=True)
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import tkinter
|
import tkinter
|
||||||
import atexit
|
import atexit
|
||||||
|
import sys
|
||||||
|
|
||||||
# load generated Statechart code
|
# load generated Statechart code
|
||||||
from srcgen.water_level_simulator import WaterLevelSimulator
|
from srcgen.water_level_simulator import WaterLevelSimulator
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import functools
|
import functools
|
||||||
from lib.test import run_scenario
|
from lib.test import run_scenarios
|
||||||
|
|
||||||
# from srcgen.lock_controller import LockController
|
# from srcgen.lock_controller import LockController
|
||||||
from srcgen.solution import Solution as LockController # Teacher's solution
|
from srcgen.solution import Solution as LockController # Teacher's solution
|
||||||
|
|
@ -229,12 +229,4 @@ INITIAL = [
|
||||||
]
|
]
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
ok = True
|
run_scenarios(SCENARIOS, LockController, INITIAL, IDEMPOTENT)
|
||||||
for scenario in SCENARIOS:
|
|
||||||
print(f"Running scenario: {scenario["name"]}")
|
|
||||||
ok = run_scenario(scenario["input_events"], scenario["output_events"], LockController, INITIAL, IDEMPOTENT, verbose=False) and ok
|
|
||||||
print("--------")
|
|
||||||
if ok:
|
|
||||||
print("All scenarios passed.")
|
|
||||||
else:
|
|
||||||
print("Some scenarios failed.")
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue