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.
Files changed (25) hide show
  1. {thinking_processes-1.6.0/thinking_processes.egg-info → thinking_processes-1.7.0}/PKG-INFO +1 -1
  2. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/pyproject.toml +1 -1
  3. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/evaporating_cloud.py +49 -21
  4. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/prerequisite_tree/node.py +15 -1
  5. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/prerequisite_tree/prerequisite_tree.py +17 -3
  6. {thinking_processes-1.6.0 → thinking_processes-1.7.0/thinking_processes.egg-info}/PKG-INFO +1 -1
  7. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/LICENSE +0 -0
  8. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/MANIFEST.in +0 -0
  9. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/README.md +0 -0
  10. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/setup.cfg +0 -0
  11. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/__init__.py +0 -0
  12. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/__init__.py +0 -0
  13. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/causal_relation.py +0 -0
  14. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/current_reality_tree.py +0 -0
  15. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/current_reality_tree/node.py +0 -0
  16. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/diagram.py +0 -0
  17. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/__init__.py +0 -0
  18. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/causal_relation.py +0 -0
  19. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/future_reality_tree.py +0 -0
  20. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/future_reality_tree/node.py +0 -0
  21. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes/prerequisite_tree/__init__.py +0 -0
  22. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/SOURCES.txt +0 -0
  23. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/dependency_links.txt +0 -0
  24. {thinking_processes-1.6.0 → thinking_processes-1.7.0}/thinking_processes.egg-info/requires.txt +0 -0
  25. {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.6.0
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
@@ -7,7 +7,7 @@ include = ["thinking_processes*"]
7
7
 
8
8
  [project]
9
9
  name = "thinking-processes"
10
- version = "1.6.0"
10
+ version = "1.7.0"
11
11
  dependencies = [
12
12
  "graphviz",
13
13
  "drawpyo"
@@ -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.__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
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.__objective,
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.__need_a,
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.__need_b,
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.__conflict_part_a,
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.__conflict_part_b,
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.__objective}',
130
- f'need_a: {self.__need_a}',
131
- f'need_b: {self.__need_b}',
132
- f'conflict_a: {self.__conflict_part_a}',
133
- f'conflict_b: {self.__conflict_part_b}',
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.__objective = line.split(':', maxsplit=1)[1].strip()
178
+ ec.objective = line.split(':', maxsplit=1)[1].strip()
151
179
  elif line.startswith('need_a:'):
152
- ec.__need_a = line.split(':', maxsplit=1)[1].strip()
180
+ ec.need_a = line.split(':', maxsplit=1)[1].strip()
153
181
  elif line.startswith('need_b:'):
154
- ec.__need_b = line.split(':', maxsplit=1)[1].strip()
182
+ ec.need_b = line.split(':', maxsplit=1)[1].strip()
155
183
  elif line.startswith('conflict_a:'):
156
- ec.__conflict_part_a = line.split(':', maxsplit=1)[1].strip()
184
+ ec.conflict_part_a = line.split(':', maxsplit=1)[1].strip()
157
185
  elif line.startswith('conflict_b:'):
158
- ec.__conflict_part_b = line.split(':', maxsplit=1)[1].strip()
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
@@ -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.__objective = objective
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.__objective, fillcolor='green', style='filled,rounded')
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.__objective}\n{"\n".join(map(lambda o: obstacle_to_string(o, 1), self.__obstacles))}'
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.6.0
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