Cómo enseñar a superar dificultades y al mismo tiempo escribir ciclos

A pesar de que nos centraremos en uno de los temas básicos, este artículo está escrito para profesionales experimentados. El objetivo es mostrar qué conceptos erróneos tienen los principiantes en la programación. Para los desarrolladores en ejercicio, estos problemas han sido resueltos, olvidados o no notados en absoluto. Un artículo puede ser útil si de repente tiene que ayudar a alguien con este tema. El artículo establece paralelos con el material de varios libros sobre programación de Shildt, Straustrup, Okulov.

Se eligió el tema de los ciclos porque mucha gente lo abandona cuando domina la programación.

Esta técnica está diseñada para estudiantes débiles. Como regla, aquellos que son fuertes en este tema no se atascan y no necesitan inventar técnicas especiales para ellos. El objetivo secundario del artículo es transferir esta metodología de la clase "funciona para todos los estudiantes, pero solo para un maestro" a la clase "funciona para todos los estudiantes, todos los maestros". No pretendo ser absolutamente original. Si ya está aplicando una técnica similar para enseñar este tema, escriba cómo difiere su versión. Si decide postularse, cuéntenos por resultados cómo fue todo. Si se describe una técnica similar en un libro, escriba el nombre.


Practiqué esta técnica durante 4 años, estudiando individualmente con estudiantes de diferentes niveles de formación. Solo unos cincuenta estudiantes y dos mil horas de clases. Inicialmente, los estudiantes se quedaron atrapados y se fueron para siempre sobre este tema. Después de cada alumno, se ajustó la metodología y los materiales. El año pasado, los estudiantes ya no están estancados en este tema, así que decidí compartir mis mejores prácticas.

¿Por qué tantas letras? ¡Los ciclos son elementales!


Como escribí anteriormente, para los desarrolladores en ejercicio y para los estudiantes fuertes, la complejidad del concepto de ciclos puede subestimarse. Por ejemplo, puede organizar una larga conferencia, ver cabezas asintiendo y ojos inteligentes. Pero cuando intentas resolver un problema, comienzan un estupor y problemas inexplicables. Después de la conferencia, los estudiantes probablemente desarrollaron solo una comprensión parcial. La situación se ve agravada por el hecho de que los propios estudiantes no pueden expresar cuál es exactamente su error.
Una vez me di cuenta de que los estudiantes perciben mis ejemplos como jeroglíficos. Es decir, como fragmentos de texto indivisibles en los que necesita agregar algún tipo de letra "mágica" y funcionará.
A veces noté que los estudiantes piensan que para resolver un problema específico, se necesita otra construcción, que todavía no he dicho. Aunque la solución requirió solo una pequeña modificación del ejemplo.

Por lo tanto, se me ocurrió la idea de que el enfoque principal no debería estar en la sintaxis de las expresiones, sino en la idea de refactorizar el código repetitivo utilizando bucles. Tan pronto como los estudiantes dominen esta idea, cualquier sintaxis se endurece con un poco de ejercicio.

A quién y por qué enseño


Como no hay exámenes de ingreso, en el aula puede haber estudiantes fuertes y muy débiles. Se pueden encontrar más detalles sobre mis alumnos en el artículo Retrato de alumnos de cursos nocturnos.
Traté de asegurarme de que todos los que lo quieren dominen la programación.
Mis clases se imparten individualmente y el estudiante paga su dinero por cada una. Parece que los estudiantes optimizarán los costos y requerirán un mínimo. Sin embargo, las personas no asisten a clases de tiempo completo con un maestro en vivo por el conocimiento en sí, sino por la confianza que han aprendido, por la sensación de progreso y por la aprobación de un experto (maestro). Si los estudiantes no sienten progreso en sus estudios, se irán. En general, las clases se pueden diseñar para que los estudiantes sientan progreso en aumentar el número de diseños familiares. Es decir, primero estudiamos en detalle, luego estudiamos para, luego hacemos mientras y ahora tenemos un curso de mil y una noches, en el que estudiamos ciclos solo durante dos meses, y al final tenemos un estudiante que escribió una biblioteca estándar dictada. Sin embargo, para resolver problemas prácticos, se necesita no solo el conocimiento del material, sino también independencia en su aplicación y en la búsqueda de nueva información. Por lo tanto, para los cursos de tiempo completo, creo que el principio es correcto: enseñar un mínimo y alentar el estudio independiente de matices y temas relacionados. En el tema de los bucles, considero que la construcción while es mínima. En él puedes entender el principio. Conociendo el principio, puedes dominar tanto para ti como para hacerlo.

