Python: Comprehensions, Funciones y Manejo de Errores

26 minute read

Published:

Curso de Platzi donde se aprende conceptos como funciones, comprehensions, errores y manejo de archivos que elevarán tu nivel al programar.

Python: Comprehensions, Funciones y Manejo de Errores

Uso de Replit para ejecutar código de Python Online.

Zen de Python

import this
Los principios están listados a continuación:

    Bello es mejor que feo.
    Explícito es mejor que implícito.
    Simple es mejor que complejo.
    Complejo es mejor que complicado.
    Plano es mejor que anidado.
    Espaciado es mejor que denso.
    La legibilidad es importante.
    Los casos especiales no son lo suficientemente especiales como para romper las reglas.
    Sin embargo la practicidad le gana a la pureza.
    Los errores nunca deberían pasar silenciosamente.
    A menos que se silencien explícitamente.
    Frente a la ambigüedad, evitar la tentación de adivinar.
    Debería haber una, y preferiblemente solo una, manera obvia de hacerlo.
    A pesar de que eso no sea obvio al principio a menos que seas Holandés.
    Ahora es mejor que nunca.
    A pesar de que nunca es muchas veces mejor que *ahora* mismo.
    Si la implementación es difícil de explicar, es una mala idea.
    Si la implementación es fácil de explicar, puede que sea una buena idea.
    Los espacios de nombres son una gran idea, ¡tengamos más de esos!

Conjuntos

Conjuntos

Trabajando con conjuntos (Sets)

  • Se pueden modificar.
  • No tienen un orden.
  • No permite duplicados.
set_countries = {'col', 'mex', 'bol'}
print(set_countries)
print(type(set_countries))

set_numbers = {1, 2, 2, 443, 23}
print(set_numbers)

set_types = {1, 'hola', False, 12.12}
print(set_types)

set_from_string = set('hoola')
print(set_from_string)

set_from_tuples = set(('abc', 'cbv', 'as', 'abc'))
print(set_from_tuples)

numbers = [1,2,3,1,2,3,4]
set_numbers = set(numbers)
print(set_numbers)
unique_numbers = list(set_numbers)
print(unique_numbers)
{'col', 'bol', 'mex'}
<class 'set'>
{1, 2, 443, 23}
{False, 1, 'hola', 12.12}
{'h', 'a', 'o', 'l'}
{'as', 'cbv', 'abc'}
{1, 2, 3, 4}
[1, 2, 3, 4]

Modificando conjuntos

set_countries = {'col', 'mex', 'bol'}

size = len(set_countries)
print(size)

print('col' in set_countries)
print('pe' in set_countries)

# add
set_countries.add('pe')
print(set_countries)
set_countries.add('pe')
print(set_countries)

# update
set_countries.update({'ar', 'ecua', 'pe'})
print(set_countries)

# remove

set_countries.remove('col')
print(set_countries)

set_countries.remove('ar')
set_countries.discard('arg')
print(set_countries)
set_countries.add('arg')
print(set_countries)
set_countries.clear()
print(set_countries)
print(len(set_countries))
3
True
False
{'bol', 'col', 'pe', 'mex'}
{'bol', 'col', 'pe', 'mex'}
{'bol', 'col', 'ar', 'pe', 'ecua', 'mex'}
{'bol', 'ar', 'pe', 'ecua', 'mex'}
{'bol', 'pe', 'ecua', 'mex'}
{'bol', 'arg', 'pe', 'ecua', 'mex'}
set()
0

Operaciones con conjuntos

https://www.w3schools.com/python/python_ref_set.asp Set_oper

set_a = {'col', 'mex', 'bol'}
set_b = {'pe', 'bol'}

# Union
set_c = set_a.union(set_b)
print(set_c)
print(set_a | set_b)

# Intersection
set_c = set_a.intersection(set_b)
print(set_c)
print(set_a & set_b)

# Difference
set_c = set_a.difference(set_b)
print(set_c)
print(set_a - set_b)

# Symmetric Difference
set_c = set_a.symmetric_difference(set_b)
print(set_c)
print(set_a ^ set_b)
{'mex', 'bol', 'col', 'pe'}
{'mex', 'bol', 'col', 'pe'}
{'bol'}
{'bol'}
{'mex', 'col'}
{'mex', 'col'}
{'mex', 'col', 'pe'}
{'mex', 'col', 'pe'}

