Fundamentos de Programación y Python

1

Fundamentos de Programación con Python: Tipos y Paradigmas

2

Instalación de Python en Windows y Mac

3

Sintaxis y Semántica en Python: Comprensión y Aplicaciones

4

Práctica: Te doy la bienvenida a los ejercicios interactivos

5

Manipulación de Cadenas en Python: Comillas, Indexación y Métodos

6

Variables y Tipos de Datos en Python: Enteros, Flotantes y Booleanos

7

Técnicas avanzadas de impresión con `print` en Python

8

Operadores Matemáticos y Booleanos en Python

9

Manejo de Input en Python: Variables, Casting y Tipos de Datos

Colección y Procesamiento de Datos en Python

10

Manipulación de Listas en Python: Métodos y Funciones Básicas

11

Copiar listas en Python: referencias vs slicing

12

Matrices y Tuplas en Python: Manipulación y Acceso de Datos

13

Matrices en Python para Tableros de Juegos y Más

14

Manipulación de diccionarios en Python: claves, valores y métodos

Control de Flujo en Python

15

Condicionales en Python: if, elif, else y combinaciones lógicas

16

Bucles e Iteraciones: For y While en Python

17

Generadores e iteradores en Python: eficiencia en manejo de datos

18

Comprensión de Listas en Python: Cómo Usarlas y Cuándo Aplicarlas

Funciones y Manejo de Excepciones en Python

19

Uso de Funciones en Python para Dividir y Optimizar Código

20

Funciones Lambda en Python: Operaciones y Filtrado Eficiente

21

Recursividad en Python: Factoriales y Fibonacci

22

Manejo de Excepciones en Python: Identificación y Solución de Errores

Programación Orientada a Objetos en Python

23

Manipulación de Cuentas Bancarias con Clases en Python

24

Creación de Clases en Python: Biblioteca, Libros y Usuarios

25

Herencia en Programación con Python: Vehículos y Clases Derivadas

26

Clase Python: Herencia y Polimorfismo en Vehículos

27

Programación Orientada a Objetos: Polimorfismo en Acción

28

Uso de super() para herencia en clases Python

29

Uso de `super()` para Heredar Métodos en Python

Lectura y escritura de archivos

30

Tratamiento de Archivos TXT en Python: Lectura y Escritura

31

Manipulación de archivos CSV con Python: lectura y escritura efectiva

32

Manejo de Archivos JSON en Python: Lectura y Escritura

Biblioteca estándar de Python

33

Programación Eficiente con la Biblioteca Estándar de Python

34

Uso de Librerías OS, Math y Random en Python

35

Análisis de datos de ventas con Python y librería Statistics

36

Programación del Juego Batalla Naval en Python

Conceptos avanzados de Python

37

POO: Diseño de Clases y Objetos en Python

38

Buenas prácticas en Python: código limpio y eficiente

39

Comentarios y Docstrings: Buenas Prácticas en Python

40

Variables locales y globales en Python

41

Anotaciones de tipo en Python: mejora la legibilidad del código

42

Validación de tipos de datos en Python: Técnicas y buenas prácticas

43

Estructuras de Datos Avanzadas en Collections y Enum en Python

Decoradores

44

Decoradores en Python: Añadir Funcionalidad sin Modificar Código

45

Uso de Decoradores Anidados y con Parámetros en Python

46

Decoradores en Python: Staticmethod, Classmethod y Property

Métodos y estructura de clases en Python

47

Métodos Mágicos en Python: Personalización de Clases y Objetos

48

Sobrecarga de Operadores en Python: Sumando e Igualando Objetos

49

Uso de "__name__ == '__main__'" en Scripts Python

50

Programación Orientada a Objetos en Python: Métodos `__init__` y `__new__`

51

Funcionamiento de ARGS y KWARGS en Python

52

Métodos y Atributos Privados en Python

53

Uso del decorador property en Python para atributos privados

54

Métodos estáticos y de clase en Python: prácticas avanzadas

Programación concurrente y asíncrona

55

Concurrencia y paralelismo en Python: manejo eficiente de procesos

56

Concurrente: Hilos y Procesos en Python

