diff --git a/01_curso/Modulo_1/README.md b/01_curso/Modulo_1/README.md index ece62db..046efb5 100644 --- a/01_curso/Modulo_1/README.md +++ b/01_curso/Modulo_1/README.md @@ -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 "", 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 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