Test: Elimina elementos duplicados usando conjuntos

countries = {"MX", "COL", "ARG", "USA"}
northAm = {"USA", "CANADA"}
centralAm = {"MX", "GT", "BZ"}
southAm = {"COL", "BZ", "ARG"}

new_set = set()
# Escribe tu solución 👇
new_set = countries.union(northAm, centralAm, southAm)
print(new_set)
{'BZ', 'GT', 'ARG', 'MX', 'CANADA', 'USA', 'COL'}

Comprehensions

https://www.w3schools.com/python/python_lists_comprehension.asp

Estructura básica de List Comprehension

[elemento for elemento in iterable if condition]

Ejemplo

numbers = []
for i in range(1, 11):
  if i % 2 == 0:
    numbers.append(i * 2)

print(numbers)

numbers_v2 = [i * 2 for i in range(1, 11) if i % 2 == 0]
print(numbers_v2)

Estructura básica de Dictionary Comprehension

{key:value for var in iterable}

{key:value for var in iterable if condition}

Ejemplo

names = ['rigo', 'mari', 'robe']
ages = [12, 56, 98]

print(list(zip(names, ages)))

new_dict = {name: age for (name, age) in zip(names, ages)}
print(new_dict)
[('rigo', 12), ('mari', 56), ('robe', 98)]
{'rigo': 12, 'mari': 56, 'robe': 98}
import random
countries = ['cub', 'crc', 'pan', 'urg']

population_v2 = { country: random.randint(20, 40)  for country in countries}
print(population_v2)

result = { country: population for (country, population) in population_v2.items() if population > 25 }
print(result)

text = 'Buenas, me presento soy Rigo'
unique = { c: c.upper() for c in text if c in 'aeiou' }
print(unique)
{'cub': 31, 'crc': 24, 'pan': 22, 'urg': 34}
{'cub': 31, 'urg': 34}
{'u': 'U', 'e': 'E', 'a': 'A', 'o': 'O', 'i': 'I'}

Test: Crea una lista usando List Comprehension

numbers = [35, 16, 10, 34, 37, 25]

even_numbers = []
for number in numbers:
  if number % 2 == 0:
    even_numbers.append(number)
print('v1 =>', even_numbers)

# Ahora usando List Comprehension 👇
even_numbers_v2 = [val for val in numbers if val%2==0]

print('v2 =>', even_numbers_v2)
v1 => [16, 10, 34]

v2 => [16, 10, 34]

List vs Tuple vs Set

Comparation

En el contexto de listas, tuplas y conjuntos en Python, “ordenada” significa que los elementos mantienen un orden específico basado en la secuencia en que fueron añadidos. Esto permite acceder a los elementos por su índice, realizar búsquedas en rangos específicos y mantener la posición de los elementos. Es importante destacar que tanto las listas como las tuplas son estructuras de datos ordenadas, mientras que los conjuntos no tienen un orden definido.

Funciones

https://www.w3schools.com/python/python_functions.asp

Intro Funciones

print('Hola Mundo!!')

def my_print(texto):
  print(texto * 4)

my_print('Texto de prueba')
my_print('Hola Mundo!!')

a = 10
b = 90

c = a + b


def func_suma(a, b):
  print(a + b)

func_suma(1 ,5)
func_suma(10, 4)
Hola Mundo!!
Texto de pruebaTexto de pruebaTexto de pruebaTexto de prueba
Hola Mundo!!Hola Mundo!!Hola Mundo!!Hola Mundo!!
6
14

Funciones: return

El concepto de return en funciones de Python permite que una función envíe un valor de vuelta al lugar donde fue llamada. Cuando se utiliza return, la función termina su ejecución y el valor especificado se asigna a la variable que recibió la llamada. Esto hace que las funciones sean más versátiles y reutilizables, ya que se pueden usar para procesar datos y devolver resultados que pueden ser utilizados en otras partes del código. Así, facilitan la creación de programas más organizados y mantenibles.

Ejemplo

def sum_with_range(min, max):
  print(min, max)
  sum = 0
  for x in range(min, max):
    sum += x
  return sum

result = sum_with_range(1, 10)
print(result)
result_2 = sum_with_range(result, result + 10)
print(result_2)
1 10
45
45 55

Funciones: return & args

Podemos en las funciones tener parámetros por defecto y la capacidad de retornar múltiples valores.

