2015 lines
41 KiB
Markdown
2015 lines
41 KiB
Markdown
**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
|
|
|
|
# shift + Enter para terminar de ingresar el ciclo while
|
|
# en consola, o agregar otra linea con Enter.
|
|
```
|
|
|
|
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
|
|
```
|
|
|
|
Además de **int** y **float**, Python soporta otros como **Decimal** y **Fraction**, además
|
|
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'**
|
|
```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]
|
|
x
|
|
x[0]
|
|
x[0][1]
|
|
```
|
|
|
|
[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**:
|
|
* ` 1 + 1 ` : Expresión que combina **dos valores** y **un operador**.
|
|
|
|
* ` numero + 1 ` : Expresión que combina **una variable**, **un valor** y **un operador**.
|
|
|
|
|
|
### 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
|
|
|
|
|Op1|Op2|Resultado
|
|
|-|-|-|
|
|
| True | True | True |
|
|
| True | False | False |
|
|
| False | True | False |
|
|
| False | False | False |
|
|
|
|
#### or
|
|
|
|
|Op1|Op2|Resultado
|
|
|-|-|-|
|
|
| True | True | True |
|
|
| True | False | True |
|
|
| False | True | True |
|
|
| False | False | False |
|
|
|
|
#### not
|
|
|
|
|Op|Resultado
|
|
|-|-|
|
|
| True |False|
|
|
| False|True |
|
|
|
|
### 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
|
|
|
|
Forma parte de la libreria estandar de python
|
|
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
|
|
def cero():
|
|
return 0
|
|
|
|
cero() # 0
|
|
cero() + 1 # 1
|
|
c = cero()
|
|
c # 0
|
|
```
|
|
|
|
```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**:
|
|
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**.
|
|
|
|
```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))
|
|
```
|
|
|
|
#### Función que rercibe entrada de usuario
|
|
|
|
```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
|
|
```
|
|
|
|
Los valores por omisión son evaluados en el momento de la definición de la función,
|
|
en el ámbito de la definición, entonces:
|
|
```python
|
|
i = 5
|
|
|
|
def f(arg=i):
|
|
print(arg)
|
|
|
|
i = 6
|
|
|
|
f()
|
|
# 5
|
|
|
|
f(6)
|
|
# 6
|
|
|
|
f()
|
|
#5
|
|
```
|
|
|
|
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:
|
|
```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]
|
|
```
|
|
|
|
|
|
Si no se quiere que el valor por omisión sea compartido entre subsiguientes llamadas,
|
|
la función se puede escribir así:
|
|
```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]
|
|
```
|
|
|
|
|
|
#### Palabras clave como argumentos
|
|
|
|
Las funciones también puede ser llamadas usando argumentos de palabras clave
|
|
(o **argumentos nombrados**) de la forma `keyword = value`. Por ejemplo:
|
|
|
|
```python
|
|
def loro(tension, estado='muerto', accion='explotar', tipo='Azul Nordico'):
|
|
print("-- Este loro no va a", accion, end=' ')
|
|
print("si le aplicas", tension, "voltios.")
|
|
print("-- Gran plumaje tiene el", tipo)
|
|
print("-- Está", estado,"!")
|
|
```
|
|
|
|
- 1 argumento posicional
|
|
```python
|
|
loro(1000)
|
|
# -- Este loro no va a explotar si le aplicas 1000 voltios.
|
|
# -- Gran plumaje tiene el Azul Nordico
|
|
# -- Está muerto !
|
|
```
|
|
|
|
- 1 argumento nombrado
|
|
```python
|
|
loro(tension=1000)
|
|
# -- Este loro no va a explotar si le aplicas 1000 voltios.
|
|
# -- Gran plumaje tiene el Azul Nordico
|
|
# -- Está muerto !
|
|
```
|
|
|
|
- 2 argumentos nombrados
|
|
```python
|
|
loro(tension=1000000, accion='VOOOOM')
|
|
# -- Este loro no va a VOOOOM si le aplicas 1000000 voltios.
|
|
# -- Gran plumaje tiene el Azul Nordico
|
|
# -- Está muerto !
|
|
```
|
|
|
|
- 2 argumentos nombrados
|
|
```python
|
|
loro(accion='VOOOOM', tension=1000000)
|
|
# -- Este loro no va a VOOOOM si le aplicas 1000000 voltios.
|
|
# -- Gran plumaje tiene el Azul Nordico
|
|
# -- 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.
|
|
# -- Gran plumaje tiene el Azul Nordico
|
|
# -- Está despojado de vida !
|
|
```
|
|
|
|
- 1 arg. posicional y 1 nombrado.
|
|
```python
|
|
loro('mil', estado='viendo crecer las flores desde abajo')
|
|
# -- Este loro no va a explotar si le aplicas mil voltios.
|
|
# -- Gran plumaje tiene el Azul Nordico
|
|
# -- 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
|
|
```
|
|
|
|
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.
|
|
|
|
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 `**.
|
|
|
|
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.
|
|
Antes del número variable de argumentos, cero o más argumentos normales
|
|
pueden estar presentes.
|
|
|
|
```python
|
|
def muchos_items(archivo, separador, *args):
|
|
archivo.write(separador.join(args))
|
|
```
|
|
|
|
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.
|
|
```python
|
|
concatenar("tierra", "marte", "venus")
|
|
# 'tierra/marte/venus'
|
|
|
|
concatenar("tierra", "marte", "venus", sep=" @ ")
|
|
# 'tierra @ marte @ venus'
|
|
```
|
|
|
|
#### Desempaquetando una lista de argumentos
|
|
|
|
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.
|
|
|
|
También se puede llamar a la función con el operador para desempaquetar argumentos
|
|
de una lista o tulpa **`*`**
|
|
|
|
```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
|
|
```
|
|
|
|
Las funciones Lambda pueden ser usadas en cualquier lugar donde sea requerido
|
|
un objeto de tipo función.
|
|
|
|
Están sintácticamente restringidas a una sola expresión.
|
|
|
|
Semánticamente, son solo azúcar sintáctica para definiciones normales de funciones.
|
|
|
|
Al igual que las funciones anidadas, las funciones lambda pueden hacer referencia a
|
|
variables desde el ámbito que la contiene.
|
|
|
|
```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**
|
|
```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**
|
|
|
|
Se almacenan en el atributo ***__annotations__*** de la función como un
|
|
diccionario y no tienen efecto enninguna otra parte de la función.
|
|
|
|
Las anotaciones de los parámetros se definen luego de dos puntos
|
|
después del nombre delparámetro, seguido de una expresión que evalúa
|
|
al valor de la anotación.
|
|
|
|
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 `**.
|
|
|
|
El siguiente ejemplo tiene **un argumento posicional, uno nombrado, y el valor de retorno anotado**.
|
|
|
|
```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
|
|
Consola python: `python -i`
|
|
```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
|
|
```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
|
|
```python
|
|
class MyClaseVacia:
|
|
pass
|
|
```
|
|
|
|
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.
|
|
|
|
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
|
|
```
|
|
|
|
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
|
|
|
|
**` __name__ `** : variable global que contiene el nombre del modulo
|
|
|
|
Usando módulo de ejemplo creado como ***[fibo.py](#modulo-fibo)***
|
|
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:
|
|
```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)
|
|
```python
|
|
if __name__ == "__main__":
|
|
import sys
|
|
fib(int(sys.argv[1]))
|
|
```
|
|
|
|
en terminal:
|
|
```bash
|
|
$ python fibo.py 50
|
|
1 1 2 3 5 8 13 21 34
|
|
```
|
|
|
|
Si el módulo se importa, ese código no se ejecuta:
|
|
```
|
|
>>> import fibo
|
|
>>>
|
|
```
|
|
|
|
Importar módulos individuales
|
|
```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:
|
|
```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
|
|
|
|
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__`**
|
|
- **` __iter__ `** : retorna un objeto iterador.
|
|
- **` __next__ `** : retorna el próximo elemento de la secuencia.
|
|
|
|
ej:
|
|
```python
|
|
lista = [1, 2, 3, 4, 5]
|
|
|
|
for elemento in lista:
|
|
print('\t ',elemento, end=' ')
|
|
|
|
# 1 2 3 4 5
|
|
```
|
|
|
|
**`for`** llama a la función **`iter()`** de la **`lista`** (objeto iterable) y recibe un
|
|
elemento definido por **`__next__`**.
|
|
|
|
Cuando no hay mas elementos __next__ levanta una excepción del tipo **Stoplteration**
|
|
que notifica al ciclo for que debe finalizar.
|
|
|
|
Conociendo el uso interno del ciclo for podemos crear iteradores propios.
|
|
|
|
**`__next__`** : debe contiener la lógica de como acceder al siguiente elemento de la secuencia.
|
|
|
|
**`__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.
|
|
|
|
Ejemplo de un iterador que recorre elementos de una lista en sentido inverso
|
|
|
|
```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()`**
|
|
```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
|
|
|
|
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.
|
|
|
|
El programa deberá imprimirlos en pantalla, imprimir su suma y preguntarle al usuario si
|
|
quiere tirar los dados otra vez.
|
|
```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)
|