{ "cells": [ { "cell_type": "markdown", "source": [ "# Estructuras de Control" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "## Operadores\n", "\n", "Los operadores se pueden definir como símbolos que permiten realizar diferentes operaciones entre valores o datos de un programa. Con ellos se pueden conectar dos más expresiones, cuyo valor final para la expresión compuesta depende del valor de las expresiones que fueron conectadas.\n", "\n", "Existen diferentes tipos de operadores, entre ellos: aritméticos, asignación, relacionales, lógicos, etc. De ellos se hace especial mención de los operadores lógicos y relacionales, ya que son usados para la creación de test o comprobaciones con los cuales es posible controlar el **flujo de un programa** junto con las denominadas **estructuras de control**.\n", "\n", "Los operadores lógicos y relacionales permiten evaluar y crear expresiones booleanas. Las expresiones de este tipo son aquellas que pueden tener la condición de `true` o `false`. \n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "### Operadores relacionales\n", "Son operadores que nos permiten determinar un valor de verdad para una situación concreta, en el cual se necesita comparar determinados valores. Las operaciones de comparación estándar, en Julia, se definen para todos los tipos numéricos primitivos y estos son:\n", "\n", "#### Operador de igualdad:\n", "El operador de igualdad es denotado por `==`\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "(5 == 4, 5 == 5.0, 5 == 5)\n", "", "" ], "metadata": {}, "execution_count": 93 }, { "cell_type": "markdown", "source": [ "\n", "#### Operador de igualdad estricto:\n", "El operador de igualdad estricta se denotado por `===` o bien, `≡`\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "(5 === 5.0, 5.0 ≡ 5.0)\n", "", "" ], "metadata": {}, "execution_count": 94 }, { "cell_type": "markdown", "source": [ "El símbolo ≡ se introduce escribiendo `\\equiv+`.\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "#### Operador de desigualdad o no-igualdad:\n", "El operador de desigualdad o no-igualdad se denota por `!=` o `≠`.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "(1 != 1, 1 ≠ 3)\n", "", "" ], "metadata": {}, "execution_count": 95 }, { "cell_type": "markdown", "source": [ "El símbolo ≠ se introduce escribiendo `\\ne+`.\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "#### Operador de desigualdad estricto:\n", "El operador de desiagualdad o no-igualdad estricta es denotado por `!==` o `≢`.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "(5 !== 5.0, 5 ≢ 5)\n", "", "" ], "metadata": {}, "execution_count": 96 }, { "cell_type": "markdown", "source": [ "El símbolo ≢ se introduce escribiendo `\\nequiv+`.\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "#### Operador de comparación mayor y menor que:\n", "Tenemos múltiples operadores de comparación de órden, o comúnmente conocidos por desigualdades (en dicho caso, se llama a las comparaciones anteriores no-igualdades). Estas son:\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "(-1 < 1, -1 <= -2, -1 ≤ -1, 1.0 > 3, 1 >= 1.0, -1.5 ≥ 1.0)\n", "", "" ], "metadata": {}, "execution_count": 97 }, { "cell_type": "markdown", "source": [ "El símbolo ≥ se introduce escribiendo `\\ge+` y el símbolo ≤ se introduce mediante `\\le+`\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "### Operadores lógicos\n", "Son operadores que trabajan sobre valores del tipo booleano (`true`, `false`) y componen expresiones booleanas más complejas, en su mayoría a partir de varias expresiones que involucran operadores relacionales. \n", "\n", "Los lenguajes de programación incorporan 3 operadores: AND y OR, los cuales son operadores binarios; NOT, que es un operador unario.\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "#### Operador AND\n", "\n", "Este operador retorna el valor booleano `true` solamente si los dos operandos son verdaderos (`true`). En Julia el símbolo usado para el operador es `&&`.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "true && true\n", "", "" ], "metadata": {}, "execution_count": 98 }, { "outputs": [], "cell_type": "code", "source": [ "true && false\n", "", "" ], "metadata": {}, "execution_count": 99 }, { "outputs": [], "cell_type": "code", "source": [ "false && true\n", "", "" ], "metadata": {}, "execution_count": 100 }, { "outputs": [], "cell_type": "code", "source": [ "false && false\n", "", "" ], "metadata": {}, "execution_count": 101 }, { "cell_type": "markdown", "source": [ "\n", "#### Operador OR\n", "Este operador retorna el valor booleano `false` solamente si los dos operandos son falsos (`false`). En Julia el símbolo usado para el operador es `||`.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "false || false\n", "", "" ], "metadata": {}, "execution_count": 102 }, { "outputs": [], "cell_type": "code", "source": [ "false || true\n", "", "" ], "metadata": {}, "execution_count": 103 }, { "outputs": [], "cell_type": "code", "source": [ "true || false\n", "", "" ], "metadata": {}, "execution_count": 104 }, { "outputs": [], "cell_type": "code", "source": [ "true || true\n", "", "" ], "metadata": {}, "execution_count": 105 }, { "cell_type": "markdown", "source": [ "\n", "#### Operador de cortocircuito\n", "\n", "Los operadores lógicos en Julia se evaluan mediante 'Short-Circuit Evaluation', esto significa que se siempre se trata de hacer el menor número de evaluaciones.\n", "+ Para la expresión `a && b`, la subexpresión `b` se evalúa sólo si `a` es `true`, ya que la expresión será `false` si `a` lo es y ello independiente del valor de `b`.\n", "+ Para la expresión `a || b`, la subexpresión `b` se evalúa sólo si `a` es `false`, ya que la expresión será `true` si `a` lo es y ello independiente del valor de `b.\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "**NOTA:** Los operadores `&&` y `||` no deben ser confundidos con los operadores `&` y `|`, estos últimos son operadores denominados bitwise (bit a bit).\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "####### Operador NOT\n", "Este operador retorna el valor booleano contrario sobre el cual opera. En Julia el símbolo usado para el operador es `!`.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "!false\n", "", "" ], "metadata": {}, "execution_count": 106 }, { "outputs": [], "cell_type": "code", "source": [ "!true\n", "", "" ], "metadata": {}, "execution_count": 107 }, { "cell_type": "markdown", "source": [ "\n", "#### Precedencia de los operadores\n", "Los operadores lógicos pueden escribirse de la siguiente forma:\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ " 1-5 > 0 && 2+2 == 4 || 10-4 == 2*3 && true\n", "", "" ], "metadata": {}, "execution_count": 108 }, { "cell_type": "markdown", "source": [ "\n", "La expresión anterior es ambigua porque no se conoce cómo se ejecutan los operadores. Para aclarar la forma en que Julia ejecuta la sentencia, se debe tomar en cuenta la precedencia de los operadores. \n", "\n", "En primer lugar los operadores lógicos tienen mayor precedencia, por lo que la expresión de ejemplo se reduce a:\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "false && true || true && true\n", "", "" ], "metadata": {}, "execution_count": 109 }, { "cell_type": "markdown", "source": [ "\n", "Finalmente, la última expresión se evalúa de izquierda a derecha. Aunque es útil saber la manera en que Julia ejecuta los operadores lógicos, a menudo se prefiere utilizar los paréntesis para eliminar las ambiguedades, permite que exista más legibilidad en el código.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ " ((1-5 > 0 && 2+2 == 4)|| 10-4 == 2*3) && true\n", "", "" ], "metadata": {}, "execution_count": 110 }, { "outputs": [], "cell_type": "code", "source": [ " 1-5 > 0 && (2+2 == 4 || 10-4 == 2*3) && true\n", "", "" ], "metadata": {}, "execution_count": 111 }, { "cell_type": "markdown", "source": [ "\n", "#### Otros operadores\n", "Los lenguajes de programación implementan otros tipos de operadores, los mencionados a continuación son importantes para el uso de estructuras de control.\n", "\n", "##### Operadores de pertenencia\n", "Son usados para comprobar si un elemento se encuentra en un determinado conjunto de datos, los cuales pueden ser del tipo: array, matrices, diccionarios o conjuntos.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "1 in [0,2,3,5]\n", "", "" ], "metadata": {}, "execution_count": 112 }, { "outputs": [], "cell_type": "code", "source": [ "1 ∈ [0,1,2,3,5]\n", "", "" ], "metadata": {}, "execution_count": 113 }, { "outputs": [], "cell_type": "code", "source": [ "6.0 ∉ [0,1,2,3,5]\n", "", "" ], "metadata": {}, "execution_count": 114 }, { "cell_type": "markdown", "source": [ "Los símbolos anteriores se introducen de la siguiente manera: ∈ mediante `\\in+`,∉ mediante `\\notin+`\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "**NOTA:** Una fuente de consulta adicional sobre los diferentes tipos operadores y funciones especiales en Julia, puede encontrarlo en el [manual de Julia.](https://docs.julialang.org/en/v1/manual/mathematical-operations/##Mathematical-Operations-and-Elementary-Functions)\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "## Estructuras de Control\n", "\n", "En general un programa está definido por un algoritmo, que constituye una guía que lista los pasos a seguir para la resolución de un problema. Es por ello que todo lenguaje de programación de alto nivel posee definida ciertas estructuras que proveen una forma útil para organizar el algoritmo y permiten manipular el flujo de un programa, esto es, crear diferentes caminos para la ejecución de tareas o sentencias que definen el programa.\n", "\n", "Las estructuras de control, en lenguajes de programación, a menudo están referidos a sentencias que permiten: la elección de ejecución de código mediante condiciones o decisiones y repetición en la ejecución de bloques de código mediante bucles. En la construcción de tales estructuras se utilizan los operadores anteriormente mencionados.\n", "\n", "### Estructura secuencial\n", "Por defecto las instrucciones de un programa se ejecutan de manera secuencial, es decir, en el orden en el cual están descritas; esta forma de ejecución se conoce como estructura secuencial. \n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "begin\n", "\tx = 1\n", "\ty = 2\n", "\tx + y;\n", "end\n", "", "" ], "metadata": {}, "execution_count": 115 }, { "cell_type": "markdown", "source": [ "\n", "Los keywords `begin` y `end` conforman delimitadores para un bloque de código, considerandolo como una expresión. Incluso, el bloque de código puede ser asignado a una variable. Su principal uso consiste en evaluar varias expresiones encadenadas, retornando el valor de la última subexpresión.\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "### Estructura de selección\n", "Esta estructura permite decidir qué bloque debe ejecutarse mediante la evaluación de una condición o expresión booleana. Julia implementa diferentes formatos: \n", "- if\n", "- if-elseif\n", "- Operador ternario\n", "\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "#### Instrucción if\n", "La instrucción `if` permite comprobar el cumplimiento de una condición, en dicho caso se ejecuta un determinado bloque de código, si es lo contrario es posible ejecutar un grupo diferente de líneas de código.\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "La función `testtriangle` respresenta un test de comprobación para saber si dada una terna de números, estos pueden representar las longitudes de los lados de un triángulo. \n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "function testtriangle(a,b,c)\n", "\tif a+b>c && a+c>b && b+c>a ##Condición\n", "\t\treturn \"Las longitudes dadas representan los lados de un triángulo\"\n", "\telse ##Bloque de código alternativo en caso de no cumplirse la condicíon\n", "\t\treturn \"Las longitudes dadas no representan los lados de un triángulo\"\n", "\tend\n", "end\n", "", "" ], "metadata": {}, "execution_count": 116 }, { "outputs": [], "cell_type": "code", "source": [ "testtriangle(1,1,5)\n", "", "" ], "metadata": {}, "execution_count": 117 }, { "cell_type": "markdown", "source": [ "\n", "En el dessarrollo de la función se implementa la estructura de control `if`, donde si en efecto se cumple el criterio que en un triángulo la longitud de cada lado debe ser menor que la suma de los otros dos lados, se imprime la oración 'Las longitudes dadas representan los lados de un triángulo', en caso contrario se imprime 'Las longitudes dadas no representan los lados de un triángulo'.\n", "\n", "El bloque de código alternativo, `else`, es opcional, por ello puede prescindirse de dicho bloque si en el problema no se considera necesario.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "function testtriangle2(a,b,c)\n", "\tif a+b>c && a+c>b && b+c>a\n", "\t\treturn \"Las longitudes dadas representan los lados de un triángulo\"\n", "\tend\n", "end\n", "", "" ], "metadata": {}, "execution_count": 118 }, { "outputs": [], "cell_type": "code", "source": [ "testtriangle2(5,5,5)\n", "", "" ], "metadata": {}, "execution_count": 119 }, { "cell_type": "markdown", "source": [ "\n", "#### Instrucción if-elseif\n", "Esta instrucción permite implementar instrucciones `if` encadenadas, sucediendo lo anterior en caso que se necesite realizar más de una comprobación.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "function whichtriangle(a,b,c)\n", "\tif a==b && b==c\n", "\t\treturn \"El triángulo es rectángulo\"\n", "\telseif a==b || b==c || a==c\n", "\t\treturn \"El triángulo es isóceles\"\n", "\telse\n", "\t\treturn \"El triángulo es escaleno\"\n", "\tend\n", "end\n", "", "" ], "metadata": {}, "execution_count": 120 }, { "outputs": [], "cell_type": "code", "source": [ "whichtriangle(5,5,5)\n", "", "" ], "metadata": {}, "execution_count": 121 }, { "outputs": [], "cell_type": "code", "source": [ "whichtriangle(4,5,5)\n", "", "" ], "metadata": {}, "execution_count": 122 }, { "cell_type": "markdown", "source": [ "\n", "#### Operador ternario\n", "En otros lenguajes este operador también es llamado operador elvis. Permite tener una versión simplificada del operador `if`, el cual puede ser escrito en una sola línea de código. \n", "\n", "Se suele utilizar cuando se requiere una elección condicional entre valores de expresión única, en contraposición a la ejecución condicional de bloques de código más largos. \n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "mayor = x>y ? x : y ##las variables \"x\" y \"y\" fueron definidas previamente.\n", "", "" ], "metadata": {}, "execution_count": 123 }, { "cell_type": "markdown", "source": [ "\n", "Al igual que las instrucción `if`, el operador ternario puede encadenarse.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "begin\n", "\ttestcomparación(x,y) = x>y ? \"x es mayor a y\" :\n", "\t\t\t\t\t\t x \"x tiene el valor de 1\"\n", "\t\t2 \t => \"x tiene el valor de 2\"\n", "\t\t3||4 => \"tres o cuatro\"\n", "\t\t3:10 => \"x es el rango 3:10\"\n", "\t\t_ => \"Caso default\"\n", "\tend\n", "end\n", "", "" ], "metadata": {}, "execution_count": 126 }, { "outputs": [], "cell_type": "code", "source": [ "switchselect(3)\n", "", "" ], "metadata": {}, "execution_count": 127 }, { "cell_type": "markdown", "source": [ "\n", "Las posibilidades con el paquete mencionados son varias, este guía la macro bajo la política de primera coinicidencia y se pueden establecer comparaciones entre distintos tipos de datos, además, coincidencia profunda con matrices. Puede encontrar mayor información en la [documentación del paquete Match.jl](https://kmsquire.github.io/Match.jl/latest/)\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "En determinadas ocasiones esta instrucción suele ser más eficiente que el encadenamiento de instrucciones `if`. Lo anterior debido que, cuando se tienen múltiples casos los `if` encadenados son evaluados hasta que se encuentra la condición que se cumple y en el peor de los casos se pueden evaluar todas las condiciones sin encontrar una condición que se cumple, ello hace que se tome un tiempo considerable de cálculo. Mientras que en la instrucción `switch`, la ejecución de un bloque de código está atada al valor de una expresión, por ello la ejecución o no del bloque es más directa que las los `if` encadenados.\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "### Estructura de repetición\n", "Esta estructura permite repetir un código las ocasiones que fueren necesarios. Julia implementa dos instrucciones para la evaluación repetida de expresiones: el bucle `while` y el bucle `for`.\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "#### Instrucción while\n", "Con esta instrucción se especifica que una serie de tareas o líneas de código se ejecutan de forma repetida mientras una condición sea verdadera. \n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "begin\n", "\ti = 0\n", "\te = 0\n", "\twhile i < 20 ##Condición\n", "\t\tt = 1/factorial(i) ##Cuerpo de la instrucción while\n", "\t\te += t\n", "\t\ti+= 1\n", "\tend\n", "end\n", "", "" ], "metadata": {}, "execution_count": 128 }, { "cell_type": "markdown", "source": [ "\n", "La rutina anterior calcula el valor aproximado del número e, evaluando una serie hasta el vigésimo término. Se puede observar que las sentencias: `e += 1/factorial(i)` y `i+= 1` se repiten, hasta que la condición (i < 20) deja de cumplirse.\n", "\n", "El símbolo `+=` es un operador de actualización, la línea de código `i+=1` es equivalente a `i=i+1`. Existen diversos operadores de asignación similares, los cuales pueden ser consultados en la sección [Updating operators](https://docs.julialang.org/en/v1/manual/mathematical-operations/##Updating-operators) del manual de Julia.\n", "\n", "Cuando se utiliza el bucle `while` se debe tener el cuidado de asegurar que, en algún punto después de un número de repeticiones, la condición debe ser falso; de no hacerlo se tendrá un número infinito de repeticiones y por tanto el conocido *bucle infinito*, lo que constituye un error de programación.\n", "\n", "En Julia la instrucción `while`, a diferencia de la instrucción `if`, introduce un nuevo scope o ámbito local; ello significa que cualquier variable al cual se asigna un valor dentro del `while`, este vive solo dentro del bucle mientras no se haya declarado antes de la instrucción `while`. \n", "\n", "Para ilustrar este hecho puede observar las variables `e` y `t` del ejemplo anterior, como la variable `e` fue declarado antes de `while` este pertenece al ámbito global y posee un valor luego que el bucle se ejecuta.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "e\n", "", "" ], "metadata": {}, "execution_count": 129 }, { "cell_type": "markdown", "source": [ "\n", "t, a diferencia de `e`, pertenece al ámbito local al `while` porque fue declarado dentro de este. Por ello al querer utilizar la variable en el ámbito local se genera un error.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "## t # <- Dará error al ser evaluado, dado que t no está definido en el ámbito global.\n", "", "" ], "metadata": {}, "execution_count": 130 }, { "cell_type": "markdown", "source": [ "\n", "#### Instrucción for\n", "La instrucción `for` es similar al `while`, permite tener bucles o repetición de código controlado. Sin embargo, tiene algunas diferencias fundamentales. El ciclo for se constituye como sigue:\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "begin\n", "\te₁ = 0\n", "\tfor i ∈ 0:20 ##Encabezado\n", "\t\tt = 1/factorial(i) ##Cuerpo de la instrucción for\n", "\t\te₁ += t\n", "\t\ti+= 1\n", "\tend\n", "end\n", "", "" ], "metadata": {}, "execution_count": 131 }, { "outputs": [], "cell_type": "code", "source": [ "e₁\n", "", "" ], "metadata": {}, "execution_count": 132 }, { "outputs": [], "cell_type": "code", "source": [ "##t # Causará error por la misma razón del ejemplo anterior. \n", "", "" ], "metadata": {}, "execution_count": 133 }, { "cell_type": "markdown", "source": [ "\n", "El ciclo `for` introduce un nuevo ámbito local como la hace el ciclo `while`, puede observar el comportamiento de las variables `e₁` y `t`.\n", "\n", "El encabezado del ciclo `for` está constituido por una variable (`i` en el ejemplo) y un iterable (el objeto `0:20`) que constituye un secuencia de números desde 0 hasta 20 y cuyo incremento es de uno en uno. Además se define la relación de pertenencia entre la variable y el iterable.\n", "\n", "El iterable contiene los valores que toma la variable (`i`) en cada iteración, por ello no necesariamente el ciclo `for` itera sobre valores numéricos. Además, si los valores son numéricos no necesariamente estos deberán tener un orden específico.\n", "\n", "Observe que la cantidad de elementos que contiene el iterable constituye el número de iteraciones en el ciclo `for`.\n", "\n", "\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "#### Sentencias break y continue\n", "`break` y `continue` son keywords que permiten manipular las iteraciones en las estructuras de control de repetición.\n", "\n", "El keyword `break` para la ejecución del bucle.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "begin\n", "\tz = 0\n", "\tfor i in 1:10\n", "\t\tif i >= 6\n", "\t\t\tz = i\n", "\t\t\tbreak\n", "\t\tend\n", "\t\tz = i\n", "\tend\n", "\tz\n", "end\n", "", "" ], "metadata": {}, "execution_count": 134 }, { "cell_type": "markdown", "source": [ "\n", "Aunque el ciclo for está definido para iterar sobre los números del 1-10, se observa que solo itera sobre los números 1-6, debido a que en su interior se encuentra la sentencia `if` que ejecuta `break` cuando la variable `i` alcanza o supera el valor de `6`.\n", "\n", "El keyword `continue` detiene la iteración actual y hace que el ciclo continúe en la iteración siguiente.\n", "\n" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "begin\n", "\tw = \"\"\n", "\tfor i in 1:10\n", "\t\tif i%2 == 0\n", "\t\t\tcontinue\n", "\t\tend\n", "\t\tw *= \"$i\"\n", "\tend\n", "\tw\n", "end\n", "", "" ], "metadata": {}, "execution_count": 135 }, { "cell_type": "markdown", "source": [ "\n", "Como se puede observar el valor de la cadena final solo contiene los elementos que son impares, debido a que `w *= \\\"$i\\\"` no se ejecuta para `i` par, lo anterior porque se observa el efecto de ejecutar `continue`.\n", "\n" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "\n", "**NOTA:** Para conocer más detalles acerca de las estructura de control en Julia puede consultar la sección [Control Flow](https://docs.julialang.org/en/v1/manual/control-flow/##Control-Flow) del maual de Julia.\n", "\n" ], "metadata": {} } ], "nbformat_minor": 2, "metadata": { "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.5.1" }, "kernelspec": { "name": "julia-1.5", "display_name": "Julia 1.5.1", "language": "julia" } }, "nbformat": 4 }