REVIT ARCHITECTURE (985) – PYTHON – Bucles (69) – While y for aplicados al flujo Open Source Converter en Revit

Objetivos

  • Comprender la diferencia entre los bucles while y for.

  • Analizar ejemplos simples línea por línea.

  • Relacionar el uso de bucles con la automatización de procesos en un proyecto Revit Open Source Converter.

Parte 1: El bucle While

El bucle while ejecuta un bloque de instrucciones mientras se cumpla una condición booleana.

Ejemplo: Contar hacia arriba hasta un límite

Explicación línea por línea

Inicializamos la variable contador con el valor 1.

Iniciamos un bucle while que se repetirá mientras contador sea menor o igual que 5.

Imprime en pantalla el texto «Valor actual:» seguido del número actual de contador.

Incrementa el valor de contador en 1. Esto evita que el bucle sea infinito, ya que eventualmente contador será mayor que 5 y el while se detendrá.

Salida esperada

Parte 2: El bucle For

El bucle for se utiliza para recorrer secuencias (listas, cadenas, diccionarios, etc.) o para repetir un bloque de código un número específico de veces.

Ejemplo: Recorrer una lista de nombres

Explicación línea por línea

Creamos una lista con tres elementos de tipo string.

Iniciamos un bucle for que recorrerá la lista. En cada iteración, la variable nombre tomará uno de los valores de la lista.

Imprime un saludo personalizado para cada nombre de la lista.

Salida esperada

Parte 3: Conexión con el flujo Revit Open Source Converter

En un proyecto de conversión open source para Revit, los bucles son herramientas clave porque:

  1. Con while:
    Se usan para recorrer elementos hasta que se cumpla una condición dinámica. Por ejemplo:

    • Procesar elementos del modelo mientras queden elementos pendientes en una cola de trabajo.

    • Seguir ajustando parámetros hasta que cumplan un criterio (ej.: que el espesor de un muro esté dentro de un rango aceptable).

    Ejemplo conceptual:

¡Vamos línea por línea!

Llama a una función (de ejemplo) que recupera los elementos del modelo de Revit que quedan por procesar en una cola de trabajo.

Esperamos que devuelva una secuencia (normalmente una lista) como [{…}, {…}, …].

Si devolviera None o algo no iterable, el resto del código fallaría. En un flujo real conviene validar: pendientes = list(obtener_elementos_revit() or []).

  • Inicializa un índice entero para recorrer la lista desde el primer elemento (posición 0).

  • Este patrón es el de un bucle controlado por índice.

  • Inicia un bucle que se repetirá mientras i sea menor que la longitud actual de pendientes.

  • len(pendientes) se evalúa en cada iteración.

  • Garantiza que los accesos pendientes[i] estarán en rango (evita IndexError).

  • Si modificas la lista dentro del bucle (añadir/quitar), la longitud cambia y puedes saltar o repetir elementos sin querer. En este patrón, no conviene mutar pendientes.

  • Obtiene el elemento en la posición i y lo pasa a la función procesar.

  • procesar(...) es un placeholder: en un Open Source Converter para Revit podría:

    • Normalizar categorías/parametría,

    • Convertir geometrías/propiedades a un esquema abierto,

    • Marcar/registrar para exportación,

    • Escribir a JSON/IFC/otro formato.

  • Ojo a los efectos secundarios: si procesar modifica pendientes, aplica el aviso anterior (modificar una lista).

  • Incrementa el índice para pasar al siguiente elemento.

  • Evita que el while sea infinito: si te olvidas de esta línea, la condición nunca cambia y el bucle no termina.

Qué hace en conjunto

  • Recorre secuencialmente todos los elementos devueltos por obtener_elementos_revit() y aplica procesar(...) a cada uno.

  • Complejidad temporal: O(n) (una vez por elemento), espacial: O(1) adicional (solo un índice).

Buenas prácticas y alternativas “más Pythonic”

  1. Evitar índice manual cuando no es necesario

Más legible y seguro si no necesitas la posición.

  1. Si necesitas la posición

Obtienes i y el elemento sin calcular len(...) ni manejar el índice.

  1. Si quieres consumir una cola de trabajo (y la lista puede cambiar):

Ideal para workflows donde procesar puede añadir más tareas.

  1. Defensivo (validar entrada):

En el flujo Open Source Converter (Revit)

  • obtener_elementos_revit() podría envolver un FilteredElementCollector y mapear cada elemento a un diccionario intermedio (id, categoría, parámetros relevantes).

  • procesar(...) aplicaría reglas de conversión (por ejemplo, mapear "Muro Estructural""Wall/Structural", normalizar materiales, convertir unidades, preparar payload de exportación).

  • El bucle garantiza que cada elemento del modelo pase por la misma tubería de transformación, clave para una exportación consistente y reproducible.

2. Con for:

Son ideales para recorrer conjuntos definidos de elementos, parámetros o categorías.

  • Iterar sobre todos los muros de un modelo para exportarlos.

  • Recorrer una lista de materiales y convertirlos a un formato estándar.

Ejemplo conceptual:

La explicación línea por línea del código es:

Línea 1 — muros = obtener_muros_revit()

  • Qué hace: llama a una función (ejemplo) que recupera del modelo todos los muros que quieres procesar y asigna esa colección a la variable muros.

  • Qué tipo de dato es muros: normalmente una secuencia iterable — puede ser una list, un tuple, o incluso un generator / un objeto lazy (por ejemplo el FilteredElementCollector de la API de Revit).

  • Por qué importa el tipo:

    • Si es una lista, puedes consultarla varias veces, usar len(muros), o indexarla.

    • Si es un generator o un objeto lazy, se consumirá al iterarlo una vez (más eficiente en memoria si hay miles de muros).

  • Validación recomendada: comprobar que no sea None y manejar el caso vacío:

Contexto Revit: obtener_muros_revit() suele envolver un FilteredElementCollector(doc).OfCategory(OST_Walls).WhereElementIsNotElementType() y devolver list(collector) o directamente el collector para iteración lazy.

Línea 2 — for muro in muros:

  • Qué hace: inicia un bucle que toma cada elemento de muros en orden; en cada iteración la variable muro referencia al objeto actual.

  • Por qué usar for aquí: es la forma pythónica y segura de recorrer colecciones (menos propensa a errores que manejar índices manualmente con while).

  • Comportamiento importante:

    • Si muros es un generator, esta línea consumirá elementos de ese generator.

    • Si muros cambia durante la iteración (por ejemplo si exportar_muro añade/quita elementos de la misma colección), el comportamiento puede ser inesperado; mejor iterar sobre una copia si vas a mutar la colección: for muro in list(muros):

  • Si necesitas la posición: usa enumerate:

Línea 3 — exportar_muro(muro)

  • Qué hace: llama a una función que realiza la operación de exportación sobre el muro actual.

  • Qué puede incluir exportar_muro: leer parámetros (tipo, material, dimensiones), convertir geometría a formato abierto, escribir a JSON/IFC/BD, marcar el muro como “procesado”, etc.

  • Efectos secundarios y precauciones:

    • Lectura vs escritura: si exportar_muro sólo lee parámetros y genera archivos externos, no necesita transacción.

    • Si modifica el modelo (escribe parámetros o cambia elementos): debe hacerse dentro de una Transaction (Revit API) y con cuidado para no abrir/commitear muchas transacciones por cada elemento (mejor agrupar cambios).

    • Manejo de errores: envolver con try/except para que un error en un muro no rompa todo el bucle.

    • Idempotencia: ideal que exportar_muro sea idempotente (ej., poder ejecutarlo varias veces sin duplicar datos).

  • Ejemplo de patrón seguro:

Ejemplo práctico (pseudo-código Revit + buenas prácticas)

Notas Revit específicas:

  • Si exportar_muro necesita escribir en el documento Revit (p.ej. marcar una propiedad), hay que hacer esos cambios dentro de una Transaction.

  • La API de Revit no es threadsafe: el código debe ejecutarse en el hilo principal de Revit (o usar ExternalEvent / IExternalCommand según el host).

  • Para grandes conjuntos, evita abrir/cerrar archivos o transacciones por cada muro: agrupa operaciones y escribe en lotes para mejorar rendimiento.

Conclusiones:

Así como en los ejemplos básicos de Python en los 60 primeros artículos sobre Python en este blog, Revit Architecture serie,  recorríamos números o nombres, en un proyecto BIM usamos bucles para recorrer elementos del modelo. La diferencia está en la complejidad de los objetos que procesamos, pero la lógica es idéntica.

  • El bucle while es útil cuando no sabemos de antemano cuántas veces se repetirá el ciclo, y la condición depende del estado de los datos.

  • El bucle for es útil cuando sí conocemos la colección de elementos que vamos a recorrer.

  • En el contexto del Revit Open Source Converter, ambos son fundamentales para automatizar procesos repetitivos: iterar sobre elementos, validar parámetros y preparar exportaciones.

  • for muro in muros es la forma más clara de aplicar una operación a cada elemento de una colección.

  • Asegúrate de saber si muros es una lista (reiterable) o un generator (consumible una vez).

  • Maneja excepciones y registra errores para no interrumpir todo el proceso.

  • En el contexto Open Source Converter, obtener_muros_revit() es la entrada a la tubería de conversión y exportar_muro() es la transformación/salida — igual que los ejemplos simples, pero con reglas, transacciones y restricciones del API de Revit.

Bonus: una forma más compacta de recorrer elementos

Hasta ahora hemos usado bucles while y for para recorrer elementos de Revit. Sin embargo, Python tiene un truco muy elegante llamado comprensión de listas (list comprehension).

Con ella podemos transformar y exportar muros en una sola línea:

En un flujo de trabajo Open Source Converter para Revit, esto puede servir para generar listas rápidas de parámetros o rutas de exportación, manteniendo el código limpio y eficiente.

Es como comprimir todo un bucle en una sola frase: menos líneas, más claridad.

Las tres formas de recorrer elementos en Python —while, for, y comprensión de listas— aplicado a Revit se pueden ver en el siguiente esquema:

Este es el esquema visual que muestra las tres formas de recorrer elementos en Python aplicadas a un flujo de trabajo de Revit:

  • while loop

  • for loop

  • list comprehension

De un vistazo se ve la progresión: de más líneas y control manual, a más elegancia y compacidad en el código.

Licencia Creative Commons@Yolanda Muriel Attribution-NonCommercial-NoDerivs 3.0 Unported (CC BY-NC-ND 3.0)

Deja un comentario