Code Monkey home page Code Monkey logo

pyno's People

Contributors

bilderbuchi avatar drtrigon avatar honix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyno's Issues

Pyno requires pyglet 1.5.27 and a patch on Python 3.11

See below how to make it run on Python 3.11 and why it fails with pyglet version 2.0.7:

import pyglet #o#0#o# requires pyglet version 1.5.27
# With pyglet 2.0.7 there is an error:
#   File "~/.local/lib/python3.11/site-packages/pyno/draw.py", line 7, in <module>
#     class UIGroup(pyglet.graphics.OrderedGroup):
#                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# AttributeError: module 'pyglet.graphics' has no attribute 'OrderedGroup'
# Because: 
# pyglet-2.0.7/doc/programming_guide/migration.rst:50:`OrderedGroup` has been removed. Instead, all Groups now have an `order`

from inspect import getfullargspec as getargspec  #o#0#o# OK on Python 3.11
# from inspect import getargspec # fails on Python 3.11 with:
#     from inspect import getargspec  
#     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# ImportError: cannot import name 'getargspec' from 'inspect' (/usr/local/lib/python3.11/inspect.py)

Flow-control concept

Im considering to develop flow-control mechanics for pyno.

Right now pyno do the update of all nodes 60 times per second. It is good for real-time systems, but bad for other classes of programs, for example calculator. It is also a waste of processor time.

This aproach also seen in vvvv visual language. It also reminds me functional nature of algorithms. In some cases it seems more natural to just define operators, put some data and dynamicly (!) see the process. Dynamic nature is one of main goals of pyno.

Another approach is flow-control - the way to execute nodes in order you need. It will allow to do condition branches and loops (can be main loop done this way?).

Examples is UnrealEngine's blueprints, cables.gl and VL from vvvv guys.

They differently solve this concept. I mostly like cables.gl approach, it bulds around signal concept as i understand it. There is signal and data wires. Signal wire activates execution of node. The semantics of signal wire may vary from node to node.

My goal is to do easy to understand but powerfull flow-control concept, so pyno will be used for broader classes of programming.

Ideas are welcome.

Crash on OS X when pushing load or save

Python 3.6.3, OS X 10.11.6 (15G18013)

