Python para desarrolladores
Funciones conocidas
# Printing
print(“Texto”)
# Check data type
type(print)
# range (El primer valor es literal, el segundo cuenta hasta uno menos del indicado)
for attempt in range (1, 4): # esto es un bucle for
print (“Attempe”, attempt) # Está indentado para que Python sepa que depende de lo anterior
# max() and min() → máximo y mínimo valor
preparation_times = [19.23, 15.67, 48.56, 23.45, 12.06, 34.56, 45.67] # esto es una lista
print(max(preparation_times))
print(min(preparation_times))
# sum() and round() → suma y redondeo
print(sum(preparation_times)) # => 199.21
total_time = sum(preparation_times) #declaración de variable y asignación del valor de la suma
print(round(total_time, 1)) #esto redondea el valor anterior a 199.2 – El segundo número indica el
número de decimales
# len() → cuenta el número de elementos
print(len(preparation_times)) # => 7
print(sum(preparation_times) / len(preparation_times)) # => Calcula el tiempo medio
print(len(“burger hub”)) # => 10 → Cuenta el número de elementos en un string, incluidos los
espacios
# sorted() → Ordena una lista ascendentemente, string o numerico
print(sorted(preparation_times))
# ------
Modulos “Modules”
ficheros teminados en “.py”
Más de 200 módulos incluidos (ver documentación)
Los más habituales:
• os: Interactuar con el Sistema operativo, comprobar el directorio, ficheros disponibles,
variables de entorno
• string: simplifica las tareas de procesado de textos
Importar módulo “os”
import <nombre> → import os
Funciones de un módulo
¿Qué contiene un módulo? Ver documentación o help(): print(help(os))
Hacen tareas.
Directorio actual: print([Link]())
Podemos asignarlo a una variable: work_dir = [Link]()
Cambiar directorio: [Link](“/home/courses”)
Atributos
Devuelven valores, no se usan parentesis
print([Link])
Importar módulo “string”
import string
Funciones del módulo
Tiene funciones para comprobar si un strig tiene letras, números, caracteres específicos
print(string.ascii_lowercase) → letras minúsculas
print([Link]) → números del 0 al 9
print([Link]) → caracteres especiales
Muy útil para comprobar si un string tiene los caracteres requeridos, como puede ser una contraseña
fuerte
Paquetes “Packages”
Como los módulos son ficheros “.py” muchos desarrolladores han creado sus propios módulos, o
colecciones de módulos llamados “package” o “library”. Para usarlos hay que descargarlos del
índice de paquetes de Pyton, conocido como PyPI. Para importarlos igual que los módulos.
Tras descargarlos hay que instalarlos a través de la terminal con la instrucción:
python3 -m pip instal <package_name>
python3 → Ejecuta Python desde la terminal
pip → se refiere al instalador
Un paquete conocido y habitual es “pandas” para manipulación y análisis de datos.
Primero lo instalamos:
python3 -m pip install pandas
Despues lo importamos:
import pandas
Es habitual usar un alias al importar un paquete para acorar el código:
import pandas as pd
ejemplo de uso:
sales = {“user_id”: [“KM37”, “PR19”, “YU88”],
“order_value”: [197.75, 208.21, 134.99]} # Tenemos un set de tipo matriz
sales_df = [Link](sales) #convertimos el set en una tabla con DataFrame
print(sales_df) #imprimimos y nos muestra la información del set en formato tabla
Leer csv
sales_df = pd.read_csv(“[Link]”)
Previsualización de los primeros datos
print(sales_df.head())
Comprobar la información del ficheros
print(sales_df.info() )
Funciones vs metodos
Una función es código para hacer una tarea (Ej.: sum(), [Link]()...)
Un método es una función que es específica para un tipo de dato (Ej.: head())
Funciones personalizadas
Si vamos a repetir muchas veces el mismo código complejo, es mejor hacer una función
personalizada, recordando el principio DRY (Don’t Repeat Yourself)
# Create a custom function
def average(values): # → values es un argumento
# Calculate the average
average_value = sum(values) / len(values)
# Round the results
rounded_average = round(average_value, 2)
# Return value
return rounded_ average
Las variables creadas dentro de una función, sólo están disponibles en esa función.
Uso de la función personalizada:
print(average(preparation_times)) # → 28.46
print(average(orders)) # → 12.86
average_time = average(preparation_times)
print(average_time) # → 28.46
Tipos de argumentos
• Positional: argumentos en orden separados por una coma:
Ej.: print(round(3.1415926535, 2)) # → 3.14
• Keyword: tenemos que definir cada argumento con su nombre:
Ej.: print(round(number=3.1415926535, ndigits=2)) # → 3.14
Cuando pasamos las palabras clave debemos usar el nombre de los argumentos, este nombre se
obtiene con la función help(): print(help(round)). Aquí vemos que “ndigits” tiene como valor por
defecto “None”, que en Pyton significa sin valor o vacío, por lo que si no se le añade ese argumento
devolverá un número entero, sin decimales.
Vamos a cambiar la función personalizada anterior:
# Create a custom function
def average(values, rounded=False): # → Argumentos: values y rounded, por defecto Falso
# Round average to two decimal places if rounded is True
if rounded == True:
average_value = sum(values) / len(values)
rounded_average = round(average_value, 2)
return rounded_ average
# Otherwise, don’t round
else:
average_value = sum(values) / len(values)
return average_value
Como usarla:
print(average(preparation_times, False)) # → 28.4585714
print(average(preparation_times)) # → 28.4585714
print(average(preparation_times, rounded=True)) # → 28.46
Docstring
Es la cadena de de documentación que se muestra cuando llamamos a help(<funcion>)
Si sólo queremos la documentación, y no la información de la propia función la llamamos así:
print(round.__doc__)
Esto se llama “dunder-doc”.
Podemos agregar una docstring al crear una función personalizada, para ello usamos triples comillas
“””texto””” después de definir la función, indentándolo, como es lógico. Ej.:
def average(values):
# one-line docstring
“””Find the mean in a squence of values and round to two decimal places.”””
Al ser un atributo de una función se puede modificar: average.__doc__ = “Nuevo docstring”
Podemos crear un docstring con varias líneas:
def average(values):
# one-line docstring
“””
Find the mean in a squence of values and round to two decimal places.
Args:
Values (list): A list of numeric values.
Returns:
rounded_average (float): The mean of values, rounded to two decimal places.
”””
Arbitrary Arguments
Nuestra función «Average» sólo acepta una lista, por lo que si se le pasa un diccionario o una serie
de valores individuales nos dará error. Para prevenir esto podemos usar los «Arbitrary arguments»,
de tal forma que la función acepte más tipos de valores.
Para ello cambiaríamos la definición de la función por esta otra:
def average(*args):
Se pone un «*» delante de un sólo argumento, que por convenio se llama «args». Lo que ocurre
cuando ponemos el «*» es que le estamos diciendo a Python que considere los argumentos que
reciba como una «tupla». Si le estamos pasando varios argumentos se puede poner el «*» en cada
uno de ellos para que los trate la misma forma.
También se pueden usar «Arbitrary keyword» arguments usando «**», esta estructura recibe el
nombre de kwargs, que es la palabra que se usa por convenio.
Si queremos que nuestra función acepte diccionarios, la tenemos que cambiar de esta forma:
def average(**kwargs):
average_value = sum([Link]()) / len([Link]())
rounded_average = round(average_value, 2)
return rounded_ average
También le podemos pasar una lista de atributos, pero en este caso debemos ponerle un nombre:
# Calling average with six kwargs
print(average(a=15, b=29, c=4, d=13, e=11, f=8))
También se puede llamar con un único argumento como si fuera un diccionario:
# Calling average with one kwarg
print(average(**{“a”:15, “b”:29, “c”:4, “d”:13, “e”:11, “f”:8}))
También se pueden usar los «**» delante de varios kwargs:
print(average(**{“a”:15, “b”:29}, **{“c”:4, “d”:13}, **{“e”:11, “f”:8}))
Lambda Functions
Las funciones personalizadas pueden requerir mucho código, para optimizar se usan las funciones
lambda que son funciones anónimas que no necesitan ser guardadas como una variable:
lambda arguments: expresion
Por convenio, se usa «x» para un sólo argumento, la expresión sería el cuerpo de la función y no
necesita un «return»ya que está implícito. Un ejemplo para calcular la media sería:
(lambda x: sum(x) / len(x))([3, 6, 9])
print((lambda x: sum(x) / len(x))([3, 6, 9])) # → 6
Si queremos usar una función lambda más de una vez la podemos guardar en una variable:
average = lambda x: sum(x) / len(x)
Ahora podemos llamar a la función pasándole los atributos:
print(average([3, 6, 9])) # → 6
Podemos extender las funciones lambda de varias maneras.
Podemos pasarles más de un parámetro:
power = lambda x, y: x**y
print(power(2,3)) # → 8
Podemos usar las funciones lambda en funciones iterables, como una lista, para ello debemos
hacerlo dentro de la función «map()»:
names = [“john”, “sally”, “leah”]
capitalize = map(lambda x: [Link](), names)
No podemos imprimir «capitalize» directamente ya que es un objeto, estemos trabajando con una
lista por lo que tenemos que convertirla en una estructura de datos:
print(list(capitalize)) # → [“John”, “Sally”, “Leah”]
¿Cuando usar funciones personalizadas o lambda?
Si la función es compleja o sí se va a realizar la misma tarea muchas veces es mejor usar una
función personalizada, pero si la tarea a realizar es simple o se va a realizar una única vez es mejor
usar una función lambda.
Introducción a errores
Código que infringe una regla, excepciones o errores, un error causa la finalización abrupta del
programa.
Tipos de datos incompatibles: cuando intentamos usar un tipo de dato incorrecto, la consola nos
muestra información sobre el error y su ubicación.
Cuando importamos paquetes externos, se llama código fuente y si se produce un error al ejecutar
una función de ese código fuente externo, o paquete, nos muestra mucha más información sobre el
error: nos indica el origen del paquete, indicándonos la fila del código fuente externo, no de nuestro
progrma, debajo nos da información sobre el tipo de error y su posible origen.
Error handling
Las palabras reservadas except y raise nos indican formas de prevenir errores.
Por ejemplo, nuestra función «average» se hizo esperando que se le pase un sólo argumento y que
este sea una lista o set, si el usuario le pasa más argumentos o un diccionario, nos daría error.
Para prevenir estos errores vamos a usar una estructura llamada «try-except»
def average(values):
try:
# Code that might cause an error
average_value = sum(values) / len(values)
return average_value
except:
# Code to run if an error occurs
print(“average() accepts a list or a set. Please provide a correct data type.”)
Otra forma de tratar con los errores es mediante la palabra reservada «raise», con la que le
indicaríamos a Python que genere una excepción:
def average(values):
# Check data type
if type(values) in (list, set):
# Run if appropiate data type was used
average_value = sum(values) / len(values)
return average_value
else:
rasise TypeError(“average() accepts a list or a set. Please provide...”)
El uso de una u otra forma de tratar los errores depende de cada caso.
«try-except» se usa cuando queremos evitar los errores y se ejecuta el resto del código, esto sólo es
posible si el código está dividido en secciones independientes.
«raise» producirá un error y cortará la ejecución del resto del código, evitando así que se pueda
obtener un resultado no deseado.
Introduction to iterators
Iteradores los podemos encontrar en los bucles y se pueden aplicar a una lista a un string.
Objetos iterables: Listas, strings, dictionaries, file connections. Cualquier objeto que tenga asociado
el método «iter()». Al aplicar el método «iter()» a un objeto iterable, obtenemos un iterador.
Un iterador es un objeto que tiene el métido «next()» para acceder al siguiente elemento asociado.
Iterating over iterables: next()
Todo lo que tenemos que hacer es usar la función «iter()» en un elemento y pasarle el iterable:
word = “Da”
it = iter(word)
Una vez creado el iterable, llamamos a la función «next()» y nos devuelve el siguiente valor:
next(it) # → “D”
next(it) # → “a”
Si ya no puede devolver valores nos dará un error de tipo “StopIteration”.
También puedes imprimir todos los valores de un iterador de una vez usando el operador estrella
«*», también conocido como splat:
word = “Data”
it = iter(word)
print(*it) # → D a t a
El operador estrella descomprime todos los elementos de un iterador o un iterable. Una vez hecho
ya no se podrá volver a hacer, dado que no hay más elementos, habría que redefinir el iterador.
También se puede iterar sobre diccionarios, para lo que tendremos que descomprimirlos:
pythonistas = {‘hugo’ : ‘bowne-anderson’, ‘francis’: ‘castro’}
for key, value in [Link]():
print(key, value)
# → francis castro
# → hugo bowne-anderson
También se puede iterar sobre conexiones a ficheros:
file = open(‘[Link]’)
it = iter(file)
print(next(it)) # → This is the first line of the file
print(next(it)) # → This is the second line of the file