Saltar al contenido principal

# 11.10: Ejercicio- Bucles

$$\newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} }$$

$$\newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}}$$

$$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$

( \newcommand{\kernel}{\mathrm{null}\,}\) $$\newcommand{\range}{\mathrm{range}\,}$$

$$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$

$$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}[1]{\| #1 \|}$$

$$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$

$$\newcommand{\Span}{\mathrm{span}}$$

$$\newcommand{\id}{\mathrm{id}}$$

$$\newcommand{\Span}{\mathrm{span}}$$

$$\newcommand{\kernel}{\mathrm{null}\,}$$

$$\newcommand{\range}{\mathrm{range}\,}$$

$$\newcommand{\RealPart}{\mathrm{Re}}$$

$$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$

$$\newcommand{\Argument}{\mathrm{Arg}}$$

$$\newcommand{\norm}[1]{\| #1 \|}$$

$$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$

$$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\AA}{\unicode[.8,0]{x212B}}$$

$$\newcommand{\vectorA}[1]{\vec{#1}} % arrow$$

$$\newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow$$

$$\newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} }$$

$$\newcommand{\vectorC}[1]{\textbf{#1}}$$

$$\newcommand{\vectorD}[1]{\overrightarrow{#1}}$$

$$\newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}}$$

$$\newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}}$$

$$\newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} }$$

$$\newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}}$$

