El primer paso para depurar un script es meterse en una máquina del tiempo, volver al momento en que empezaste a escribir el guión y decirte a ti mismo que ahora estás perdiendo una gran cantidad de tiempo tratando de depurar el script. “Por favor”, deberías decírtelo antes, “sigue las buenas prácticas de programación mientras escribes este guión para que no tenga que perder tanto tiempo. Estoy aún más ocupado ahora que cuando escribí el guión por primera vez”.
Si no tienes una máquina del tiempo, debes resolver seguir buenas prácticas de programación a partir de ahora. Tomará un poco más de tiempo ahora, pero le estarás dando un gran regalo a tu yo futuro. Como dijo Ben Franklin, “una onza de prevención vale una libra de cura”.
Esta sección contiene un conjunto de buenas prácticas de programación que encuentro particularmente relevantes para los científicos que están analizando datos EEG/ERP en Matlab y son relativamente nuevos en la codificación.
Ciclos rápidos entre codificación y pruebas
Quizás el error más común que cometen los programadores novatos es intentar escribir un guión completo sin hacer ninguna prueba en el camino. Si escribes un guión de 30 líneas, probablemente tendrás 8 errores diferentes en el guión, y será muy difícil averiguar qué está pasando mal.
Como mencioné antes, el mejor enfoque es escribir una pequeña cantidad de código, probarlo, depurarlo si es necesario y luego agregar más código. Cuando eres nuevo en la programación, esto podría ser solo 1-3 líneas de código a la vez. A medida que adquieras experiencia, puedes escribir más líneas antes de probar, pero incluso un programador experimentado suele hacer algunas pruebas después de cada 20-40 nuevas líneas de código.
Definir todos los valores como variables en la parte superior del script
Si ya has leído el capítulo sobre scripting, sabrás que este es mi principio #1 de escribir un buen código. Por ejemplo, en el experimento N170 que es el foco del capítulo, analizamos los datos de los sujetos 1-10, pero dejando fuera el sujeto t. Cuando recorrimos los sujetos, necesitábamos una línea de código como esta:
for subject = [1 2 3 4 6 7 8 9 10] # Tenga en cuenta que falta 5 en esta lista
Imagine que necesitamos recorrer los temas en tres partes diferentes del script (por ejemplo, una vez para el procesamiento de EEG pre-ICA, una vez para el procesamiento EEG post-ICA y una vez para el procesamiento ERP). Podríamos simplemente repetir ese mismo bucle en cada una de estas tres partes distintas del guión. Pero ahora imagina que, un año después de haber analizado los datos, obtenemos reseñas de una revista y un revisor quiere que reanalicemos los datos sin excluir al sujeto 5. Ahora necesitamos encontrar todas las partes del script con este bucle y modificarlas. ¿Recordaremos que teníamos tres bucles? Hay una buena posibilidad de que nos habremos olvidado y no los encontraremos a los tres. Como resultado, tendremos un error. Y o bien terminaremos con el resultado equivocado o perderemos horas de tiempo tratando de encontrar el problema.
Para evitar este problema, siempre debes, siempre, SIEMPRE usar una variable en la parte superior del script para definir una lista como esta. Aquí hay un ejemplo:
% Esta línea se encuentra en la sección superior del script
SUB = [1 2 3 5 6 7 8 9 10];% Array of subject IDs, excluyendo subject 5
% Así es como usamos la lista más adelante en el script
para subject = SUB
El mismo principio se aplica a números individuales (por ejemplo, el número de sujetos) y cadenas (por ejemplo, un nombre de archivo).
Aunque entiendas y aprecies este consejo, es fácil ignorarlo diciéndote a ti mismo: “Este guión es solo de unas pocas líneas. No necesito preocuparme por poner los valores en variables en la parte superior”. La mayoría de los guiones largos comienzan como guiones cortos, y esto es solo ser miope. Entonces, a riesgo de repetirme, siempre debes, siempre, SIEMPRE usar una variable en la parte superior del script para definir valores.
Tenga en cuenta que ceros y unos pueden ser una excepción a esta regla cuando se están utilizando de manera más conceptual. Por ejemplo, cero y uno a veces se usan para significar VERDADERO y FALSO. O podrías hacer algo como esto:
% Esta línea se encuentra en la sección superior del script
SUB = [1 2 3 5 6 7 8 9 10];% Array of subject IDs, excluyendo subject 5
num_subject = length (SUB);% Número de asignaturas
% Así es como usamos la lista más adelante en el script
para subject_num =
1:num_subject subject = SUB (subject_num);
% Más código aquí para procesar los datos de este asunto
fin
Haz que tu código sea legible
La realidad de la ciencia es que a menudo iniciarás un guión, volverás a él unas semanas después para terminarlo, pero luego lo modificarás 18 meses después (después de recibir las reseñas de un manuscrito). Y alguien más puede obtener una copia de tu guión y modificarlo para sus propios estudios. Si el código no es fácil de leer, es probable que se introduzcan errores en estos momentos. Aquí hay algunas cosas simples que puede hacer que su código sea más legible:
- Incluye mucha documentación interna en tus scripts. Es un gran regalo para tu yo futuro.
- Definir todos los valores como variables en la parte superior, como se señaló anteriormente, pero también asegúrese de que haya un comentario que indique el propósito de cada variable
- Divide tu código en pequeñas secciones modulares (o funciones separadas), con un comentario al principio de cada sección o función que explique lo que hace esa sección o función
- Utilice nombres de variables intrínsecamente significativos (por ejemplo, num_sujetos en lugar de ns) y nombres de funciones (por ejemplo, ploterps en lugar de npbd). Perdí un par de horas una noche en mi primer año de posgrado porque alguien había usado el nombre npbd para una función que trazaba formas de onda ERP, y sigo amargada...
Puedes encontrar más discusión sobre la importancia de la legibilidad en el capítulo de scripting.
Haz tu código modular
Si tiene un solo script que tiene más de 200 líneas de largo, probablemente debería dividirse en una secuencia de múltiples scripts. Es mucho más difícil encontrar problemas en un guión largo que en un guión corto. Y es mucho más fácil introducir problemas en un script largo (por ejemplo, agregando código a la sección incorrecta). Por ejemplo, la canalización de procesamiento EEG/ERP en el Capítulo 10 consiste en una serie de 7 scripts. En los experimentos ERP CORE, teníamos alrededor de 20 scripts diferentes para cada experimento individual.
Haga que su código sea portátil mediante rutas relativas
Casi todos los scripts de procesamiento EEG/ERP necesitan acceder a los archivos a través de una ruta. La peor manera de manejar esto es algo como esto (para cargar un conjunto de datos):
EEG = pop_loadset ('nombre de archivo', '/Users/luck/erp_analysis_book/appendix_2_Troubleshooting/ejercicios/1_n170.set');
Esto viola el principio de definir todos los valores en la parte superior del guión. Un enfoque mejor, pero aún problemático, es este:
% Variables definidas en la parte superior del script
data_dir = '/Users/luck/erp_analysis_book/appendix_2_Troubleshooting/ejercicios/';
setname = '1_n170.set';
% Cargando los datos más tarde en el script
EEG = pop_loadset ('filename', setname, 'filepath', data_dir);
El problema con este enfoque es que se romperá si cambias a una computadora diferente, mueves tus datos a una ubicación diferente o compartes tu script con otra persona.
Un mejor enfoque es determinar la ruta desde la ubicación del script (asumiendo que el script se mantiene con los datos):
data_dir = pwd; %Carpeta actual (donde se debe ubicar el script)
En el capítulo 10 se describe esto con mucho más detalle.
Revisión de código
Se está volviendo muy común (y a veces requerido) que los investigadores publiquen su código de análisis de datos en línea junto con sus datos al publicar un artículo. De esa manera, otros investigadores pueden verificar que obtienen los mismos resultados con tus datos y pueden usar tu código en sus propios estudios. Creo que esta es una tendencia maravillosa.
Cuando te das cuenta de que otras personas estarán mirando y ejecutando tu código, esto tiende a aumentar la presión para asegurarse de que el código realmente funcione correctamente. En teoría, ya deberías estar muy motivado para asegurarte de que tu código funcione, porque tus hallazgos dependen del código que funcione correctamente. Pero el escrutinio público suele ser un motivador aún más fuerte.
Una muy buena manera de asegurarse de que su código funcione correctamente es usar la revisión de código. Este es solo un término elegante para que alguien más revise tu código para asegurarse de que sea correcto. Por supuesto, la revisión de código es mucho más fácil y efectiva si has hecho que tu código sea legible y portátil. La persona que revisa tu código probablemente también tendrá sugerencias para hacer que tu código sea aún más legible y proporcionará una buena prueba de si tu código es portátil (es decir, si funciona en la computadora del revisor).