thinking-processes 1.6.0__tar.gz → 1.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {thinking_processes-1.6.0/thinking_processes.egg-info → thinking_processes-1.7.0}/PKG-INFO +1 -1
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/pyproject.toml +1 -1
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/evaporating_cloud.py +49 -21
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/prerequisite_tree/node.py +15 -1
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/prerequisite_tree/prerequisite_tree.py +17 -3
- {thinking_processes-1.6.0 → thinking_processes-1.7.0/thinking_processes.egg-info}/PKG-INFO +1 -1
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/LICENSE +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/MANIFEST.in +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/README.md +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/setup.cfg +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/__init__.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/__init__.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/causal_relation.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/current_reality_tree.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/node.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/diagram.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/__init__.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/causal_relation.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/future_reality_tree.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/node.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/prerequisite_tree/__init__.py +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/SOURCES.txt +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/dependency_links.txt +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/requires.txt +0 -0
- {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thinking-processes
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: Diagramming tools for the Thinking Processes from the Theory of Constraints
|
|
5
5
|
Author-email: Boris Wiegand <boris.wiegand@stahl-holding-saar.de>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
{thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/evaporating_cloud.py
RENAMED
|
@@ -31,11 +31,11 @@ class EvaporatingCloud(Diagram):
|
|
|
31
31
|
self, objective: str = '?',
|
|
32
32
|
need_a: str = '?', need_b: str = '?',
|
|
33
33
|
conflict_part_a: str = '?', conflict_part_b: str = '?'):
|
|
34
|
-
self.
|
|
35
|
-
self.
|
|
36
|
-
self.
|
|
37
|
-
self.
|
|
38
|
-
self.
|
|
34
|
+
self.objective = objective
|
|
35
|
+
self.need_a = need_a
|
|
36
|
+
self.need_b = need_b
|
|
37
|
+
self.conflict_part_a = conflict_part_a
|
|
38
|
+
self.conflict_part_b = conflict_part_b
|
|
39
39
|
self.__assumptions_between_conflict_parts: list[tuple[str,bool|None]] = []
|
|
40
40
|
self.__assumptions_on_need_a: list[tuple[str,bool|None]] = []
|
|
41
41
|
self.__assumptions_on_need_b: list[tuple[str,bool|None]] = []
|
|
@@ -49,11 +49,39 @@ class EvaporatingCloud(Diagram):
|
|
|
49
49
|
def add_assumption_on_need_b(self, text: str, is_true: bool|None = None):
|
|
50
50
|
self.__assumptions_on_need_b.append((text, is_true))
|
|
51
51
|
|
|
52
|
+
def get_total_nr_of_assumptions(self) -> int:
|
|
53
|
+
return (
|
|
54
|
+
len(self.__assumptions_between_conflict_parts)
|
|
55
|
+
+ len(self.__assumptions_on_need_a)
|
|
56
|
+
+ len(self.__assumptions_on_need_b)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def remove_assumption(self, text: str):
|
|
60
|
+
"""
|
|
61
|
+
removes any assumption equalling the given text.
|
|
62
|
+
if there is no matching node in the diagram, nothing happens.
|
|
63
|
+
"""
|
|
64
|
+
self.__assumptions_between_conflict_parts = [
|
|
65
|
+
(assumption, is_true)
|
|
66
|
+
for assumption, is_true in self.__assumptions_between_conflict_parts
|
|
67
|
+
if assumption != text
|
|
68
|
+
]
|
|
69
|
+
self.__assumptions_on_need_a = [
|
|
70
|
+
(assumption, is_true)
|
|
71
|
+
for assumption, is_true in self.__assumptions_on_need_a
|
|
72
|
+
if assumption != text
|
|
73
|
+
]
|
|
74
|
+
self.__assumptions_on_need_b = [
|
|
75
|
+
(assumption, is_true)
|
|
76
|
+
for assumption, is_true in self.__assumptions_on_need_b
|
|
77
|
+
if assumption != text
|
|
78
|
+
]
|
|
79
|
+
|
|
52
80
|
@override
|
|
53
81
|
def to_graphviz(self) -> Graph:
|
|
54
82
|
graph = Digraph(graph_attr=dict(rankdir="RL", nodesep='0.5'))
|
|
55
83
|
graph.node(
|
|
56
|
-
'objective', self.
|
|
84
|
+
'objective', self.objective,
|
|
57
85
|
fillcolor='lightgreen', shape='rect', style='rounded,filled',
|
|
58
86
|
)
|
|
59
87
|
with graph.subgraph(graph_attr=dict(concentrate='true', rank='same')) as subgraph:
|
|
@@ -65,11 +93,11 @@ class EvaporatingCloud(Diagram):
|
|
|
65
93
|
)
|
|
66
94
|
with graph.subgraph(graph_attr=dict(rank="same")) as subgraph:
|
|
67
95
|
subgraph.node(
|
|
68
|
-
'need_a', self.
|
|
96
|
+
'need_a', self.need_a,
|
|
69
97
|
fillcolor='lightblue', shape='rect', style='rounded,filled',
|
|
70
98
|
)
|
|
71
99
|
subgraph.node(
|
|
72
|
-
'need_b', self.
|
|
100
|
+
'need_b', self.need_b,
|
|
73
101
|
fillcolor='lightblue', shape='rect', style='rounded,filled',
|
|
74
102
|
)
|
|
75
103
|
graph.edge('need_a', 'objective')
|
|
@@ -83,11 +111,11 @@ class EvaporatingCloud(Diagram):
|
|
|
83
111
|
)
|
|
84
112
|
with graph.subgraph(graph_attr=dict(rank="same")) as subgraph:
|
|
85
113
|
subgraph.node(
|
|
86
|
-
'conflict_part_a', self.
|
|
114
|
+
'conflict_part_a', self.conflict_part_a,
|
|
87
115
|
fillcolor='darkorange', shape='rect', style='rounded,filled',
|
|
88
116
|
)
|
|
89
117
|
subgraph.node(
|
|
90
|
-
'conflict_part_b', self.
|
|
118
|
+
'conflict_part_b', self.conflict_part_b,
|
|
91
119
|
fillcolor='darkorange', shape='rect', style='rounded,filled',
|
|
92
120
|
)
|
|
93
121
|
subgraph.edge('conflict_part_a', 'conflict_part_b', dir='both')
|
|
@@ -112,7 +140,7 @@ class EvaporatingCloud(Diagram):
|
|
|
112
140
|
color = 'green'
|
|
113
141
|
else:
|
|
114
142
|
color = 'red'
|
|
115
|
-
graph.node(node_id, assumption, color=color)
|
|
143
|
+
graph.node(node_id, assumption, color=color, fillcolor='white')
|
|
116
144
|
graph.edge(node_id, target_a, dir='none', color='gray')
|
|
117
145
|
if target_b is not None:
|
|
118
146
|
graph.edge(node_id, target_b, dir='none', color='gray')
|
|
@@ -126,11 +154,11 @@ class EvaporatingCloud(Diagram):
|
|
|
126
154
|
else:
|
|
127
155
|
return 'false_'
|
|
128
156
|
return '\n'.join([
|
|
129
|
-
f'obj: {self.
|
|
130
|
-
f'need_a: {self.
|
|
131
|
-
f'need_b: {self.
|
|
132
|
-
f'conflict_a: {self.
|
|
133
|
-
f'conflict_b: {self.
|
|
157
|
+
f'obj: {self.objective}',
|
|
158
|
+
f'need_a: {self.need_a}',
|
|
159
|
+
f'need_b: {self.need_b}',
|
|
160
|
+
f'conflict_a: {self.conflict_part_a}',
|
|
161
|
+
f'conflict_b: {self.conflict_part_b}',
|
|
134
162
|
] + [
|
|
135
163
|
f'{assumption_state_prefix(assumption_state)}assumption_on_conflict: {assumption}'
|
|
136
164
|
for assumption, assumption_state in sorted(self.__assumptions_between_conflict_parts)
|
|
@@ -147,15 +175,15 @@ class EvaporatingCloud(Diagram):
|
|
|
147
175
|
ec = EvaporatingCloud()
|
|
148
176
|
for line in s.splitlines():
|
|
149
177
|
if line.startswith('obj:'):
|
|
150
|
-
ec.
|
|
178
|
+
ec.objective = line.split(':', maxsplit=1)[1].strip()
|
|
151
179
|
elif line.startswith('need_a:'):
|
|
152
|
-
ec.
|
|
180
|
+
ec.need_a = line.split(':', maxsplit=1)[1].strip()
|
|
153
181
|
elif line.startswith('need_b:'):
|
|
154
|
-
ec.
|
|
182
|
+
ec.need_b = line.split(':', maxsplit=1)[1].strip()
|
|
155
183
|
elif line.startswith('conflict_a:'):
|
|
156
|
-
ec.
|
|
184
|
+
ec.conflict_part_a = line.split(':', maxsplit=1)[1].strip()
|
|
157
185
|
elif line.startswith('conflict_b:'):
|
|
158
|
-
ec.
|
|
186
|
+
ec.conflict_part_b = line.split(':', maxsplit=1)[1].strip()
|
|
159
187
|
else:
|
|
160
188
|
if line.startswith('true_'):
|
|
161
189
|
assumption_state = True
|
{thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/prerequisite_tree/node.py
RENAMED
|
@@ -38,8 +38,15 @@ class Obstacle:
|
|
|
38
38
|
def text(self) -> str:
|
|
39
39
|
return self.__obstacle
|
|
40
40
|
|
|
41
|
+
@text.setter
|
|
42
|
+
def text(self, value: str):
|
|
43
|
+
self.__obstacle = value
|
|
44
|
+
|
|
41
45
|
def iter_solutions(self) -> Iterator['Solution']:
|
|
42
46
|
return iter(self.__solutions)
|
|
47
|
+
|
|
48
|
+
def iter_subnodes(self) -> Iterator['Solution']:
|
|
49
|
+
return iter(self.__solutions)
|
|
43
50
|
|
|
44
51
|
def add_solution(self, solution: str) -> 'Solution':
|
|
45
52
|
child_node = Solution(f'{self.__id}.{len(self.__solutions)}', solution)
|
|
@@ -75,10 +82,17 @@ class Solution:
|
|
|
75
82
|
@property
|
|
76
83
|
def text(self) -> str:
|
|
77
84
|
return self.__solution
|
|
78
|
-
|
|
85
|
+
|
|
86
|
+
@text.setter
|
|
87
|
+
def text(self, value: str):
|
|
88
|
+
self.__solution = value
|
|
89
|
+
|
|
79
90
|
def iter_obstacles(self) -> Iterator[Obstacle]:
|
|
80
91
|
return iter(self.__obstacles)
|
|
81
92
|
|
|
93
|
+
def iter_subnodes(self) -> Iterator[Obstacle]:
|
|
94
|
+
return iter(self.__obstacles)
|
|
95
|
+
|
|
82
96
|
def add_obstacle(self, obstacle: str) -> Obstacle:
|
|
83
97
|
child_node = Obstacle(f'{self.__id}.{len(self.__obstacles)}', obstacle)
|
|
84
98
|
self.__obstacles.append(child_node)
|
|
@@ -32,7 +32,7 @@ class PrerequisiteTree(Diagram):
|
|
|
32
32
|
"""
|
|
33
33
|
creates a new prerequisite tree with the given objective
|
|
34
34
|
"""
|
|
35
|
-
self.
|
|
35
|
+
self.objective = objective
|
|
36
36
|
self.__obstacles: list[Obstacle] = []
|
|
37
37
|
|
|
38
38
|
def add_obstacle(self, obstacle: str) -> Obstacle:
|
|
@@ -58,7 +58,7 @@ class PrerequisiteTree(Diagram):
|
|
|
58
58
|
@override
|
|
59
59
|
def to_graphviz(self) -> Graph:
|
|
60
60
|
graph = Digraph(graph_attr=dict(rankdir="BT"))
|
|
61
|
-
graph.node('objective', self.
|
|
61
|
+
graph.node('objective', self.objective, fillcolor='green', style='filled,rounded')
|
|
62
62
|
for obstacle in self.__obstacles:
|
|
63
63
|
obstacle.add_to_graphviz_graph(graph, 'objective')
|
|
64
64
|
return graph
|
|
@@ -153,4 +153,18 @@ class PrerequisiteTree(Diagram):
|
|
|
153
153
|
obstacle_to_string(o, level + 1)
|
|
154
154
|
for o in solution.iter_obstacles()
|
|
155
155
|
])
|
|
156
|
-
return f'{self.
|
|
156
|
+
return f'{self.objective}\n{"\n".join(map(lambda o: obstacle_to_string(o, 1), self.__obstacles))}'
|
|
157
|
+
|
|
158
|
+
def get_node_by_id(self, node_id: str) -> Obstacle|Solution:
|
|
159
|
+
"""
|
|
160
|
+
returns the node with the given id.
|
|
161
|
+
The id of a node is a string that is generated when the node is created.
|
|
162
|
+
Raises an IndexError if no node with the given id exists in this tree.
|
|
163
|
+
"""
|
|
164
|
+
candidate_nodes = list(self.__obstacles)
|
|
165
|
+
while candidate_nodes:
|
|
166
|
+
node = candidate_nodes.pop()
|
|
167
|
+
if node.id == node_id:
|
|
168
|
+
return node
|
|
169
|
+
candidate_nodes.extend(node.iter_subnodes())
|
|
170
|
+
raise IndexError(f'no node with id "{node_id}" found in this tree')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thinking-processes
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: Diagramming tools for the Thinking Processes from the Theory of Constraints
|
|
5
5
|
Author-email: Boris Wiegand <boris.wiegand@stahl-holding-saar.de>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/node.py
RENAMED
|
File without changes
|
|
File without changes
|
{thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/requires.txt
RENAMED
|
File without changes
|
{thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/top_level.txt
RENAMED
|
File without changes
|