$$\newcommand{\avec}{\mathbf a}$$ $$\newcommand{\bvec}{\mathbf b}$$ $$\newcommand{\cvec}{\mathbf c}$$ $$\newcommand{\dvec}{\mathbf d}$$ $$\newcommand{\dtil}{\widetilde{\mathbf d}}$$ $$\newcommand{\evec}{\mathbf e}$$ $$\newcommand{\fvec}{\mathbf f}$$ $$\newcommand{\nvec}{\mathbf n}$$ $$\newcommand{\pvec}{\mathbf p}$$ $$\newcommand{\qvec}{\mathbf q}$$ $$\newcommand{\svec}{\mathbf s}$$ $$\newcommand{\tvec}{\mathbf t}$$ $$\newcommand{\uvec}{\mathbf u}$$ $$\newcommand{\vvec}{\mathbf v}$$ $$\newcommand{\wvec}{\mathbf w}$$ $$\newcommand{\xvec}{\mathbf x}$$ $$\newcommand{\yvec}{\mathbf y}$$ $$\newcommand{\zvec}{\mathbf z}$$ $$\newcommand{\rvec}{\mathbf r}$$ $$\newcommand{\mvec}{\mathbf m}$$ $$\newcommand{\zerovec}{\mathbf 0}$$ $$\newcommand{\onevec}{\mathbf 1}$$ $$\newcommand{\real}{\mathbb R}$$ $$\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}$$ $$\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}$$ $$\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}$$ $$\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}$$ $$\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}$$ $$\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}$$ $$\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}$$ $$\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}$$ $$\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}$$ $$\newcommand{\laspan}[1]{\text{Span}\{#1\}}$$ $$\newcommand{\bcal}{\cal B}$$ $$\newcommand{\ccal}{\cal C}$$ $$\newcommand{\scal}{\cal S}$$ $$\newcommand{\wcal}{\cal W}$$ $$\newcommand{\ecal}{\cal E}$$ $$\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}$$ $$\newcommand{\gray}[1]{\color{gray}{#1}}$$ $$\newcommand{\lgray}[1]{\color{lightgray}{#1}}$$ $$\newcommand{\rank}{\operatorname{rank}}$$ $$\newcommand{\row}{\text{Row}}$$ $$\newcommand{\col}{\text{Col}}$$ $$\renewcommand{\row}{\text{Row}}$$ $$\newcommand{\nul}{\text{Nul}}$$ $$\newcommand{\var}{\text{Var}}$$ $$\newcommand{\corr}{\text{corr}}$$ $$\newcommand{\len}[1]{\left|#1\right|}$$ $$\newcommand{\bbar}{\overline{\bvec}}$$ $$\newcommand{\bhat}{\widehat{\bvec}}$$ $$\newcommand{\bperp}{\bvec^\perp}$$ $$\newcommand{\xhat}{\widehat{\xvec}}$$ $$\newcommand{\vhat}{\widehat{\vvec}}$$ $$\newcommand{\uhat}{\widehat{\uvec}}$$ $$\newcommand{\what}{\widehat{\wvec}}$$ $$\newcommand{\Sighat}{\widehat{\Sigma}}$$ $$\newcommand{\lt}{<}$$ $$\newcommand{\gt}{>}$$ $$\newcommand{\amp}{&}$$ $$\definecolor{fillinmathshade}{gray}{0.9}$$

En este ejercicio, presentaremos el concepto de loops, que te harán la vida mucho más fácil al permitirte automatizar el procesamiento de múltiples participantes. Hay varios tipos de bucles, pero el más común se llama bucle for. Permite repetir la misma secuencia de pasos varias veces, pero con una variable cambiando (por ejemplo, una variable que indica qué participante debe procesarse). Vamos a pasar por varios ejemplos en este ejercicio, comenzando simple y trabajando nuestro camino hasta un script que procesa los datos de múltiples participantes.

Como de costumbre, comencemos saliendo de EEGLAB, escribiendo clear all y reiniciando EEGLAB. Luego abra Script3.m haciendo doble clic sobre él en el panel Carpeta Actual. Ejecute el script (por ejemplo, haciendo clic en el botón Ejecutar) y vea lo que hace. Deberías ver que imprime una lista de números entre 1 y 10. En un guión posterior, estos serán los números de identificación de nuestros participantes. Tenga en cuenta que falta el número 5. Esto pretende indicar que el Sujeto 5 está siendo excluido (porque ese sujeto tenía demasiados artefactos y fue excluido de los análisis finales).

Ahora echa un vistazo al guión. El cuerpo principal del guión es el siguiente:

para sujeto = [1 2 3 4 6 7 8 9 10]

pantalla (sujeto);

final

En Matlab, un bucle for comienza con for y termina con final. Las líneas de código entre las líneas for y end son el cuerpo del bucle. Este cuerpo se ejecutará varias veces, una vez por cada elemento especificado en la matriz en la línea for. La línea for define una variable (que hemos nombrado subject en este ejemplo) y especifica una matriz de valores que se almacenarán en esta variable a medida que avanzamos por el bucle ([1 2 3 4 6 7 8 9 10] en este ejemplo).

En Script3.m, el cuerpo del bucle es una sola línea que consiste en el comando display (subject), que simplemente imprime el valor de la variable llamada subject que especificamos en la línea for. Tenga en cuenta que es convencional sangrar el cuerpo de un bucle usando pestañas. Las pestañas son ignoradas por Matlab, pero hacen que sea más fácil ver la estructura de un guión. No requerido, ¡pero muy recomendable!

Cada vez que pasamos por el bucle, la variable llamada subject se establece en un nuevo valor en la matriz de valores que siguen al signo igual. Cuando se inicia el bucle, subject se establecerá en 1 (porque 1 es el primer valor de la matriz). La línea display (subject) se ejecutará entonces, y mostrará un valor de 1 porque ese es el valor de la variable subject. Entonces se produce la línea final, diciéndole a Matlab que vuelva al inicio del bucle y establezca sujeto al siguiente valor en la matriz (2). La línea display (subject) se ejecutará entonces, pero esta vez mostrará un valor de 2 porque ese es ahora el valor de la variable subject.

Matlab seguirá repitiendo el bucle, fijando sujeto a 3, luego a 4, luego a 6, etc. No hay 5 en nuestra matriz de valores, por lo que el sujeto nunca tomará ese valor. La matriz es solo una lista de valores, y cualquier secuencia de valores funcionará. Por ejemplo, podríamos usar [3 1 5 9] y luego sujeto tomaría ese conjunto de valores en ese orden (3, luego 1, luego 5, luego 9). Incluso podríamos usar números no enteros (por ejemplo, [5.23 6.1 -5.442 10021.2]) o cadenas de caracteres (por ejemplo, ['S1' 'S2' 'S3' 'S5']). Matlab es mucho más flexible que la mayoría de los lenguajes de programación en este sentido. Pasa algún tiempo jugando con la matriz en el guión para que tengas una buena idea de cómo funciona.

Ahora cierra Script3.m y abre Script3b.m, que es una versión un poco más sofisticada del mismo conjunto de ideas. Ejecute el script para ver qué hace. Deberías ver un conjunto de líneas comenzando con esto:

Materia de Tramitación 1

Materia de procesamiento 2

Materia de Procesamiento 3

Ahora mira el guión. Notarás dos cambios principales desde el primer guión. Primero, en lugar de proporcionar una lista explícita de ID de asunto en la línea for, hemos definido una variable llamada SUB que almacena esta matriz:

SUB = [1 2 3 4 6 7 8 9 10]; %Matriz de IDs de sujetos

Luego especificamos esta variable como nuestro array en la sentencia for:

para sujeto = SUB

Este enfoque encarna mi principio #1 de escribir un buen código: Todos los valores utilizados por un script deben definirse como variables en la parte superior del script. Diré más sobre este principio más adelante en el capítulo.

El segundo cambio al script es que utiliza el comando fprintf en lugar del comando display para imprimir el valor de la variable subject. El comando fprintf es mucho más potente y flexible. Se necesita un poco de tiempo para aprender a usarlo, pero bien merece la pena el tiempo. Aquí está la versión específica utilizada en nuestro script:

fprintf ('Asunto de procesamiento %d\ n', asunto);

El primer parámetro en el comando fprintf es una cadena de formato. Contiene texto plano que es impreso por la rutina, y también incluye instrucciones de formato para variables que aparecen como parámetros posteriores. El %d le dice al comando que imprima un número entero (el valor de la variable subject), y el\ n le dice que imprima una nueva línea (un retorno). Puedes hacer mucho más que esto con fprintf, pero lo estamos manteniendo simple por ahora (consulta la documentación de fprintf para más detalles).

Una vez que entiendas cómo funciona este script, ciérralo y abre Script3C.m. Si lo ejecuta, verá que la salida tiene más información que la proporcionada por el script anterior. Para cada iteración del bucle, indica cuántas veces hemos pasado por el bucle, más el ID del sujeto. Esto nos permite ver que el quinto sujeto tiene una identificación de 6, no de 5.

Mira el guión para ver cómo funciona. Cerca de la parte superior, verás que usamos una función de Matlab llamada length para definir una variable llamada num_subject que almacena el número de sujetos en la matriz SUB:

núm_sujetos = longitud (SUB);

Luego hemos usado esta nueva variable para definir la matriz de valores para el bucle, que hemos definido como 1:num_subject. Escriba 1:num_subject en la línea de comandos. Verás que es equivalente a una lista de enteros entre 1 y núm_sujetos (en lugar de 1 a 10, saltándose 5). Como resultado, ya no estamos recorriendo los ID del sujeto. Como resultado, he cambiado el nombre de la variable en la sentencia for a subject_index.

Cada vez que pasa por el bucle, obtenemos el ID del sujeto al encontrar el elemento en SUB que corresponde a subject_index y lo almacenamos como una cadena de texto en una variable llamada ID. Por ejemplo, cuando subject_index es 5, obtenemos el elemento de SUB, que es 6 (porque SUB omite el sujeto 5). SUB es una matriz de números, pero como verás en el siguiente script, es útil almacenar el ID como una cadena de texto. Por lo tanto, utilizamos una función de Matlab llamada num2str para convertir el número en una cadena antes de almacenarlo en ID. Tenga en cuenta que la cadena de formato para el comando fprintf usa %s para indicar que este comando debe imprimir una variable de cadena para ID.

##### Por qué vale la pena incluir buenos comentarios y nombres de variables significativos en sus guiones

Cuando estás en medio de escribir un guión para procesar los datos para un experimento, te concentrarás mucho en hacer el trabajo. Es decir, solo quieres escribir un guión para trabajar para que puedas llegar al siguiente paso del proyecto (y en última instancia hasta el punto de enviar un trabajo para su publicación). Sin embargo, la ruta más rápida hacia una meta no siempre es la más recta: Si te enfocas demasiado en el objetivo inmediato de conseguir que el guión funcione, en realidad puedes ralentizar tu avance hacia el objetivo final de enviar el trabajo. Realmente vale la pena tomarse su tiempo al escribir un guión y escribir el código de una manera que sea óptima a la larga.

En la práctica, esto significa seguir buenas prácticas de codificación que reducen la probabilidad de errores, como definir todos los valores importantes como variables en la parte superior del script. Los errores realmente pueden ralentizarte si no te das cuenta del error hasta que estás cerca del punto de enviar el trabajo y ahora necesitas repetir todos los análisis, cambiar todas las cifras y actualizar el texto de tu trabajo. También es importante darse cuenta de que probablemente necesitará volver a su guión muchos meses después de haberlo escrito (por ejemplo, cuando esté escribiendo su sección Método o se dé cuenta de que necesita reanalizar sus datos), y se ahorrará mucho tiempo si escribe su código de una manera fácil de leer más tarde.

Hay dos formas sencillas de hacer que su código sea más legible. El primero es usar nombres de variables que tengan un significado obvio. Por ejemplo, podría haber usado algo como ns como el nombre de la variable que contiene el número de sujetos, pero en su lugar usé num_subject. El segundo es agregar muchos comentarios. Para ejemplos, eche un vistazo a los scripts de ejemplo que creé para este capítulo. Por supuesto, estos guiones fueron diseñados para ser leídos por otras personas, así que puse más trabajo en esos comentarios del que podría tener para un guión regular que no planeaba compartir. Pero aún incluyo toneladas de comentarios en guiones que no planeo compartir. Es un regalo para mi yo futuro, porque sé que probablemente tendré que volver a esos guiones después de meses o incluso años, y los comentarios me harán la vida mucho más fácil entonces. Y cuando vuelvo a un guión con buenos comentarios, siempre trato de agradecer a mi yo pasado por el regalo.

También debes tener en cuenta que cada vez es más común hacer que tus datos y scripts estén disponibles en línea cuando publicas un artículo. Esto significa que en realidad nunca estás escribiendo guiones solo para ti mismo. Otros investigadores van a estar mirando tus guiones, así que no quieres que los guiones sean embarazosos, y quieres que los otros investigadores puedan entender tu código. Si haces que el código sea fácil de entender, esto aumenta la probabilidad de que los otros investigadores hagan un seguimiento de tu investigación, lo que significa que tu investigación tendrá un mayor impacto. ¿Y no estás investigando para que tenga un impacto?

He descubierto que la gente suele pasar una gran cantidad de tiempo puliendo sus guiones (haciéndolos más lógicos y agregando muchos comentarios) justo antes de que vayan a enviar el artículo para su publicación. A menudo encuentran errores, y luego terminan teniendo que cambiar sus cifras y las estadísticas en sus secciones de Resultados. Es realmente ineficiente. Tiene mucho más sentido escribir sus guiones con la intención de compartirlos, incluida una lógica clara y muchos comentarios, desde el principio. Esto requiere mucha disciplina, porque cuando estás escribiendo el guión solo quieres hacer el trabajo. Pero este enfoque te ahorrará mucho tiempo y agonía a la larga.

This page titled 11.10: Ejercicio- Bucles is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by Steven J Luck directly on the LibreTexts platform.