apollov@apollov-macbook-local-en0 ~/work/Pyno % python Pyno.py
Loading...
2017-12-19 18:26:19.620 python[94919:2273428] -[NSApplication _setup:]: unrecognized selector sent to instance 0x7fdf63113e40
2017-12-19 18:26:19.623 python[94919:2273428] An uncaught exception was raised
2017-12-19 18:26:19.623 python[94919:2273428] -[NSApplication _setup:]: unrecognized selector sent to instance 0x7fdf63113e40
2017-12-19 18:26:19.623 python[94919:2273428] (
	0   CoreFoundation                      0x00007fff96e34452 __exceptionPreprocess + 178
	1   libobjc.A.dylib                     0x00007fff93b4b73c objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff96e9e18d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
	3   CoreFoundation                      0x00007fff96da44c1 ___forwarding___ + 1009
	4   CoreFoundation                      0x00007fff96da4048 _CF_forwarding_prep_0 + 120
	5   Tk                                  0x0000000106c61948 TkpInit + 476
	6   Tk                                  0x0000000106bdca6e Tk_Init + 1799
	7   _tkinter.cpython-36m-darwin.so      0x0000000106ab9dd2 Tcl_AppInit + 82
	8   _tkinter.cpython-36m-darwin.so      0x0000000106ab4d48 _tkinter_create + 1112
	9   python                              0x000000010029212c _PyCFunction_FastCallDict + 172
	10  python                              0x000000010031eb0f call_function + 479
	11  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	12  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	13  python                              0x0000000100320552 _PyFunction_FastCallDict + 802
	14  python                              0x0000000100248018 _PyObject_FastCallDict + 360
	15  python                              0x0000000100248135 _PyObject_Call_Prepend + 149
	16  python                              0x0000000100247d65 PyObject_Call + 101
	17  python                              0x00000001002aa89e slot_tp_init + 158
	18  python                              0x00000001002a69e9 type_call + 313
	19  python                              0x0000000100247fe5 _PyObject_FastCallDict + 309
	20  python                              0x000000010031ea09 call_function + 217
	21  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	22  python                              0x000000010032016e fast_function + 574
	23  python                              0x000000010031eae9 call_function + 441
	24  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	25  python                              0x000000010032016e fast_function + 574
	26  python                              0x000000010031eae9 call_function + 441
	27  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	28  python                              0x00000001003205ec _PyFunction_FastCallDict + 956
	29  python                              0x0000000100248018 _PyObject_FastCallDict + 360
	30  python                              0x0000000100248135 _PyObject_Call_Prepend + 149
	31  python                              0x0000000100247d65 PyObject_Call + 101
	32  python                              0x000000010031b80a _PyEval_EvalFrameDefault + 26954
	33  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	34  python                              0x0000000100314e6b PyEval_EvalCodeEx + 107
	35  python                              0x0000000100270c1d function_call + 381
	36  python                              0x0000000100247d65 PyObject_Call + 101
	37  python                              0x000000010031b80a _PyEval_EvalFrameDefault + 26954
	38  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	39  python                              0x0000000100320216 fast_function + 742
	40  python                              0x000000010031eae9 call_function + 441
	41  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	42  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	43  python                              0x0000000100314e6b PyEval_EvalCodeEx + 107
	44  python                              0x0000000100270c1d function_call + 381
	45  python                              0x0000000100247d65 PyObject_Call + 101
	46  python                              0x000000010031b80a _PyEval_EvalFrameDefault + 26954
	47  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	48  python                              0x0000000100314e6b PyEval_EvalCodeEx + 107
	49  python                              0x0000000100270c1d function_call + 381
	50  python                              0x0000000100247d65 PyObject_Call + 101
	51  _ctypes.cpython-36m-darwin.so       0x0000000100c380d0 closure_fcn + 448
	52  _ctypes.cpython-36m-darwin.so       0x0000000100c3dec2 ffi_closure_unix64_inner + 674
	53  _ctypes.cpython-36m-darwin.so       0x0000000100c3d3f6 ffi_closure_unix64 + 70
	54  AppKit                              0x00007fff877f93ad -[NSWindow _reallySendEvent:isDelayedEvent:] + 212
	55  AppKit                              0x00007fff87238539 -[NSWindow sendEvent:] + 517
	56  AppKit                              0x00007fff871b8a38 -[NSApplication sendEvent:] + 2540
	57  _ctypes.cpython-36m-darwin.so       0x0000000100c3d277 ffi_call_unix64 + 79
	58  ???                                 0x00007fff5f9c17e0 0x0 + 140734797453280
)
2017-12-19 18:26:19.624 python[94919:2273428] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSApplication _setup:]: unrecognized selector sent to instance 0x7fdf63113e40'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff96e34452 __exceptionPreprocess + 178
	1   libobjc.A.dylib                     0x00007fff93b4b73c objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff96e9e18d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
	3   CoreFoundation                      0x00007fff96da44c1 ___forwarding___ + 1009
	4   CoreFoundation                      0x00007fff96da4048 _CF_forwarding_prep_0 + 120
	5   Tk                                  0x0000000106c61948 TkpInit + 476
	6   Tk                                  0x0000000106bdca6e Tk_Init + 1799
	7   _tkinter.cpython-36m-darwin.so      0x0000000106ab9dd2 Tcl_AppInit + 82
	8   _tkinter.cpython-36m-darwin.so      0x0000000106ab4d48 _tkinter_create + 1112
	9   python                              0x000000010029212c _PyCFunction_FastCallDict + 172
	10  python                              0x000000010031eb0f call_function + 479
	11  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	12  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	13  python                              0x0000000100320552 _PyFunction_FastCallDict + 802
	14  python                              0x0000000100248018 _PyObject_FastCallDict + 360
	15  python                              0x0000000100248135 _PyObject_Call_Prepend + 149
	16  python                              0x0000000100247d65 PyObject_Call + 101
	17  python                              0x00000001002aa89e slot_tp_init + 158
	18  python                              0x00000001002a69e9 type_call + 313
	19  python                              0x0000000100247fe5 _PyObject_FastCallDict + 309
	20  python                              0x000000010031ea09 call_function + 217
	21  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	22  python                              0x000000010032016e fast_function + 574
	23  python                              0x000000010031eae9 call_function + 441
	24  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	25  python                              0x000000010032016e fast_function + 574
	26  python                              0x000000010031eae9 call_function + 441
	27  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	28  python                              0x00000001003205ec _PyFunction_FastCallDict + 956
	29  python                              0x0000000100248018 _PyObject_FastCallDict + 360
	30  python                              0x0000000100248135 _PyObject_Call_Prepend + 149
	31  python                              0x0000000100247d65 PyObject_Call + 101
	32  python                              0x000000010031b80a _PyEval_EvalFrameDefault + 26954
	33  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	34  python                              0x0000000100314e6b PyEval_EvalCodeEx + 107
	35  python                              0x0000000100270c1d function_call + 381
	36  python                              0x0000000100247d65 PyObject_Call + 101
	37  python                              0x000000010031b80a _PyEval_EvalFrameDefault + 26954
	38  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	39  python                              0x0000000100320216 fast_function + 742
	40  python                              0x000000010031eae9 call_function + 441
	41  python                              0x000000010031b4f2 _PyEval_EvalFrameDefault + 26162
	42  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	43  python                              0x0000000100314e6b PyEval_EvalCodeEx + 107
	44  python                              0x0000000100270c1d function_call + 381
	45  python                              0x0000000100247d65 PyObject_Call + 101
	46  python                              0x000000010031b80a _PyEval_EvalFrameDefault + 26954
	47  python                              0x000000010031fa19 _PyEval_EvalCodeWithName + 3641
	48  python                              0x0000000100314e6b PyEval_EvalCodeEx + 107
	49  python                              0x0000000100270c1d function_call + 381
	50  python                              0x0000000100247d65 PyObject_Call + 101
	51  _ctypes.cpython-36m-darwin.so       0x0000000100c380d0 closure_fcn + 448
	52  _ctypes.cpython-36m-darwin.so       0x0000000100c3dec2 ffi_closure_unix64_inner + 674
	53  _ctypes.cpython-36m-darwin.so       0x0000000100c3d3f6 ffi_closure_unix64 + 70
	54  AppKit                              0x00007fff877f93ad -[NSWindow _reallySendEvent:isDelayedEvent:] + 212
	55  AppKit                              0x00007fff87238539 -[NSWindow sendEvent:] + 517
	56  AppKit                              0x00007fff871b8a38 -[NSApplication sendEvent:] + 2540
	57  _ctypes.cpython-36m-darwin.so       0x0000000100c3d277 ffi_call_unix64 + 79
	58  ???                                 0x00007fff5f9c17e0 0x0 + 140734797453280
)
libc++abi.dylib: terminating with uncaught exception of type NSException
[1]    94919 abort      python Pyno.py ../moduleq/daf/exceptions.py