No es suficiente describir la sintaxis para lograr el dominio del material por parte de estudiantes débiles. Necesita dar tareas más simples pero diversas y ejemplos de pintura con más detalle. En última instancia, la velocidad de desarrollo está limitada por la capacidad del estudiante para transformar expresiones y buscar patrones. Para los estudiantes inteligentes, la mayoría de las tareas serán aburridas. Al practicar con ellos, no puedes insistir en resolver el 100% de las tareas. Mi material se puede ver en mi github . Es cierto, el repositorio es más como un grimorio de un brujo: nadie excepto yo entenderá dónde está , y si no pasa el cheque, puede volverse loco.

Practica práctica orientada


La teoría se explica por el ejemplo de resolver un problema. En las clases sobre los conceptos básicos de la programación, donde se estudian las ramificaciones y los bucles, simplemente no podrá dar una conferencia útil sobre un tema durante una hora completa. 15-20 minutos son suficientes para explicar el concepto. Las principales dificultades aparecen al realizar tareas prácticas.
Los maestros novatos pueden volcar declaraciones, ramas, bucles y matrices en una sola conferencia. Estos son solo los estudiantes con los que se encontrarán con el problema de asimilación de esta información.
No solo debe contar el material, sino también asegurarse de que el público lo haya entendido.

El hecho de dominar el tema está determinado por la forma en que el estudiante maneja el trabajo independiente.
Si un estudiante logró resolver un problema sobre un tema sin la ayuda de un maestro, entonces el tema se ha aprendido. Para proporcionar la autoverificación, cada tarea se describe en una tabla con scripts de prueba. Las tareas tienen un orden pronunciado. No se recomienda omitir tareas. Si la tarea actual es demasiado complicada, entonces pasar a la siguiente es inútil. Ella es aún más dura. Para que el alumno pueda dominar la tarea difícil actual, se le explican varios trucos sobre el ejemplo de la primera tarea. En realidad, todo el contenido del tema se reduce a métodos para superar las dificultades. Los ciclos tienen más probabilidades de ser un efecto secundario.

La primera tarea es siempre un ejemplo. El segundo difiere ligeramente y se lleva a cabo "independientemente" inmediatamente después del primero bajo la supervisión de un maestro. Todas las tareas posteriores tienen como objetivo llamar la atención sobre varias pequeñas cosas que pueden causar confusión.

La explicación del ejemplo es un diálogo en el que el alumno necesita recuperar la propagación y la validación cruzada para asegurarse de que asimila una parte del material.

Seré banal y declararé que el primer ejemplo sobre el tema es muy importante. Si hay material para un trabajo independiente extenso, las omisiones del primer ejemplo pueden corregirse. Si, aparte del ejemplo, no hay nada más, entonces el estudiante probablemente no dominará el tema.

¿Mientras o para?


Uno de los temas controvertidos es la elección del constructo para un ejemplo: while o for. Una vez, un amigo mío, un desarrollador en ejercicio sin experiencia docente, me convenció durante una hora de que el ciclo for era el más fácil de entender. Los argumentos se redujeron a "todo está claro en él y se presenta en lugares". Sin embargo, la causa raíz de las dificultades de los verdaderos principiantes está en la idea misma del ciclo, y no en su escritura. Si una persona no comprende esta idea, tendrá dificultades con la sintaxis. Tan pronto como se realiza la idea, los problemas de diseño de código desaparecen por sí mismos.

En mis materiales, el tema de los ciclos sigue el tema de la ramificación. La similitud externa de if y while nos permite dibujar una analogía directa: "cuando la condición en el encabezado es verdadera, entonces el cuerpo está satisfecho". La peculiaridad del ciclo es que el cuerpo se realiza muchas veces.

Mi segundo argumento es que mientras requiere menos decoración que para. Menos estilo: menos errores estúpidos con comas y corchetes faltantes. Los principiantes aún no son tan atentos y meticulosos que evitan automáticamente los errores de sintaxis.
El tercer argumento es que muchos buenos, mientras que los libros se explican primero.

