Depurando errores en ciencia de datos: 5 lecciones básicas del CS50 de Harvard
Esta publicación traduce conceptos básicos de informática del CS50 de Harvard en modelos mentales prácticos para que los profesionales de datos creen canales de datos más robustos y de mayor rendimiento.
Introducción
Todos hemos estado allí: un script de datos que se ejecuta inexplicablemente lento, un error que desaparece cuando agregas un print() statement, or a piece of code that’s impossible to automate. These common frustrations for data practitioners often have roots in fundamental computer science concepts that are easy to overlook when working with high-level tools like Python or RAl comprender lo que sucede internamente, podemos construir mejores modelos mentales para diagnosticar problemas, optimizar el rendimiento y crear canales de datos robustos. Esta publicación es una síntesis basada en CS50x 2025 (Harvard) en YouTube. Explora las conclusiones clave de la conferencia sobre matrices, memoria y depuración, conectándolas directamente con los desafíos diarios del trabajo con datos.

Conclusión 1: La compilación no es magia, es un proceso
Lo simple make command in C, much like running a Python script, hides a multi-step process. Just as high-level data tools abstract away underlying complexity, compilation is not a single action but a four-stage pipeline that transforms human-readable source code into machine-readable instructions.
Las cuatro etapas distintas de la compilación son:
- Preprocesamiento: Este es un paso de copiar y pegar automatizado. Cuando el compilador ve una directiva como
#include, it finds the specified library file and pastes its contents into your code. - Compilando: Esta etapa traduce el código C legible por humanos a un lenguaje de nivel inferior llamado código ensamblador, que consiste en instrucciones específicas del procesador de la computadora.
- Montaje: Este paso convierte el código de ensamblaje en el binario puro del código de máquina (los ceros y unos que la CPU de la computadora puede ejecutar directamente).
- Enlace: La etapa final combina el código de máquina de su programa con el código de máquina de cualquier biblioteca que haya utilizado (por ejemplo,
cs50.c,stdio.c) into a single, complete, executable file.
Este proceso es gestionado por un programa compilador como clang, which uses flags like -o to define the output file and -l to link necessary libraries—a process that make conveniently automates for us.
Conexión con la ciencia de datos: Esta canalización es un potente modelo mental para la depuración de entornos de datos. Así como el enlazador de C requiere que todos los archivos de componentes estén presentes, un entorno de datos moderno (como un contenedor Docker) requiere que todas las dependencias estén en requirements.txt to be correctly installed. A linking error is directly analogous to a ModuleNotFoundError that breaks an entire Airflow DAG. This understanding helps a data scientist debug environmental issues systemically, recognizing them as dependency failures rather than random errors.
Conclusión 2: La memoria es una cuadrícula y sus datos tienen una dirección
Resulta útil visualizar la memoria de una computadora como una enorme red de casillas individuales, o bytes, cada una con una dirección numérica única. Al declarar una variable, se le pide al sistema que reserve una o más de estas casillas para almacenar los datos.
Los diferentes tipos de datos ocupan distintas cantidades de espacio: a char is 1 byte, a float is 4 bytes, an int is 4 bytes, and a long is 8 bytes. Until a variable is explicitly initialized, its reserved memory can hold random, leftover data. In the lecture’s debug50 demonstration, an uninitialized variable H was shown to hold a bizarre garbage value like 32766 before it was assigned a value by the program.
Conexión con la ciencia de datos: Este modelo de memoria es fundamental para el rendimiento en análisis de los datos. Elegir float64 (a double in C, 8 bytes) when float32 (a float in C, 4 bytes) would suffice can literally double your memory usage for that column. For large datasets, this choice is the difference between a job that runs smoothly and one that crashes. Likewise, “garbage values” explain the unpredictable bugs that can arise from uninitialized variables or unhandled NULL values in a data transformation script.
Conclusión 3: Una cadena es una matriz con un peligro oculto
En un lenguaje de bajo nivel como C, una cadena es simplemente una matriz de caracteres. La cadena "¡Hola!" no es una sola entidad, sino que se almacena en memoria como tres caracteres consecutivos. char variables: ‘H’, ‘i’, and ‘!’.
El "peligro oculto", o giro, es cómo la computadora sabe dónde termina la cadena. C agrega automáticamente un carácter especial, el terminador nulo (\0), to the end of every string. This character, which has a numerical value of 0, acts as a stop sign. This means a string’s actual memory footprint is always its visible length plus one extra byte for this terminator. The lecture demonstrates this by printing the characters of “Hi!” and then showing that the value at the very next position is 0, followed by garbage values.
“…la forma en que una computadora mantiene un registro de dónde está el final de una cadena, incluso si esa cadena tiene tres caracteres; la longitud de la cadena, la longitud de la matriz que realmente almacena la cadena es técnicamente cuatro; es uno más la longitud real de la frase…” — Harvard CS50x 2025 (YouTube) — Clase: CS50x 2025 – Clase 2 – Matrices
Conexión con la ciencia de datos: Esto tiene implicaciones directas para la limpieza de datos y el procesamiento de texto. La estructura subyacente de la matriz de texto explica por qué salirse de los límites (intentar acceder a un carácter más allá del final de una cadena) puede provocar errores extraños o vulnerabilidades de seguridad críticas, como desbordamientos de búfer. El concepto de un terminador especial también es común en muchos formatos de datos, como el carácter de nueva línea (\n) that separates rows in CSV files or log files. Understanding this helps in writing more robust parsers for unstructured text data.
Conclusión 4: Deje de usar print() and Start Using a Debugger
La depuración es una habilidad fundamental, y el término en sí tiene un origen famoso. Como se mencionó en la conferencia, la contralmirante Grace Hopper documentó el primer caso real de detección de un error al retirar físicamente una polilla de la computadora Harvard Mark I. Hoy en día, los errores son menos tangibles, pero nuestros métodos para encontrarlos se han vuelto mucho más sofisticados que la simple impresión de variables.
Un depurador es una herramienta que te da control directo sobre la ejecución de tu código. Como se muestra en la lección con debug50, its key features include:
- Puntos de interrupción: La capacidad de establecer una “señal de stop” en una línea específica de código, pausando la ejecución del programa en ese punto exacto.
- Paso a paso: El poder de ejecutar código línea por línea.
Step overexecutes a function as a single action, which is ideal for trusted library functions (like a pandasgroupby). In contrast,step intoenters a function to inspect its internal logic, which is essential for finding errors in your own custom functions. - Inspeccionando: La capacidad de observar los valores en tiempo real de todas las variables mientras se ejecuta el código, revelando cómo cambian paso a paso.
Conexión con la ciencia de datos: Esta es una habilidad fundamental para los profesionales de datos. Depurar una transformación compleja de pandas con múltiples pasos imprimiendo data frames intermedios es engorroso y lento. Usar un depurador en un IDE como VS Code o PyCharm proporciona una forma sistemática y repetible de encontrar la causa raíz de un error en la lógica, en lugar de depender de conjeturas y saturar el código con instrucciones de impresión temporales.
Conclusión 5: El resultado más importante de su guión es un solo número
La razón por la main function in C programs is defined to return an int is to provide an código de estado de salida Al sistema operativo. Este número único indica si el programa finalizó correctamente o si se produjo un error.
La convención descrita en la conferencia es universal en informática:
return 0;signifies éxito.return 1;(or any other non-zero number) signifies el fracaso.
Esta convención existe porque, si bien un programa solo tiene una forma de tener éxito (que haya cumplido su función), puede haber muchas razones diferentes para que falle. Se pueden usar diferentes números distintos de cero para representar distintos tipos de errores, de forma similar al código de error. 1132 in Zoom or the 404 code for a missing web page.
Conexión con la ciencia de datos: Los códigos de salida son fundamentales para los flujos de trabajo y las canalizaciones de datos automatizadas gestionadas por herramientas como Airflow, cron o dbt. Un programador ejecuta un script y comprueba su código de salida para determinar el siguiente paso. Un código distinto de cero indica que algo salió mal, lo que puede detener la canalización, evitar la propagación de datos erróneos y activar una alerta para el analista de guardia. Crear scripts que indiquen correctamente el éxito o el fracaso mediante códigos de salida es esencial para desarrollar sistemas automatizados robustos y fiables.
Qué aplicar hoy
A continuación se presentan cinco pasos prácticos y viables que un profesional de datos puede adoptar basándose en estas conclusiones:
- Inspeccione la memoria de sus datos. Utilice un comando como
df.info(memory_usage='deep')in pandas to see how much memory your data types are consuming. Question if afloat64is necessary when afloat32would suffice. - Utilice un depurador real una vez. La próxima vez que tenga un error, resista la tentación de agregar un
print()statement. Instead, set a breakpoint in your IDE (like VS Code or PyCharm) and step through your code. - Mapee sus dependencias. Para su canal de datos más crítico, dibuje un diagrama simple de sus dependencias: qué scripts llaman a cuáles, qué bibliotecas se importan y a qué fuentes de datos se accede. Esto refleja la etapa de "vinculación" y le ayuda a anticipar los puntos de fallo.
- Añade un código de salida. En un script de automatización simple, agregue un
try...exceptblock. If an error occurs, print a message and exit with a non-zero status code (e.g.,sys.exit(1)in Python). - Piense en la terminación. Al analizar un archivo de texto o un registro, identifique conscientemente el “terminador nulo”, el carácter (como una nueva línea) que señala el final de un registro.
Cierre
Comprender los fundamentos de la informática básica proporciona modelos mentales potentes que se aplican directamente al trabajo con datos de alto nivel. Conceptos como la gestión de memoria, la depuración y los códigos de salida no son solo trivialidades académicas; son la base para escribir código más eficiente, fiable y escalable. Estos principios son la base de temas más avanzados, como algoritmos y estructuras de datos, cruciales para abordar retos de datos más grandes y complejos.
¿Qué error de datos de alto nivel has encontrado y que ahora tiene más sentido a través de la lente de estas mecánicas de bajo nivel?

