generated from pyiron/pyiron_module_template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[minor] Replace while with a macro pattern (#364)
* Add a new standard node for appending to a list * Demonstrate and test while loops as a macro This is pickleable and clear to write and read. I don't have a convenience wrapper yet to get rid of the "universal" stuff though. * Remove the while-loop metanode It was janky, the UI was not even particularly nice, and it wouldn't pickle. Just axe it. * 🐛 include the new standard node in the exported `nodes` list * Improve test comments * Update deepdive to use the new while example Instead of the old while metanode * Remove unused import
- Loading branch information
Showing
7 changed files
with
1,012 additions
and
673 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,4 +53,3 @@ | |
inputs_to_list, | ||
list_to_outputs, | ||
) | ||
from pyiron_workflow.nodes.while_loop import while_loop |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import pickle | ||
import unittest | ||
|
||
from pyiron_workflow import as_macro_node, standard_nodes as std | ||
|
||
|
||
@as_macro_node("greater") | ||
def AddWhileLessThan(self, a, b, cap): | ||
""" | ||
Add :param:`b` to :param:`a` while the sum is less than or equal to :param:`cap`. | ||
A simple but complete demonstrator for how to construct cyclic flows, including | ||
logging key outputs during the loop. | ||
""" | ||
# Bespoke logic | ||
self.body = std.Add(obj=a, other=b) | ||
self.body.inputs.obj = self.body.outputs.add # Higher priority connection | ||
# The output is NOT_DATA on the first pass and `a` gets used, | ||
# But after that the node will find and use its own output | ||
self.condition = std.LessThan(self.body, cap) | ||
|
||
# Universal logic | ||
self.switch = std.If() | ||
self.switch.inputs.condition = self.condition | ||
|
||
self.starting_nodes = [self.body] | ||
self.body >> self.condition >> self.switch | ||
self.switch.signals.output.true >> self.body | ||
|
||
# Bespoke logging | ||
self.history = std.AppendToList() | ||
self.history.inputs.existing = self.history | ||
self.history.inputs.new_element = self.body | ||
self.body >> self.history | ||
|
||
# Returns are pretty universal for single-value body nodes, | ||
# assuming a log of the history is not desired as output, | ||
# but in general return values are also bespoke | ||
return self.body | ||
|
||
|
||
class TestWhileLoop(unittest.TestCase): | ||
def test_while_loop(self): | ||
a, b, cap = 0, 2, 5 | ||
n = AddWhileLessThan(a, b, cap, run_after_init=True) | ||
self.assertGreaterEqual( | ||
6, | ||
n.outputs.greater.value, | ||
msg="Verify output" | ||
) | ||
self.assertListEqual( | ||
[2, 4, 6], | ||
n.history.outputs.list.value, | ||
msg="Verify loop history logging" | ||
) | ||
self.assertListEqual( | ||
[ | ||
'body', | ||
'history', | ||
'condition', | ||
'switch', | ||
'body', | ||
'history', | ||
'condition', | ||
'switch', | ||
'body', | ||
'history', | ||
'condition', | ||
'switch' | ||
], | ||
n.provenance_by_execution, | ||
msg="Verify execution order -- the same nodes get run repeatedly in acyclic" | ||
) | ||
reloaded = pickle.loads(pickle.dumps(n)) | ||
self.assertListEqual( | ||
reloaded.history.outputs.list.value, | ||
n.history.outputs.list.value, | ||
msg="Should be able to save and re-load cyclic graphs just like usual" | ||
) |
Oops, something went wrong.