Si un estudiante logra transformar fácilmente expresiones, entonces puede hablar de pasada. El alumno elegirá lo que más le guste. Si las transformaciones causan dificultades, es mejor no dispersar la atención. Deje que el alumno resuelva todo con la ayuda de while. Una vez que haya dominado el tema de los bucles, puede reescribir soluciones para resolver la conversión de while a for.
Los ciclos posteriores al acondicionamiento son un animal raro. No paso tiempo en eso en absoluto. Si un estudiante ha dominado las ideas de patrones reveladores y expresiones transformadoras, podrá resolverlo sin mi ayuda.

Al mostrar el primer ejemplo a estudiantes fuertes, llamo la atención sobre el hecho de que en el primer ejemplo es importante arreglar no solo la solución, sino también toda la cadena de acciones que condujeron al resultado. Los estudiantes perezosos pueden descuidar los escritos y transferir solo el algoritmo finito a sí mismos. Deben estar convencidos de que algún día se encontrarán con una tarea difícil. Para resolverlo, deberá seguir los pasos como en este ejemplo. Por eso es importante arreglar todas las etapas. En las siguientes tareas, será posible dejar solo la solución final.

La idea principal de la automatización es que le indiquemos a la computadora que realice un trabajo de rutina por persona. Uno de los trucos básicos es escribir ciclos. Se utiliza cuando varias acciones repetitivas idénticas se escriben en un programa en una fila.

Explícito es mejor que implícito


Puede parecer una buena idea en la primera tarea en ciclos mostrar una frase idéntica varias veces. Por ejemplo:
¡Hurra, funciona!
¡Hurra, funciona!
¡Hurra, funciona!
¡Hurra, funciona!
¡Hurra, funciona!
¡Hurra, funciona!
¡Hurra, funciona!
¡Hurra, funciona!

Esta opción es mala porque la salida no muestra el valor del contador. Este es un problema para principiantes. No lo subestimes. Al principio, esta tarea fue la primera, y la tarea de generar una serie de números en orden ascendente fue la segunda. Tuve que introducir términos adicionales "ciclo N veces" y "ciclo de A a B", que son esencialmente lo mismo. Para no producir entidades innecesarias, decidí mostrar solo un ejemplo con una serie de números. Pocos logran aprender cómo mantener un contador en su cabeza y simular el comportamiento de un programa en su cabeza sin preparación. Por primera vez, algunos estudiantes se enfrentan con modelos "en la mente" sobre el tema de los ciclos.
Después de un poco de práctica, le doy la tarea de repetir el mismo texto a una solución independiente. Si primero le das un contador visible, y luego invisible, entonces los estudiantes tienen menos problemas. A veces, las indicaciones "no escriba el contador en la pantalla" son suficientes.

¿Cómo lo explican los demás?


En la mayoría de los materiales educativos en Internet, la sintaxis de bucle se da como parte de una "conferencia". Por ejemplo, en developer.mozilla.org (actualmente), se describen varias construcciones más junto con el ciclo while. En este caso, solo las construcciones mismas se dan en forma de plantillas. El resultado de su lanzamiento se describe en palabras, pero falta la ilustración. En mi opinión, tal presentación del tema multiplica la utilidad de dichos materiales por cero. El alumno puede reescribir el código y ejecutarlo él mismo, pero aún se necesita el punto de referencia para la comparación. ¿Cómo entender que el ejemplo se reescribe correctamente si no hay nada con lo que comparar el resultado?
Cuando solo se da una plantilla, sin un ejemplo, se vuelve aún más difícil para un estudiante. ¿Cómo entender que los fragmentos de código se colocan en la plantilla correctamente? Puedes intentar escribir de alguna manera y luego correr. Pero si no hay un estándar para comparar el resultado, el lanzamiento tampoco ayudará.

En el curso de C ++ sobre intuición, la sintaxis de bucle está enterrada en la tercera página de la Lección 4 sobre el tema de "operadores". Al explicar la sintaxis de los bucles, se hace especial hincapié en el término "operador". El término se presenta como un conjunto de hechos como "símbolo; esto es un operador "," {} este es un operador compuesto "," el cuerpo del bucle debe ser un operador ". No me gusta este enfoque porque parece ocultar relaciones importantes en un solo término. El análisis del código fuente del programa en términos a tal nivel es necesario para que los desarrolladores del compilador implementen la especificación del lenguaje, pero no para los estudiantes en la primera aproximación. Los principiantes en programación rara vez tienen la meticulosidad de estar tan atentos a los términos. Una persona rara recuerda y entiende nuevas palabras la primera vez. Prácticamente nadie puede aplicar correctamente el término que acaba de aprender. Por lo tanto, los estudiantes tienen un montón de errores como "escribió while (a <7); {, pero el programa no funciona".
En mi opinión, al principio es mejor dar la sintaxis de la construcción inmediatamente entre paréntesis. La opción sin paréntesis solo se explica si el alumno tiene una pregunta específica "por qué funciona sin paréntesis".

