Esta parte del manual de introducción se ha organizado como un diario de "prácticas recomendadas". Ofrece información sobre varias estrategias que hemos aprendido a través de la experiencia y la investigación para ser más favorables a los flujos de trabajo paramétricos de calidad. Como diseñadores y programadores, nuestro indicador de calidad se basa principalmente en la capacidad de mantenimiento, fiabilidad, facilidad de uso y eficacia de nuestras herramientas. Aunque estas prácticas recomendadas presentan ejemplos específicos para secuencias de comandos visuales o basadas en texto, los principios se aplican a todos los entornos de programación y pueden informar de muchos flujos de trabajo computacionales.
Antes de este capítulo, en el manual de introducción, se describe cómo implementar las eficaces funciones de creación de secuencias de comandos visuales de Dynamo. Un conocimiento exhaustivo de estas funciones constituye una base sólida y el primer paso para la creación de programas visuales potentes. Cuando utilizamos los programas visuales sobre el terreno, los compartimos con compañeros, solucionamos errores o probamos los límites, nos encontraremos con problemas adicionales que deberemos afrontar. Si otra persona va a utilizar el programa o espera abrirlo dentro de seis meses, este debe tener una claridad gráfica y lógica inmediata. Dynamo dispone de numerosas herramientas para gestionar la complejidad del programa y, en este capítulo, se proporcionan las directrices para utilizarlas.
A medida que desarrolla el gráfico de Dynamo y prueba sus ideas, su tamaño y su complejidad pueden aumentar rápidamente. Aunque es importante crear un programa que funcione, es igualmente importante hacerlo lo más sencillo posible. No solo el gráfico se ejecutará de forma más rápida y predecible, sino que además usted y los demás usuarios entenderán su lógica más adelante. A continuación, se incluyen varias formas que le ayudarán a aclarar la lógica del gráfico.
Los grupos permiten crear partes con diferentes funciones a medida que se genera un programa
Los grupos permiten desplazar grandes partes del programa sin perder la modularidad y la alineación
Puede cambiar el color del grupo para diferenciar su finalidad (entradas y funciones)
Puede utilizar grupos para empezar a organizar el gráfico a fin de simplificar la creación de nodos personalizados.
Los colores de este programa identifican la finalidad de cada grupo. Esta estrategia se puede utilizar para crear una jerarquía en cualquier norma o plantilla gráficas que desarrolle.
Grupo de funciones (azul)
Grupo de entradas (naranja)
Grupo de secuencias de comandos (verde)
Para obtener información sobre cómo utilizar los grupos, consulte Administración del programa.
En ocasiones, se puede utilizar un bloque de código para escribir un método de nodo o número de forma más rápida que con la búsqueda (Point.ByCoordinates, Number, String y Formula).
Los bloques de código son útiles cuando se desean definir funciones personalizadas en DesignScript para reducir el número de nodos de un gráfico.
Los ejemplos 1 y 2 realizan la misma función. Se tardó mucho menos en escribir unas pocas líneas de código que en buscar y añadir cada nodo individualmente. El bloque de código también es mucho más conciso.
DesignScript escrito en bloques de código
Programa equivalente en nodos
Para obtener información sobre cómo utilizar el bloque de código, consulte ¿Qué es un bloque de código?.
Puede reducir la complejidad de un gráfico mediante el método de nodo a código, que utilizará una colección de nodos sencillos y escribirá la secuencia DesignScript correspondiente en un único bloque de código.
El método de nodo a código** permite condensar código sin que el programa pierda claridad**.
A continuación, se indican las ventajas de utilizar el método de nodo a código:
Condensa el código fácilmente en un componente que aún puede editarse.
Puede simplificar una parte significativa del gráfico.
Es útil si no se modifica con frecuencia el "miniprograma".
Permite incorporar otras características de bloque de código, como las funciones.
A continuación, se indican las desventajas de utilizar el método de nodo a código:
La asignación de nombres genéricos reduce su facilidad de lectura.
Es más difícil de comprender para otros usuarios.
No hay una forma sencilla de volver a la versión de programación visual.
Programa existente
Bloque de código creado con el método de nodo a código
Para obtener información sobre cómo utilizar el método de nodo a código, consulte Sintaxis de DesignScript.
El uso de List@Level puede ayudarle a reducir la complejidad del gráfico mediante la sustitución de los nodos List.Map y List.Combine, que pueden ocupar una cantidad considerable de espacio en el lienzo.
List@Level proporciona un** método más rápido que List.Map/List.Combine para crear una lógica de nodo**, lo que permite acceder a los datos de cualquier nivel de una lista directamente desde el puerto de entrada de un nodo
Podemos comprobar cuántos valores devuelve True BoundingBox.Contains y en qué listas mediante la activación de List@Level para la entrada "list" de CountTrue. List@Level permite al usuario determinar de qué nivel se obtendrán los datos. El uso de List@Level es flexible, eficaz y muy recomendado frente a otros métodos en los que se utilizan List.Map y List.Combine.
Recuento de valores "true" (verdaderos) en el nivel de lista 2
Recuento de valores "true" (verdaderos) en el nivel de lista 3
Para obtener información sobre cómo utilizar List@Level, consulte Listas de listas.
Además de conseguir que el gráfico sea lo más sencillo y eficaz posible, intente lograr una claridad gráfica. A pesar de hacer todo lo posible para que el gráfico sea intuitivo con agrupaciones lógicas, es posible que las relaciones no sean evidentes a simple vista. Una sencilla nota dentro de un grupo o el cambio de nombre de un control deslizante puede ahorrarle a usted u otro usuario confusión innecesaria o tener que desplazarse por el gráfico. A continuación, se describen varias formas que le ayudarán a aplicar coherencia dentro de los gráficos y entre ellos.
Para reducir el trabajo después de terminar de generar el gráfico, debe intentar asegurarse de que el diseño del nodo sea legible mediante la alineación de los nodos con frecuencia y a medida que progresa.
Si otros van a trabajar con el gráfico, asegúrese de que el diseño de cables y nodos fluya con facilidad antes de enviarlo.
Para facilitar la alineación, utilice la función "Presentación de nodo de limpieza" para alinear automáticamente el gráfico, aunque de forma menos precisa que manualmente.
Gráfico desorganizado
Gráfico alineado
Para obtener información sobre cómo utilizar la alineación de nodos, consulte Administración del programa.
El cambio de nombre de las entradas puede ayudar a otros a comprender más fácilmente el gráfico, sobre todo, si los elementos a los que se van a conectar no aparecen en la pantalla.
Tenga cuidado de no cambiar el nombre de los nodos que no sean entradas. Una alternativa a esto es crear un nodo personalizado a partir de un clúster de nodos y cambiarle el nombre; se comprenderá que contiene otro elemento.
Entradas para la manipulación de superficies
Entradas para los parámetros arquitectónicos
Entradas para la secuencia de comandos de simulación de drenaje
Para cambiar el nombre de un nodo, haga clic con el botón derecho en su nombre y seleccione "Cambiar nombre de nodo".
Debe añadir una nota si alguna parte del gráfico requiere una explicación en lenguaje sencillo que los nodos no pueden expresar.
Debe añadir una nota si un conjunto de nodos o un grupo son demasiado grandes o complejos y no se pueden entender al instante.
Una nota que describe la parte del programa que devuelve distancias de traslado sin procesar.
Una nota que describe el código que asigna esos valores a una onda sinusoidal.
Para obtener información sobre cómo añadir una nota, consulte Administración del programa.
Al crear la secuencia de comandos visual, es importante comprobar que se devuelve lo que se esperaba. No todos los errores o los problemas provocarán que el programa falle inmediatamente, sobre todo, los valores nulos o cero que podrían afectar a niveles inferiores. Esta estrategia también se aborda en el contexto de la creación de secuencias de comandos de texto en las Estrategias de creación de secuencias de comandos. El siguiente procedimiento le ayudará a asegurarse de que obtiene lo que esperaba.
Utilice las burbujas de visualización y vista preliminar al crear el programa para** comprobar que las salidas clave devuelvan lo que esperaba**.
Los nodos de visualización se utilizan para comparar:
Las distancias de traslado sin procesar.
Los valores que se transfieren a través de la ecuación de seno.
Para obtener información sobre cómo utilizar la visualización, consulte Biblioteca.
Es muy probable que otro usuario abra el programa en algún momento, incluso aunque trabaje de forma independiente. Este debería poder comprender rápidamente lo que el programa necesita y genera a partir de sus entradas y salidas. Esto es especialmente importante cuando se desarrolla un nodo personalizado que se compartirá con la comunidad de Dynamo y se utilizará en el programa de otro usuario. Estos procedimientos generan programas y nodos fiables y reutilizables.
Para garantizar la legibilidad y la escalabilidad, debe probar y minimizar las entradas y las salidas lo máximo posible.
Debe intentar elaborar una estrategia de creación de la lógica mediante la elaboración inicial de un esquema aproximado de cómo puede funcionar la lógica antes de añadir un único nodo al lienzo. A medida que desarrolle el esquema aproximado, debe realizar un seguimiento de las entradas y las salidas que se incluirán en las secuencias de comandos.
Si desea insertar en el gráfico condiciones u opciones específicas, debe utilizar valores predefinidos para acceder a ellos rápidamente.
También puede utilizar valores predefinidos para reducir la complejidad mediante el almacenamiento en caché de los valores de controles deslizantes de un gráfico con tiempos de ejecución prolongados.
Para obtener información sobre cómo utilizar los valores predefinidos, consulte Administración de datos con valores predefinidos.
Debe utilizar un nodo personalizado si el programa se puede agrupar en un único contenedor.
Debe utilizar un nodo personalizado si una parte del gráfico se reutilizará a menudo en otros programas.
Debe utilizar un nodo personalizado si desea compartir una función con la comunidad de Dynamo.
La recopilación del programa de traslado de puntos en un nodo personalizado consigue que un programa potente y exclusivo sea más fácil de comprender. Los puertos de entrada con nombres adecuados ayudarán a otros usuarios a comprender cómo utilizar el nodo. No olvide añadir descripciones y los tipos de datos necesarios para cada entrada.
Programa de atractor existente.
Nodo personalizado que recopila este programa, PointGrid.
Para obtener información sobre cómo utilizar nodos personalizados, consulte Introducción a los nodos personalizados.
Puede crear plantillas para establecer normas gráficas en todos los gráficos visuales a fin de garantizar que los colaboradores dispongan de una forma normalizada de comprender el gráfico.
Al crear una plantilla, puede normalizar los colores de grupo y los tamaños de tipo de letra para organizar en categorías los flujos de trabajo o las acciones de datos.
Al crear una plantilla, puede incluso normalizar el modo en que desea utilizar una etiqueta, un color o un estilo para indicar la diferencia entre los flujos de trabajo front-end y back-end del gráfico.
La interfaz de usuario, o front-end, del programa incluye un nombre de proyecto, controles deslizantes de entrada y geometría de importación.
El back-end del programa.
Categorías de colores de grupo (el diseño general, las entradas, las secuencias de comandos de Python y la geometría importada).
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
Ahora que hemos establecido algunos procedimientos recomendados, vamos a aplicarlos a un programa que hemos creado rápidamente. Aunque el programa genera correctamente la cubierta, el estado del gráfico es un "mapa mental" del autor. Carece de organización o una descripción de su uso. Recorreremos los procedimientos recomendados para organizar, describir y analizar el programa a fin de que otros usuarios puedan comprender cómo utilizarlo.
El programa funciona, pero el gráfico está desorganizado.
Comencemos por determinar los datos y la geometría devueltos por el programa.
Es crucial comprender cuándo se producen cambios importantes en los datos para establecer divisiones lógicas o modularidad. Pruebe a inspeccionar el resto del programa con nodos de visualización para ver si se pueden determinar los grupos antes de pasar al siguiente paso.
Este bloque de código con una ecuación matemática parece una parte crucial del programa. Un nodo Watch indica que se devuelven listas de distancias de traslado.
La finalidad de esta área no es evidente a simple vista. La disposición de los valores "True" (verdadero) en el nivel de lista L2 de BoundingBox.Contains y la presencia de List.FilterByBoolMask sugiere que se están obteniendo muestras de una parte de la rejilla de puntos.
Una vez que entendemos las partes elementales del programa, organicémoslas en grupos.
Los grupos permiten al usuario diferenciar visualmente las partes del programa.
Importar el modelo de emplazamiento 3D.
Trasladar la rejilla de puntos en función de la ecuación de seno.
Obtener muestra de la rejilla de puntos.
Crear una superficie de cubierta arquitectónica.
Crear un muro cortina de vidrio.
Con los grupos establecidos, alinee los nodos para crear continuidad visual en el gráfico.
La continuidad visual ayuda al usuario a ver el flujo del programa y las relaciones implícitas entre nodos.
Consiga que el programa sea más accesible mediante la adición de otra capa de mejoras gráficas. Añada notas para describir cómo funciona un área específica del programa, proporcione nombres personalizados a las entradas y asigne colores a los distintos tipos de grupos.
Estas mejoras gráficas permiten al usuario obtener más información sobre lo que realiza el programa. Los diferentes colores de grupo ayudan a distinguir las entradas de las funciones.
Notas
Entradas con nombres descriptivos
Antes de empezar a condensar el programa, busquemos una ubicación estratégica para introducir el simulador de drenaje de la secuencia de comandos de Python. Conecte la salida de la primera superficie de cubierta a escala con la entrada de secuencias de comandos respectiva.
Hemos optado por integrar secuencias de comandos en este punto del programa para que la simulación de drenaje pueda ejecutarse en la superficie de cubierta original. No se está previsualizando esa superficie específica, pero esto nos evita tener que elegir la superficie superior de la PolySurface achaflanada.
Geometría de origen para la entrada de secuencia de comandos
Nodo de Python
Controles deslizantes de entrada
"Conmutador" de activación/desactivación
Ahora que todo está en su lugar, vamos a simplificar el gráfico.
La condensación del programa con el método de nodo a código y el nodo personalizado ha reducido considerablemente el tamaño del gráfico. Los grupos que crean la superficie de cubierta y los muros se han convertido en código, ya que son muy específicos de este programa. El grupo de traslado de puntos se encuentra en un nodo personalizado, ya que podría utilizarse en otro programa. En el archivo de ejemplo, cree su propio nodo personalizado a partir del grupo de puntos de traslado.
Nodo personalizado que contiene el grupo de "rejilla de puntos de traslado".
Método de nodo a código para condensar los grupos de "crear superficie de cubierta arquitectónica y muro cortina".
Como paso final, cree valores predefinidos para formas de cubierta de ejemplo.
Estas entradas son los controladores principales de la forma de cubierta y ayudarán a los usuarios a ver el potencial del programa.
Nuestro programa con vistas de dos valores predefinidos.
Los patrones de drenaje de la cubierta proporcionan al usuario una vista analítica de los valores predefinidos respectivos.
Las secuencias de comandos basadas en texto en el entorno de creación de secuencias de comandos visual permite relaciones visuales y potentes mediante DesignScript, Python y ZeroTouch (C#). El usuario puede visualizar elementos como, por ejemplo, controles deslizantes de entrada, condensar operaciones grandes en DesignScript y acceder a herramientas y bibliotecas eficaces a través de Python o C# en el mismo espacio de trabajo. Si se administran de manera eficaz, la combinación de estas estrategias puede proporcionar una gran cantidad de personalización, claridad y eficacia a todo el programa. A continuación, se ofrece un conjunto de directrices para ayudarle a aumentar la secuencia de comandos visual con la secuencia de comandos de texto.
La creación de secuencias de comandos de texto puede establecer relaciones de una mayor complejidad que la programación visual, aunque sus funciones también se solapan considerablemente. Esto es así porque los nodos son código compilado previamente de forma eficaz y es probable que podamos escribir un programa de Dynamo completo en DesignScript o Python. Sin embargo, utilizamos la creación de secuencias de comandos visuales porque la interfaz de nodos y cables crea un flujo intuitivo de información gráfica. Saber dónde las funciones de creación de secuencias de comandos de texto superan a la creación de secuencias de comandos visuales le proporcionará importantes pistas sobre cuándo deben utilizarse sin renunciar a la naturaleza intuitiva de los nodos y los cables. A continuación, se proporcionan directrices sobre cuándo crear una secuencia de comandos y qué lenguaje se debe utilizar.
Utilice secuencias de comandos de texto para:
Creación de bucles
Repetición
Acceso a bibliotecas externas
Elija un lenguaje:
Creación de bucles
Repetición
Condensar nodos
Bibliotecas ext.
Abreviatura
DesignScript
Sí
Sí
Sí
No
Sí
Python
Sí
Sí
Parcialmente
Sí
No
ZeroTouch (C#)
No
No
No
Sí
No
Consulte Referencia de secuencias de comandos para obtener una lista de los elementos a los que cada biblioteca de Dynamo proporciona acceso.
Al crear secuencias de comandos en Dynamo, un entorno inevitablemente paramétrico, es aconsejable estructurar el código en relación con la estructura de nodos y cables en los que se basará. Considere el nodo que contiene la secuencia de comandos de texto como si se tratara de cualquier otro nodo del programa con unas pocas entradas específicas, una función y una salida prevista. Esto proporciona al instante al código del nodo un conjunto de variables desde las que trabajar, la clave para obtener un sistema paramétrico limpio. A continuación, se proporcionan algunas directrices para una integración más eficaz del código en un programa visual.
Identifique las variables externas:
Intente determinar los parámetros especificados en el problema de diseño para que pueda construir un modelo que se base directamente en esos datos.
Antes de escribir el código, identifique las variables:
Un conjunto mínimo de entradas
La salida deseada
Constantes
Se han establecido varias variables antes de escribir el código.
La superficie en la que vamos a simular la lluvia.
El número de gotas de lluvia (agentes) que deseamos.
Hasta dónde deseamos que se desplacen las gotas de lluvia.
Alterne entre descender la ruta más escarpada o atravesar la superficie.
El nodo de Python con el número respectivo de entradas.
Un bloque de código para establecer en azul las curvas devueltas.
Diseñe las relaciones internas:
El uso de parámetros permite editar determinados parámetros o variables para manipular o modificar el resultado final de una ecuación o un sistema.
Siempre que las entidades de la secuencia de comandos estén relacionadas lógicamente, el objetivo es definirlas como funciones entre sí. De este modo, al modificar una, la otra se puede actualizar de forma proporcional.
Minimice el número de entradas visualizando solo los parámetros clave:
Si un conjunto de parámetros se puede derivar de más parámetros principales, solo se mostrarán los parámetros principales como entradas de la secuencia de comandos. Esto aumenta la facilidad de uso de la secuencia de comandos al reducir la complejidad de su interfaz.
El código "modules" del ejemplo de nodo de Python.
Entradas.
Variables internas de la secuencia de comandos.
Un bucle que utiliza estas entradas y variables para realizar su función.
Consejo: Céntrese tanto en el proceso como lo hace en la solución.
Cuando hay varias formas de expresar lo mismo en la secuencia de comandos, en algún momento, las representaciones duplicadas quedarán fuera de la sincronización, lo que puede llevar a problemas de mantenimiento, factorización incorrecta y contradicciones internas.
El principio de no repetición (DRY, Don't Repeat Yourself) se define como "Cada parte del conocimiento debe tener una representación única, sin ambigüedades y autorizada dentro de un sistema":
Si se aplica correctamente este principio, todos los elementos relacionados de la secuencia de comandos cambiarán de forma predecible y uniforme, y todos los elementos no relacionados no presentarán consecuencias lógicas entre sí.
Consejo: Antes de duplicar entidades en la secuencia de comandos (como la constante en el ejemplo anterior), pregúntese si puede establecer un vínculo con el origen en su lugar.
A medida que aumenta la longitud y la complejidad del código, la "gran idea" (o el algoritmo general) se vuelve cada vez más ilegible. También resulta más difícil realizar un seguimiento de los eventos y su ubicación, identificar errores cuando hay problemas, integrar otro código y asignar tareas de desarrollo. Para evitar estos problemas, es aconsejable escribir código en módulos, una estrategia organizativa que divide el código en función en la tarea que ejecuta. A continuación, se incluyen algunos consejos para que las secuencias de comandos sean más manejables a través de la modularización.
Escribir código en módulos:
Un "módulo" es un grupo de código que realiza una tarea específica, similar a un nodo de Dynamo en el espacio de trabajo.
Puede tratarse de cualquier elemento que se deba separar visualmente del código adyacente (una función, una clase, un grupo de entradas o las bibliotecas que se van a importar).
El desarrollo de código en módulos aprovecha la calidad visual e intuitiva de los nodos, así como las relaciones complejas que solo pueden obtenerse mediante secuencias de comandos de texto.
Estos bucles llaman a una clase denominada "agente" que desarrollaremos más detalladamente en el ejercicio.
Un módulo de código que define el punto inicial de cada agente.
Un módulo de código que actualiza el agente.
Un módulo de código que dibuja una trayectoria para la ruta del agente.
Detección de la reutilización de código:
Si detecta que el código realiza la misma tarea (o una muy similar) en más de una ubicación, busque formas de agruparlo en una función a la que se pueda llamar.
Las funciones de "administrador" controlan el flujo del programa y contienen principalmente llamadas a funciones de "trabajo" que gestionan detalles de bajo nivel, como desplazar datos entre estructuras.
En este ejemplo, se crean esferas con radios y colores basados en el valor Z de los centros.
Dos funciones principales de "trabajo": una que crea esferas con radios y colores de visualización en función del valor Z del centro.
Una función principal de "administrador" que combina las dos funciones de trabajo. Al llamar a esta, se llamará a las dos funciones incluidas en ella.
Muestre solo lo que se necesite ver:
Una interfaz de módulo indica los elementos que el módulo proporciona y necesita.
Una vez definidas las interfaces entre las unidades, el diseño detallado de cada unidad puede continuar por separado.
Capacidad de separación/sustitución:
Los módulos no se conocen ni se preocupan entre sí.
Formas generales de modularización:
Agrupación de código:
Funciones:
Clases:
Al desarrollar secuencias de comandos de texto en Dynamo, es recomendable asegurarse constantemente de que lo que se crea en realidad está en consonancia con lo que se espera. Esto garantizará que los eventos imprevistos, como errores de sintaxis, discrepancias lógicas, valores imprecisos y salidas anómalas, entre otros, se detecten y se aborden rápidamente a medida que aparecen en lugar de todos al final. Como las secuencias de comandos se encuentran dentro de los nodos en el lienzo, ya están integradas en el flujo de datos del programa visual. Esto permite que la supervisión continua de la secuencia de comandos sea tan sencilla como asignar los datos que se van a obtener, ejecutar el programa y evaluar los flujos externos a la secuencia de comandos que utilizan un nodo de visualización. A continuación, se proporcionan algunos consejos para inspeccionar de forma continua las secuencias de comandos a medida que las crea.
Realice pruebas durante el proceso:
Cuando complete un grupo de funciones, realice lo siguiente:
Retroceda y revise el código.
Sea crítico. ¿Un colaborador puede entender la finalidad del código? ¿Es necesario que haga esto? ¿Esta función se puede realizar de forma más eficaz? ¿Estoy creando dependencias o duplicados innecesarios?
Realice pruebas rápidas para asegurarse de que se devuelven datos que "tienen sentido".
Asigne los datos más recientes con los que está trabajando en la secuencia de comandos como salida para que el nodo siempre presente datos pertinentes cuando se actualice la secuencia de comandos:
Compruebe que todos los bordes del sólido se devuelvan como curvas para crear un cuadro delimitador alrededor.
Compruebe que las entradas de recuento se hayan convertido correctamente en intervalos.
Compruebe que los sistemas de coordenadas se hayan trasladado y rotado correctamente en este bucle.
Anticipar "casos extremos":
Durante la creación de secuencias de comandos, establezca los parámetros de entrada en los valores mínimo y máximo del dominio asignado para comprobar si el programa sigue funcionando en condiciones extremas.
Aunque el programa funcione en los extremos, compruebe si devuelve valores nulos, vacíos o cero no deseados.
En algunos casos, los errores y las incidencias que revelan algún problema subyacente en la secuencia de comandos solo se detectarán durante estos casos extremos.
Conozca las causas del error y decida posteriormente si se debe corregir internamente o si se debe volver a definir un dominio de parámetro para evitar el problema.
Consejo: Siempre presuponga que el usuario utilizará todas las combinaciones de cada uno de los valores de entrada que se le hayan presentado. Esto ayudará a eliminar sorpresas no deseadas.
La depuración es el proceso de eliminar "errores" de la secuencia de comandos. Los errores pueden ser incidencias, aspectos ineficaces, imprecisiones o resultados no deseados. La resolución de errores puede ser tan sencilla como corregir un nombre de variable mal escrito hasta hacer frente a problemas generalizados y estructurales en la secuencia de comandos. Lo ideal es que el ajuste de la secuencia de comandos durante el proceso de creación le ayude a detectar estos problemas potenciales en una fase inicial, aunque esto no garantiza que esté libre de errores. A continuación, se revisan varios procedimientos recomendados indicados anteriormente para ayudarle a resolver los errores de forma sistemática.
Utilice la burbuja de visualización:
Compruebe los datos devueltos en diferentes partes del código. Para ello, asígnelos a la variable OUT, de modo similar al proceso de ajuste del programa.
Escriba comentarios descriptivos:
Un módulo de código será mucho más fácil de depurar si se describe con claridad el resultado previsto.
Por lo general, esto supone una cantidad excesiva de comentarios y líneas en blanco, pero, cuando se depura, puede ser útil dividir la información en partes manejables.
Aproveche la modularidad del código:
El origen de un problema se puede aislar en determinados módulos.
Una vez identificado el módulo defectuoso, se puede corregir de forma mucho más fácil el problema.
Cuando se debe modificar un programa, el código desarrollado en los módulos será mucho más fácil de cambiar:
Puede insertar módulos nuevos o depurados en un programa existente con la seguridad de que el resto del programa no cambiará.
Depuración del archivo de ejemplo del nodo de Python.
La geometría de entrada devuelve un cuadro delimitador de mayor tamaño, como podemos ver si se asigna xDist e yDist a OUT.
Las curvas de borde de la geometría de entrada devuelven un cuadro delimitador adecuado con las distancias correctas para xDist e yDist.
El "módulo" de códigos que hemos insertado para solucionar el problema del valor de xDist e yDist.
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
Teniendo en cuenta los procedimientos recomendados de creación de secuencias de comandos de texto, vamos a escribir una secuencia de comandos de simulación de lluvia. Aunque hemos podido aplicar los procedimientos recomendados a un programa visual desorganizado en Estrategias gráficas, es mucho más difícil hacerlo con el lenguaje de secuencias de comandos de texto. Las relaciones lógicas establecidas en las secuencias de comandos de texto son menos visibles y pueden ser casi imposibles de desentrañar en un código complicado. La eficacia que proporciona la creación de secuencias de comandos de texto también conlleva una mayor responsabilidad en cuanto a la organización. Recorreremos cada paso y aplicaremos los procedimientos recomendados durante el proceso.
La secuencia de comandos se aplica a una superficie deformada por un atractor.
Lo primero que debemos hacer es importar las bibliotecas de Dynamo necesarias. Esto proporcionará acceso global a las funciones de Dynamo en Python.
Todas las bibliotecas que tenemos intención de utilizar deben importarse aquí.
A continuación, debemos definir las entradas y las salidas de la secuencia de comandos, que se mostrarán como puertos de entrada en el nodo. Estas entradas externas son la base de nuestra secuencia de comandos y la clave para establecer un entorno paramétrico.
Se deben definir entradas que se correspondan con variables en la secuencia de comandos de Python y determinar la salida deseada:
La superficie que deseamos descender.
El número de agentes que deseamos que realicen el recorrido.
El número máximo de pasos que pueden dar los agentes.
Una opción para tomar la ruta descendente más corta por la superficie o para atravesarla.
El nodo de Python con identificadores de entrada que corresponden a entradas de la secuencia de comandos (IN[0], IN[1]).
Las curvas de salida que se pueden mostrar con un color diferente.
Ahora utilicemos el procedimiento de modularidad y creemos el cuerpo de nuestra secuencia de comandos. La simulación de la ruta descendente más corta por una superficie para varios puntos iniciales es una tarea importante que requerirá varias funciones. En lugar de llamar a las diferentes funciones a lo largo de la secuencia de comandos, podemos modularizar el código recopilándolas en una sola clase, nuestro agente. Se puede llamar a las diferentes funciones de esta clase o "módulo" con distintas variables, o incluso volver a utilizarlas en otra secuencia de comandos.
Necesitaremos definir una clase o un plan de acción para un agente con la intención de descender la superficie optando por el desplazamiento en la dirección más escarpada posible cada vez que este dé un paso:
Nombre.
Atributos globales que comparten todos los agentes.
Atributos de ejemplar exclusivos de cada agente.
Una función para dar un paso.
Una función para catalogar la posición de cada paso en una lista de trayectorias.
Inicializaremos los agentes mediante la definición de su ubicación inicial. Esta es una buena oportunidad para ajustar nuestra secuencia de comandos y asegurarnos de que funciona la clase de agente.
Tendremos que crear una instancia de todos los agentes cuyo descenso por la superficie deseamos observar y definir sus atributos iniciales:
Una nueva lista de trayectorias vacía.
La ubicación en la que se iniciará el paseo por la superficie.
Hemos asignado la lista de agentes como salida para comprobar lo que devuelve la secuencia de comandos aquí. Se devuelve el número correcto de agentes, pero necesitaremos ajustar de nuevo la secuencia de comandos más adelante para comprobar la geometría que devuelve.
Actualice cada agente en cada paso. A continuación, deberemos introducir un bucle anidado en el que, para cada agente y paso, actualizaremos y registraremos la posición en la lista de trayectorias. En cada paso, también nos aseguraremos de que el agente no haya alcanzado un punto de la superficie donde no pueda dar otro paso, lo que le permitirá descender. Si se cumple esa condición, finalizaremos el desplazamiento del agente.
Ahora que se han actualizado por completo los agentes, volvamos a la geometría que los representa. Una vez que todos los agentes hayan alcanzado su límite de descenso o su número máximo de pasos, crearemos una PolyCurve a través de los puntos de la lista de trayectorias y generaremos las trayectorias de PolyCurve.
Nuestra secuencia de comandos para buscar las rutas más escarpadas.
Un valor predefinido que simula la lluvia en la superficie subyacente.
En lugar de buscar la ruta más escarpada, se pueden activar o desactivar los agentes para que atraviesen la superficie subyacente.
La secuencia de comandos de texto completa de Python.
Esta página de referencia amplía las prácticas recomendadas incluidas en las estrategias de creación de secuencias de comandos con más detalles sobre las bibliotecas de códigos, el etiquetado y la aplicación de estilos. Utilizaremos Python para ilustrar los conceptos que se indican a continuación; no obstante, tenga en cuenta que se aplican los mismos principios en Python y C#(Zerotouch), solo que con una sintaxis diferente.
Las bibliotecas estándar son externas a Dynamo y están presentes en los lenguajes de programación Python y C# (Zerotouch). Dynamo también tiene su propio conjunto de bibliotecas que corresponden directamente con su jerarquía de nodos, lo que permite al usuario crear mediante código cualquier elemento que se pueda crear con nodos y líneas. A continuación, se muestra una guía sobre los elementos a los que cada biblioteca de Dynamo proporciona acceso y cuándo utilizar una biblioteca estándar.
Bibliotecas estándar y bibliotecas de Dynamo
Las bibliotecas estándar de Python y C# se pueden utilizar para generar datos avanzados y estructuras de flujo en el entorno de Dynamo.
Las bibliotecas de Dynamo se corresponden directamente con la jerarquía de nodos para crear geometría y otros objetos de Dynamo.
Bibliotecas de Dynamo
ProtoGeometry*
Funciones: Arco, Cuadro delimitador, Círculo, Cono, Sistema de coordenadas, Cubo, Curva, Cilindro, Borde, Elipse, Arco de elipse, Cara, Geometría, Hélice, Grupo de índice, Línea, Malla, Curva Nurbs, Superficie Nurbs, Plano, Punto, Polígono, Rectángulo, Sólido, Esfera, Superficie, Topología, T-Spline, UV, Vector, Vértice.
Cómo importar: import Autodesk.DesignScript.Geometry
``
DSCoreNodes
Funciones: Color, Rango de colores 2D, Fecha y hora, Intervalo de tiempo, IO, Fórmula, Lógica, Lista, Matemáticas, Árbol cuádruple, Cadena, Rosca.
Cómo importar: import DSCore
Teselación
Funciones: Rejilla convexa, Delaunay, Voronoi.
Cómo importar: import Tessellation
DSOffice
Función: Excel.
Cómo importar: import DSOffice
Nota: Tenga en cuenta que, al utilizar ProtoGeometry a través de Python o C#, se crean objetos no administrados, que requieren que la memoria se administre manualmente. Consulte la sección Objetos no administrados mostrada a continuación para obtener más información.
Durante la creación de secuencias de comandos, utilizamos constantemente identificadores para indicar elementos como variables, tipos, funciones y otras entidades. A través de este sistema de notación simbólica, podemos hacer referencia cómodamente a la información mediante etiquetas (normalmente compuestas por una secuencia de caracteres) mientras creamos los algoritmos. En la escritura de código, una correcta denominación de los elementos es importante para que este se pueda leer y entender con facilidad por parte de otras personas y por usted mismo en un momento posterior. A continuación se indican algunos consejos que se deben tener en cuenta al asignar nombres a los elementos de su secuencia de comandos:
Está bien utilizar abreviaturas, pero explique la abreviatura con un comentario:
Evite el etiquetado redundante:
Utilice lógica positiva para los nombres de las variables, en lugar de lógica negativa:
Dé preferencia a la "notación inversa":
Es más apropiado en términos estructurales.
Los alias se deben utilizar para acortar cadenas demasiado largas y a menudo repetidas:
El uso de alias puede generar rápidamente programas muy confusos y no estándares.
Utilice solo las palabras necesarias:
"Todo debe hacerse tan simple como sea posible, pero no más". – Albert Einstein
Por lo general, hay más de una manera de programar prácticamente cualquier cosa, por lo que su "estilo personal" de crear secuencias de comandos es el resultado de las innumerables pequeñas decisiones que usted toma (o no toma) a lo largo del camino. Dicho esto, la legibilidad y las posibilidades de mantenimiento del código son resultado directo de su coherencia interna, así como del cumplimiento de las convenciones estilísticas generales. Como regla general, el código que tiene el mismo aspecto en dos lugares diferentes, también debería funcionar de la misma manera. A continuación, se ofrecen algunos consejos para escribir código claro y coherente.
Convenciones para los nombres: (elija una de las convenciones siguientes para cada tipo de entidad del código y úsela siempre)
Variables, funciones, métodos, paquetes y módulos:
lower_case_with_underscores
Clases y excepciones:
CapWords
Métodos protegidos y funciones internas:
_single_leading_underscore(self, ...)
Métodos privados:
__double_leading_underscore(self, ...)
Constantes:
ALL_CAPS_WITH_UNDERSCORES
Consejo: Evite las variables de una sola letra (especialmente, l, O, I) excepto en bloques muy cortos, cuando el significado es claramente visible desde el contexto inmediato.
Uso de líneas en blanco:
Rodee las definiciones de clase y función de nivel superior con dos líneas en blanco.
Las definiciones de método dentro de una clase se rodean con una sola línea en blanco.
Se pueden utilizar líneas en blanco adicionales (con moderación) para separar grupos de funciones relacionadas.
Evite los espacios innecesarios:
Inmediatamente después de paréntesis, corchetes o llaves:
Inmediatamente antes de coma, punto y coma o dos puntos:
Inmediatamente antes del paréntesis de apertura que inicia la lista de argumentos de una llamada de función:
Inmediatamente antes del paréntesis de apertura que inicia una indexación o un fragmento:
Rodee siempre estos operadores binarios con un solo espacio a cada lado:
Vigile la longitud de las líneas:
No las alargue más allá de aproximadamente 79 caracteres.
La limitación de la anchura necesaria en la ventana del editor permite tener varios archivos abiertos en paralelo y posibilita el correcto funcionamiento de las herramientas de revisión de código que presentan las dos versiones en columnas adyacentes.
Las líneas largas se pueden dividir en varias líneas encerrando las expresiones entre paréntesis:
Evite los comentarios obvios y redundantes:
En algunos casos, se requieren menos comentarios para obtener un código más legible. Especialmente si ello le obliga a utilizar nombres de símbolo significativos en lugar de descripciones.
La adopción de buenos hábitos de codificación reduce la dependencia de los comentarios:
Consejo: Los comentarios indican por qué y el código indica cómo.
Tenga en cuenta el código abierto:
Los proyectos de código abierto se basan en los esfuerzos colaborativos de muchos desarrolladores. Estos proyectos necesitan mantener un alto nivel de legibilidad del código para que el equipo pueda trabajar en conjunto de la forma más eficiente posible. Por lo tanto, es recomendable examinar el código fuente de estos proyectos para observar lo que hacen estos desarrolladores.
Mejore las convenciones:
Pregúntese si cada una de las convenciones funciona o no para las necesidades en cuestión.
¿Se está poniendo en peligro la funcionalidad/eficiencia?
Consulte estas páginas wiki para obtener instrucciones sobre cómo escribir C# para Zerotouch y contribuir con Dynamo:
Objetos no administrados:
Solo es necesario eliminar los recursos no administrados que no se devuelvan al gráfico y los que no almacenan una referencia. En el resto de esta sección, nos referiremos a estos objetos como geometría intermedia. Puede ver un ejemplo de esta clase de objeto en el código siguiente. La función de Zero Touch C# singleCube devuelve un único cubo, pero crea 10 000 cubos adicionales durante su ejecución. Podemos fingir que esta otra geometría se ha utilizado como geometría de construcción intermedia.
Es muy probable que esta función de Zero Touch bloquee Dynamo. Esto se debe a que hemos creado 10 000 sólidos, pero solo hemos almacenado uno de ellos y solo hemos devuelto ese mismo. Deberíamos desechar todos los cubos intermedios, excepto el que devolvemos. No debemos desechar lo que devolvemos, ya que se propaga en el gráfico y lo utilizan otros nodos.
El código fijo tendría un aspecto similar al siguiente:
Por lo general, solo es necesario eliminar geometría como Surfaces
, Curves
y Solids
. No obstante, por seguridad, puede eliminar todos los tipos de geometría (Vectors
, Points
y CoordinateSystems
).
Este wiki describe algunas normas de codificación generales para documentar y probar el código: .
Este wiki describe específicamente las normas de nomenclatura de bibliotecas, categorías, nombres de nodos, nombres de puertos y abreviaturas: .
Cuando se utiliza la biblioteca de geometría de Dynamo (ProtoGeometry) desde Python o C#, los objetos de geometría que se creen no se gestionarán mediante la máquina virtual, y la memoria de muchos de estos objetos deberá limpiarse manualmente. Para limpiar objetos nativos o no administrados, puede utilizar el método Dispose o la palabra clave using. Consulte esta entrada wiki para obtener una descripción general: .
Trabajar en un proceso de programación visual puede ser una potente actividad creativa, pero en muy poco tiempo el flujo de programa y las entradas clave de usuario pueden verse eclipsados por la complejidad o la presentación del espacio de trabajo. Veamos algunos procedimientos recomendados para administrar el programa.
Una vez que hemos añadido varios nodos al espacio de trabajo, es posible que deseemos reorganizar el diseño de los nodos para obtener mayor claridad. Al seleccionar más de un nodo y hacer clic con el botón derecho en el espacio de trabajo, la ventana emergente incluye un menú Alinear selección con opciones de justificación y distribución en X e Y.
Seleccione varios nodos.
Haga clic con el botón derecho en el espacio de trabajo.
Utilice las opciones de Alinear selección.
Con cierta experiencia, es posible que podamos "leer" el programa visual revisando los nombres de nodo y siguiendo el flujo de programa. Para los usuarios de todos los niveles de experiencia, es recomendable también incluir etiquetas y descripciones en lenguaje sencillo. Para ello, Dynamo presenta un nodo Notes con un campo de texto editable. Podemos añadir notas al espacio de trabajo de dos formas:
Vaya al menú Editar > Crear nota.
Utilice el método abreviado de teclado Ctrl + W.
Una vez que se ha añadido la nota al espacio de trabajo, aparece un campo de texto que nos permite editar el texto de la nota. Una vez creada, se puede editar la nota. Para ello, haga doble clic o haga clic con el botón derecho en el nodo Note.
Cuando aumente el tamaño del programa visual, resultará útil identificar los pasos más grandes que se ejecutarán. Podemos resaltar conjuntos más grandes de nodos con un grupo para etiquetarlos con un rectángulo de color en el fondo y un título. Hay tres formas de crear un grupo con más de un nodo seleccionado, como se indica a continuación:
Vaya al menú Editar > Crear grupo.
Utilice el acceso directo de teclado Ctrl + G.
Haga clic con el botón derecho en el espacio de trabajo y seleccione Crear grupo.
Una vez creado un grupo, se pueden editar sus parámetros, como el título y el color.
Consejo: El uso de notas y grupos es una forma eficaz de anotar el archivo y aumentar la legibilidad.
A continuación, se muestra un ejemplo de programa con notas y grupos añadidos:
Nota: "Grid Parameters" (Parámetros de rejilla)
Nota: "Grid Points" (Puntos de rejilla)
Grupo: "Create a Grid of Points" (Crear una rejilla de puntos)
Grupo: "Create an Attractor Point" (Crear un punto de atractor)
Nota: "Calibrate Distance Values" (Calibrar valores de distancia)
Nota: "Variable Grid of Circles" (Rejilla variable de círculos)