57

Técnicas de Asincronismo en Python: Uso de AsyncIO y Corrutinas

58

Concurrencia y Asincronía en Python para Gestión de Pedidos

Creación de módulos y paquetes

59

Módulos y paquetes en Python: reutilización de código eficiente

60

Uso de Paquetes y Subpaquetes en Python

61

Publicación de paquetes en PyPI: guía paso a paso

Proyecto final

62

Sistema de Gestión de Reservas de Hotel con Python

63

Gestión de Reservas de Hotel con Python Avanzado

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Python

Curso de Python

Carli Code

Carli Code

Validación de tipos de datos en Python: Técnicas y buenas prácticas

42/63
Recursos

¿Cómo manejar excepciones y validar tipos en Python?

La validación de tipos y manejo de excepciones en Python es esencial, sobre todo en proyectos colaborativos o críticos donde los datos externos juegan un papel crucial. Aunque Python permite especificar tipos de datos para los parámetros de una función, no garantiza que estos sean correctos en tiempo de ejecución. Esta lección explora cómo validar tipos de datos y personalizar excepciones para asegurar un comportamiento consistente del código bajo diferentes circunstancias.

¿Cómo se crea una función que divide dos números?

Primero, vamos a crear una función que se encargará de dividir dos números enteros. El resultado de esta función será de tipo flotante. Aquí está el enfoque básico:

def dividir(a: int, b: int) -> float:
    return a / b

Al llamar a la función dividir(10, 2), obtendremos el resultado esperado. Sin embargo, si ingresamos un string en lugar de un número entero, como dividir(10, '2'), obtendremos un error de tipo (type error).

¿Cómo validar que los parámetros sean enteros?

Para evitar errores de tipo, validamos que ambos parámetros sean enteros o flotantes antes de ejecutar la división:

def dividir(a, b):
    if not isinstance(a, int) or not isinstance(b, int):
        raise TypeError("Ambos parámetros deben ser enteros")
    if b == 0:
        raise ValueError("El divisor no puede ser cero")
    return a / b

¿Cómo se manejan las excepciones con try y except?

El manejo de excepciones es crucial para dar más información sobre los errores y prevenir que el programa se detenga abruptamente. Aquí te muestro cómo manejar excepciones usando try y except:

try:
    resultado = dividir(10, '2')
except TypeError as e:
    print(f"Error: {e}")

try:
    resultado = dividir(10, 0)
except ValueError as e:
    print(f"Error: {e}")

Este enfoque permite capturar cualquier tipo de error y personalizar el mensaje de error según sea necesario, lo que mejora la depuración y la comprensión del error original.

¿Por qué es importante personalizar las excepciones?

El uso de excepciones personalizadas no solo brinda claridad sobre lo que ha salido mal, sino que también ofrece detalles específicos del error. Aquí un ejemplo de cómo podrías lanzar y personalizar excepciones:

def dividir(a, b):
    if not isinstance(a, int) or not isinstance(b, int):
        raise TypeError("Ambos parámetros deben ser enteros")
    if b == 0:
        raise ValueError("El divisor no puede ser cero")
    return a / b

Cada vez que se lanza una excepción específica, puedes proporcionar un mensaje detallado que ayude a identificar el origen del problema sin necesidad de leer todo el stack trace.

¿Cuál es la importancia de las buenas prácticas en validación y manejo de errores?

Aplicar estas técnicas de validación y manejo de excepciones es fundamental para mantener un código limpio y robusto, especialmente en ambientes de desarrollo colaborativos. Algunas de las buenas prácticas incluyen:

  • Validar Entrada de Datos: Asegurar que los datos son del tipo esperado antes de procesarlos.
  • Manejo de Excepciones: Capturar y manejar de forma adecuada las excepciones para proporcionar mensajes de error informativos.
  • Personalización: Crear excepciones personalizadas para situaciones específicas mejorando la depurabilidad del código.

Estas prácticas no solo mejoran la estabilidad y mantenibilidad del código, sino que también facilitan la colaboración efectiva en proyectos de gran escala.

