# Clase 3

## Más funciones

Aunque en principio pareciera que las funciones solo son una herramienta para ahorrarnos reescribir código que vayamos a utilizar varias veces, en realidad en Julia tienen una función más importante.

En Julia, aunque es un lenguaje interpretado, **todas las funciones pasan por un compilador que, entre otras cosas, las optimiza**. Así, al parecer Julia no es solamente interpretado, también es un lenguaje compilado de alguna manera.

Ya que las funciones se compilan, y por lo tanto se optimizan, eso quiere decir que lo mejor para hacer código en Julia **es meter todo el código en funciones y solo ejecutar dichas funciones**. En particular, la mayoría del código que les voy a pedir y que deben de entrar va a estar compuesto puramente de funciones.

### Ejemplo de función: implementar la fórmula de Herón para el área de un triángulo



Si tenemos un triangulo con lados de longitud $a,b,c$, entonces podemos calcular su área con la siguiente ecuación:

\begin{equation}
    Area = \sqrt{s(s-a)(s-b)(s-c)}
\end{equation}

Con $s = \frac{1}{2}(a+b+c)$

Vamos a hacer una función que implemente dicha fórmula


```julia
function areaTriangulo(a,b,c)
    # calcular el valor de s
    s = (1/2)*(a + b + c)
    # calcularmos el area
    area = sqrt(s*(s-a)*(s-b)*(s-c))
    # lo regresamos
    return area
end
```




    areaTriangulo (generic function with 1 method)



Para un triangulo rectangulo inscrito en un cuadrado de lado 1, sabemos que su area es 1/2. Hay que probar la función `areaTriangulo` con este resultado. Para ese triangulo, sabemos $a=1$, $b=1$ y $c = \sqrt{2}$


```julia
areaTriangulo(1,1,sqrt(2))
```




    0.49999999999999983



Todo parece estar correcto!

## Enunciados más interesantes: estructuras If

Para hacer código más interesante, nos gustaría tener una estructura que nos permitiera ejecutar distinto código dependiendo de si una **expresión booleana** sea verdadera o no

Dicha estructura existe y se llama una **Estructura If**. hagamos un ejemplo muy sencillo: hagamos una función que nos calcule la función $f(x) = |x|$. Recordando la definición:

\begin{equation}
|x| = \begin{cases}
x & x \geq 0 \\
 -x & x< 0
\end{cases}
\end{equation}


```julia
function valorAbsoluto(x)
    if x >= 0
        # se ejecuta cuando la expresion es verdadera
        return x
    else
        # se ejecuta cuando la expresion es falsa
        return -x
    end
end
```




    valorAbsoluto (generic function with 1 method)




```julia
x = valorAbsoluto(-9821)
println(x)
```

    9821



```julia
function problemasCurso(alumnos,sillas)
    if alumnos < 5
        println("No se abre el grupo")
    else
        println("El grupo si se abre")
        if alumnos > sillas
            println("Algunos van a estar parados")
        else
            println("Todos van a estar sentados")
        end
    end
end
```




    problemasCurso (generic function with 1 method)




```julia
problemasCurso(36,20)
```

    El grupo si se abre
    Algunos van a estar parados


Para sintetizar, la estructura if tiene la siguiente sintaxis

```Julia
if expresionBooleana
    # se ejecuta solo si expresionBooleana es verdadero
    instruc1
    instruc2
end
```
Cuando queremos que algo más se ejecute si la expresión es falsa
```Julia
if expresionBooleana
    # se ejecuta solo si expresionBooleana es verdadero
    instruc1
    instruc2
else
    # se ejecuta si expresionBooleana es falsa
    instruc3
    instruc4
end
```

## Ciclos While

¿Qué sucede si, en lugar de ejecutar **una vez** un pedazo de código dependiendo de si es verdadera o no una expresión boolena, quisiera ejectuar unas lineas de código **mientras  una expresión sea verdadera**?

Existe una estructura que permite eso. Es la llamada **Estructura While** o **Ciclo While**


```julia
function ejemploSimpleWhile(lim)
    # defino `c` para que cuente cuantas veces estoy en el while
    c = 1
    # `lim` es el límite de repeticiones de while
    while c <= lim
        println("Estoy en el while")
        print("c vale: ")
        println(c)
        # aumenta el valor de c en 1
        c = c + 1
    end
    println("Ya salí del While")
    print("c vale: ")
    println(c)
end
```




    ejemploSimpleWhile (generic function with 1 method)




```julia
ejemploSimpleWhile(5)
```

    Estoy en el while
    c vale: 1
    Estoy en el while
    c vale: 2
    Estoy en el while
    c vale: 3
    Estoy en el while
    c vale: 4
    Estoy en el while
    c vale: 5
    Ya salí del While
    c vale: 6


### ¿Qué pasa si la expresión booleana del While nunca cambia y siempre es verdadera?

En ese caso, el código se ejecuta **infinitamente**


```julia
function whileMalo(lim)
    c = 1
    while c <= lim
        println("Estoy en el while")
    end
    println("salí del while")
end
```




    whileMalo (generic function with 1 method)



Cuando se ejecuta infinitamente el código, por lo general el intérprete se traba y no podemos trabajar con él. **Hay que ser muy muy cuidadosos a la hora usar ciclos While**

### ¿No hay algo menos peligroso que un ciclo While que permita que cierto código se repita?

Si, si lo hay. Eso se llama un **ciclo For** y eso es el tema de la siguiente clase.

Para terminar, recordemos que la sintaxis del While es