Ejemplo

def find_volume(length=1, width=1, depth=1):
  return length * width * depth, width, 'hola'

result, width, text = find_volume(width=10)

print(result)
print(width)
print(text)
10
10
hola

Scope

Scope

El scope, o alcance, se refiere a la visibilidad y duración de las variables en tu código. Hay diferentes tipos de scope:

  • Local Scope: Las variables están disponibles solo dentro de la función o bloque donde fueron definidas.
  • Global Scope: Las variables pueden ser accedidas desde cualquier parte del archivo.
  • Enclosing Scope: Se refiere a funciones anidadas, donde la variable de la función externa es accesible en la interna.

Cada ámbito tiene su propia jerarquía y comprensión del scope es crucial para evitar errores.

Ejemplo

price = 100 # global
# result = 200

def increment():
  price = 200
  result = price + 10
  print(result)
  return result

print(price)
price_2 = increment()
print(price_2)
# print(result)
100
210
210

Refactor

Refactorizar es el proceso de reestructurar el código existente sin cambiar su funcionalidad externa. Su objetivo es mejorar la legibilidad, mantenibilidad y reducir la complejidad del código. En este contexto se aplica durante la refactorización del juego de piedra, papel o tijera, donde se dividieron grandes bloques de código en funciones más pequeñas con responsabilidades específicas, facilitando así su comprensión y mantenimiento.

import random


def choose_options():
  options = ('piedra', 'papel', 'tijera')
  user_option = input('piedra, papel o tijera => ')
  user_option = user_option.lower()

  if not user_option in options:
    print('esa opcion no es valida')
    # continue
    return None, None

  computer_option = random.choice(options)

  print('User option =>', user_option)
  print('Computer option =>', computer_option)
  return user_option, computer_option

def check_rules(user_option, computer_option, user_wins, computer_wins):
  if user_option == computer_option:
    print('Empate!')
  elif user_option == 'piedra':
    if computer_option == 'tijera':
      print('piedra gana a tijera')
      print('user gano!')
      user_wins += 1
    else:
      print('Papel gana a piedra')
      print('computer gano!')
      computer_wins += 1
  elif user_option == 'papel':
    if computer_option == 'piedra':
      print('papel gana a piedra')
      print('user gano')
      user_wins += 1
    else:
      print('tijera gana a papel')
      print('computer gano!')
      computer_wins += 1
  elif user_option == 'tijera':
    if computer_option == 'papel':
      print('tijera gana a papel')
      print('user gano!')
      user_wins += 1
    else:
      print('piedra gana a tijera')
      print('computer gano!')
      computer_wins += 1
  return user_wins, computer_wins

def run_game():
  computer_wins = 0
  user_wins = 0  
  rounds = 1
  while True:
    print('*' * 10)
    print('ROUND', rounds)
    print('*' * 10)

    print('computer_wins', computer_wins)
    print('user_wins', user_wins)
    rounds += 1

    user_option, computer_option = choose_options()
    user_wins, computer_wins = check_rules(user_option, computer_option, user_wins, computer_wins)

    if computer_wins == 2:
      print('El ganador es la computadora')
      break

    if user_wins == 2:
      print('El ganador es el usuario')
      break

run_game()

Test: Tienda de Tecnología

def message_creator(text):
   # Escribe tu solución 👇
   if text == "computadora":
      return "Con mi computadora puedo programar usando Python"
   elif text == "celular":
      return "En mi celular puedo aprender usando la app de Platzi"
   elif text == "cable":
      return "¡Hay un cable en mi bota!"
   else:
      return "Artículo no encontrado"

text = 'computadora'
response = message_creator(text)
print(response)
Con mi computadora puedo programar usando Python

Funciones anónimas

https://www.w3schools.com/python/python_lambda.asp

Las funciones lambda en Python son funciones anónimas que se definen con la palabra clave lambda. Permiten crear funciones de manera más concisa y se utilizan principalmente para operaciones simples. La sintaxis es lambda argumentos: expresión. Por ejemplo, lambda x: x + 1 es una función que incrementa x en 1. Su uso es común en funciones de orden superior, como map() y filter(), donde se necesitan funciones breves y sin nombre.

Ejemplo

def increment(x):
  return x + 1

increment_v2 = lambda x: x + 1

result = increment(10)
print(11)

result = increment_v2(20)
print(result)