En el libro de Okulov "Fundamentos de la programación" en 2012, el conocimiento de los ciclos comienza con la plantilla for, luego se dan recomendaciones para su uso, y luego sigue la sección experimental de la lección. Entiendo que el libro fue escrito para esa minoría de estudiantes muy capaces que rara vez vienen a mis clases.

En los libros populares, el resultado de los fragmentos de código siempre se escribe. Por ejemplo, la edición 2015 de Schildt "Java 8. Complete Guide". Primero, se proporciona una plantilla, luego un programa de ejemplo e inmediatamente después de que sea el resultado de la ejecución.
Como ejemplo, considere un ciclo while en el que el reverso
la cuenta regresiva, comenzando en 10, y se emiten exactamente 10 líneas de "medidas":
//    while class While { public static void main(String args []) { int n = 10; while (n > 0) { System.out.println(" " + n); n--; } } } 

Después de comenzar este programa muestra diez "medidas" de la siguiente manera:
10
9
8
7
6
5
4
3
2
1

Un enfoque que describe la plantilla, el programa de muestra y el resultado de este programa también se utiliza en el libro "Javascript para niños" y en el curso js en w3schools.com. El formato de página web incluso le permite hacer que este ejemplo sea interactivo.

En el libro de 2016 de Straustrup, Principios y prácticas con C ++, el autor fue aún más lejos. El primer paso explica cuál debería ser el resultado y, después de eso, muestra el texto del programa. Además, como ejemplo, toman no solo un programa aleatorio, sino que dan una excursión a la historia. Ayuda a llamar la atención: "Mira, esto no es solo un texto inútil. Ves algo significativo.
Como ejemplo de iteración, considere el primer programa ejecutado en una máquina con un programa almacenado (EDSAC). Fue escrito por David Wheeler en el laboratorio de computación de la Universidad de Cambridge, Inglaterra, el 6 de mayo de 1949. Este programa calcula e imprime una lista simple de cuadrados.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

Aquí, cada línea contiene un número seguido de una pestaña ('\ t') y el cuadrado de ese número. La versión C ++ de este programa se ve así:
 //      0-99 int main() { int i = 0; //    while(i < 100){ cout << i << '\t' << square(i) << '\n'; ++i; } } 

Curiosamente, la plantilla de sintaxis no se describe en este libro. Stroustrup en el manual del instructor ( traducción ) enfatiza que respeta la inteligencia de sus alumnos. Quizás la capacidad de identificar el patrón en varios ejemplos se considere una manifestación de tal inteligencia.

Como me explico


El enfoque de Straustrup: una descripción del resultado, luego una solución al problema, y ​​luego un análisis independiente por parte del estudiante, parece el más reflexivo. Por lo tanto, decidí tomarlo como base, pero contarlo con un ejemplo menos histórico: la tarea de derivar una "tabla de contenido". Forma un ancla reconocible, de modo que más tarde dice "recuerda la tarea de la tabla de contenido" y para que los estudiantes lo recuerden. En mi ejemplo, traté de advertir a dos más de los conceptos erróneos más comunes. A continuación escribiré más sobre ellos.
En esta tarea, nos familiarizamos con los métodos para resolver problemas complejos. La decisión inicial debe hacerse de manera primitiva y simple. Bueno, entonces puedes pensar en cómo mejorar esta solución.

1
2
3
4
5
6
7

Según mis observaciones, el enfoque "plantilla-ejemplo-resultado" en diferentes combinaciones todavía lleva a los estudiantes a percibir el ciclo como un jeroglífico. Esto se manifestó en el hecho de que no entendían por qué deberían escribir una condición, cómo elegir entre i ++ e i-- y otras cosas aparentemente obvias. Para evitar estos conceptos erróneos, el enfoque de la historia sobre los ciclos debe enfatizar el significado de la repetición de las mismas acciones y solo entonces: diseñarlas usando el diseño. Por lo tanto, antes de dar la sintaxis del bucle, debe resolver el problema "frente". Una solución primitiva al problema de la tabla de contenido se ve así:
 Console.WriteLine(""); Console.WriteLine(" 1"); Console.WriteLine(" 2"); Console.WriteLine(" 3"); Console.WriteLine(" 4"); Console.WriteLine(" 5"); Console.WriteLine(" 6"); Console.WriteLine(" 7"); Console.WriteLine(""); 