¡Continúa tu aprendizaje y sigue mejorando tus habilidades en programación! Entender y manejar las excepciones y tipos en Python te ayudará a escribir aplicaciones más seguras y fiables.

Aportes 22

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Buenas tardes, profesora y compañeros. La clase está mal grabada. En el minuto 11:06, mientras explica la aplicación usando Try, de pronto salta, no apareciendo las líneas que antes había escrito.
La validación de tipos en métodos en Python es una práctica que se utiliza para asegurar que los argumentos de las funciones o métodos tienen los tipos esperados. Esto puede ayudar a prevenir errores en tiempo de ejecución y facilitar la comprensión del código. A continuación, se presentan varias maneras de implementar la validación de tipos en métodos: \### 1. Anotaciones de Tipo Desde Python 3.5, se pueden utilizar anotaciones de tipo para indicar qué tipos de datos se esperan como argumentos y qué tipo se devolverá. Sin embargo, estas anotaciones son solo sugerencias y no imponen la validación de tipos en tiempo de ejecución. Aún así, se pueden usar herramientas como `mypy` para comprobar las anotaciones de tipo. ```python def add(a: int, b: int) -> int: return a + b print(add(5, 10)) # Salida: 15 ``` \### 2. Validación Manual de Tipos Si deseas realizar la validación de tipos en tiempo de ejecución, puedes hacerlo utilizando `isinstance` dentro del método. ```python def add(a: int, b: int) -> int: if not isinstance(a, int) or not isinstance(b, int): raise TypeError("Los argumentos deben ser enteros.") return a + b try: print(add(5, 10)) # Salida: 15 print(add(5, '10')) # Esto generará un TypeError except TypeError as e: print(e) # Salida: Los argumentos deben ser enteros. ``` \### 3. Uso de Decoradores También puedes crear un decorador para manejar la validación de tipos en múltiples funciones o métodos, lo que hace que tu código sea más limpio y reutilizable. ```python def type\_check(\*arg\_types): def decorator(func): def wrapper(\*args): for a, t in zip(args, arg\_types): if not isinstance(a, t): raise TypeError(f"Argumento {a} no es de tipo {t.\_\_name\_\_}.") return func(\*args) return wrapper return decorator @type\_check(int, int) def add(a, b): return a + b try: print(add(5, 10)) # Salida: 15 print(add(5, '10')) # Esto generará un TypeError except TypeError as e: print(e) # Salida: Argumento 10 no es de tipo int. ``` \### 4. Librerías de Validación Existen librerías externas como `pydantic` y `attrs` que pueden ayudarte a manejar la validación de tipos y la creación de clases de forma más robusta y concisa. \#### Ejemplo con Pydantic ```python from pydantic import BaseModel class Item(BaseModel): name: str price: float item = Item(name="Libro", price=12.99) print(item) ``` \### Conclusión La validación de tipos es una práctica importante en Python para asegurar la calidad y la robustez del código. Puedes optar por usar anotaciones de tipo junto con herramientas de análisis estático, o bien implementar validaciones manuales o usar decoradores para garantizar que los métodos reciban los tipos de datos esperados.
La actividad de la clase anterior : podran ver que importo el modulo string como strModule, esto porque inicialmente lo tenia como str, y al correr mypy, me estaba dando errores, pues tenia el mismo nombre que el tipo de dato (yo no habia caido en la cuenta) ```python import random as rand import string as strModule from typing import Union """this program recives from a data base of employes and filter by salary""" name: str=''; def names_generator() -> str: global name #no es posible unificar estas dos linea de codigo name=' pendejas ' for i in range (5): name+=(rand.choice(strModule.ascii_uppercase)) return name #for the sake of the example the data base is not in a file and is not pass as a parameter database = [ { 'name':names_generator(), 'age':rand.randint(18,68), 'salary':rand.randint(5000,20000) } for _ in range(300) ] def loadData(data:Union[list,dict],treshold:int)->list: """it lods the data from the data base""" dataToFilter= data # nunca se toca la db original def salary_filter(treshhole)->list: """it filters the data using nonlocal""" nonlocal dataToFilter return [dic for dic in dataToFilter if dic['salary']>=treshhole] return salary_filter(1) print(loadData(database,12340)) ```
hola. aca les dejo mi codigo implementando lo que se vio en la clase con el producto punto ```js from functools import reduce def dotProduct(vector1:list,vector2:list)->list: if len(vector1) != len(vector2): raise ValueError('Vectors must be of the same length') result:list=[0]*len(vector1) for index,number in enumerate(vector1): if not isinstance(vector1[index],int) or not isinstance(vector2[index],int): raise TypeError('No int values in list, just able to operate int values ') result[index]=vector1[index]*vector2[index] return reduce(lambda a,b: a+b, result) try: v=[1,2] u=[2,1] print(dotProduct(v,u)) except (TypeError,ValueError) as e: print(f'error:{e}') ```
```js def divide(a: int, b: int) -> float | str: # Validar que ambos parámetros sean enteros if not isinstance(a, int) or not isinstance(b, int): return 'Error: Both parameters must be integers' if b == 0: return "Error: The divisor can't be zero" return a / b # 🧪 Casos de prueba print(divide(10, '2')) # Error: Both parameters must be integers print(divide(10, 0)) # Error: The divisor can't be zero print(divide(10, 2)) # 5.0 ```
Me compliqué mucho entendiendo esta clase, cuando el código se pudo simplicar de la sig manera: ```js def divide(a: int, b: int) -> float | str: # Validar que ambos parámetros sean enteros if not isinstance(a, int) or not isinstance(b, int): return 'Error: Both parameters must be integers' if b == 0: return "Error: The divisor can't be zero" return a / b print(divide(10, '2')) # Error: Both parameters must be integers print(divide(10, 0)) # Error: The divisor can't be zero print(divide(10, 2)) # 5.0 ```
El error "no such file or directory" no está relacionado directamente con la función `divide`. Sin embargo, el problema principal es que estás intentando dividir un entero por una cadena (`'2'`), lo que genera un `TypeError`. Para evitar este error, asegúrate de validar que ambos parámetros sean enteros. Puedes usar `isinstance()` para verificar el tipo de datos antes de realizar la operación. Aquí tienes una versión corregida de tu función: ```python def divide(a: int, b: int) -> float: if not isinstance(a, int) or not isinstance(b, int): raise TypeError("Ambos parámetros deben ser enteros.") return a / b print(divide(10, 2)) # Esto funcionará ``` Asegúrate de ejecutar tu código en un entorno adecuado para que no aparezca el error de archivo.
Python es un lenguaje dinámicamente tipado, osea que no es extrictamente necesario la validación de datos como en otros lenguajes, no se queden trabados con estas clases!
El video quedo mal editado en la parte del try pero no se asusten. Unos minutos más adelante retoman nuevamente.
Excelente clase querida profesora
```python def divide (a:int, b:int) -> float: if not isinstance(a, int) and isinstance(b, int): raise TypeError('Los dos parametros deben ser números enteros.') if b == 0: raise ValueError('No se puede dividir por 0') return a/b try: print("¡ BIENVENIDO ! Vamos a divivir las manzanas para los niños") a = int(input("Ingresa el numero de manzanas (disponibles): ")) b = int(input("Ingresa el numero de niños: ")) print(f'A cada niño le tocan de a {divide(a, b)} manzana(s)') except (TypeError, ValueError) as e: print(f'Error: {e}') ```
*Aunque Python proporciona mensajes de error predeterminados, es recomendable utilizar* `raise `*con mensajes personalizados para indicar de manera clara y específica qué error ocurrió. Esto mejora la comunicación, la legibilidad y la claridad del código, facilitando su mantenimiento y depuración.*
¿Este tema está más relacionado a testing no? Yo, crearía que es mejor usar: `assert type(sales) == list, "sales should be a list"`
```js def divicion(a:int, b: int) -> float: #Validando que ambos parámetros sean enteros if not isinstance(a, int) or not isinstance(b, int): raise Exception(f"Los números deben ser enteror o flotantes. A: { a }, B: { b }") #Validando que no sea cero el divisor if b == 0: raise Exception("El divisor no puede ser cero 0") return a / b; try: resultado_uno = divicion(0, 5) print(resultado_uno) except Exception as e: print(f"Error { e }") try: resultado_uno = divicion(0, 0) print(resultado_uno) except Exception as e: print(f"Error { e }") try: resultado_uno = divicion(-21, 21) print(resultado_uno) except Exception as e: print(f"Error { e }") try: resultado_uno = divicion("-21", 1) print(resultado_uno) except Exception as e: print(f"Error { e }") ```def divicion(a:int, b: int) -> float:        *#Validando que ambos parámetros sean enteros*    if not isinstance(a, int) or not isinstance(b, int):        raise Exception(f"Los números deben ser enteror o flotantes. A: { a }, B: { b }")        *#Validando que no sea cero el divisor*    if b == 0:        raise Exception("El divisor no puede ser cero 0")        return a / b; try:    resultado\_uno = divicion(0, 5)    print(resultado\_uno) except Exception as e:    print(f"Error { e }") try:    resultado\_uno = divicion(0, 0)    print(resultado\_uno) except Exception as e:    print(f"Error { e }") try:     resultado\_uno = divicion(-21, 21)    print(resultado\_uno) except Exception as e:    print(f"Error { e }") try:    resultado\_uno = divicion("-21", 1)    print(resultado\_uno) except Exception as e:    print(f"Error { e }")
Aprender Python con Github Copilot y ChatGPT es profundamente enriquecedor, lo recomiendo.
que hace el raise y el None? en python
Para la division entre cero (0), el error que se debe de manejar es **ZeroDivisionError** y no ValueError. Ese seria el error correcto. Excelente clase!
Duda! para especificar el valor devuelto por la función divide, no debería ser Union\[float, None]? pues en caso de tener valores incorrectos la función regresa None
¿Por qué al poner print(f'Error: {e}') no imprimió Error sino 'ambos parámetros deben ser enteros'?
Un Ejemplo en codigo usando las Anotaciones de Tipo y las Validacion de tipos en metodos: ```python from typing import Union class Calculadora: def sumar(self, a: Union[int, float], b: Union[int, float]) -> Union[int, float]: if not isinstance(a, (int, float)) or not isinstance(b, (int, float)): raise TypeError("Los argumentos deben ser int o float") return a + b calc = Calculadora() resultado = calc.sumar(10, 5.5) print(resultado) ```from typing import Union class Calculadora: def sumar(self, a: Union\[int, float], b: Union\[int, float]) -> Union\[int, float]: if not isinstance(a, (int, float)) or not isinstance(b, (int, float)): raise TypeError("Los argumentos deben ser int o float") return a + b \# Uso del método calc = Calculadora() resultado = calc.sumar(10, 5.5) print(resultado) # Salida: 15.5
```js def divide(a: int, b: int) -> float: #Validar que los parametros sean enteros if not isinstance(a, int) or not isinstance(b, int): raise TypeError("Ambos parametros deben ser enteros") #Verificamos que el divisor no sea cero if b == 0: raise ValueError("El divisor no puede ser cero") return a/b #Ejemplo de uso try: res = divide(10, 2) print(res) except (ValueError, TypeError) as e: print(f"Error: {e}") ```def divide(a: int, b: int) -> float:    *#Validar que los parametros sean enteros*    *if* not isinstance(a, int) or not isinstance(b, int):        *raise* TypeError("Ambos parametros deben ser enteros")        *#Verificamos que el divisor no sea cero*    *if* b == 0:        *raise* ValueError("El divisor no puede ser cero")        *return* a/b *#Ejemplo de usotry*:    res = divide(10, 2)     print(res)*except* (ValueError, TypeError) *as* e:    print(f"Error: {e}")
Si bien la instrucción isinstance( ) puede realizar más acciones que Type( ), la realidad es que el código propuesto por la profesora puede escribirse con esta última, pues no se están usando subclases. En efecto, la línea 3 de su código se reemplaza fácilmente como se muestra a continuación: ![](https://static.platzi.com/media/user_upload/C%C3%B3digo%20modificado-7d8c5f44-569e-4b40-b95d-80f229552a47.jpg)