full_name = lambda name, last_name: f'Full name is {name.title()} {last_name.title()}'

text = full_name('Rigoberto', 'Acosta Gonzalez')
print(text)
11
21
Full name is Rigoberto Acosta Gonzalez

Funciones de orden superior (HOF)

Una HOF, o función de orden superior (Higher Order Function), es una función que puede recibir otras funciones como argumentos o devolver funciones como resultado. Este concepto es fundamental en Python, ya que permite una programación más flexible y dinámica. Por ejemplo, puedes tener una función que toma otra función (como increment) y un valor, aplicando esta función al valor recibido. Esto te permite crear funciones más abstractas y reutilizables, mejorando la organización de tu código.

Ejmplo

def increment(x):
  return x + 1

increment_v2 = lambda x: x +1

def high_ord_func(x, func):
  return x + func(x)

high_ord_func_v2 = lambda x, func: x + func(x)

result = high_ord_func(2, increment)
# 2 + (2 + 1)
print(result)

result = high_ord_func_v2(2, increment_v2)
print(result)
result = high_ord_func_v2(2, lambda x: x + 2)
print(result)
## change
result = high_ord_func_v2(2, lambda x: x * 5)
print(result)
5
5
6
12

Map Function

https://www.w3schools.com/python/ref_func_map.asp

La función map en Python es una higher-order function que permite transformar los elementos de una lista aplicando una función a cada uno de ellos. Retorna un iterable con el mismo número de elementos, pero con los resultados de la transformación. Puedes usarla con funciones definidas o funciones lambda para simplificar el código, permitiendo realizar la transformación en una sola línea. Por ejemplo:

numbers = [1, 2, 3]
result = list(map(lambda x: x * 2, numbers))
Devuelve [2, 4, 6]

Se puede usar también con múltiples listas, limitándose a la longitud de la lista más corta.

Ejemplo

numbers = [1, 2, 3, 4]
numbers_v2 = []
for i in numbers:
  numbers_v2.append(i * 2)

numbers_v3 = list(map(lambda i: i * 2, numbers))

print(numbers)
print(numbers_v2)
print(numbers_v3)

numbers_1 = [1, 2, 3, 4]
numbers_2 = [5, 6, 7]

print(numbers_1)
print(numbers_2)
result = list(map(lambda x, y: x + y, numbers_1, numbers_2))
print(result)
[1, 2, 3, 4]
[2, 4, 6, 8]
[2, 4, 6, 8]
[1, 2, 3, 4]
[5, 6, 7]
[6, 8, 10]
items = [
  {
    'product': 'camisa',
    'price': 100,
  },
  {
    'product': 'pantalones',
    'price': 300
  },
  {
    'product': 'pantalones 2',
    'price': 200
  }
]

prices = list(map(lambda item: item['price'], items))
print(items)
print(prices)

def add_taxes(item):
  item['taxes'] = item['price'] * .19
  return item

new_items = list(map(add_taxes, items))
print(new_items)
print(items)
[{'product': 'camisa', 'price': 100}, {'product': 'pantalones', 'price': 300}, {'product': 'pantalones 2', 'price': 200}]
[100, 300, 200]
[{'product': 'camisa', 'price': 100, 'taxes': 19.0}, {'product': 'pantalones', 'price': 300, 'taxes': 57.0}, {'product': 'pantalones 2', 'price': 200, 'taxes': 38.0}]
[{'product': 'camisa', 'price': 100, 'taxes': 19.0}, {'product': 'pantalones', 'price': 300, 'taxes': 57.0}, {'product': 'pantalones 2', 'price': 200, 'taxes': 38.0}]

Reto con map

El objetivo era crear una nueva lista a partir de un array original sin modificarlo. El problema surgía porque al modificar un diccionario dentro del map, se alteraba también el array original debido a la referencia en memoria. La solución consistió en utilizar la función copy() para crear una copia del diccionario antes de hacer cualquier modificación. Esto permitió que el nuevo diccionario tuviera una referencia diferente, manteniendo intacto el array original.

items = [
  {
    'product': 'camisa',
    'price': 100,
  },
  {
    'product': 'pantalones',
    'price': 300
  },
  {
    'product': 'pantalones 2',
    'price': 200
  }
]

def add_taxes(item):
  new_item = item.copy()
  new_item['taxes'] = new_item['price'] * .19
  return new_item