¿Cómo se puede mejorar?
Reemplazar acciones repetitivas con un bucle.
¿Qué acciones se repiten en una fila sin cambios?
No hay ninguno en este fragmento. Sin embargo, el comando para generar la palabra "Capítulo" con el número es muy similar entre sí.
Por lo tanto, el siguiente paso es la búsqueda de la diferencia entre los fragmentos. Es solo en esta tarea que todo es obvio, luego no se repetirán comandos individuales, sino bloques de código de 5 líneas o más. Tendrá que buscar no solo en la lista de comandos, sino también en las construcciones de ramas o bucles.
En el ejemplo, la diferencia entre los equipos en el número después de la palabra "Capítulo".
Una vez que se encuentra la diferencia, debe comprender el patrón de cambio. ¿Un fragmento diferente es este número? ¿Está constantemente aumentando o disminuyendo? ¿Cómo cambia el valor de un número entre dos equipos uno al lado del otro?
En el ejemplo, el número después de la palabra "Capítulo" aumenta con el paso 1. Se encuentra la diferencia, se revela el patrón. Ahora puede reemplazar el fragmento diferente con una variable.
Dicha variable debe declararse antes del primero de los fragmentos repetidos. Tal variable generalmente se llama I o j o de alguna manera más expandida. Su valor inicial debe ser igual al primer valor que se muestra en la pantalla. En el ejemplo, el primer valor es 1.
¿Qué valor inicial se debe tomar para generar una serie de números "100, 101, 102, 103, 104, 105"?
En esta fila, el primer número es 100.
Después de cada comando de salida, debe aumentar el valor de esta variable en 1. Esta unidad es un paso de cambio.
¿Qué paso habrá en la serie de números "100, 102, 104, 106"?
En esta fila, paso 2.
Después de reemplazar el fragmento diferente con una variable, el código se verá así:
 Console.WriteLine(""); int i; i = 0; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(""); 

Después de aplicar la técnica de "expresar la ley de la variable", el código produce varios grupos de acciones idénticas que van en una fila. Ahora las acciones repetidas se pueden reemplazar con un bucle.

La secuencia para resolver el problema donde necesita usar ciclos consta de los pasos:
  1. Resuelve "frente" con muchos equipos separados
  2. Encuentra un patrón
  3. Expresar la regularidad de una variable.
  4. Diseñar como un bucle


A continuación, se introducen nuevos términos para que el alumno no se encuentre en la situación "Entiendo todo, pero no puedo decir":
- un contador es siempre una variable que se necesita para rastrear el número de pasos en un ciclo. Por lo general, un número entero que se compara con una restricción.
- paso de contador: una descripción del patrón de cambio en el contador.
- restricción: un número o una variable con la que se compara el contador, de modo que el algoritmo es finito. El valor del contador cambia para acercarse al límite.
- cuerpo del ciclo - un conjunto de comandos que se repetirán. Cuando dice "el comando está escrito dentro del ciclo", significa el cuerpo.
- iteración de bucle: una única ejecución del cuerpo del bucle.
- una condición de bucle es una expresión lógica que determina si se realizará otra iteración. (Puede haber confusión con los diseños de rama)
Debe estar preparado para el hecho de que al principio los estudiantes usarán los términos para otros fines. Esto se aplica tanto a los fuertes como a los débiles. Construir un lenguaje común es todo un arte. Ahora escribiré brevemente: debe configurar la tarea "seleccionar un fragmento de código con <term>" y usar estos términos en una conversación correctamente.
Después de la conversión con un bucle, se obtiene un fragmento:
 Console.WriteLine(""); int i = 0; while (i < 7) { Console.WriteLine(" " + i); i = i + 1; } Console.WriteLine(""); 


Idea errónea principal


Un concepto erróneo popular de los estudiantes es que ponen dentro de la estructura de bucle las acciones que deben hacerse solo una vez. Por ejemplo, así:
 ; int i = 0; while (i < 7) { Console.WriteLine("") Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(""); } 

Los estudiantes constantemente tropiezan con este problema, tanto al principio como en tareas más complejas.
Sugerencia de corona en este caso:
¿Cuántas veces necesitas repetir el comando: una o varias?

Los comandos de salida para las palabras "Introducción" y "Conclusión", así como la declaración e inicialización de la variable i, no son como otras acciones repetitivas. Se ejecutan solo una vez, lo que significa que deben escribirse fuera del cuerpo del ciclo.

