with raspberry libreria interfaz interfaces instalar graficas grafica curso python user-interface design directed-graph

raspberry - libreria grafica python



¿Implementando una interfaz gráfica basada en nodo? (7)

Me gustaría implementar una interfaz nodal, básicamente un DAG donde cada nodo realiza una operación en sus conexiones de entrada, y genera algo (que puede conectar a otro nodo)

Algunas aplicaciones de ejemplo:

Como primer objetivo, me gustaría tener una aplicación gráfica con solo 2 nodos. Un "número" que simplemente genera un número fijo, y un nodo "Agregar", que toma dos entradas y produce la suma de las dos.

Como la gente ha respondido hasta ahora, tengo una idea aproximada de cómo representar los datos en el código, por ejemplo, en Python''y buscando pseudo-código:

class Number: def __init__(self, value): self.value = value def eval(self): return self.value class Add: def __init__(self, input1, input2): self.input1 = input1 self.input2 = input2 def eval(self): return self.input1.eval() + self.input2.eval() a = Number(20) b = Number(72) adder = Add(a, b) print adder.eval()

¿Cómo me gustaría envolver una GUI personalizada alrededor de esto? Algo como lo siguiente, ¡pero un poco menos dibujado a mano!

¿Dónde comenzaría? Actualmente planeo escribirlo en Objective-C / Cocoa, aunque estoy más que dispuesto a recibir sugerencias para otros idiomas.


Comenzaría modelando algunas interfaces básicas (en el sentido OOP, no en el sentido GUI). Me parece que tendrá un Nodo que aceptará una colección de entradas y una única salida. No dio ninguna indicación de qué tan amplios son los tipos de datos, pero querrá un método adecuado para representar sus entradas / salidas. Para su primer objetivo, este podría ser un número entero.

En un lenguaje OOP genérico de estilo C (espero que tenga sentido):

class Node<T> { Node<T>[] inputs; T eval(); } class AdderNode extends Node<int> { int eval() { int accum = 0; for (inputs : i) accum += i.eval(); return i; } } class ConstNode<int I> extends Node<int> { int eval() { return I; } } AdderNode a; a.inputs.add(ConstNode<2>()); a.inputs.add(ConstNode<3>()); a.eval();

Puede ampliar esto reemplazando int con alguna clase abstracta, genérica o de interfaz. La implementación real variará según el idioma real, por supuesto.


Comenzaría modelando las operaciones interesantes. En última instancia, los conectará a una interfaz de usuario, pero ese es el volante y el acelerador, no el motor.

Lo que intentas construir tiene mucho en común con los lenguajes de programación: variables, valores, tipos, expresiones, evaluación, etc. Muchas de las metáforas son aplicables y pueden proporcionar cierta orientación.

Si está utilizando .NET 3.5, tiene la opción de Árboles de expresión , que le permiten representar y compilar expresiones de código en tiempo de ejecución.

Por ejemplo, para modelar su primer objetivo:

using System.Linq.Expressions; ConstantExpression theNumber2 = Expression.Constant(2); ConstantExpression theNumber3 = Expression.Constant(3); BinaryExpression add2And3 = Expression.Add(theNumber2, theNumber3);

Para invocar la expresión, necesitamos ajustar add2And3 con un método. Esto se hace con una expresión lambda:

Expression<Func<int>> add2And3Lambda = Expression.Lambda<Func<int>>(add2And3);

Func<int> representa un método que no toma parámetros y devuelve un int . En C #, el código representado por add2And3Lambda sería:

() => 2 + 3

Entonces, lo que tenemos es un árbol de expresiones cuya raíz es un método. Como un método es invocable , podemos compilar el árbol en una instancia del tipo de delegado subyacente:

Func<int> add2And3Func = add2And3Lambda.Compile();

Ahora podemos invocar el código que creamos:

int theNumber5 = add2And3Func();

Todas las expresiones disponibles para los lenguajes .NET son compatibles.

Imagine que cada nodo en su gráfico tiene una Expression asociada a él. Eso podría darte una idea del poder de los árboles de expresión y cómo podrían ayudarte con esta tarea.



Implementé un Gráfico de ejecución como describiste en este proyecto: GRSFramework

El código fuente se puede encontrar here .

Actualmente estoy trabajando para lanzar una versión mejorada y limpia de este sistema en el proyecto ExecutionGraph .
Puede ser de interés para usted también.

Luego está también la biblioteca TensorFlow de Google que tiene un sistema similar implementado TensorFlow


Me encontré con este hilo mientras buscaba una solución similar. Recientemente encontré un buen proyecto en github https://github.com/nodebox/nodebox que parece ser exactamente lo que estás buscando. Al menos uno podría extraer y adoptar los componentes del editor del proyecto.

Saludos, Stephan


Tal vez bwise tiene algo de interés?

En la mitad inferior de esta página, se muestra un ejemplo del uso de bwise para crear un bloque de multiplicación que toma dos números como entrada.


Todos los sistemas de nodos tienen en común que describen un lenguaje de programación funcional. Una función toma múltiples parámetros y devuelve un único resultado, sin importar para qué propósito fue diseñado. Algunos ejemplos:

  • Gráficos: Desenfoque (Imagen, Núcleo, Radio) -> Imagen

  • Matemáticas: Agregar (Número, Número) -> Número

  • Relacional: filtro (tabla, predicado) -> Tabla

Básicamente eso se reduce a una firma de función como Func<object[], object> (C #).

Te enfrentarás a la pregunta de cómo hacer que tu sistema de nodos sea persistente. ¿Desea que el resultado de un nodo sea utilizable como parámetro solo por otro nodo (árbol) o por varios nodos (gráfico)?

Ejemplo de un árbol, directamente tiene los parámetros de un nodo hijo:

Add( Multiply( Constant(5), Constant(4) ), Multiply( Constant(5), Constant(3) ) )

Ejemplo de un gráfico, almacene todos los nodos en una lista y solo use referencias:

A := Constant(5) B := Constant(4) C := Constant(3) D := Func(Multiply, A, B) E := Func(Multiply, A, C) F := Func(Add, D, E)