new_items = list(map(add_taxes, items))
print('New list')
print(new_items)
print('Old list')
print(items)
New list
[{'product': 'camisa', 'price': 100, 'taxes': 19.0}, {'product': 'pantalones', 'price': 300, 'taxes': 57.0}, {'product': 'pantalones 2', 'price': 200, 'taxes': 38.0}]
Old list
[{'product': 'camisa', 'price': 100}, {'product': 'pantalones', 'price': 300}, {'product': 'pantalones 2', 'price': 200}]

Reto: Multiplica todos los elementos por dos

def multiply_numbers(numbers):
    # Escribe tu solución 👇
    return list(map(lambda x: x*2, numbers))

numbers = [1, 2, 3, 4]
response = multiply_numbers(numbers)
print(response)
[2, 4, 6, 8]

Filter Function

https://www.w3schools.com/python/ref_func_filter.asp

La función filter en Python se utiliza para crear una nueva lista a partir de una lista existente, seleccionando solo aquellos elementos que cumplen con una condición específica. Se aplica junto con una función, que puede ser una función lambda, que devuelve True o False para cada elemento. A diferencia de map, filter no transforma los elementos, sino que filtra según la condición dada, y nunca devuelve más elementos de los que se estaban evaluando.

Ejemplo

numbers = [1,2,3,4,5]
new_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(new_numbers)
print(numbers)
[2, 4]
[1, 2, 3, 4, 5]

Filter and Dict

No hay problemas con la referencia de memoria.

matches = [
  {
    'home_team': 'Bolivia',
    'away_team': 'Uruguay',
    'home_team_score': 3,
    'away_team_score': 1,
    'home_team_result': 'Win'
  },
  {
    'home_team': 'Brazil',
    'away_team': 'Mexico',
    'home_team_score': 1,
    'away_team_score': 1,
    'home_team_result': 'Draw'
  },
  {
    'home_team': 'Ecuador',
    'away_team': 'Venezuela',
    'home_team_score': 5,
    'away_team_score': 0,
    'home_team_result': 'Win'
  },
]

print(matches)
print(len(matches))

new_list = list(filter(lambda item: item['home_team_result'] == 'Win', matches))

print(new_list)
print(len(new_list))

print(matches)
print(len(matches))
[{'home_team': 'Bolivia', 'away_team': 'Uruguay', 'home_team_score': 3, 'away_team_score': 1, 'home_team_result': 'Win'}, {'home_team': 'Brazil', 'away_team': 'Mexico', 'home_team_score': 1, 'away_team_score': 1, 'home_team_result': 'Draw'}, {'home_team': 'Ecuador', 'away_team': 'Venezuela', 'home_team_score': 5, 'away_team_score': 0, 'home_team_result': 'Win'}]
3
[{'home_team': 'Bolivia', 'away_team': 'Uruguay', 'home_team_score': 3, 'away_team_score': 1, 'home_team_result': 'Win'}, {'home_team': 'Ecuador', 'away_team': 'Venezuela', 'home_team_score': 5, 'away_team_score': 0, 'home_team_result': 'Win'}]
2
[{'home_team': 'Bolivia', 'away_team': 'Uruguay', 'home_team_score': 3, 'away_team_score': 1, 'home_team_result': 'Win'}, {'home_team': 'Brazil', 'away_team': 'Mexico', 'home_team_score': 1, 'away_team_score': 1, 'home_team_result': 'Draw'}, {'home_team': 'Ecuador', 'away_team': 'Venezuela', 'home_team_score': 5, 'away_team_score': 0, 'home_team_result': 'Win'}]
3

Reto: Retorna solo palabras de 4 letras y más

def filter_by_length(words):
   # Escribe tu solución 👇
   return list(filter(lambda x: len(x)>=4, words))

words = ['amor', 'sol', 'piedra', 'día']
response = filter_by_length(words)
print(response)
['amor', 'piedra']

Reduce Function

La función reduce en Python, proveniente del módulo functools, se utiliza para aplicar una función de manera acumulativa a los elementos de una lista, reduciéndola a un solo valor. Toma dos argumentos: una función y una lista. Por ejemplo, para sumar todos los elementos de una lista, reduce inicia con el primer elemento y lo acumula aplicando la función al siguiente elemento. Este proceso continúa hasta que se itera sobre toda la lista, resultando en un único valor, como la suma total.

Ejemplo de uso