Las tres etapas de la solución deben permanecer en el código, para luego referirse a ellas en caso de dificultad. Las dos primeras opciones son suficientes para comentar para que no interfieran.
Se debe prestar atención al alumno a los siguientes hechos:
- En una condición de bucle, el contador y el límite generalmente se comparan. El contador puede cambiar en el cuerpo del bucle, pero el límite no lo es. Para romper esta regla, debe formular buenas razones.
- Los comandos para mostrar las palabras "Introducción" y "Conclusión" están fuera del cuerpo del ciclo. Necesitamos ejecutarlos 1 vez. "Introducción" - antes de repetir acciones, "Conclusión" - después.
En el proceso de arreglar este tema, dominar lo siguiente, así como los procedimientos con dificultades, es útil incluso para estudiantes fuertes hacer la pregunta: “¿Pero cuántas veces se necesita realizar esta acción? ¿Uno o muchos?

Desarrollo de habilidades adicionales.


En el proceso de estudiar los ciclos, los estudiantes aún tienen la habilidad de diagnosticar y resolver problemas. Para realizar el diagnóstico, el alumno debe presentar el resultado deseado y compararlo con el resultado real. Las acciones para la corrección dependen de la diferencia entre ellas.
Dado que los estudiantes en esta etapa todavía tienen una mala idea del resultado "deseado", pueden centrarse en los datos de las pruebas. Como regla general, nadie en esta etapa todavía comprende qué puede salir mal y cómo lidiar con eso. Por lo tanto, doy una descripción de los problemas típicos y varias formas de resolverlos debajo de una entrada en un cuaderno. La elección del más adecuado de ellos es tarea del alumno.
El registro es necesario para preguntar: "¿Qué sucedió se esperaba?", "¿Cuál de estas situaciones sucedió ahora?", "¿La solución ayudó?".
  1. El número de acciones es 1 menos o más de lo esperado. Formas de resolver:
    - aumenta el valor inicial del contador en 1.
    - reemplace el operador de comparación estricto (<o>) con uno no estricto (<= o> =).
    - cambie el valor de la restricción a 1.
  2. Las acciones en el bucle se realizan sin parar, sin fin. Formas de resolver:
    - agregue un comando de cambio de contador si está ausente.
    - Corrija el comando de cambio de contador para que su valor se acerque al límite.
    - elimine el comando para cambiar la restricción, si está en el cuerpo del ciclo.
  3. El número de acciones en el bucle es más de 1 menos o más de lo esperado. La acción en el bucle nunca se ha ejecutado. Primero debe averiguar los valores reales de las variables justo antes del inicio del ciclo. Formas de resolver:
    - cambiar el valor inicial de la restricción
    - cambiar el valor inicial del contador

Por lo general, el problema 3 está relacionado con el uso de la variable incorrecta o sin poner a cero el contador.

Después de esta explicación, el estudiante aún puede tener varios conceptos erróneos sobre el funcionamiento de los ciclos.
Para disipar los más comunes, doy tareas:
  1. En el cual la restricción, el usuario ingresa el valor inicial del contador o el paso del contador.
  2. En el que el valor del contador debe usarse en alguna expresión aritmética. Es aconsejable con el contador en la expresión radical o en el denominador para que la diferencia no sea lineal.
  3. En el que el valor del contador no se muestra durante el ciclo. Por ejemplo, la salida del número requerido de fragmentos idénticos de texto o dibujar una figura con gráficos de tortuga.
  4. En el que debe realizar primero algunas acciones repetitivas y luego otras.
  5. En el que debe realizar otras acciones antes y después de repetir

Para cada tarea, debe proporcionar datos de prueba y el resultado esperado.

Para comprender qué tan rápido puede moverse, debe leer las condiciones de estas tareas y preguntar: "¿en qué se diferencian del ejemplo?", "¿Qué se necesita cambiar en el ejemplo para resolverlas?". Si el alumno responde de manera significativa, entonces déjelo decidir al menos uno en la lección y el resto, en casa por su cuenta. Si la solución es exitosa, puede comenzar a explicar las condiciones dentro de los bucles.
Si tiene una solución independiente a las dificultades, entonces necesita resolver todo en la lección. Para resolver el problema no se parece a dibujar un búho, le recomiendo que primero resuelva el problema no universalmente. Es decir, para que la solución pase la primera prueba y no use la construcción de bucle. Bueno, entonces aplique las transformaciones para lograr la universalidad de la solución.