Do not reorder nodes on serialization

Resaving causes meaningless diff because of reordering of nodes.

Example of diff

[ . . . ]
@@ -104,7 +104,7 @@
             "#"
         ],
         "connects": [],
-        "parent": 23
+        "parent": 3
     },
     {
         "type": "field",
@@ -118,7 +118,7 @@
             "20"
         ],
         "connects": [],
-        "parent": 24
+        "parent": 4
     },
     {
         "type": "field",
@@ -134,7 +134,7 @@
         "connects": [
             {
                 "output": {
-                    "node": 21,
+                    "node": 1,
                     "put": {
                         "name": "result"
                     }
@@ -146,7 +146,7 @@
                 }
             }
         ],
-        "parent": 25
+        "parent": 5
     },
     {
         "type": "node",
@@ -171,7 +171,7 @@
         "connects": [
             {
                 "output": {
-                    "node": 27,
+                    "node": 7,
                     "put": {
                         "name": "output"
                     }
@@ -184,7 +184,7 @@
             },
             {
                 "output": {
-                    "node": 21,
+                    "node": 1,
                     "put": {
                         "name": "result"
                     }
[ . . . ]

Do not redraw each editor frame

Because of this (CPU usage):

image

When user doesn't drag or zoom the canvas, there is no need for full redraw. In this case we only need to redraw elements of field type, as they present real-time data.

Add 'cleanup' binding

Everything in node's code executed once, in "read time".

If there was 'call' binding, this 'call' function will be called as main node process - "run time".

I'm considering to add 'cleanup' binding which will be called on node deletion or restart. For example close opened graphical window.

Maybe there is more userfull bindings (callbacks) to add..

Bug: field, loading and focusing issue

From time to time I do get this error:

Traceback (most recent call last):
File "./Pyno.py", line 19, in
pyglet.app.run()
File "/usr/local/lib/python3.4/dist-packages/pyglet/app/init.py", line 138, in run
event_loop.run()
File "/usr/local/lib/python3.4/dist-packages/pyglet/app/base.py", line 142, in run
self._run()
File "/usr/local/lib/python3.4/dist-packages/pyglet/app/base.py", line 155, in _run
platform_event_loop.step(timeout)
File "/usr/local/lib/python3.4/dist-packages/pyglet/app/xlib.py", line 125, in step
device.select()
File "/usr/local/lib/python3.4/dist-packages/pyglet/canvas/xlib.py", line 168, in select
dispatch(e)
File "/usr/local/lib/python3.4/dist-packages/pyglet/window/xlib/init.py", line 922, in dispatch_platform_event_view
event_handler(e)
File "/usr/local/lib/python3.4/dist-packages/pyglet/window/xlib/init.py", line 1234, in _event_button
x, y, button, modifiers)
File "/usr/local/lib/python3.4/dist-packages/pyglet/window/init.py", line 1220, in dispatch_event
if EventDispatcher.dispatch_event(self, *args) != False:
File "/usr/local/lib/python3.4/dist-packages/pyglet/event.py", line 357, in dispatch_event
if handler(*args):
File "/home/osboxes/Downloads/Pyno-drtrigon/field.py", line 204, in on_mouse_press
self.lost_focus()
File "/home/osboxes/Downloads/Pyno-drtrigon/field.py", line 274, in lost_focus
self.caret.mark = self.caret.position = 0
File "/usr/local/lib/python3.4/dist-packages/pyglet/text/caret.py", line 212, in _set_mark
self._update(line=self._ideal_line)
File "/usr/local/lib/python3.4/dist-packages/pyglet/text/caret.py", line 398, in _update
x, y = self._layout.get_point_from_position(self._position, line)
File "/usr/local/lib/python3.4/dist-packages/pyglet/text/layout.py", line 2307, in get_point_from_position
baseline = self._document.get_style('baseline', max(0, position - 1))
AttributeError: 'NoneType' object has no attribute 'get_style'

I was able to track it down to the point that it must be related to loading a pyno file, clicking around on some field and changing its value, load another pyno file and attempt to do something in there. Sadly I was not yet able to track it down further...

field-no

I made a mistake, I wanted to mention when I said that the contents of the input and output data are stored in the node, but in fact I meant to be stored in the pyno file. pn (using this filename as test) So if it were possible to make the modification so that the input and output data were stored in an input and output text file added to the program created (pyno .pn), this would avoid overloading of the computational capacity of the system, would run the program faster and would create an interface with more options for the user.

Feature request: Add new element that represents a pyno-file

Currently there are two elements: node and field.

Can you add a third element that represents a pyno-file? That way it would be possible to group complex files/flows into several files or to reuse pyno-files for various purposes. I would propose to use either fields or the open connections of the pyno-file as connections for the new object.

Enhance install instructions

The instructions given in https://github.com/honix/Pyno#how-to-run are confusing (very brief). Am I right that they mean something like:

$ git clone https://github.com/honix/Pyno.git
$ cd Pyno
$ pip install .

... and the instructions given in https://github.com/honix/Pyno#how-to-modify in that case:

$ git clone https://github.com/honix/Pyno.git
$ cd Pyno
$ pip install -e .

I like the approach using a clone with pip install . I wonder what happens if I omit the pip install and just do a clone?

The README should be enhanced to include a bit more specific step-by-step install instructions.

Simpler node definition using decorators

Right now, the pattern to define the code of a node is, if I understand correctly:

def helper(a, b):
  return a + b

def add(a=0, b=0):
  result = helper(a, b)
  return result

call = add

or

import calendar
call = calendar.isleap

It would be nice if this additional assignment to the arbitrarily named call object could be hidden from the user. I am thinking that it should be possible using python decorators to register the wanted callable with the node it belongs to, e.g. like this:

@node_target
def helper(a, b):
  return a + b

def add(a=0, b=0):
  result = helper(a, b)
  return result

or

import calendar
node_target(calendar.isleap)

Note how it's possible to pick out which callable you want assigned from several candidates, and how you don't rely on having a specifically-named callback object that just hangs around in that scope. It would also maybe be easier to handle when creating many nodes from another module.
Does this sound attractive?

Refuses to work on ubuntu 17.10

I run Pyno.py using the py3.6 interpreter, it shows me the welcome window with some blocks, but does not allow me to click on any box OR freezes when i click some box. what could be the source of problem?

2018-04-04 15-57-27

No-field

Hello!
The whole content of the knot is stored in his internal code. When vc. works with high sequences of values, this content provokes a latência in the load of the knot. Would it have as it will prevent which data of entry and when it went out they were stored in the code of the knot, talvés, creating a textual association of entry and exit for each knot launched in the scheme of the program?
When vc. tries to carve the exit of a knot for an archive the same thing is overloaded due to operation of repetition of the fraps that I still did not stop to notice regarding the new version, that now it has the buttons of pause, to stop, to execute the block of code.
Would it be possible also to converge all the exits of the knots when values and or answers were necessary to the visualization, to be direcionadas for a specific field that it could have several entries when it was a field of exit or several exits when it was a field of entry of data?
I love your work, it grieves that I do not know planning, congratulations.

File format as json + OrderedDict?

Seeing some of the huge diffs of .pn files for small changes, and seeing the structure of the contents, I am wondering if it would be worthwhile to make the file format json instead (I think it's already quite near?), and store it in a prettyfied/line-broken form.
If you couple it with OrderedDict, this should preserve insertion order and minimise the diffs between saves.
YAML would of course also be an option.

call select

[
{
"size": [
300,
150
],
"color": [
121,
100,
104
],
"code": "def s1(a=0, b=0,modo=''):\n result1 = a + b\n return result1\ndef s2(a=0,b=0,mod=''):\n result2=abs(a-b)\n return result2\ncall = s1\ncall = s2",
"parent": 21,
"y": 43,
"connects": [
{
"input": {
"put": {
"name": "b"
}
},
"output": {
"node": 24,
"put": {
"name": "output"
}
}
},
{
"input": {
"put": {
"name": "a"
}
},
"output": {
"node": 25,
"put": {
"name": "output"
}
}
},
{
"input": {
"put": {
"name": "mod"
}
},
"output": {
"node": 23,
"put": {
"name": "output"
}
}
}
],
"type": "node",
"x": -44
}
]

call select

Is there any way for an modo input to define which call function will call.
type: modo = 's1' -> calls def s1
modo = 's2' -> calls def s2
it would be possible to create a key to execute different nunctions on the same node

Not launching on Python 3.5: Tuples cannot be used with isinstance()

When launching pyno (Ubuntu 16.04, Python 3.5 or 3.6), I get the following error:

(py3sci) plas@hg201pc58:~/dev$ pyno
Loading...
Can't load file: [Errno 2] No such file or directory: '.auto-saved.pn'
File /home/plas/dev/py3sci/lib/python3.5/site-packages/pyno/examples/welcome.pn loaded!
New pyno!
New window!
Traceback (most recent call last):
  File "/home/plas/dev/py3sci/bin/pyno", line 11, in <module>
    sys.exit(run())
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyno/runner.py", line 9, in run
    pyglet.app.run()
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyglet/app/__init__.py", line 138, in run
    event_loop.run()
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyglet/app/base.py", line 142, in run
    self._run()
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyglet/app/base.py", line 154, in _run
    timeout = self.idle()
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyglet/app/base.py", line 275, in idle
    redraw_all = self.clock.call_scheduled_functions(dt)
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyglet/clock.py", line 346, in call_scheduled_functions
    item.func(now - item.last_ts, *item.args, **item.kwargs)
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyno/window.py", line 86, in update
    self.nodes_update()
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyno/process.py", line 31, in nodes_update
    node.processor()
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyno/node.py", line 50, in processor
    return Processor.processor(self, self.connected_to, self.outputs)
  File "/home/plas/dev/py3sci/lib/python3.5/site-packages/pyno/processor.py", line 54, in processor
    if isinstance(result, Tuple) and len(outputs) > 1:
  File "/usr/lib/python3.5/typing.py", line 725, in __instancecheck__
    raise TypeError("Tuples cannot be used with isinstance().")
TypeError: Tuples cannot be used with isinstance().

Create standard/installable package

Pyno should be turned into a package that you can install with pip and/or conda. This will also make maintenance (like definining dependencies etc) easier.
It would also be sound practice to add tests (via pytest) and continuous integration (e.g. via travis-ci).

I already have an idea about the necessary steps (have created packages before), and can do that if desired.

Pass file to open to the pyno command

Now that there is a pyno command, it would probably be useful to add a minimal command line interface, so that a user can execute pyno somefile.pn to directly open that file.
I suggest implementing this with the argparse module from the standard library.

Save python script from pyno-file

This was just an idea - but can we maybe use the processor to merge and output the python code (instead of executing) and by that support saving to python script? That would allow to export complex code into a python script and import it into a compact (and may be faster) single node again. Would also allow to re-use code in other programs etc.

Add Continuos Integration

Now that it's possible to run pytest on the code, it would be wise to add a Continuos Integration service, which will run tests on all commits and PRs to minimise the amount of breakage introduced. This will also hopefully incentivise writing of further tests for the codebase.
I would recommend Travis (www.travis-ci.com) as you can just register with your github credentials, and it's free for open source projects. If not familiar with how this works for a Python project, see https://docs.travis-ci.com/user/languages/python.

Acumulator

Hey!
I do not know programming but was trying to do a commercial, something that entering a given, when this was disconnected to keep the incoming data on output, I don't know how I did it or how it works, if you guys can look!

entrance and exit

Hello !
It would be possible that the node would be freer to make the
connections of the input and output pins as in the nodes made in
the Flow-Based Programming (FBP) by J Paul Morrison ?
this would make it easier to improve the layout of the project.

Olá !
Seria possível que o nó fosse mais livre para fazer o
conexões dos pinos de entrada e saída como nos nós feitos em
a programação baseada em fluxo (FBP) por J Paul Morrison?
Isso tornaria mais fácil melhorar o layout do projeto.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.