from functools import reduce

numeros = [1, 2, 3, 4]
resultado = reduce(lambda x, y: x + y, numeros)
print(resultado)
10

Esto demuestra cómo reduce simplifica operaciones como la suma, max, etc.

Módulos

https://www.w3schools.com/python/python_modules.asp

Un módulo en Python es un archivo que contiene definiciones y declaraciones de Python. Permite organizar y reutilizar código dividiendo la aplicación en partes más manejables. Puedes importar módulos estándar de Python, como random o sys, para acceder a funcionalidades específicas. Además, puedes crear tus propios módulos para encapsular lógica y funciones, facilitando la modularización y mantenimiento de tus aplicaciones.

Ejemplo

import sys
print(sys.path)

import re
text = 'Mi numero de telefono es 311 123 121, el codigo del pais es 57, mi numero de la suerte 3'
result = re.findall('[0-9]+', text)
print(result)

import time
timestamp = time.time()
print(timestamp)

local = time.localtime()
result = time.asctime(local)
print(result)

import collections
numbers = [1,1,2,1,2,1,4,5,3,3,21]
counter = collections.Counter(numbers)
print(counter)
['/home/user/Downloads/Python-102', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']
['311', '123', '121', '57', '3']
1733451487.0499635
Thu Dec  5 23:18:07 2024
Counter({1: 4, 2: 2, 3: 2, 4: 1, 5: 1, 21: 1})

Módulos propios

Archivos empleados

## main.py
import utils
import read_csv
import charts

def run():
  data = read_csv.read_csv('./app/data.csv')
  data = list(filter(lambda item : item['Continent'] == 'South America',data))

  countries = list(map(lambda x: x['Country'], data))
  percentages = list(map(lambda x: x['World Population Percentage'], data))
  charts.generate_pie_chart(countries, percentages)
  '''
  country = input('Type Country => ')

  result = utils.population_by_country(data, country)

  if len(result) > 0:
    country = result[0]
    labels, values = utils.get_population(country)
    charts.generate_bar_chart(labels, values)
  '''

if __name__ == '__main__':
  run()
## utils.py
def get_population(country_dict):
  population_dict = {
    '2022': int(country_dict['2022 Population']),
    '2020': int(country_dict['2020 Population']),
    '2015': int(country_dict['2015 Population']),
    '2010': int(country_dict['2010 Population']),
    '2000': int(country_dict['2000 Population']),
    '1990': int(country_dict['1990 Population']),
    '1980': int(country_dict['1980 Population']),
    '1970': int(country_dict['1970 Population'])
  }
  labels = population_dict.keys()
  values = population_dict.values()
  return labels, values


def population_by_country(data, country):
  result = list(filter(lambda item: item['Country'] == country, data))
  return result

Salida de ejecutar todo el código

Imagen_Salida

Módulos como scripts: __name__ y __main__

__name__ y __main__ son atributos especiales en Python que se utilizan para determinar cómo se está ejecutando un módulo.

  • __name__: Este atributo representa el nombre del módulo. Si el módulo es importado desde otro archivo, su valor será el nombre del archivo sin la extensión .py. Si el módulo se está ejecutando directamente, su valor será __main__.

  • __main__: Es un valor que se asigna al atributo __name__ cuando el módulo se ejecuta como un script. Esto permite incluir un bloque de código que solo se ejecuta cuando el módulo se corre directamente, no cuando se importa.

Esto es útil para ejecutar pruebas o ejemplos en el mismo archivo sin interferir con el comportamiento al importarlo en otro módulo.

import main

main.run()
print(main.data)

Paquetes

Un paquete en Python es una carpeta que contiene múltiples módulos. Permite organizar y estructurar el código de manera efectiva. Para usar un paquete, se puede importar directamente o especificar el módulo y la función que se desea utilizar. Desde Python 3.3, no es necesario incluir un archivo __init__.py para reconocer un paquete, aunque es útil para inicializar variables o definir un espacio de nombres. Esto facilita la gestión del código y evita conflictos entre nombres de funciones en diferentes módulos.

Ejemplo

Estos archivos estan dentro de la carpeta pkg

Archivo __init__.py

print('Se inicio paquete')

URL = 'platzi.com'

import pkg.mod_1, pkg.mod_2
## mod_1.py
def func_1():
  return 'func 1'

def func_2():
  return 'func 2'
## mod_2.py
def func_3():
  return 'func 3'

def func_4():
  return 'func 4'
import pkg
print(pkg.URL)
print(pkg.mod_1.func_1())
Se inicio paquete
platzi.com
func 1

Reto: Calcular la suma de todas las compras

def get_total(orders):
  total = 0
  for order in orders:
    total += order["total"]
  return total

orders = [
  {
    "customer_name": "Nicolas",
    "total": 100,
    "delivered": True,
  },
  {
    "customer_name": "Zulema",
    "total": 120,
    "delivered": False,
  },
  {
    "customer_name": "Santiago",
    "total": 20,
    "delivered": False,
  }
]

total = get_total(orders)
print(total)
100

120

20

240

Manipulación de archivos y errores

Iterables

https://www.w3schools.com/python/python_iterators.asp

Los iterables son objetos en Python que pueden ser iterados (recorridos) uno a uno. Pueden ser listas, tuplas, diccionarios, conjuntos y strings. Estos objetos implementan el método __iter__() o el método __getitem__(), lo que permite utilizarlos en bucles for. En la clase, se explicó cómo los iterables se pueden convertir en iteradores usando la función iter(), permitiendo un control más manual sobre las iteraciones con next(). Esto es útil para manejar grandes conjuntos de datos sin consumir mucha memoria.

Ejemplo

for i in range(1, 10):
  print(i)

my_iter = iter(range(1, 4))
print(my_iter)
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))
1
2
3
4
5
6
7
8
9
<range_iterator object at 0x7e636dece190>
1
2
3
Traceback (most recent call last):
  File "/home/riacosta/Downloads/Python-102/20_iter.py", line 9, in <module>
    print(next(my_iter))