Bucles y ramas


En mi opinión, es útil dar el tema "bucles dentro de las ramas" por separado. Para que luego pueda ver la diferencia entre una verificación de condición múltiple y una sola.
Las tareas para arreglar serán sobre la salida de números de A a B, que son ingresados ​​por el usuario:
- Siempre ascendente.
- ascendente o descendente según los valores de A y B.

El tema de "bifurcación dentro de los ciclos" debe pasarse solo después de que el estudiante haya dominado los trucos: "reemplazar patrones con una variable" y "reemplazar acciones repetidas con un ciclo".
La razón principal para usar la ramificación dentro de los bucles son las anomalías en los patrones. En el medio, se rompe dependiendo de los datos de origen.
Para aquellos estudiantes que pueden buscar una solución combinando técnicas simples, es suficiente decir "la ramificación se puede escribir dentro de los bucles" y asignar la tarea "por ejemplo" completamente a una solución independiente.
Tarea por ejemplo:
El usuario ingresa el número X. Muestra en la columna los números del 0 al 9 y coloca el signo '+' frente al número que es igual a X.

Si se ingresó 0
0+
1
2
3
4 4
5 5
6 6
7 7
8
9 9

Si se ingresó 6
0 0
1
2
3
4 4
5 5
6+
7 7
8
9 9

Si se ingresó 9
0 0
1
2
3
4 4
5 5
6 6
7 7
8
9+

Si se ingresó 777
0 0
1
2
3
4 4
5 5
6 6
7 7
8
9 9

Si una breve explicación no es suficiente para escribir con un bucle, entonces necesita lograr una solución universal al mismo problema sin un bucle.
Obtendrá una de dos opciones:
Deseado
 string temp; temp = Console.ReadLine(); int x; x = int.Parse(temp); if (x==0) { Console.WriteLine(0 + "+"); } else { Console.WriteLine(0); } if (x==1) { Console.WriteLine(1 + "+"); } else { Console.WriteLine(1); } if (x==2) { Console.WriteLine(2 + "+"); } else { Console.WriteLine(2); } if (x==3) { Console.WriteLine(3 + "+"); } else { Console.WriteLine(3); } if (x==4) { Console.WriteLine(4 + "+"); } else { Console.WriteLine(4); } if (x==5) { Console.WriteLine(5 + "+"); } else { Console.WriteLine(5); } if (x==6) { Console.WriteLine(6 + "+"); } else { Console.WriteLine(6); } if (x==7) { Console.WriteLine(7 + "+"); } else { Console.WriteLine(7); } if (x==8) { Console.WriteLine(8 + "+"); } else { Console.WriteLine(8); } if (x==9) { Console.WriteLine(9 + "+"); } else { Console.WriteLine(9); } 


Posible
 string temp; temp = Console.ReadLine(); int x; x = int.Parse(temp); if (x==0) { Console.WriteLine("0+\n1\n2\n3\n4\n5\n6\n7\n8\n9"); } if (x==1) { Console.WriteLine("0\n1+\n2\n3\n4\n5\n6\n7\n8\n9"); } if (x==2) { Console.WriteLine("0\n1\n2+\n3\n4\n5\n6\n7\n8\n9"); } if (x==3) { Console.WriteLine("0\n1\n2\n3+\n4\n5\n6\n7\n8\n9"); } if (x==4) { Console.WriteLine("0\n1\n2\n3\n4+\n5\n6\n7\n8\n9"); } if (x==5) { Console.WriteLine("0\n1\n2\n3\n4\n5+\n6\n7\n8\n9"); } if (x==6) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6+\n7\n8\n9"); } if (x==7) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6\n7+\n8\n9"); } if (x==8) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6\n7\n8+\n9"); } if (x==9) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6\n7\n8\n9+"); } 


Doy un problema similar por adelantado, mientras estudio el tema de la ramificación.
Si el estudiante tiene una opción "posible", entonces debe decir que puede haber muchas soluciones al mismo problema. Sin embargo, difieren en su resistencia a los requisitos cambiantes. Haga la pregunta: "¿Cuántos lugares en el código deberán corregirse si tiene que agregar otro número?" En la versión "posible", deberá agregar otra sucursal y agregar un nuevo número en otros 10 lugares. En el "deseado", es suficiente agregar solo una rama.
Configure la tarea para reproducir la opción "deseada", luego encuentre un patrón en el código, realice una sustitución de variables y escriba un bucle.
Si tiene una idea de cómo resolver este problema sin un bucle de otra manera, escriba en los comentarios.

