mejora markdown REAMDE Curso Modulo 1

This commit is contained in:
devfzn 2022-12-25 16:04:37 -03:00
parent b41be38b22
commit 8edb6f019a

View File

@ -48,9 +48,6 @@ 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
@ -115,15 +112,15 @@ round(8.6786346, 1)
# 8.7
```
Además de **int** y **float**, Python soporta otros como **Decimal** y **Fraction**, además
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')
@ -216,9 +213,10 @@ len(letras)
a = ['a', 'b', 'c']
n = [1, 2, 3]
x = [a, n]
x
x[0]
x[0][1]
x # [['a', 'b', 'c'], [1, 2, 3]]
x[0] # ['a', 'b', 'c']
x[0][1] # 'b'
```
[1-1_primeros_pasos.py](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/01_curso/Modulo_1/1-1_primeros_pasos.py)
@ -266,10 +264,9 @@ Consola python: `python -i`
```
**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**.
* ` 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:
@ -299,28 +296,28 @@ Ejemplos operadores de comparación
#### and
|Op1|Op2|Resultado
|-|-|-|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
|Var. A|Op.|Var. B|Resultado
|-|-|-|-|
| `True` | **and** | `True` | True |
| `True` | **and** | `False` | False |
| `False` | **and** | `True` | False |
| `False` | **and** | `False` | False |
#### or
|Op1|Op2|Resultado
|-|-|-|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
|Var. A|Op.|Var. B|Resultado
|-|-|-|-|
| True | **or** | True | True |
| True | **or** | False | True |
| False | **or** | True | True |
| False | **or** | False | False |
#### not
|Op|Resultado
|-|-|
| True |False|
| False|True |
| Op. | Var. | Resultado |
|-|-|-|
| **not** | True | False |
| **not** | False | True |
### Precedencia de operadores
@ -396,7 +393,7 @@ Consola de python: `python -i`
## Modulo Random
Forma parte de la libreria estandar de python
Forma parte de la libreria estandar de python
Consola de python: `python -i`
```python
@ -625,13 +622,13 @@ else:
ej.
```python
def cero():
return 0
def cero():
return 0
cero() # 0
cero() + 1 # 1
c = cero()
c # 0
cero() # 0
cero() + 1 # 1
c = cero()
c # 0
```
```python
@ -754,8 +751,8 @@ fibo(2000)
```
- **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**.
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
@ -805,7 +802,7 @@ def fibo(n):
print(fibo(35))
```
#### Función que rercibe entrada de usuario
#### Función que recibe entrada de usuario
```python
def pedir_confirmacion(prompt, reintentos=4, msj='Intenta nuevamente'):
@ -847,9 +844,10 @@ def pedir_confirmacion(prompt, reintentos=4, msj='Intenta nuevamente'):
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,
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
@ -868,10 +866,12 @@ 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.
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:
La siguiente función acumula los argumentos que se le pasan en subsiguientes llamadas:
```python
def f(a, L=[]):
L.append(a)
@ -882,9 +882,9 @@ 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í:
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:
@ -904,18 +904,14 @@ print(f(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'):
def loro(tension, estado='muerto', accion='explotar', color='Azul Nordico'):
print("-- Este loro no va a", accion, end=' ')
print("si le aplicas", tension, "voltios.")
print("-- Gran plumaje tiene el", tipo)
print("-- Hermoso plumaje", color)
print("-- Está", estado,"!")
```
@ -923,7 +919,7 @@ def loro(tension, estado='muerto', accion='explotar', tipo='Azul Nordico'):
```python
loro(1000)
# -- Este loro no va a explotar si le aplicas 1000 voltios.
# -- Gran plumaje tiene el Azul Nordico
# -- Hermoso plumaje Azul Nordico
# -- Está muerto !
```
@ -931,23 +927,23 @@ def loro(tension, estado='muerto', accion='explotar', tipo='Azul Nordico'):
```python
loro(tension=1000)
# -- Este loro no va a explotar si le aplicas 1000 voltios.
# -- Gran plumaje tiene el Azul Nordico
# -- Hermoso plumaje 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
loro(tension=1000000, accion='volar')
# -- Este loro no va a volar si le aplicas 1000000 voltios.
# -- Hermoso plumaje 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
loro(accion='volar', tension=1000000)
# -- Este loro no va a volar si le aplicas 1000000 voltios.
# -- Hermoso plumaje Azul Nordico
# -- Está muerto !
```
@ -955,15 +951,16 @@ def loro(tension, estado='muerto', accion='explotar', tipo='Azul Nordico'):
```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
# -- Hermoso plumaje 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
# -- Hermoso plumaje Azul Nordico
# -- Está viendo crecer las flores desde abajo !
```
@ -983,13 +980,13 @@ 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.
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 `**.
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:
@ -1025,19 +1022,21 @@ ventadequeso("Limburger", "Es muy liquido, sr.",
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.
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.
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.
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'
@ -1048,12 +1047,13 @@ concatenar("tierra", "marte", "venus", sep=" @ ")
#### 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.
Cuando los argumentos ya pertences a una lista o tupla, se pueden desempaquetar
para llamar una funcion que requiere argumetnoss posicionaes separados.
También se puede llamar a la función con el operador para desempaquetar argumentos
de una lista o tulpa **`*`**
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
@ -1066,7 +1066,6 @@ list (range(*args))
# [3, 4, 5]
```
Los **diccionarios** pueden entregar argumentos nombrados con el operador ` ** `
```python
@ -1093,15 +1092,16 @@ Funciones anónimas, pequeñas son creadas con **lambda**.
lambda a, b: a + b
```
Las funciones Lambda pueden ser usadas en cualquier lugar donde sea requerido
un objeto de tipo función.
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.
Están sintácticamente restringidas a una sola expresión.
Semánticamente, son solo azúcar sintáctica para definiciones normales de funciones.
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.
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):
@ -1149,6 +1149,7 @@ f(5) = 6
## Docstrings
### Ejemplo de un **docstring multi-línea**
```python
def mi_funcion():
"""Esta funcion solo muestra documentacion.
@ -1165,17 +1166,19 @@ print(mi_funcion.__doc__)
**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.
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 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.
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 `**.
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**.
El siguiente ejemplo tiene **un argumento posicional, uno nombrado, y el valor
de retorno anotado**.
```python
def f(jamon: str, huevos: str = 'huevos') -> str:
@ -1223,7 +1226,9 @@ print([1,2,3,4,5])
```
### if
Consola python: `python -i`
```python
x = int(input("Ingresa un entero: "))
@ -1247,6 +1252,7 @@ else:
### for
Midiendo cadenas de texto
```python
palabras = ['gato','ventana','defenestrado']
@ -1486,13 +1492,15 @@ while True:
```
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.
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:
@ -1593,18 +1601,19 @@ 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
Python tiene una manera de poner definiciones en un archivo y usarlos en un
script o en una instancia interactiva del intérprete.
**` __name__ `** : variable global que contiene el nombre del modulo
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)***
Usando módulo de ejemplo creado como ***[fibo.py](#modulo-fibo)***
Consola python: `python -i`
```python
@ -1639,6 +1648,7 @@ directamente al espacio de nombres del módulo que hace la importación.
```
Variante para importar todos los nombres que un módulo define:
```python
>>> from fibo import *
>>> fib(500)
@ -1664,6 +1674,7 @@ 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
@ -1671,18 +1682,21 @@ if __name__ == "__main__":
```
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:
Si el módulo se importa ese código no se ejecuta:
```
>>> import fibo
>>>
```
Importar módulos individuales
```python
import sound.effects.echo
@ -1691,6 +1705,7 @@ 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
@ -1733,13 +1748,15 @@ if __name__ == "__main__":
## Iteradores
Tipos de datos que pueden ser recorridos secuencialmente mediante el uso del ciclo for.
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__`**
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]
@ -1749,21 +1766,22 @@ for elemento in lista:
# 1 2 3 4 5
```
**`for`** llama a la función **`iter()`** de la **`lista`** (objeto iterable) y recibe un
elemento definido por **`__next__`**.
**`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.
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.
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.
**`__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.
**`__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
Ejemplo de un iterador que recorre elementos de una lista en sentido inverso.
```python
class Reversa:
@ -1890,6 +1908,7 @@ pdb.set_trace()
```
ej. breakpoint **`pdb.set_trace()`**
```python
pdb.set_trace() # <-- Breakpoint
def a_function(a_number):
@ -1969,12 +1988,14 @@ eval()
#### Requerimientos
Crear un programa que simule la tirada de dados.
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.
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.
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