StopIteration

Se detiene debido a que el máximo del rango es 3.

Errores

https://www.w3schools.com/python/python_ref_exceptions.asp

Existen varios tipos de errores en Python que debes conocer:

  1. Errores de Sintaxis: Ocurren cuando el código no sigue las reglas del lenguaje. Ejemplo: paréntesis mal colocados.

  2. NameError: Se genera al referirse a una variable que no ha sido definida.

  3. ZeroDivisionError: Ocurre al intentar dividir entre cero.

  4. AssertionError: Se lanza cuando una afirmación con assert no se cumple.

  5. Excepciones Personalizadas: Puedes crear tus propios errores usando raise para manejar situaciones específicas, como no permitir menores de edad.

Recuerda que los errores detienen la ejecución del programa, así que es fundamental manejarlos adecuadamente.

Ejemplo

print('Hola')

suma = lambda x,y: x + y
assert suma(2,2) == 4

print('Hola 2')

age = 10
if age < 18:
  raise Exception('No se permiten menores de edad')

print('Hola 2')
Hola
Hola 2
Traceback (most recent call last):
  File "/home/riacosta/Downloads/Python-102/21_errors.py", line 12, in <module>
    raise Exception('No se permiten menores de edad')
Exception: No se permiten menores de edad

Manejo de Excepciones

https://www.w3schools.com/python/python_try_except.asp

El manejo de excepciones en Python es una técnica que permite controlar y gestionar errores que pueden ocurrir durante la ejecución de un programa. Utiliza las palabras clave try y except. El código que puede causar un error se coloca dentro del bloque try, y si ocurre un error, el flujo del programa se transfiere al bloque except, donde se puede manejar el error sin que el programa se detenga. Esto es esencial para crear aplicaciones robustas que puedan continuar funcionando incluso cuando surgen problemas imprevistos.

Ejemplo

try:
  print(0 / 0)
  assert 1 != 1, 'Uno no es igual que uno'
  age = 10
  if age < 18:
    raise Exception('No se permiten menores de edad')
except ZeroDivisionError as error:
  print(error)
except AssertionError as error:
  print(error)
except Exception as error:
  print(error)

print('Hola')
print('Hola 2')
division by zero
Hola
Hola 2

Reto: Captura la excepción: ZeroDivisionError

def my_divide(a, b):
   # Escribe tu solución 👇
   try:
      result = a / b
      return result
   except ZeroDivisionError as error:
      return "No se puede dividir por 0"
      
    
response = my_divide(10, 2)
print(response) # 5

response = my_divide(10, 0)
print(response) # No se puede dividir por 0
5.0

No se puede dividir por 0

Leer archivo de texto

