Objetivos
En este artículo aprenderás a:
- Usar el bucle while en Python.
- Traducir un proceso definido verbalmente en un algoritmo real.
- Aplicar la lógica a un caso concreto dentro de un proyecto open source para Revit.
Escenario: La Conjetura de Collatz
En 1937, el matemático alemán Lothar Collatz formuló una hipótesis aún sin demostrar:
-
Toma cualquier número natural (mayor que 0).
-
Si es par, divídelo entre 2.
-
Si es impar, multiplícalo por 3 y súmale 1.
-
Repite el proceso hasta llegar al número 1.
Lo interesante es que ningún número probado hasta hoy escapa de la secuencia y todos terminan en 1.
Ejemplo en Python
Vamos a implementar este proceso con un bucle while. El programa pedirá un número al usuario, lo procesará según la regla y mostrará todos los pasos hasta llegar a 1, contando además cuántas iteraciones han sido necesarias.
Ejemplo de ejecución para el número 15:
Explicando cada línea de código:
-
input(...)muestra el mensaje y lee texto del usuario. -
int(...)convierte ese texto a entero (si el usuario escribe algo no convertible, lanzaValueError). -
Asigna el valor convertido a la variable
c0, que será nuestro número actual en la secuencia.
Inicializa un contador de iteraciones. Empezamos en 0 porque aún no hemos aplicado ninguna regla.
Inicia un bucle while que continuará mientras c0 sea distinto de 1. Cuando c0 llegue a 1, el bucle termina.
Comprueba si c0 es par.
-
c0 % 2calcula el resto de dividirc0entre 2. -
Si el resto es 0, es par.
Si es par, reemplaza c0 por c0 // 2.
-
//es división entera (redondea hacia abajo). Comoc0es no negativo, equivale a “dividir por 2 y quedarse con el entero”.
Si es impar, aplica la regla de Collatz: 3*c0 + 1. Se actualiza c0 con ese nuevo valor.
Muestra el nuevo valor de c0 tras aplicar la regla. Por eso la salida empieza con el primer valor transformado, no con el inicial.
Incrementa el contador de pasos en 1. Equivale a pasos = pasos + 1.
Cada vuelta del bucle cuenta como una transformación.
Fuera del bucle (es decir, cuando c0 ya es 1), imprime el total de pasos.print con comas separa con un espacio por defecto, de modo que la salida queda como steps = 17.
Notas útiles y pequeños detalles
-
Entrada 1: si el usuario introduce
1, elwhileno se ejecuta ysteps = 0. -
Entrada inválida: si escribe algo no numérico o un número negativo/cero, el código tal cual fallará o no tendrá sentido para el problema.
-
Tamaño de números: Python maneja enteros grandes (precisión arbitraria), así que no hay desbordamiento aunque
3*c0+1crezca mucho. -
Orden de
printypasos: primero imprimimos el nuevoc0y luego sumamos 1 al contador. Esto hace que el número de líneas impresas coincida consteps.
También se puede realizar una versión del código con validación mínima (opcional), que podría ser la siguiente:
De la Matemática al Mundo BIM: Aplicación en Revit
Ahora, llevemos esta idea al proyecto Revit Open Source Converter.
En Revit, un flujo muy común es recorrer elementos del modelo y aplicarles reglas, de forma similar al proceso de Collatz. Por ejemplo:
-
Si el elemento cumple cierta condición (ej. es un muro de hormigón), aplicar una conversión o exportación.
-
Si no cumple, aplicar otra regla (ej. agruparlo, renombrarlo, o excluirlo).
-
Repetir hasta que todos los elementos hayan sido procesados.
El esquema es el mismo que en Collatz: un bucle que va transformando los datos paso a paso.
Ejemplo práctico con Revit (simplificado)
Supongamos que tenemos una lista de elementos de un modelo en formato genérico (open source) y queremos transformarlos a un formato más ligero para exportación.
Posible salida:
Explicación línea a línea
Declaración de la variable elementos: es una lista que contiene tres diccionarios.
-
Cada diccionario representa un elemento del modelo (a modo de ejemplo).
-
Claves:
id(entero),tipo(string: «muro», «puerta», «ventana»),material(string).
En un flujo real con Revit, estos elementos serían objetos del API con parámetros, pero aquí se usan diccionarios para simplificar.
Crea una lista vacía procesados donde guardaremos la versión transformada (resultado del procesamiento/normalización).
Inicializa el índice i en 0. Este índice se usará para recorrer la lista por posición.
Bucle while que itera mientras i sea menor que len(elementos) (la longitud de la lista).
-
len(elementos)devuelve 3 en este ejemplo. -
La condición garantiza que se acceda a índices válidos: 0, 1 y 2.
Nota: si la lista cambiara tamaño dentro del bucle, esto podría alterar las iteraciones.
Se asigna a elem el diccionario que está en la posición i de la lista.
-
elemes una referencia al diccionario original; si se mutaraelemcambiaría el elemento en la lista.
Comprueba si el valor asociado a la clave "tipo" es exactamente la cadena "muro".
-
Si la clave
"tipo"no existiera, esto lanzaría unKeyError. En código más robusto usaríamoselem.get("tipo").
Si el elemento es un muro: crea un nuevo diccionario nuevo con tres claves:
-
id: copia elidoriginal. -
categoria: se normaliza a"Wall"(convención inglesa que tal vez sea la requerida al exportar). -
export: booleanoTrueindicando que este tipo debe incluirse en la exportación.
Estenuevoes independiente del diccionario original (no se modifica el original).
Para cualquier otro tipo (puerta, ventana, etc.):
-
categoriase construye a partir deelem["tipo"].capitalize(), que pone la primera letra en mayúscula (por ejemplo «puerta» → «Puerta»). -
exportse pone aFalse(no exportar por defecto).
Es un comportamiento sencillo; en producción probablemente querrás reglas más precisas.
Añade el diccionario nuevo a la lista procesados. Así vamos acumulando el resultado del procesamiento.
Incrementa el índice i en 1. Equivalente a i = i + 1. Esto permite avanzar al siguiente elemento en la siguiente iteración del while.
Imprime por pantalla la lista completa procesados. Python mostrará la representación literal de la lista de diccionarios.
Conclusión
Lo que hemos visto es un patrón de programación universal:
-
En la Conjetura de Collatz: números que siguen reglas hasta llegar a 1.
-
En un proyecto BIM Open Source: elementos de un modelo que siguen reglas hasta transformarse en datos exportables.
En ambos casos, Python y los bucles while nos permiten convertir procesos verbales en instrucciones repetitivas y sistemáticas, lo que abre la puerta a la automatización.
Notas prácticas y mejoras
Forma más idiomática en Python
Es más claro usar un for en vez de manejar índices manualmente:
Evitar KeyError usando .get()
Si no estás 100% seguro de que las claves existen:
Usar un mapa de conversión (más escalable que if/else)
Si tienes muchas reglas de tipo → categoría/flag, usa un diccionario de mapeo:
Ventaja: centralizas reglas y es fácil añadir o cambiar mapeos.
En contexto Revit real
-
Los
elementosllegarían desde el API (por ejemploFilteredElementCollector) y no como diccionarios. -
Para leer parámetros usarías métodos del API (ej.
elem.GetParameters("Material")oelem.LookupParameter("Material").AsString()). -
El
idseríaelem.Id.IntegerValueo similar según la API. -
En lugar de
print, en un add-in usarías logs o escribirías a un archivo/JSON para la exportación.
Inmutabilidad
Crear nuevo evita tocar el diccionario original. En pipelines de conversión esto es buena práctica para auditar cambios.
Testing y trazabilidad
Añadir logging en vez de print y tests unitarios que verifiquen que el mapeo produce lo esperado.
En el próximo artículo exploraremos cómo refinar este código usando funciones en Python para que sea aún más reutilizable dentro del flujo de trabajo de un Revit Open Source Converter.

























@Yolanda Muriel 