El control de flujo determina el orden en que el código de un programa se va ejecutando. En Python, el flujo está controlado por estructuras condicionales, loops y funciones.
### 4.3.1. - Estructuras condicionales (if)
- Expresión de resultado booleano (True/False)
- La indentación es obligatoria en Python
- Los dos puntos (:) dan paso al código que se ejecuta si expresión = True
```python
if expresión:
código a ejecutarse
elif expresión:
código a ejecutarse
elif expresión:
código a ejecutarse
...
else:
código a ejecutarse
```
- *else & elif* son opcionales y pueden incluirse varias cláusulas elif
Si bien los loops while son otro tipo de bucles, resultan más parecidos a los condicionales if que a los loops for. Podemos pensar a los loops while como una estructura condicional que se ejecuta en repetición, hasta que se convierte en falsa.
```python
while condición:
expresión
else:
expresión
```
- Se compone de la Estructura condicional seguida de dos puntos (:)
- La indentación es obligatoria en Python.
- Este código se ejecutará cuando la condición se convierta en False
### 4.4.1. - instrucciones especiales
- Si el código llega a una instrucción break, se produce la salida del bucle.
- La instrucción continue interrumpe la iteración actual dentro del bucle, llevando al programa a la parte superior del bucle.
- La instrucción pass no altera el programa: ocupa un lugar donde se espera una declaración, pero no se desea realizar una acción.
La función range( ) devuelve una secuencia de números dados 3 parámetros. Se utiliza fundamentalmente para controlar el número de ejecuciones de un loop o para crear rápidamente una serie de valores.
- *valor_inicio* - número a partir del cual inicia el rango (incluido)
- *valor_final* - número antes del cual el rango finaliza (no incluido)
- *paso* - diferencia entre cada valor consecutivo de la secuencia
Sintaxis:
```python
range(valor_inicio, valor_final, paso)
print(list(range(1,13,3)))
```
[1,4,7,10]
El único parámetro obligatorio es *valor_final*. Los valores predeterminados para *valor_inicio* y *paso* son 0 y 1 respectivamente.
La función enumerate( ) nos facilita llevar la cuenta de las iteraciones, a través de un contador de índices de un iterable, que se puede utilizar de manera directa en un loop, o convertirse en una lista de tuplas con el método list( ).
- *iterable* - Cualquier objeto que pueda ser iterado
- *inicio* - Valor [int] de inicio del índice (por defecto iniciado en 0)
La función zip( ) crea un iterador formado por los elementos agrupados del mismo índice provenientes de dos o más iterables. Zip deriva de zipper (cremallera o cierre), de modo que es una analogía muy útil para recordar.
La función se detiene al cuando se agota el iterable con menor cantidad de elementos.
La función min( ) retorna el item con el valor más bajo dentro de un iterable. La función max( ) funciona del mismo modo, devolviendo el valor más alto del iterable. Si el iterable contiene strings, la comparación se realiza alfabéticamente.
Python nos facilita un módulo (un conjunto de funciones disponibles para su uso) que nos permite generar selecciones pseudo-aleatorias* entre valores o secuencias.
Nombre del módulo:
```python
from random import *
```
* = Todos los métodos
También pueden importarse de manera independiente aquellos a utilizar.
**randint(min, max)**: devuelve un integer entre dos valores dados (ambos límites incluidos)
**uniform(min, max)**: devuelve un float entre un valor mínimo y uno máximo
**random(sin parámetros)**: devuelve un float entre 0 y 1
**choice(secuencia)**: devuelve un elemento al azar de una secuencia de valores (listas, tuples, rangos, etc.)
**shuffle(secuencia)**: toma una secuencia de valores mutable (como una lista), y la retorna cambiando el orden de sus elementos aleatoriamente.
* La mecánica en cómo se generan dichos valores aletorios viene en realidad predefinida en "semillas". Si bien sirve para todos los usos habituales, no debe emplearse con fines de seguridad o criptográficos, ya que son vulnerables.
La comprensión de listas es una manera dinámica de construir una lista. Ofrece una sintaxis más breve en la creación de una nueva lista basada en valores disponibles en otra secuencia. Vale la pena mencionar que la brevedad se logra a costo de una menor interpretabilidad. Sintaxis:
```python
nueva_lista= [expresion for item in iterable if condicion == True]
```
*expresión* - fórmula matemática
*Item* - cada elemento del iterable
*iterable* - tuplas, sets, otras listas...
*condicion == True * - operación lógica
Caso especial con else:
```python
nueva_lista= [expresion if condicion == True else otra_expresion for item in iterable]
```
Ejemplo:
```python
nueva_lista = [num**2 for num in range(10) if num <5]
En Python 3.10, se incorpora la coincidencia de patrones estructurales mediante las declaraciones match y case. Esto permite asociar acciones específicas basadas en las formas o patrones de tipos de datos complejos.
```python
match objeto:
case <patron_1>:
<accion_1>
case <patron_2>:
<accion_2>
case <patron_3>:
<accion_3>
case _:
<accion_comodin>
```
El caracter _ es un comodín que actúa como coincidencia si la misma no se produce en los casos anteriores.
Es posible detectar y deconstruir diferentes estructuras de datos: esto quiere decir que los patrones no son únicamente valores literales (strings o números), sino también estructuras de datos, sobre los cuales se buscan coindicencias de construcción.
La consigna es esta: el programa le va a preguntar al usuario su nombre, y luego le va a decir algo así como “Bueno, Juan, he pensado un número entre 1 y 100, y tienes solo ocho intentos para adivinar cuál crees que es el número”. Entonces, en cada intento el jugador dirá un número y el programa puede responder cuatro cosas distintas:
- Si el número que dijo el usuario es menor a 1 o superior a 100, le va a decir que ha elegido un número que no está permitido.
- Si el número que ha elegido el usuario es menor al que ha pensado el programa, le va a decir que su respuesta es incorrecta y que ha elegido un número menor al número secreto.
- Si el usuario eligió un número mayor al número secreto, también se lo hará saber de la misma manera.
- Y si el usuario acertó el número secreto, se le va a informar que ha ganado y cuántos intentos le ha tomado.
Si el usuario no ha acertado en este primer intento, se le va a volver a pedir que elija otro número. Y así hasta que gane o hasta que se agoten los ocho intentos.