Apuntes_Python/01_curso/Modulo_1/README.md

2036 lines
41 KiB
Markdown
Raw Normal View History

2022-12-24 22:41:20 -03:00
**Ir a:**
[*Repositorio*](https://gitea.kickto.net/devfzn/Apuntes_Python),
[*Modulo 2*](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_2#modulo-2-python-basico)
## Modulo 1 - Python basico
#### [Indice](#modulo-1-python-basico)
- [Primeros Pasos](#primeros-pasos)
- [Tipos de Datos](#tipos-de-datos)
- [Modulo Math](#modulo-math)
- [Condicionales](#condicionales)
- [Funciones](#funciones)
- [Expresiones Lambda](#expresiones-lambda)
- [Docstrings](#docstrings)
- [Ejemplos print, if, for, range y while](#ejemplos-print-if-for-range-while)
- [Sentencias brake, else y continue](#sentencias-brake-else-y-continue)
- [Entorno Virtual](#entorno-virtual)
- [import](#import)
- [modulo fibo](#modulo-fibo)
- [Iteradores](#iteradores)
- [Debugger](#debugger)
- [Ejercicios](#ejercicios)
- [Actividad 1](#actividad-1)
- [Actividad Dados](#actividad-dados)
## Primeros Pasos
Hola Mundo!
```python
print("Hola Mundo")
```
Entrada de usuario
```python
nombre = input("Ingresa tu nombre: ")
print("Hola", nombre, "!")
```
Ejemplo fibo
```python
# Serie de Fibonacci: La suma de dos elementos define el sgte.
a, b = 0, 1
while b < 10:
print(b, end=', ')
a, b = b, a+b
```
Print básico
```python
a = input("ingresa un número: ")
b = input("ingresa otro número: ")
a = int(a)
b = int(b)
c = a * b
print("La Multiplicación de los números",a,"y",b,"es",c)
a = input("ingresa un número: ")
b = input("ingresa otro número: ")
a = int(a)
b = int(b)
c = a + b
print("La SUMA de los números",a,"y",b,"es ",c)
```
### Operaciones aritméticas
**Division sin resto** ` // `
```python
4//3
# 1
```
**Resto** ` % `
```python
4%3
# 1
```
**Potencia** ` ** `
```python
# 5 al cuadrado
5 ** 2
# 2 a la potencia de 7
2 ** 7
```
**Última expresion** ` _ `
```python
1+3
# 4
3 + _
# 7
```
**Redondeo** `round("número", "decimales")`
```python
round(8.6786346, 1)
# 8.7
```
2022-12-25 16:04:37 -03:00
Además de **int** y **float**, Python soporta otros como **Decimal** y **Fraction**, además
2022-12-24 22:41:20 -03:00
tiene soporte integrado para **números complejos**.
> usa **j** o **J** para indicar la parte imaginaria, ej.
> **` 3+5+j `**
### Strings
Cadena Cruda **r'cadena'**
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
print(r'C:\\algun\directorio')
print('\t',r'~/Documentos')
print("""...\
Fin de linea
es automatico
puedes evitarlo con \\
""")
```
Las cadenas de texto pueden ser *operadas* con **` + `** y **` \ `**
```python
3 * 'al' + 'mendra'
# 'alalalmendra'
palabra = 'Python'
palabra[0]
# 'P'
palabra[5]
#'n'
# último caracter
palabra[-1]
# 'n'
# penúltimo caracter
palabra[-2]
# 'o'
palabra[-6]
# 'P'
# caracteres desde pos 0 (incluida) a 2 (exluida)
palabra[0:2]
# 'Py'
# caracteres desde pos 2 (incluida) a 5 (exluida)
palabra[2:5]
# 'tho'
palabra[:2] + palabra[2:]
# 'Python'
palabra[:4] + palabra[4:]
# 'Python'
len(palabra)
# 6
```
### Listas
```python
# definir
cuadrados = [1, 4, 9, 16]
# sumar listas
cuadrados + [36, 49, 64, 81, 100]
# modificar lista
cubos = [1, 8, 27, 65, 125 ] # cubos[3] debiera ser 64
cubos[3] = 64
# Agregar el cubo de 6
cubos.append(216)
# y el cubo de 7
cubos.append(7 ** 3)
```
```python
letras = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# reemplazar algunos valores
letras[2:5] = ['C', 'D', 'E']
# borrarlas
letras[2:5] = []
# reemplazar los elementos por una lista vacia
letras[:]
# Largo( lista )
len(letras)
# Listas agurapdas
a = ['a', 'b', 'c']
n = [1, 2, 3]
x = [a, n]
2022-12-25 16:04:37 -03:00
x # [['a', 'b', 'c'], [1, 2, 3]]
x[0] # ['a', 'b', 'c']
x[0][1] # 'b'
2022-12-24 22:41:20 -03:00
```
[1-1_primeros_pasos.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-1_primeros_pasos.py)
----
# Tipos de Datos
Consola python: `python -i`
```python
>>> type(8)
<class 'int'>
>>> type(10.5)
<class 'float'>
>>> type(True)
<class 'bool'>
>>> type('hola')
<class 'str'>
>>> type(3+4j)
<class 'complex'>
```
### Variables
- Tipado dinámico
- CaseSensitive
```python
>>> numero = 4
>>> type(numero)
<class 'int'>
>>> numero = 4.5
>>> type(numero)
<class 'float'>
>>> nada = None
>>> type(nada)
<class 'NoneType'>
```
**Expresiones**:
2022-12-25 16:04:37 -03:00
* ` 1 + 1 ` : Expresión que combina **dos valores** y **un operador**.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
* ` numero + 1 ` : Expresión que combina **una variable**, **un valor** y **un operador**.
2022-12-24 22:41:20 -03:00
### Operadores:
* **Unarios** y **Binarios**, que requieren uno o dos operandos.
- Operadores **Aritmeticos**: **`+` `-` `*` `/` `//` `%` `**`**
- Operadores **Asignación**: **`=` `+=` `-=` `*=` `/=` `//=` `%=` `**=`**
- Operadores **Comparación**: **`==` `!=` `<` `<=` `>` `>=`**
- Operadores **Lógicos**: **`and` `or` `not`**
Ejemplos operadores de comparación
|Ejm. op.|Resultado|
|-|-|
|`1 == 1 `|True |
|`1 != 1 `|False|
|`1 > 2 `|False|
|`2 > 3 `|False|
|`1 >= 1 `|True|
|`2 <= 3 `|True|
|`a == b`|False|
|`a != b`|True|
|`a < b `|True|
|`1 < 2 < 3 `|True|
### Tablas de Verdad
#### and
2022-12-25 16:04:37 -03:00
|Var. A|Op.|Var. B|Resultado
|-|-|-|-|
| `True` | **and** | `True` | True |
| `True` | **and** | `False` | False |
| `False` | **and** | `True` | False |
| `False` | **and** | `False` | False |
2022-12-24 22:41:20 -03:00
#### or
2022-12-25 16:04:37 -03:00
|Var. A|Op.|Var. B|Resultado
|-|-|-|-|
| True | **or** | True | True |
| True | **or** | False | True |
| False | **or** | True | True |
| False | **or** | False | False |
2022-12-24 22:41:20 -03:00
#### not
2022-12-25 16:04:37 -03:00
| Op. | Var. | Resultado |
|-|-|-|
| **not** | True | False |
| **not** | False | True |
2022-12-24 22:41:20 -03:00
### Precedencia de operadores
| Orden Predecendencia|Operadores|
|:-:|---------------|
| 1 | `**` |
| 2 | ` * `, ` / `, ` % `, ` // ` |
| 3 | ` + `, ` - ` |
| 4 | ` <= `, ` < `, ` > `, ` >= `|
| 5 | ` == `, ` != ` |
| 6 | ` not `, ` or `, `and ` |
| 7 | ` = `, ` %= `, ` /= `, ` -= `, ` += `, ` *= `, ` **= ` |
[1-2a_tipos_datos.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-2a_tipos_datos.py)
----
## Modulo Math
```python
import math
```
Constantes:
```python
pi, e, tau, inf, nan ( math.pi ; math.cos(0) )
```
#### Funciones math
|Función|Detalle|Ejemplo|
|-|-|-|
|ceil | Redondea al sgte. entero | `ceil(3.2) # 4`|
|floor | Redondea al entero anterior| `floor(3.2) # 3`|
|ceil | Valor absoluto | `fabs(-4) # 4`|
|factiorial | Func. factorial | `factorial(4) # 24`|
#### Funciones de potencia y logarítmicas
|Función|Detalle|Ejemplo|
|-|-|-|
|exp | e^x | `exp(1) # e` |
|expm1 | (e^x) -1 | `exp(1)e -1 # e-1` |
|log | logaritmo natural | `log(e) # 1` |
|log2 | logaritmo en base 2 | `log(2) # 1` |
|log10 | logaritmo en base 10 | `log(10) # 1` |
|pow | Potencia | `pow(3,2) # 9` |
|sqrt | Raíz cuadrada | `sqrt(9) # 3` |
#### Funciones trigonométricas
|Función|Detalle|Ejemplo|
|-|-|-|
|acos | arco coseno | `acos(1) # 0` |
|asin | arco seno | `asin(0) # 0` |
|atan | arco tangente | `atan(0) # 0` |
|cos | coseno | `cos(pi) # -1` |
|hypot | hipotenusa | `hypot(1,1) # 1.14121356...` |
|sin | seno | `sin(pi/2) # 1` |
|tan | tangente | `tan(pi/4) # 0.99999999...` |
Consola de python: `python -i`
```python
>>> import math
>>> help(math)
>>> math.sqrt(16)
4.0
>>> math.log(math.e)
1.0
```
## Modulo Random
2022-12-25 16:04:37 -03:00
Forma parte de la libreria estandar de python
2022-12-24 22:41:20 -03:00
Consola de python: `python -i`
```python
>>> import random
>>> random.random()
0.1430076482629129
>>> random.random()*10
6.753608889973483
>>> (random.random()*10)%6+1
2.279082688613001
>>> (int(random.random()*10)%6+1)
4
>>> (int(random.random()*10)%6+1)
4
>>> (int(random.random()*10)%6+1)
6
>>> (int(random.random()*10)%6+1)
4
>>> (int(random.random()*10)%6+1)
3
>>> clear
```
### Choice
Consola de python: `python -i`
```python
>>> random.choice([1,2,3,4,5,6])
1
>>> random.choice([1,2,3,4,5,6])
1
>>> random.choice([1,2,3,4,5,6])
2
>>> random.choice([1,2,3,4,5,6])
4
>>> random.choice(['Rojo', 'Verde', 'Azul])
random.choice(['Rojo', 'Verde', 'Azul])
>>> random.choice(['Rojo', 'Verde', 'Azul'])
'Verde'
>>> random.choice(['Rojo', 'Verde', 'Azul'])
'Verde'
>>> random.choice(['Rojo', 'Verde', 'Azul'])
'Rojo'
>>> random.choice(['Rojo', 'Verde', 'Azul'])
'Verde'
```
### Choices
Consola de python: `python -i`
```python
>>> random.choices([1,2,3,4,5,6], k=2)
[4, 6]
>>> random.choices([1,2,3,4,5,6], k=2)
[4, 3]
>>> random.choices([1,2,3,4,5,6], k=2)
[3, 4]
```
[1-2b_libreria_math.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-2b_libreria_math.py)
----
## Condicionales
```python
x = 2
if x >= 0:
print('El número',x,'es positivo')
else:
print('El número',x,'es negativo')
# El número 2 es positivo
```
#### Condicionales Encadenados
```python
if x >= 0:
print('El número',x,'es positivo')
elif x < 0:
print('El número',x,'es negativo')
else:
print('El número es igual a cero')
# El número 2 es positivo
```
#### Condicionales Anidados
```python
x = 0
if x > 0:
print('El número',x,'es positivo')
else:
if x < 0:
print('El número',x,'es negativo')
else:
print('El número es igual a cero')
# El número es igual a cero
```
#### Mas ejemplos
```python
x = 1
if x > 0:
print('El número es positivo')
# El número es positivo
```
```python
x = -1
if x > 0:
print('El número es positivo')
```
```python
x = 1
if x % 2 == 0:
print('El número',x,'es par')
else:
print('El número',x,'es impar')
# El número 1 es impar
```
```python
x = 4
if x % 2 == 0:
print('El número',x,'es par')
else:
print('El número',x,'es impar')
# El número 4 es par
```
```python
x = 3
print('El número',x,'es par') if x % 2 == 0 else print('El número',x,'es impar')
# El número 3 es impar
```
#### Otros ejemplos de encadenado
```python
x = 1
y = 2
if x < y:
print(x,'es menor q', y)
elif x > y:
print(x,'es mayor q', y)
else:
print(x,'es igual a', y)
# 1 es menor q 2
```
```python
x = 3
if x < y:
print(x,'es menor q', y)
elif x > y:
print(x,'es mayor q', y)
else:
print(x,'es igual a', y)
# 3 es mayor q 2
```
```python
x = 2
if x < y:
print(x,'es menor q',y)
elif x > y:
print(x,'es mayor q',y)
else:
print(x,'es igual a', y)
# 2 es igual a 2
```
```python
x = 5
if x == y:
print(x,'es igual a',y)
else:
if x < y:
print(x,'es menor q',y)
else:
print(x,'es mayor q',y)
# 5 es mayor q 2
```
[1-3a_condicionales.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-3a_condicionales.py)
----
## Funciones
- **FUNCION**
Es una secuencia de sentencias que realiza una operación.
Las mismas tienen un nombre y pueden recibir o no parámetros y
devolver o no resultados.
ej.
```python
2022-12-25 16:04:37 -03:00
def cero():
return 0
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
cero() # 0
cero() + 1 # 1
c = cero()
c # 0
2022-12-24 22:41:20 -03:00
```
```python
def suma_uno(un_numero):
return un_numero + 1
suma_uno(3)
# 4
suma_uno(cero())
#1
def suma(a, b):
resultado = a + b
return resultado
def suma(a, b):
resultado = a + b
return resultado
def maximo_2(a, b):
"Devuelve el máximo entre a y b"
maximo = a
if b > a:
maximo = b
return maximo
def maximo_3(a, b, c):
"Devuelve el máximo enter a, b, y c"
return maximo_2(a, maximo_2(b,c))
print(maximo_2(2,5))
# 5
print(maximo_3(6, 1, 5))
# 6
```
## Parametros de función
```python
def peso(masa, gravedad=9.8):
"Fórmula del peso"
return masa * gravedad
```
#### Parametros opcionales
```python
print("Peso en la tierra:", peso(10))
# Peso en la tierra: 98.0
print("Peso en la luna:", peso(10, 1.63))
# Peso en la luna: 16.299999999999997
```
#### Parámetros con palabras claves (o argumentos nombrados)
```python
print("Peso en la luna:", peso(10, gravedad=1.63))
# Peso en la luna: 16.299999999999997
print("Peso en la luna:", peso(masa=10, gravedad=1.63))
# Peso en la luna: 16.299999999999997
print("Peso en la luna:", peso(gravedad=1.63, masa=10))
# Peso en la luna: 16.299999999999997
```
> Los parámetros posicionales **no pueden ir despues de un keyword**
> ```python
> print("Peso en la luna:", peso(masa=10, 1,63))
> # SyntaxError: positional argument follows keyword argument
> ```
### Lista de parámetros
```python
def suma_numeros(*args):
"Suma los números pasados por párametro"
return sum(args)
print("6 + 7 + 8 =", suma_numeros(*[6,7,8]))
# 6 + 7 + 8 = 21
print("6 + 7 + 8 =", suma_numeros(6,7,8))
# 6 + 7 + 8 = 21
```
### Diccionario de parámetros
```python
def imprimir_ticket(*args, **kwargs):
"Imprime el ticket de una compra"
print("Detalle Ticket")
for item, precio in kwargs.items():
print(item, ":", precio)
```
### Argumentos de función
- Distintas formas de pasar los argumentos
- Definir funciones anónimas o expresiones lambda
#### Definiendo Funcion Fibonacci (hasta limite determinado)
```python
# *def para definir la funcion
def fibo(n):
"""Muestra la serie Fibonacci hasta n."""
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
fibo(2000)
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
```
- **return**:
2022-12-25 16:04:37 -03:00
Devuelve un valor en una función, **sin una expresión** como argumento
retorna **None**, si se alcanza el fuba de una función, también retorna **None**.
2022-12-24 22:41:20 -03:00
```python
f = fibo
f(1000)
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
print(f(0))
# None
type(f)
# <class 'function'>
```
#### Fibo 2
```python
def fibo2(n):
"""Devuelve una lista con la serie de Fibonacci hasta n."""
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
f100 = fibo2(100)
f100
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
```
#### Ejemplo de función que llama a otra
```python
def fib(n):
a, b = 0, 1
for i in range(n):
a, b = b, a+b
return a
print(fib(35))
def fibo(n):
a = fib(n-1) + fib(n-2)
return a
print(fibo(35))
```
2022-12-25 16:04:37 -03:00
#### Función que recibe entrada de usuario
2022-12-24 22:41:20 -03:00
```python
def pedir_confirmacion(prompt, reintentos=4, msj='Intenta nuevamente'):
while True:
ok = input(prompt)
if ok in ('s', 'S', 'si', 'Si', 'SI'):
return True
if ok in ('n', 'no', 'No', 'NO'):
return False
reintentos -= 1
if reintentos < 0:
raise ValueError('Respuesta de usuario invalida')
print(msj)
```
```python
> pedir_confirmacion('¿Quieres Salir?')
> ¿Quieres Salir?no
> False
> pedir_confirmacion('Sobreescribir?', 2, 'eeey! si o no?')
> Sobreescribir?o
> eeey! si o no?
> Sobreescribir?no
> False
```
#### Levantando excepción **ValueError**
```python
> pedir_confirmacion('¿Sobreescribir?', 2)
> ¿Sobreescribir?e
> Intenta nuevamente
> ¿Sobreescribir?3
> Intenta nuevamente
> ¿Sobreescribir?3
> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 10, in pedir_confirmacion
ValueError: Respuesta de usuario invalida
```
2022-12-25 16:04:37 -03:00
Los valores por omisión son evaluados en el momento de la definición de la función,
2022-12-24 22:41:20 -03:00
en el ámbito de la definición, entonces:
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
i = 5
def f(arg=i):
print(arg)
i = 6
f()
# 5
f(6)
# 6
f()
#5
```
2022-12-25 16:04:37 -03:00
El valor por omisión es evaluado solo una vez. Existe una diferencia cuando
el valor por omisión es un objeto mutable como una lista, diccionario, o
instancia de la mayoría de las clases. Por ejemplo.
La siguiente función acumula los argumentos que se le pasan en subsiguientes llamadas:
2022-12-24 22:41:20 -03:00
```python
def f(a, L=[]):
L.append(a)
return L
print(f(1)) #[1]
print(f(2)) #[1, 2]
print(f(3)) #[1, 2, 3]
```
2022-12-25 16:04:37 -03:00
Si no se quiere que el valor por omisión sea compartido entre subsiguientes
llamadas, la función se puede escribir así:
2022-12-24 22:41:20 -03:00
```python
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
print(f(1))
# [1]
print(f(2))
# [2]
print(f(3))
# [3]
print(f(1, [1,2,3]))
# [1, 2, 3, 1]
```
(o **argumentos nombrados**) de la forma `keyword = value`. Por ejemplo:
```python
2022-12-25 16:04:37 -03:00
def loro(tension, estado='muerto', accion='explotar', color='Azul Nordico'):
2022-12-24 22:41:20 -03:00
print("-- Este loro no va a", accion, end=' ')
print("si le aplicas", tension, "voltios.")
2022-12-25 16:04:37 -03:00
print("-- Hermoso plumaje", color)
2022-12-24 22:41:20 -03:00
print("-- Está", estado,"!")
```
- 1 argumento posicional
```python
loro(1000)
# -- Este loro no va a explotar si le aplicas 1000 voltios.
2022-12-25 16:04:37 -03:00
# -- Hermoso plumaje Azul Nordico
2022-12-24 22:41:20 -03:00
# -- Está muerto !
```
- 1 argumento nombrado
```python
loro(tension=1000)
# -- Este loro no va a explotar si le aplicas 1000 voltios.
2022-12-25 16:04:37 -03:00
# -- Hermoso plumaje Azul Nordico
2022-12-24 22:41:20 -03:00
# -- Está muerto !
```
- 2 argumentos nombrados
```python
2022-12-25 16:04:37 -03:00
loro(tension=1000000, accion='volar')
# -- Este loro no va a volar si le aplicas 1000000 voltios.
# -- Hermoso plumaje Azul Nordico
2022-12-24 22:41:20 -03:00
# -- Está muerto !
```
- 2 argumentos nombrados
```python
2022-12-25 16:04:37 -03:00
loro(accion='volar', tension=1000000)
# -- Este loro no va a volar si le aplicas 1000000 voltios.
# -- Hermoso plumaje Azul Nordico
2022-12-24 22:41:20 -03:00
# -- Está muerto !
```
- 3 args posicionales
```python
loro('un millón', 'despojado de vida', 'saltar')
# -- Este loro no va a saltar si le aplicas un millón voltios.
2022-12-25 16:04:37 -03:00
# -- Hermoso plumaje Azul Nordico
2022-12-24 22:41:20 -03:00
# -- Está despojado de vida !
```
- 1 arg. posicional y 1 nombrado.
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
loro('mil', estado='viendo crecer las flores desde abajo')
# -- Este loro no va a explotar si le aplicas mil voltios.
2022-12-25 16:04:37 -03:00
# -- Hermoso plumaje Azul Nordico
2022-12-24 22:41:20 -03:00
# -- Está viendo crecer las flores desde abajo !
```
#### Llamadas invalidas
```python
loro()
# falta argumento obligatorio
loro(tension=5.0, 'muerto')
# argumento posicional luego de uno nombrado
loro(110, tension=220)
# valor duplicado para el mismo argumento
loro(actor='Juan Garau')
# nombre del argumento desconocido
```
2022-12-25 16:04:37 -03:00
Cuando un parámetro formal de la forma **nombre** está presente al final,
recibe un diccionario (ver *tipos integrados*) conteniendo todos los argumentos
nombrados excepto aquellos correspondientes a un parámetro formal.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Esto puede ser combinado con un parámetro formal de la forma **nombre**, que
recibe una **tupla** conteniendo los argumentos posicionales además de la lista de
parámetros formales. **` *nombre `** debe ocurrir antes de **` **nombre `**.
2022-12-24 22:41:20 -03:00
Ejemplo:
```python
def ventadequeso(tipo, *argumentos, **palabrasclave):
print("-- ¿Tiene", tipo,"?")
print("-- Lo siento, nos quedamos sin", tipo)
for arg in argumentos:
print(arg)
print("-" * 40)
for c in palabrasclave:
print(c, ":", palabrasclave[c])
```
```python
ventadequeso("Limburger", "Es muy liquido, sr.",
"Realmente es muy muy liquido, sr.",
cliente="Juan Garau",
vendedor="Miguel Paez",
puesto="Venta de Queso")
#- ¿Tiene Limburger ?
#- Lo siento, nos quedamos sin Limburger
# Es muy liquido, sr.
# Realmente es muy muy liquido, sr.
# ----------------------------------------
# cliente : Juan Garau
# vendedor : Miguel Paez
# puesto : Venta de Queso Argentino
```
#### Listas de argumentos arbitrarios
Una función puede ser llamada con un número arbitrario de argumentos.
Estos serán organizados en una tupla.
2022-12-25 16:04:37 -03:00
Antes del número variable de argumentos, cero o más argumentos normales
pueden estar presentes.
2022-12-24 22:41:20 -03:00
```python
def muchos_items(archivo, separador, *args):
archivo.write(separador.join(args))
```
2022-12-25 16:04:37 -03:00
Generalmente, argumentos de cantidad variable son útilmos en la lista de
parametros formales, porque toman el remanente de argumentos q se pasan a la
función.
Cualquier parametro que suceda luego del +args solo sera del tipo **nombrado**,
es decir, solo se pueden utilizar nombradros y no posicionales.
2022-12-24 22:41:20 -03:00
```python
concatenar("tierra", "marte", "venus")
# 'tierra/marte/venus'
concatenar("tierra", "marte", "venus", sep=" @ ")
# 'tierra @ marte @ venus'
```
#### Desempaquetando una lista de argumentos
2022-12-25 16:04:37 -03:00
Cuando los argumentos ya pertences a una lista o tupla, se pueden desempaquetar
para llamar una funcion que requiere argumetnoss posicionaes separados.
ej. `range()` espera los argumentos inicio y fin.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
También se puede llamar a la función con el operador para desempaquetar argumentos
de una lista o tulpa **`*`**
2022-12-24 22:41:20 -03:00
```python
# llamada normal con argumentos separados
list(range(3, 6))
# [3, 4, 5]
# argumentos desempaquetados de la lista
args = [3, 6]
list (range(*args))
# [3, 4, 5]
```
Los **diccionarios** pueden entregar argumentos nombrados con el operador ` ** `
```python
def loro(tension, estado='rostizado', accion='apestar'):
print("-- Este loro no va a", accion, end=' ')
print("si toca", tension, "voltios.", end=' ')
print("Está", estado, "!")
d = {"tension": "cinco mil", "estado": "demacrado", "accion": "VOLAR"}
loro(**d)
# -- Este loro no va a VOLAR si toca cinco mil voltios. Está demacrado !
```
[1-3b_funciones.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-3b_funciones.py)
----
## Expresiones Lambda
Funciones anónimas, pequeñas son creadas con **lambda**.
```python
# retorna la suma de sus dos argumentos
lambda a, b: a + b
```
2022-12-25 16:04:37 -03:00
Las funciones Lambda pueden ser usadas en cualquier lugar donde sea requerido
un objeto de tipo función.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Están sintácticamente restringidas a una sola expresión.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Semánticamente, son solo azúcar sintáctica para definiciones normales de
funciones.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Al igual que las funciones anidadas, las funciones lambda pueden hacer
referencia a variables desde el ámbito que la contiene.
2022-12-24 22:41:20 -03:00
```python
def hacer_incrementador(n):
return lambda x: x + n
f = hacer_incrementador(42)
f(0)
# 42
f(1)
# 43
f(10)
# 52
```
```python
import time
f = lambda x: x + 1
print("Tipo de f:", type(f))
# Tipo de f: <class 'function'>
print("f(3)=", f(3))
# f(3)= 4
def funcioN_time(f, *args):
start_time = time.time()
result = f(*args)
end_time = time.time()
print("Tiempo de ejecución: ", end_time - start_time, "milisegundo(s)")
return result
print("f(5) =", funcioN_time(f, 5))
# Tiempo de ejecución: 2.86102294921875e-06 milisegundo(s)
f(5) = 6
```
[1-3c_expresiones_lambda.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-3c_expresiones_lambda.py)
----
## Docstrings
### Ejemplo de un **docstring multi-línea**
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
def mi_funcion():
"""Esta funcion solo muestra documentacion.
Nada mas.
"""
pass
print(mi_funcion.__doc__)
# Esta funcion solo muestra documentacion.
#
# Nada mas.
```
**Anotación de funciones**
2022-12-25 16:04:37 -03:00
Se almacenan en el atributo ***__annotations__*** de la función como un
diccionario y no tienen efecto enninguna otra parte de la función.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Las anotaciones de los parámetros se definen luego de dos puntos después del
nombre del parámetro, seguido de una expresión que evalúa al valor de la
anotación.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Las anotaciones de retorno son definidas por el literal **` -> `**, seguidas
de una expresión, entre la lista de parámetros y los **` : `** que marcan el
final de la declaración **` def `**.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
El siguiente ejemplo tiene **un argumento posicional, uno nombrado, y el valor
de retorno anotado**.
2022-12-24 22:41:20 -03:00
```python
def f(jamon: str, huevos: str = 'huevos') -> str:
print("Anotaciones:", f.__annotations__)
print("Argumentos:", jamon, huevos)
return jamon + ' y ' + huevos
f('carne')
# Anotaciones: {'jamon': <class 'str'>, 'huevos': <class 'str'>, 'return': <class 'str'>}
# Argumentos: carne huevos
# 'carne y huevos'
```
[1-3d_cadena_de_txt_de_documentacion.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-3d_cadena_de_txt_de_documentacion.py)
----
## Ejemplos print, if, for ,range, while
### print
```python
print("El número es: ", 5)
# El número es: 5
```
```python
print(1,2,3,4,5, sep=', ')
# 1, 2, 3, 4, 5
```
```python
print(1,2,3,4,5, sep='-')
# 1-2-3-4-5
```
```python
# Cambio salto de lina por end=''
print(1,2,3,4,5, sep=' - ', end='')
# 1 - 2 - 3 - 4 - 5
```
```python
print([1,2,3,4,5])
# [1, 2, 3, 4, 5]
```
### if
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
Consola python: `python -i`
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
x = int(input("Ingresa un entero: "))
# Ingresa un entero: 42
x = 42
if x < 0:
x = 0
print('Negativo cambiado a cero')
elif x == 0:
print('Cero')
elif x == 1:
print('Simple')
else:
print('Más')
'Más'
```
### for
Midiendo cadenas de texto
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
palabras = ['gato','ventana','defenestrado']
for p in palabras:
print(p, len(p))
# gato 4
# ventana 7
# defenestrado 12
for p in palabras[:]:
if len(p) > 6:
palabras.insert(0, p)
palabras
# ['defenestrado', 'ventana', 'gato', 'ventana', 'defenestrado']
```
```python
for i in range(10):
print(i, end=' ')
print('\n')
for i in 'Hola Mundo!':
print(i, end=' - ')
print('\n')
def contador(n):
c = 0
for i in range(n):
c += 1
return c
contador(10)
print(contador(10),'\n')
def sumatoria(numeros):
acum = 0
for n in numeros:
acum += n
return acum
print(sumatoria([1,2,3,4,5]), '\n')
def tabla_multip(numero):
"Imprime la tabla de multiplicar"
for indice in [1, 2, 3, 4, 5, 6, 7, 8, 9 ,10]:
print(f"{numero} * {indice} = {numero * indice}")
tabla_multip(2)
```
### range
```python
range( desde<0>, hasta<definir>, paso<1> )
<Valores por defecto>
```
```python
for x in range(10):
print(x, end=' ')
# 0 1 2 3 4 5 6 7 8 9
```
```python
for x in range(1,10):
print(x, end=' ')
# 1 2 3 4 5 6 7 8 9
```
```python
for x in range(1,10,2):
print(x, end=' ')
# 1 3 5 7 9
```
```python
for x in range(10,0,-1):
print(x, end=' ')
# 10 9 8 7 6 5 4 3 2 1
```
```python
for x in range(2):
print(i)
# 0
# 1
# 2
```
```python
range(5, 10)
# 5, 6, 7, 8, 9
```
```python
range(0, 10, 3)
# 0, 3, 6, 9
```
```python
range(-10, -100, -30)
# -10, -40, -70
```
```python
a = ['Mary','tenía','un','corderito']
for i in range(len(a)):
print(i, a[i])
# 0 Mary
# 1 tenía
# 2 un
# 3 corderito
```
#### Crear lista a partir de objeto iterable
```python
# list(enumerate())
list(range(5))
# [0, 1, 2, 3, 4]
```
### Ciclo while
```python
import time
def suma_n(n):
"Suma los números de 1 a n"
result = 0
x = n
while x > 0:
result += x
x -= 1
return result
print(suma_n(5))
```
```python
def ciclo_infinito():
"Imprime el número 1 unfinitas veces"
i = 1
while i <= 10:
print(i, end=" ")
time.sleep(.5)
#ciclo_infinito()
```
[1-4a_if_for_range_while.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-4a_if_for_range_while.py)
----
## Sentencias brake, else y continue
```python
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n,'es igual a',x,'*',n/x)
break
else:
# "else" de un ciclo "for"
# Si no encuentra un factor
print(n, 'es un número primo')
# 2 es un número primo
# 3 es un número primo
# 4 es igual a 2 * 2.0
# 5 es un número primo
# 6 es igual a 2 * 3.0
# 7 es un número primo
# 8 es igual a 2 * 4.0
# 9 es igual a 3 * 3.0
```
```python
for num in range(2, 10):
if num % 2 == 0:
print("Encontré un número par", num)
# "continue" continua con la sgte. iteracion del ciclo for
continue
print("Encontré un número", num)
# Encontré un número par 2
# Encontré un número 3
# Encontré un número par 4
# Encontré un número 5
# Encontré un número par 6
# Encontré un número 7
# Encontré un número par 8
# Encontré un número 9
```
#### else, break
```python
def buscar_numero_en(numero, lista):
for i, item in enumerate(lista):
if item == numero:
indice = i
break
else:
indice = -1
return indice
print( buscar_numero_en(1, [2,3,1,4,5]))
# 2
print( buscar_numero_en(1, [2,6,3,4,5]))
# -1
```
La sentencia **pass** no hace nada, se puede usar cuando una sentencia es requerida
por la sintáxis, pero no se requiere ningúna acción, ej.
```python
# Espera hasta una interrupción de teclado [Ctrl]+[C]
while True:
pass
```
Es usada normalmente para crear **clases** en su mínima expresión
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
class MyClaseVacia:
pass
```
2022-12-25 16:04:37 -03:00
Otro lugar donde se puede usar "pass" es como marca de para una función o un
cuerpo condicional (ej. en código nuevo), te permite pensar a un nivel de
abstracción mayor.
2022-12-24 22:41:20 -03:00
El pass se ignora silenciosamente:
```python
class initlog(*args):
pass # Recordar implementar esto!!!
```
```python
def a_function(x):
result = 0
if x > 0 and x < 5:
result = x ** 2
elif x >= 5 and x < 10:
pass
else:
result = (x ** 4) + 1
return result
print(a_function(2))
print(a_function(7))
print(a_function(12))
```
[1-4b_brake-else-continue.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-4b_brake-else-continue.py)
----
## Entorno Virtual
ej. **tutorial-env**
#### Crear Entorno Virtual
```bash
python3 -m venv tutorial-env
```
#### Activar Entorno Virtual
```bash
source tutorial-env/bin/activate
```
#### Acceder a la consola de Python en el entorno virtual
```bash
(tutorial-env) python
Python 3.8.2 (default, Apr 27 2020, 15:53:34)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
import sys
sys.path
['',
'/usr/lib/python38.zip', '/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/Coursera1/modulo4/tutorial-env/lib/python3.8/site-packages'
]
```
[1-4c_entorno_virtual.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-4c_entorno_virtual.py)
----
### import
```python
import sentencia_break
sentencia_break.buscar_numero_en(1, [3,2,1,0])
# 2
```
```python
from sentencia_break import buscar_numero_en
buscar_numero_en(1, [3,5,2,1,6])
# 3
```
```python
from sentencia_break import buscar_numero_en as bn
bn(1, [5,7,9,3,9,1,0])
# 5
```
Crear archivo **` __init__.py `** en carpeta modulo4, acceder a la consola
de python un nivel mas arriba en el árbol de directorios.
```python
import modulo4
from modulo4 import sentencia_break
from modulo4.sentencia_break import buscar_numero_en as bn
bn(4,[0,1,2,3,4,5,6])
# 4
```
2022-12-25 16:04:37 -03:00
Python tiene una manera de poner definiciones en un archivo y usarlos en un
script o en una instancia interactiva del intérprete.
Tal archivo es llamado módulo, las definiciones de un módulo pueden ser
importadas a otros módulos o al módulo principal.
Un módulo contiene definiciones y declaraciones de Python, el nombre del
archivo es ***modulo***.py
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
**` __name__ `** : variable global que contiene el nombre del modulo.
Usando módulo de ejemplo creado como ***[fibo.py](#modulo-fibo)***
2022-12-24 22:41:20 -03:00
Consola python: `python -i`
```python
>>> import fibo
>>>
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib(100)
1 1 2 3 5 8 13 21 34 55 89
>>> fibo.__name__
'fibo'
>>> # Se puede usar un variable local asignandole la funcion
>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
```
Cada módulo tiene su propio espacio de nombres usado de forma global por todas
las funciones definidas en el módulo.
Se pueden modificar las variables globales de un módulo **`nombre_modulo.nombre_item`**.
Los módulos pueden importar otros módulos.
Una variante de la declaración import que importa los nombres de un módulo
directamente al espacio de nombres del módulo que hace la importación.
```python
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
```
Variante para importar todos los nombres que un módulo define:
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
```
La práctica de importar **` * `** de un módulo o paquete es mal vista. Ya que, frecuentemente
genera un código poco legible. Sin embargo, está bien usarlo en sesiones interactivas.
#### Recargar modulo:
```python
import importlib
importlib.reload(modulename)
```
#### Ejecutando módulos como scripts
```bash
python fibo.py <argumentos>
```
El codigo en el módulo es ejecutado como si fuese importado producto de : **`__name__ = "__main__"`**.
Si agregamos al final del modulo [fibo.py](#modulo-fibo)
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
```
en terminal:
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```bash
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
```
2022-12-25 16:04:37 -03:00
Si el módulo se importa ese código no se ejecuta:
2022-12-24 22:41:20 -03:00
```
>>> import fibo
>>>
```
Importar módulos individuales
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
import sound.effects.echo
# uso
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4){1}
```
Otra alternativa para importar el submódulos es:
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
from sound.effects import echo
# uso
echo.echofilter(input, output, delay=0.7, atten=4
```
[1-4d_import_modulos_paquetes.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-4d_import_modulos_paquetes.py)
----
## Modulo fibo
Modulo para obtener los números de fibonacci
***./fibo.py***
```python
def fib(n): # escribe la serie Fibonacci hasta n
a, b = 0, 1
while b < n:
print(b, end=' ')
a, b = b, a+b
print()
def fib2(n): # devuelve la serie Fibonacci hasta n
resultado = []
a, b = 0, 1
while b < n:
resultado.append(b)
a, b = b, a+b
return resultado
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
```
[fibo.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/fibo.py)
----
## Iteradores
2022-12-25 16:04:37 -03:00
Tipos de datos que pueden ser recorridos secuencialmente mediante el uso del ciclo for.
Los objetos iterables dében responder los mensajes: **`__iter__`** y **`__next__`**
2022-12-24 22:41:20 -03:00
- **` __iter__ `** : retorna un objeto iterador.
- **` __next__ `** : retorna el próximo elemento de la secuencia.
ej:
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
lista = [1, 2, 3, 4, 5]
for elemento in lista:
print('\t ',elemento, end=' ')
# 1 2 3 4 5
```
2022-12-25 16:04:37 -03:00
**`for`** llama a la función **`iter()`** de la **`lista`** (objeto iterable)
y recibe un elemento definido por **`__next__`**.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Cuando no hay mas elementos __next__ levanta una excepción del tipo
**Stoplteration** que notifica al ciclo for que debe finalizar.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Conociendo el uso interno del ciclo for podemos crear iteradores propios.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
**`__next__`** : debe contiener la lógica de como acceder al siguiente elemento
de la secuencia.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
**`__iter__`** y **`__next__`** : y todos aquellos metodos que comienzan y
terminan con **doble guión** bajo, su proposito es ser invocado por Python
internamente, en este ejemplo por el ciclo for.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
Ejemplo de un iterador que recorre elementos de una lista en sentido inverso.
2022-12-24 22:41:20 -03:00
```python
class Reversa:
"""
Iterador inverso.
"""
def __init__(self, datos):
self.datos = datos
self. indice = len(datos)
def __iter__(self):
return self
def __next__(self):
if self.indice == 0:
raise StopIteration()
self.indice -= 1
return self.datos[self.indice]
for elemento in Reversa([1, 2, 3, 4]):
print(elemento, end=' ')
```
`python -v`
```python
>>> lista = [1, 2, 3]
>>> it = iter(lista)
>>> it
<list_iterator object at 0x7fce335ce610>
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>>next(it)
Traceback (most recent call last):
File "/usr/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
StopIteration
```
```python
class Iterator:
"""
Iterador, retorna elementos de
posiciones pares de una lista
"""
def __init__(self, data):
self.data = data
self.indice = 0
def __iter__(self):
return self
def __next__(self):
if self.indice >= len(self.data):
raise StopIteration()
elem = self.data[self.indice]
self.indice += 2
return elem
it = Iterator([1, 2, 3, 4, 5, 6])
for e in it:
print('\t', e)
# 1
# 3
# 5
```
[1-4e_iteradores.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-4e_iteradores.py)
----
## Debugger
```python
import pdb
```
#### Breakpoint en la linea donde se requiera:
```python
pdb.set_trace()
```
#### Comandos para tomar control de la ejecución
|Comando|Detalle|
|-|-|
|h(elp)|Muestra la ayuda de todos los comandos que provee pdb.|
|s(tep)|Ejecuta la línea actual, si hay una llamada de función se mete dentro del código <br> de la función para poder seguir la ejecución de la misma.|
|n(ext)|Continúa la ejecución hastala próxima línea.|
|r(eturn)|Continúa la ejecución hasta el return de la función actual.|
|c(ontinue)|Continúa la ejecución hasta el próximo breakpoint o hasta el fin del programa.|
|l(ist)|Muestra el código del archivo actual.|
|p|Evalúa la expresión pasada como parámetro, en el contexto actual e imprime su valor.|
|q(uit)|Sale del depurador. El programa es abortado.|
### Ayuda del debugger
```
> (Pdb) h
Documented commands (type help <topic>):
========================================
EOF c d h list q rv undisplay
a cl debug help ll quit s unt
alias clear disable ignore longlist r source until
args commands display interact n restart step up
b condition down j next return tbreak w
break cont enable jump p retval u whatis
bt continue exit l pp run unalias where
Miscellaneous help topics:
==========================
exec pdb
```
ej. breakpoint **`pdb.set_trace()`**
2022-12-25 16:04:37 -03:00
2022-12-24 22:41:20 -03:00
```python
pdb.set_trace() # <-- Breakpoint
def a_function(a_number):
"""
La función recibe un número @a_number y:
Si es par:
Si es múltiplo de 10:
devuelve el número dividido en 2
Si es múltiplo de 8:
devuelve el número dividido en 4
si es otro resta 1
Si es impar:
Si es múltiplo de 3:
devuelve el número multiplicado por 11
Si es múltiplo de 7:
devuelve el número multiplicado por 23
si es otro suma 1
"""
pdb.set_trace() # <-- Breakpoint
result = None
if a_number %2 == 0:
if a_number % 10 == 0:
result = a_number / 2
elif a_number % 8 == 0:
result = a_number - 1
else:
result = a_number -1
else:
if a_number % 3 == 0:
result = a_number * 11
elif a_number % 7 == 0:
result = a_number * 23
else:
result = a_number + 1
return result
result_1 = a_function(20)
print(result_1)
print('END')
```
[1-4f_debugger.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-4f_debugger.py)
----
## Ejercicios
### Actividad 1
En la consola interactiva de Python o en un script de Python,
escribir un programa para resolver el siguiente problema:
¿Cuál es el resultado de sumar los primeros 50 números pares?
(Desde el 2 inclusive hasta el 100 inclusive)
```python
def eval():
"""
Imprime la suma de los primeros 50 pares de 2 a 100
"""
var = 0
for i in range(2,101):
if i % 2 == 0:
var += i
print(var)
eval()
# 2550
```
[1-4g_actividad_evaluada.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-4g_actividad_evaluada.py)
----
### Actividad Dados
#### Requerimientos
2022-12-25 16:04:37 -03:00
Crear un programa que simule la tirada de dados.
Cada vez que ejecutamos el programa, éste elegirá dos números aleatorios
entre el 1 y el 6.
2022-12-24 22:41:20 -03:00
2022-12-25 16:04:37 -03:00
El programa deberá imprimirlos en pantalla, imprimir su suma y preguntarle
al usuario si quiere tirar los dados otra vez.
2022-12-24 22:41:20 -03:00
```python
from random import random # importe de la función random() del modulo random
def tirar_dados():
"""Retorna una lista de 3 enteros [dado1, dado2, dado1 + dado2]"""
# llamado a random.random() y se define un "rango"
dado1 = int((random() * 10) % 6 + 1)
dado2 = int((random() * 10) % 6 + 1)
suma_dados = dado1 + dado2
return [dado1, dado2, suma_dados]
# Variable usada para indicar el término de la ejecución
continuar = True
while continuar:
# Asignación de la lista retornada por la función tirar_dados()
dados = tirar_dados()
# Formateo de texto según valores en la lista dados[]
print('''
Lanzando dados!
dado 1 -> [{0}]
dado 2 -> [{1}]
---------------
TOTAL --> [{2}]
'''.format(dados[0], dados[1], dados[2]))
# Pregunta y asignación, simula un "si por defecto"
respuesta = input('¿Tirar dados nuevamente? [SI/no]: ').upper()
# Lista de posibles respuestas de usuario para finalizar el programa
if respuesta in 'NO':
# Indica el fin del ciclo while y finaliza el programa.
continuar = False
quit()
```
[1-5_evaluacion_dados.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-5_evaluacion_dados.py)