```Julia
while expresionBooleana
    instruccion1
    instruccion2
end
```

Se repite mientras la condicion booleana sea cierta.

## Introducción a las arreglos, listas y rangos

En la clase 1 vimos que los **arreglos** eran una sucesión finita de objetos del mismo tipo. Para definir un arreglo, utilizamos la sintaxis siguiente:

```Julia
arreglo = [obj1,obj2,obj3]
```

En Julia, las posiciones se empiezan a contar desde 1. Es decir:
* arreglo[1] = obj1
* arreglo[2] = obj2


```julia
arreglo1 = [1,2,3,4,5,6,7,8]
println(typeof(arreglo1))
println(arreglo1[1])
arreglo2 = [2.3,4.0,4.4,-9.23,8.57]
println(typeof(arreglo2))
println(arreglo2[2])
# si utilizamos `end` accedemos al último elemento
println(arreglo2[end])
```

    Array{Int64,1}
    1
    Array{Float64,1}
    4.0
    8.57


Las **listas** son sucesiones finitas de objetos de disntito tipo. Se definen igual que un arreglo.


```julia
lista1 = [1,"Aldo",false,9.87]
println(typeof(lista1))
println(lista1[2])
println(lista1[end])
```

    Array{Any,1}
    Aldo
    9.87


En Julia, hay algo todavía más sofisticado. Los **rangos**. Un rango es un intervalo de números definido por tres valores: el menor valor posible, el mayor valor posible, y la separación entre cada elemento

La sintaxis de un rango es:

```Julia
rango1 = inicial:separacion:final
```


```julia
rango1 = 1:1:10
println(collect(rango1))
rango2 = 1:1.2:10
println(collect(rango2))
# si no especifica la separacion, se asume que la separacion es 1
rango3 = 3.3:5.3
println(collect(rango3))
```

    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    [1.0, 2.2, 3.4, 4.6, 5.8, 7.0, 8.2, 9.4]
    [3.3, 4.3, 5.3]


### ¿Un rango es igual a un arreglo?

**No**. Mientras que un arreglo de $n$ elementos, se tiene que representar en la memoria como $n$ elementos distintos, un rango que puede tener muchos elementos solo se representa en la memoria como tres cosas: el valor incial, la separacion y el limite superior.

**Esto ahora mucha memoria** y nos permite describir más rápidamente un arreglo


```julia
println(collect(1:8))
```

    [1, 2, 3, 4, 5, 6, 7, 8]



```julia
# imprimirlos así no me da mucha información
println(1:8)
```

    1:8


La función `collect(ran)` convierte explícitamente un rango `ran` en un arreglo


```julia
println(typeof(1:8))
# lo convierto con collect a un arreglo
println(typeof(collect(1:8)))
```

    UnitRange{Int64}
    Array{Int64,1}


# Ejercicios 

1. Escribe una función que tome como argumento dos números reales $r$ y  $h$ y nos regrese el valor del volumen de un cono circular de radio $r$ y altura $h$.

2. En un laboratorio se mide la concentración de monóxido de carbono en el aire. Si la concentración es menor a 0.05, no hay ningún problema de oxígenación. Si la concentración es mayor a 0.50, entonces hay un problema de oxigenación. Si la oxigenación está entre 0.05 y 0.50, entonces hay dos casos:


* Si hay más de 20 personas en el laboratorio, entonces hay un riesgo de oxigenación. 
* Si hay menos de 20, entonces no hay ningún riesgo.

Escribe una función que tome como argumento dos números `co` y `personas`, que representan, respectivamente, la concentración de monóxido de carbono y el número de personas en el cuarto, y nos imprima si hay o no un riesgo de oxigenación en el laboratorio.


3. Escribe una función que tome como argumento un número real $x$ y regrese el valor de la función $f$, definida por

\begin{equation}
    f(x) = \begin{cases}
    \sqrt{x-3} & x \geq 3 \\
    -3x^2 & -1 \leq x < 3 \\
    2x - 1 & x < -1 \\
    \end{cases}
\end{equation}

4. Escribe una función que tome como argumento un numero entero positivo `edad` e imprima el texto `saludos, tengo x años`, donde `x` es remplazado por cada uno de tus años, empezando en 1.

**Sugerencia:** usar un ciclo While y utilizar las funciones `print` y `println`


5. Mediante el uso de un ciclo While, escribe una función que tome como argumento tres números reales $a,b$ y $l$ con $a<b$ y $0<l<b-a$ e imprima en la pantalla todos los números reales $r$ de la forma $r = a+nl$ con $n \in \mathbb{N}$ tales que $a\leq r \leq b$.

**Sugerencia:** primero construir a mano los valores toma que $r$, después pensar como irlos construyendo partiendo de $a$ y luego implementar eso desde un ciclo While.



```julia

```

1b8c791866afcc45f2b3cbb16904e807704c6df3
ipynb
Jupyter Notebook
files/fiscomp_2020-4/material/clase03.ipynb
sayeg84/sayeg84.github.io
18f2e36dd7252603fad8f7093dc5aa00fc721be4
MIT
files/fiscomp_2020-4/material/clase03.ipynb
sayeg84/sayeg84.github.io
18f2e36dd7252603fad8f7093dc5aa00fc721be4
MIT
files/fiscomp_2020-4/material/clase03.ipynb
sayeg84/sayeg84.github.io
18f2e36dd7252603fad8f7093dc5aa00fc721be4
MIT
Qwen/Qwen-72B
1. YES
2. YES