Skip to content

Commit 1d6972d

Browse files
Experimenting with automatically generating mermaid diagrams from examples
1 parent 4a94cf7 commit 1d6972d

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

app/tests/example_tests.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,12 @@ def test_custom_comparison_with_criteria_order(self, response, value, tags):
573573
}
574574
answer = "2*x^2"
575575
result = evaluation_function(response, answer, params, include_test_data=True)
576+
with open("diagrams.html", "a") as f:
577+
f.write(r'<!DOCTYPE html><html lang="en"><body><style>.mermaid {display: inline-flex;}</style>\n')
578+
for g in result["criteria_graphs_vis"].values():
579+
print(g)
580+
f.write('<pre class="mermaid">\n'+g+'\n</pre>\n')
581+
f.write('<script type="module"> import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";</script></body></html>')
576582
assert result["is_correct"] is value
577583
assert set(tags) == set(result["tags"])
578584

app/utility/criteria_graph_utilities.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,16 +180,22 @@ def json(self):
180180
return str(json.dumps(graph))
181181

182182
def mermaid(self):
183-
output = ["graph TD"]
183+
output = ["flowchart TD"]
184+
linebreak = '<br/>---<br/>'
184185
edges = set()
185186
sufficiencies = set()
186187
node_sets = [self.evaluations, self.criteria, self.outputs]
187188
node_styles = [evaluation_style, criterion_style, output_style]
189+
node_keys = {}
190+
for set_index, nodes in enumerate(node_sets):
191+
index = 0
192+
for (label, node) in nodes.items():
193+
node_keys.update({label: "N_"+str(set_index)+"_"+str(index)})
188194
for set_index, nodes in enumerate(node_sets):
189195
style = node_styles[set_index]
190196
for (label, node) in nodes.items():
191-
output.append(label+style[0]+'"'+node.summary+'"'+style[1])
192-
edges.update([(edge.source.label, edge.target.label) for edge in node.outgoing+node.incoming])
197+
output.append(node_keys[label]+style[0]+'"'+label+linebreak+node.summary+'"'+style[1])
198+
edges.update([(node_keys[edge.source.label], node_keys[edge.target.label]) for edge in node.outgoing+node.incoming])
193199
if self.sufficiencies.get(label, None) is not None:
194200
sufficiencies.update([(label, sufficiency) for sufficiency in self.sufficiencies.get(label, None)])
195201
for edge in edges:

app/utility/evaluation_result_utilities.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ def __init__(self):
55
self._feedback = [] # A list that will hold all feedback items
66
self._feedback_tags = {} # A dictionary that holds a list with indices to all feedback items with the same tag
77
self._criteria_graphs = {}
8+
self._criteria_graphs_vis = {}
89
self.latex = ""
910
self.simplified = ""
1011

@@ -41,6 +42,7 @@ def add_feedback_from_tags(self, tags, graph, custom_feedback=None):
4142

4243
def add_criteria_graph(self, name, graph):
4344
self._criteria_graphs.update({name: graph.json()})
45+
self._criteria_graphs_vis.update({name: graph.mermaid()})
4446

4547
def _serialise_feedback(self) -> str:
4648
feedback = []
@@ -56,6 +58,7 @@ def serialise(self, include_test_data=False) -> dict:
5658
out.update(dict(tags=list(self._feedback_tags.keys())))
5759
if include_test_data is True:
5860
out.update(dict(criteria_graphs=self._criteria_graphs))
61+
out.update(dict(criteria_graphs_vis=self._criteria_graphs_vis))
5962
if self.latex is not None:
6063
out.update(dict(response_latex=self.latex))
6164
if self.simplified is not None:

diagrams.html

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!DOCTYPE html><html lang="en"><body><style>.mermaid {display: inline-flex;}</style>
2+
<pre class="mermaid">
3+
flowchart TD
4+
subgraph "answer <= response"
5+
N_0_0(["answer <= response<br/>---<br/>answer <= response"])
6+
N_1_0["answer <= response_TRUE<br/>---<br/>True"]
7+
N_1_0["answer <= response_FALSE<br/>---<br/>True"]
8+
N_1_0["answer <= response_UNKNOWN<br/>---<br/>True"]
9+
N_2_0{{"END<br/>---<br/>END"}}
10+
N_1_0 --> N_2_0
11+
N_0_0 --> N_1_0
12+
end
13+
subgraph "2+answer > response"
14+
N_0_0(["2+answer > response<br/>---<br/>2+answer > response"])
15+
N_1_0["2+answer > response_TRUE<br/>---<br/>True"]
16+
N_1_0["2+answer > response_FALSE<br/>---<br/>True"]
17+
N_1_0["2+answer > response_UNKNOWN<br/>---<br/>True"]
18+
N_2_0{{"END<br/>---<br/>END"}}
19+
N_1_0 --> N_2_0
20+
N_0_0 --> N_1_0
21+
end
22+
</pre>
23+
<script type="module"> import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";</script></body></html><!DOCTYPE html><html lang="en"><body><style>.mermaid {display: inline-flex;}</style>\n<pre class="mermaid">
24+
flowchart TD
25+
N_0_0(["2+answer > response<br/>---<br/>2+answer > response"])
26+
N_1_0["2+answer > response_TRUE<br/>---<br/>True"]
27+
N_1_0["2+answer > response_FALSE<br/>---<br/>True"]
28+
N_1_0["2+answer > response_UNKNOWN<br/>---<br/>True"]
29+
N_2_0{{"END<br/>---<br/>END"}}
30+
N_1_0 --> N_2_0
31+
N_0_0 --> N_1_0
32+
</pre>
33+
<pre class="mermaid">
34+
flowchart TD
35+
N_0_0(["answer <= response<br/>---<br/>answer <= response"])
36+
N_1_0["answer <= response_TRUE<br/>---<br/>True"]
37+
N_1_0["answer <= response_FALSE<br/>---<br/>True"]
38+
N_1_0["answer <= response_UNKNOWN<br/>---<br/>True"]
39+
N_2_0{{"END<br/>---<br/>END"}}
40+
N_1_0 --> N_2_0
41+
N_0_0 --> N_1_0
42+
</pre>
43+
<script type="module"> import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";</script></body></html>

0 commit comments

Comments
 (0)