Para leer un archivo de texto en Python, sigue estos pasos:

  • Abrir el archivo: Usa open('ruta/del/archivo.txt', 'r') para abrir el archivo en modo lectura.

  • Leer el contenido: Utiliza file.read() para leer todo el contenido o file.readline() para leer línea por línea. También puedes usar un bucle for para iterar sobre las líneas.
  • Cerrar el archivo: Es importante cerrar el archivo con file.close(), o mejor aún, usa with open('ruta/del/archivo.txt', 'r') as file: para que se cierre automáticamente.

Esto te permitirá manipular y gestionar archivos de texto eficientemente.

Ejemplo

file = open('./text.txt')

for line in file:
  print(line)

file.close()

with open('./text.txt') as file:
  for line in file:
    print(line)
nuevas cosas en este archivo

otra linea

 mas linea

nuevas cosas en este archivo

otra linea

 mas linea

Escribir archivo de texto

Para escribir en un archivo en Python, debes usar la función open() con el modo de apertura adecuado. Por ejemplo, para abrir un archivo para escritura, puedes usar open('archivo.txt', 'w') para sobrescribir o open('archivo.txt', 'a') para agregar contenido. Usa file.write('tu texto') para escribir en el archivo. No olvides cerrar el archivo con file.close() después de terminar. Para permitir lectura y escritura simultáneamente, usa open('archivo.txt', 'r+').

Ejemplo

with open('./texs.txt', 'w+') as file:
  for line in file:
    print(line)
  file.write('nuevas cosas en este archivo\n')
  file.write('otra linea\n')
  file.write(' mas linea\n')
## texs.tex
nuevas cosas en este archivo
otra linea
 mas linea

Leer csv

https://www.w3schools.com/python/python_file_open.asp

Para leer archivos CSV en Python, puedes utilizar el módulo csv. A continuación, te muestro un ejemplo básico:

  1. Importa el módulo CSV: import csv.

  2. Abre el archivo CSV usando with open(‘ruta/del/archivo.csv’, mode=’r’) as file:.

  3. Crea un lector: reader = csv.reader(file).

  4. Itera sobre las filas del archivo:

      for row in reader:
       print(row)
    

    Esto imprimirá cada fila del archivo como una lista. Puedes adaptar este código según tus necesidades.

Ejemplo

import csv

def read_csv(path):
  with open(path, 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    header = next(reader)
    data = []
    for row in reader:
      iterable = zip(header, row)
      country_dict = {key: value for key, value in iterable}
      data.append(country_dict)
    return data

if __name__ == '__main__':
  data = read_csv('./app/data.csv')
  print(data[0])

Reto: Lee un CSV para calcular el total de gastos

import csv

def read_csv(path):
   # Tu código aquí 👇
   total = 0
   with open(path, 'r') as csvfile:
      reader = csv.reader(csvfile, delimiter=',')
      for row in reader:
         total += float(row[1])
         print(total)
   return total

response = read_csv('./data.csv')
print(response)
1499.0

Gráficas en Python

Links:

Para generar un gráfico en Python utilizando Matplotlib, sigue estos pasos:

  • Instala Matplotlib: Asegúrate de tener la librería instalada en tu entorno. pip install matplotlib

  • Importa la librería:
    import matplotlib.pyplot as plt
    
  • Define los datos: Crea listas para los labels y los valores.
    labels = ['A', 'B', 'C']
    values = [100, 200, 80]
    
  • Crea la función para el gráfico:
    def generateBarChart(labels, values):
        plt.bar(labels, values)
        plt.show()  # Muestra el gráfico
    
  • Ejecuta la función: generateBarChart(labels, values)

Con estos pasos, habrás generado un gráfico de barras.

Ejemplo

## charts.py
import matplotlib.pyplot as plt

def generate_bar_chart(labels, values):
  fig, ax = plt.subplots()
  ax.bar(labels, values)
  plt.show()

def generate_pie_chart(labels, values):
  fig, ax = plt.subplots()
  ax.pie(values, labels=labels)
  ax.axis('equal')
  plt.show()

if __name__ == '__main__':
  labels = ['a', 'b', 'c']
  values = [10, 40, 800]
  # generate_bar_chart(labels, values)
  generate_pie_chart(labels, values)

Salida de ejecutar todo el código

Imagen_Salida

Next

Curso de PIP y entornos virtuales con Python