Bucles dentro de bucles


En este hilo, debe prestar atención al hecho de que:
- Los contadores para el bucle interno y externo deben ser variables diferentes.
- el contador del bucle interno debe reiniciarse muchas veces (es decir, en el cuerpo del bucle externo).
- en las tareas de salida de texto, no puede escribir primero una letra en varias líneas, y luego la segunda. Primero debe imprimir todas las letras de la primera línea, luego todas las letras de la segunda y así sucesivamente.

Una explicación del tema sobre los bucles dentro de los bucles se inicia mejor explicando la importancia de restablecer el contador.
Tarea por ejemplo:
El usuario ingresa dos números: R y T. Imprime dos líneas de caracteres "#". La primera línea debe contener caracteres R. La segunda línea son las piezas T. Si algún número es negativo, muestre un mensaje de error.

R = 5, T = 11
#####
############

R = 20, T = 3
######################
###

R = -1, T = 6
El valor de R debe ser no negativo

R = 6, T = -2
El valor de T debe ser no negativo

Obviamente, este problema también tiene al menos dos soluciones.
Deseado
 string temp; int R; int T; temp = Console.ReadLine(); R = int.Parse(temp); temp = Console.ReadLine(); T = int.Parse(temp); int i = 0; while (i < R) { Console.Write("#"); i = i + 1; } Console.WriteLine(); i = 0; while (i < T) { Console.Write("#"); i = i + 1; } 


Posible No. 1
 string temp; int R; int T; temp = Console.ReadLine(); R = int.Parse(temp); temp = Console.ReadLine(); T = int.Parse(temp); int i = 0; while (i < R) { Console.Write("#"); i = i + 1; } Console.WriteLine(); int j = 0; j = 0; while (j < T) { Console.Write("#"); j = j + 1; } 


La diferencia es que en la solución "posible", la segunda variable se usó para mostrar la segunda línea. Debe insistir en usar la misma variable para ambos ciclos. Se puede argumentar a favor de tal limitación, ya que una solución con un contador para dos ciclos será una ilustración del término "contador cero". Comprender este término es necesario al resolver los siguientes problemas. Como compromiso, puede guardar ambas soluciones al problema.

Un problema típico con el uso de una variable de contador único durante dos ciclos aparece de la siguiente manera:
R = 5, T = 11
#####
######

El número de caracteres en la segunda línea no coincide con el valor de T. Si se necesita ayuda con este problema, debe "meter la nariz" en la sinopsis sobre los problemas típicos con los bucles. Este es el síntoma número 3. Se diagnostica si agrega la salida del valor del contador inmediatamente antes del segundo ciclo. Corregido por reducción a cero. Pero es mejor no decirlo de inmediato. El alumno debe tratar de formular al menos una hipótesis.

Por supuesto, todavía hay tal solución. Pero nunca lo he visto entre estudiantes. En la etapa de estudio de los ciclos, la historia sobre él dispersará la atención. Puede volver a él más tarde, cuando estudie las funciones de trabajar con cadenas.
Posible número 2
 string temp; int R; int T; temp = Console.ReadLine(); R = int.Parse(temp); temp = Console.ReadLine(); T = int.Parse(temp); Console.WriteLine(new String('#', R)); Console.WriteLine(new String('#', T)); 



La siguiente tarea requerida:
Muestra los números del 0 al 9. Cada dígito debe estar en su propia línea. El número de dígitos por línea (W) se ingresa desde el teclado.

W = 1
0 0
1
2
3
4 4
5 5
6 6
7 7
8
9 9

W = 10
0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999


Si un estudiante ha dominado la técnica de reemplazar una variable, lo hará con bastante rapidez. Un posible problema será nuevamente poner a cero la variable. Si no puede hacer frente a la conversión, tiene prisa y necesita resolver problemas más simples.

Gracias por su atencion Me gusta, suscríbete al canal.

PD: si encuentra errores tipográficos o errores en el texto, hágamelo saber.Esto se puede hacer resaltando parte del texto y presionando "⌘ + Enter" en la Mac, y en los teclados clásicos "Ctrl / Enter", o mediante mensajes privados. Si estas opciones no están disponibles, escriba sobre los errores en los comentarios. Gracias

Source: https://habr.com/ru/post/456500/


All Articles