-
Notifications
You must be signed in to change notification settings - Fork 3
Inject output nodes #125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inject output nodes #125
Conversation
So we can inject length checks on OutputData values
by injecting new nodes!
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferencesYou may notice some variations in coverage metrics with the latest Coverage engine update. For more details, visit the documentation |
Pull Request Test Coverage Report for Build 7138622706
💛 - Coveralls |
This is necessary for node injection when processing output: if you're injecting a node on top of an existing result you probably want the injection immediately available, but if you're injecting it at the end of something that hasn't run yet you don't want to see an error.
I used this class to try out ChatGPT3.5. It was almost entirely drivel, but I'll be damned if it didn't notice that I defined this property twice.
Ok, so I can chain in slices now just fine. The only catch is that the unary operators like Thus you need to use the dunder directly, and I think I want to replace these guys with regular methods instead, e.g. from pyiron_workflow import Workflow
Workflow.register("plotting", "pyiron_workflow.node_library.plotting")
n = 5
wf = Workflow("injection_demo")
wf.half_list = wf.create.standard.UserInput(list(range(n)))
wf.other_half = wf.create.standard.UserInput(list(range(n, 2*n)))
@Workflow.wrap_as.single_value_node("arange")
def Arange(length):
import numpy as np
return np.arange(length)
wf.arange = Arange(3 * n)
wf.full_list = wf.half_list + wf.other_half # Adds two lists -- i.e. appending
wf.scatter = wf.create.plotting.Scatter(
wf.full_list,
(wf.arange**2)[:wf.full_list.__len__()] # Chains the power of a numpy array with a slice
)
wf() |
So it doesn't execute prematurely with all those defaults and crash hard
Some operators like `len(obj)` get really pissy if `obj.__len__()` doesn't return the type they're expecting. Since we want to be returning, e.g. here, channels instead of ints, we'd better not mess with these operators. I'm following the practice of using their dunder names as the basis for a method.
The builtin functions do a stupid type check
And the way they propagate all the way to SingleValue
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
Allow operations directly on output channels (e.g. addition, item access, etc.) and resolve this by dynamically injecting a new node from the standard library to handle the operation.
E.g.
Closes #90
TODO:
SingleValue
to be used directlyEDIT: A more powerful example with
SingleValue
:The output being a nice y=x^2 matplotlib scatter plot.
Note that you can't replace
[:2*n]
with[:len(wf.half_list + wf.other_half)]
. You can almost get there by chaining together actual nodes in the standard package, but we don't yet have good enough treatment of slices to get all the way there. E.g. you could pull out a single element (the (2n)th one) like this:(I guess adding a
Slice
node would do it, and maybe there is some tricks nesting this inGetItem
with some type checks to get the syntactic sugar version working too...)Nonetheless, this really gets a long way towards writing "organic" python with the nodes.