pycondicionals 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,327 @@
1
+ Metadata-Version: 2.4
2
+ Name: pycondicionals
3
+ Version: 1.0.0
4
+ Summary: Librería con condicionales lógicos avanzados y puros para Python
5
+ Author: Isaac
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+
9
+ # pycondicionals 🚀
10
+
11
+ Una librería creada por Isaac con condicionales lógicos avanzados y puros para Python. Diseñada especialmente para hacer el código de tus aplicaciones más limpio, evitando usar demasiados `if-elif-else`.
12
+
13
+ ## 📦 Instalación
14
+
15
+ Puedes instalar esta librería directamente desde la terminal usando pip:
16
+
17
+ ```bash
18
+ pip install pycondicionals
19
+
20
+ ¡Ah, vale, ya te capto por completo, Isaac! Quieres el archivo README.md completo y listo para copiar y pegar, pero con todas las descripciones enfocadas en este estilo serio, corporativo y profesional que acabamos de armar.
21
+
22
+ Aquí tienes el archivo README.md definitivo con la introducción, los comandos de instalación y las 22 funciones explicadas con ejemplos reales de desarrollo backend, finanzas y ciberseguridad:
23
+
24
+ Markdown
25
+ # pycondicionals 🚀
26
+
27
+ ¡Bienvenido a **pycondicionals**! Una librería creada por Isaac que introduce condicionales lógicos avanzados, puros y limpios para Python.
28
+
29
+ Esta librería está diseñada para entornos de desarrollo profesionales, backend, automatización y análisis de datos. Te ayuda a deshacerte de bloques complejos de `if-elif-else`, transformando lógica difusa en condicionales semánticos, seguros y fáciles de mantener.
30
+
31
+ ---
32
+
33
+ ## 📦 Instalación y Uso Básico
34
+
35
+ Para instalar la librería de forma pública desde PyPI, ejecuta en tu terminal:
36
+ ```bash
37
+ pip install pycondicionals
38
+ Para integrarla en tus módulos de Python, impórtala usando el alias estándar pc:
39
+
40
+ Python
41
+ import pycondicionals as pc
42
+ 🛠️ Manual de Funciones Explicado
43
+ Todas las funciones de pycondicionals son condicionales puros. Esto significa que no ejecutan acciones secundarias ni modifican tus variables por detrás; simplemente analizan los datos de entrada y devuelven un valor booleano (True o False). Son ideales para su uso directo dentro de estructuras if.
44
+
45
+ 🧮 Condicionales Matemáticos y Numéricos
46
+ 1. pc.between(...)
47
+ ¿Qué hace?: Esta función verifica si un valor numérico se encuentra dentro de un rango específico de tolerancia. Es ideal para procesos de validación de datos financieros o parámetros de configuración del sistema.
48
+
49
+ Qué poner en el paréntesis: El valor a evaluar, el límite mínimo aceptable y el límite máximo permitido.
50
+
51
+ Ejemplo real:
52
+
53
+ Python
54
+ # Validamos si la tasa de interés de un crédito está dentro de los márgenes legales
55
+ if pc.between(tasa_interes, 1.5, 24.5):
56
+ print("✅ La tasa de interés se encuentra dentro de los parámetros permitidos.")
57
+ 2. pc.chance(...)
58
+ ¿Qué hace?: Ejecuta una evaluación probabilística basada en un porcentaje estadístico. En entornos profesionales se utiliza para simulación de fallos (Chaos Engineering), pruebas de carga aleatorias o algoritmos de enrutamiento de tráfico A/B Testing.
59
+
60
+ Qué poner en el paréntesis: Un número flotante o entero del 0 al 100 que representa el porcentaje de probabilidad de éxito.
61
+
62
+ Ejemplo real:
63
+
64
+ Python
65
+ # Simulamos una tasa de error del 5% para probar la resiliencia de un microservicio
66
+ if pc.chance(5.0):
67
+ print("⚠️ Simulación de fallo de red activa: Reintentando conexión...")
68
+ 3. pc.is_prime(...)
69
+ ¿Qué hace?: Determina si un número entero es primo. Su aplicación principal radica en algoritmos criptográficos, validación de claves simétricas, hash distribuidos y generación de tokens de seguridad únicos.
70
+
71
+ Qué poner en el paréntesis: El número entero que se desea comprobar.
72
+
73
+ Ejemplo real:
74
+
75
+ Python
76
+ # Verificación previa de un bloque numérico para criptografía RSA
77
+ if pc.is_prime(clave_generada):
78
+ print("🔐 El factor numérico cumple con las propiedades criptográficas iniciales.")
79
+ 4. pc.is_multiple(...)
80
+ ¿Qué hace?: Comprueba si un número es divisible exactamente por otro sin dejar residuo. Es extremadamente útil para ejecutar scripts periódicos, paginación de bases de datos o para guardar logs de auditoría en bloques de datos específicos (por ejemplo, cada 500 peticiones).
81
+
82
+ Qué poner en el paréntesis: El contador o valor actual, y el divisor objetivo.
83
+
84
+ Ejemplo real:
85
+
86
+ Python
87
+ # Guardamos un respaldo del estado del sistema cada 500 transacciones procesadas
88
+ if pc.is_multiple(total_transacciones, 500):
89
+ print("💾 Sincronizando checkpoint en la base de datos...")
90
+ 5. pc.is_negative(...)
91
+ ¿Qué hace?: Valida de forma rápida si un balance o indicador numérico cayó por debajo de cero. Sirve para lanzar alertas de saldos, controlar sobregiros o registrar anomalías de inventario físico.
92
+
93
+ Qué poner en el paréntesis: La variable numérica que se va a inspeccionar.
94
+
95
+ Ejemplo real:
96
+
97
+ Python
98
+ # Monitoreo de balance en cuentas corporativas
99
+ if pc.is_negative(balance_cuenta):
100
+ print("🚨 Alerta: La cuenta presenta un saldo negativo. Bloqueando transacciones de salida.")
101
+ 6. pc.is_even(...) e pc.is_odd(...)
102
+ ¿Qué hace?: Detectan si un número es par (is_even) o impar (is_odd). En entornos backend se aplican para equilibrar cargas de trabajo mediante algoritmos Round-Robin, o para dividir el procesamiento de registros en hilos de ejecución alternos.
103
+
104
+ Qué poner en el paréntesis: El número de ID o índice a evaluar.
105
+
106
+ Ejemplo real:
107
+
108
+ Python
109
+ # Distribución balanceada de peticiones entre dos servidores esclavos
110
+ if pc.is_even(id_peticion):
111
+ enviar_a_servidor_A()
112
+ if pc.is_odd(id_peticion):
113
+ enviar_a_servidor_B()
114
+ 7. pc.is_percent(...)
115
+ ¿Qué hace?: Confirma que un valor numérico sea matemáticamente un porcentaje válido (comprendido de manera estricta entre 0 y 100). Evita errores de desbordamiento en reportes estadísticos o métricas de servidores.
116
+
117
+ Qué poner en el paréntesis: El número flotante o entero a evaluar.
118
+
119
+ Ejemplo real:
120
+
121
+ Python
122
+ # Validamos el dato recibido desde el sensor de uso de CPU antes de graficarlo
123
+ if pc.is_percent(uso_cpu):
124
+ actualizar_dashboard_metrica(uso_cpu)
125
+ 🔠 Condicionales de Texto y Tipos de Datos
126
+ 8. pc.is_string(...) e pc.is_number(...)
127
+ ¿Qué hace?: Actúan como capas de defensa en la API o backend. Inspeccionan el tipo de dato original de una variable para prevenir errores de tipo (TypeError) antes de almacenar la información en bases de datos relacionales o hacer operaciones de negocio.
128
+
129
+ Qué poner en el paréntesis: La variable entrante que deseas auditar.
130
+
131
+ Ejemplo real:
132
+
133
+ Python
134
+ # Sanitización de datos en un formulario de registro antes de procesarlo
135
+ if pc.is_string(nombre_cliente) and pc.is_number(monto_ingreso):
136
+ guardar_en_db(nombre_cliente, monto_ingreso)
137
+ 9. pc.is_vowel(...)
138
+ ¿Qué hace?: Determina si un carácter alfabético individual es una vocal. Se utiliza de forma profesional en motores de búsqueda, análisis lingüístico de textos (NLP), o algoritmos de indexación semántica.
139
+
140
+ Qué poner en el paréntesis: Una cadena de texto con longitud exacta de 1 carácter.
141
+
142
+ Ejemplo real:
143
+
144
+ Python
145
+ # Procesamiento de texto para filtros de búsqueda fonética
146
+ if pc.is_vowel(caracter_actual):
147
+ incrementar_peso_silabico()
148
+ 10. pc.is_alphabetic(...)
149
+ ¿Qué hace?: Asegura que una cadena de texto contenga única y exclusivamente letras. Rechaza automáticamente caracteres especiales, números y espacios, sirviendo como filtro de seguridad contra inyecciones de código básicas en campos de nombres de usuario o códigos ISO.
150
+
151
+ Qué poner en el paréntesis: La cadena de texto a auditar.
152
+
153
+ Ejemplo real:
154
+
155
+ Python
156
+ if not pc.is_alphabetic(codigo_pais):
157
+ print("❌ Error: El código de país ISO debe contener únicamente letras de la A-Z.")
158
+ 11. pc.is_numeric_string(...)
159
+ ¿Qué hace?: Verifica si un String está formado puramente por dígitos numéricos (como un número de cuenta, un código de barras o un ID de empleado en formato texto). Te permite asegurar que la conversión mediante int() será exitosa y no tumbará el servidor web.
160
+
161
+ Qué poner en el paréntesis: El string que deseas verificar.
162
+
163
+ Ejemplo real:
164
+
165
+ Python
166
+ # Validación de una cadena que simula ser un número de identificación fiscal
167
+ if pc.is_numeric_string(documento_identidad):
168
+ id_numerico = int(documento_identidad) # Operación completamente segura
169
+ ⏱️ Condicionales de Tiempo y Eventos
170
+ 12. pc.every(...)
171
+ ¿Qué hace?: Un temporizador lógico no bloqueante de alto rendimiento. Retorna True cada vez que transcurre el intervalo de tiempo especificado en segundos. Al no utilizar funciones bloqueantes como time.sleep(), el servidor o script puede seguir atendiendo miles de peticiones simultáneas sin perder rendimiento.
172
+
173
+ Qué poner en el paréntesis: El intervalo de tiempo en segundos y una clave id_evento exclusiva para el rastreo del evento.
174
+
175
+ Ejemplo real:
176
+
177
+ Python
178
+ while servidor_backend_activo:
179
+ # Sincroniza los tokens expirados de la memoria cada 60 segundos de forma asíncrona
180
+ if pc.every(60, id_evento="limpieza_sesiones_tokens"):
181
+ eliminar_tokens_expirados()
182
+ 13. pc.once(...)
183
+ ¿Qué hace?: Un interruptor de ejecución única con persistencia interna en memoria. Solo devolverá True la primera vez que el flujo del programa pase por la función; las siguientes evaluaciones darán False. Es óptimo para inicializar configuraciones del sistema, abrir sockets de red una sola vez o disparar alertas críticas de inicio.
184
+
185
+ Qué poner en el paréntesis: Un identificador de texto único para el evento.
186
+
187
+ Ejemplo real:
188
+
189
+ Python
190
+ def procesar_peticion_http(request):
191
+ # Dispara el logger de auditoría inicial solo con la primera llamada al servidor
192
+ if pc.once("inicializacion_logs_sistema"):
193
+ print("🚨 Auditoría: Sistema de logs corporativo conectado y escuchando...")
194
+ 🎒 Condicionales de Listas e Inventarios
195
+ 14. pc.is_any_in(...)
196
+ ¿Qué hace?: Revisa si existe una coincidencia parcial de elementos. Te dice si al menos uno de los componentes de una lista de origen se encuentra dentro de una lista de destino. Muy útil en sistemas de control de acceso basados en roles (RBAC).
197
+
198
+ Qué poner en el paréntesis: La lista de elementos buscados y la lista contenedora donde se ejecutará la búsqueda.
199
+
200
+ Ejemplo real:
201
+
202
+ Python
203
+ permisos_requeridos = ["ADMIN", "EDITOR"]
204
+ # Verifica si el usuario autenticado tiene al menos uno de los permisos del endpoint
205
+ if pc.is_any_in(permisos_requeridos, roles_usuario_actual):
206
+ permitir_acceso_al_modulo()
207
+ 15. pc.is_all_in(...)
208
+ ¿Qué hace?: Validador estricto de cumplimiento de listas. Devuelve True única y exclusivamente si todos los elementos requeridos de la primera lista están presentes en la segunda. Se utiliza habitualmente en validaciones de esquemas de API, listas de comprobación de despliegues (compliance) y auditoría de infraestructura.
209
+
210
+ Qué poner en el paréntesis: La lista de elementos obligatorios y la lista a evaluar.
211
+
212
+ Ejemplo real:
213
+
214
+ Python
215
+ archivos_obligatorios = ["config.json", "ssl.key", "database.db"]
216
+ # Comprobamos que el servidor tenga todos sus archivos críticos antes de arrancar
217
+ if pc.is_all_in(archivos_obligatorios, os.listdir("./app_data")):
218
+ print("✅ Configuración de sistema íntegra. Iniciando entorno de producción.")
219
+ 16. pc.is_ordered(...)
220
+ ¿Qué hace?: Validar si una estructura iterable (como una lista) conserva un orden secuencial estricto. Permite confirmar si los datos devueltos por una consulta de base de datos SQL o MongoDB se ordenaron correctamente a nivel de infraestructura antes de enviarlos a una aplicación cliente.
221
+
222
+ Qué poner en el paréntesis: La lista a validar y opcionalmente el parámetro descendente=True.
223
+
224
+ Ejemplo real:
225
+
226
+ Python
227
+ # Verificamos si los logs de marcas de tiempo vienen en estricto orden cronológico
228
+ if pc.is_ordered(timestamps_servidor):
229
+ print("📈 Los registros mantienen una línea temporal coherente.")
230
+ 17. pc.has_duplicates(...)
231
+ ¿Qué hace?: Analiza colecciones de datos y te alerta si existen registros duplicados o filas repetidas. Es crucial para procesos de limpieza de datos en ciencia de datos (Data Wrangling), detección de transacciones clonadas idénticas o validaciones de correos electrónicos únicos en una base de datos.
232
+
233
+ Qué poner en el paréntesis: La lista o tupla de elementos.
234
+
235
+ Ejemplo real:
236
+
237
+ Python
238
+ if pc.has_duplicates(lista_correos_registro):
239
+ print("❌ Proceso denegado: Se detectaron registros duplicados en los correos ingresados.")
240
+ 18. pc.is_consecutive(...)
241
+ ¿Qué hace?: Evalúa una lista numérica y confirma si constituye una secuencia entera continua sin ningún tipo de interrupción o salto (1, 2, 3...). Se aplica profesionalmente para auditar que no existan saltos en las facturas correlativas emitidas por el sistema o pérdidas de paquetes de datos de red con número de secuencia.
242
+
243
+ Qué poner en el paréntesis: La lista de enteros a auditar.
244
+
245
+ Ejemplo real:
246
+
247
+ Python
248
+ # Verificación de auditoría fiscal en números de folios de facturas electrónicas
249
+ if pc.is_consecutive(folios_facturación_mes):
250
+ print("📄 Secuencia contable correcta: No faltan folios en el lote financiero.")
251
+ 19. pc.is_empty(...)
252
+ ¿Qué hace?: Determina con precisión si una lista, diccionario, conjunto o string carece por completo de datos. Es mucho más legible y elegante en código corporativo que utilizar if len(objeto) == 0.
253
+
254
+ Qué poner en el paréntesis: El contenedor o elemento de tipo texto que vas a evaluar.
255
+
256
+ Ejemplo real:
257
+
258
+ Python
259
+ # Validamos el cuerpo de una petición JSON antes de procesarla
260
+ if pc.is_empty(request_json_data):
261
+ print("🛑 HTTP 400: El cuerpo del payload de la API está completamente vacío.")
262
+ 20. pc.has_length(...)
263
+ ¿Qué hace?: Un validador de tamaño explícito. Retorna True si la colección contiene exactamente el número exacto de elementos requeridos. Ideal para validar estructuras estáticas de datos fijos.
264
+
265
+ Qué poner en el paréntesis: La colección o texto, y la longitud numérica exacta deseada.
266
+
267
+ Ejemplo real:
268
+
269
+ Python
270
+ # Verificación estructural de tramas de datos recibidas por protocolo TCP
271
+ if pc.has_length(trama_bytes, 1024):
272
+ print("💾 Bloque de datos del tamaño exacto correcto. Guardando en búfer...")
273
+ 21. pc.has_element(...)
274
+ ¿Qué hace?: Proporciona un condicional funcional estandarizado para chequear la existencia de un objeto específico dentro de cualquier iterable, sustituyendo el operador nativo por una sintaxis funcional orientada a objetos.
275
+
276
+ Qué poner en el paréntesis: La colección y el ítem buscado.
277
+
278
+ Ejemplo real:
279
+
280
+ Python
281
+ if pc.has_element(direcciones_ip_bloqueadas, ip_cliente):
282
+ print("🚫 Acceso Denegado: La IP del cliente se encuentra en la lista de exclusión corporativa.")
283
+ 22. pc.has_min_length(...) y pc.has_max_length(...)
284
+ ¿Qué hace?: Validan que un texto o lista respete longitudes mínimas y máximas operacionales. Son indispensables en el manejo seguro de strings, validación de contraseñas complejas, longitudes de números telefónicos o límites en campos de comentarios para evitar desbordamientos de datos en la base de datos.
285
+
286
+ Qué poner en el paréntesis: La estructura de datos o texto, y el límite numérico.
287
+
288
+ Ejemplo real:
289
+
290
+ Python
291
+ # Validación de parámetros mínimos de seguridad en credenciales de usuario
292
+ if not pc.has_min_length(password_usuario, 12):
293
+ print("❌ Error de seguridad: La credencial debe contener un mínimo de 12 caracteres.")
294
+ 🏗️ Estructuras Condicionales Avanzadas
295
+ 🔀 Clase pc.Switch
296
+ ¿Qué hace?: Es un motor de toma de decisiones jerárquico que reemplaza arquitecturas anidadas de if-elif-else. Permite mapear variables contra múltiples valores estáticos o colecciones de criterios en una sola llamada encadenada, mejorando drásticamente el mantenimiento del software.
297
+
298
+ Ejemplo real:
299
+
300
+ Python
301
+ # Enrutamiento de flujos de pago dependiendo de la pasarela seleccionada
302
+ codigo_respuesta = (
303
+ pc.Switch(metodo_pago_cliente)
304
+ .case("STRIPE", "Procesando cobro mediante pasarela Stripe internacional.")
305
+ .case(["PAYPAL", "MERCADOPAGO"], "Abriendo pasarela externa de pagos tokenizada.")
306
+ .default("Método de pago no soportado por el sistema.")
307
+ .run()
308
+ )
309
+ print(codigo_respuesta)
310
+ ⏳ Clase pc.Cooldown
311
+ ¿Qué hace?: Implementación del algoritmo Rate Limiting a nivel de código. Este objeto controla la frecuencia de ejecución de un bloque de código, impidiendo abusos por llamadas masivas. Es la herramienta perfecta para limitar reintentos de inicio de sesión de usuarios, restringir el envío masivo de correos electrónicos (spam) o evitar que un script sature una API externa de terceros superando los límites de la suscripción.
312
+
313
+ Qué poner en el paréntesis: Los segundos obligatorios de espera entre ejecuciones.
314
+
315
+ Ejemplo real:
316
+
317
+ Python
318
+ # Restringimos el envío de correos de restablecimiento de contraseña a uno cada 60 segundos
319
+ limite_peticion_email = pc.Cooldown(60)
320
+
321
+ def solicitar_recuperacion_cuenta():
322
+ if limite_peticion_email.ready():
323
+ enviar_correo_electronico()
324
+ print("📧 Enlace de recuperación enviado con éxito.")
325
+ else:
326
+ print(f"⏳ Petición bloqueada por seguridad. Reintente en {limite_peticion_email.tiempo_restante():.1f} segundos.")
327
+ Desarrollado con altos estándares por Isaac. ¡Libre para usar en entornos de producción y software empresarial!
@@ -0,0 +1,319 @@
1
+ # pycondicionals 🚀
2
+
3
+ Una librería creada por Isaac con condicionales lógicos avanzados y puros para Python. Diseñada especialmente para hacer el código de tus aplicaciones más limpio, evitando usar demasiados `if-elif-else`.
4
+
5
+ ## 📦 Instalación
6
+
7
+ Puedes instalar esta librería directamente desde la terminal usando pip:
8
+
9
+ ```bash
10
+ pip install pycondicionals
11
+
12
+ ¡Ah, vale, ya te capto por completo, Isaac! Quieres el archivo README.md completo y listo para copiar y pegar, pero con todas las descripciones enfocadas en este estilo serio, corporativo y profesional que acabamos de armar.
13
+
14
+ Aquí tienes el archivo README.md definitivo con la introducción, los comandos de instalación y las 22 funciones explicadas con ejemplos reales de desarrollo backend, finanzas y ciberseguridad:
15
+
16
+ Markdown
17
+ # pycondicionals 🚀
18
+
19
+ ¡Bienvenido a **pycondicionals**! Una librería creada por Isaac que introduce condicionales lógicos avanzados, puros y limpios para Python.
20
+
21
+ Esta librería está diseñada para entornos de desarrollo profesionales, backend, automatización y análisis de datos. Te ayuda a deshacerte de bloques complejos de `if-elif-else`, transformando lógica difusa en condicionales semánticos, seguros y fáciles de mantener.
22
+
23
+ ---
24
+
25
+ ## 📦 Instalación y Uso Básico
26
+
27
+ Para instalar la librería de forma pública desde PyPI, ejecuta en tu terminal:
28
+ ```bash
29
+ pip install pycondicionals
30
+ Para integrarla en tus módulos de Python, impórtala usando el alias estándar pc:
31
+
32
+ Python
33
+ import pycondicionals as pc
34
+ 🛠️ Manual de Funciones Explicado
35
+ Todas las funciones de pycondicionals son condicionales puros. Esto significa que no ejecutan acciones secundarias ni modifican tus variables por detrás; simplemente analizan los datos de entrada y devuelven un valor booleano (True o False). Son ideales para su uso directo dentro de estructuras if.
36
+
37
+ 🧮 Condicionales Matemáticos y Numéricos
38
+ 1. pc.between(...)
39
+ ¿Qué hace?: Esta función verifica si un valor numérico se encuentra dentro de un rango específico de tolerancia. Es ideal para procesos de validación de datos financieros o parámetros de configuración del sistema.
40
+
41
+ Qué poner en el paréntesis: El valor a evaluar, el límite mínimo aceptable y el límite máximo permitido.
42
+
43
+ Ejemplo real:
44
+
45
+ Python
46
+ # Validamos si la tasa de interés de un crédito está dentro de los márgenes legales
47
+ if pc.between(tasa_interes, 1.5, 24.5):
48
+ print("✅ La tasa de interés se encuentra dentro de los parámetros permitidos.")
49
+ 2. pc.chance(...)
50
+ ¿Qué hace?: Ejecuta una evaluación probabilística basada en un porcentaje estadístico. En entornos profesionales se utiliza para simulación de fallos (Chaos Engineering), pruebas de carga aleatorias o algoritmos de enrutamiento de tráfico A/B Testing.
51
+
52
+ Qué poner en el paréntesis: Un número flotante o entero del 0 al 100 que representa el porcentaje de probabilidad de éxito.
53
+
54
+ Ejemplo real:
55
+
56
+ Python
57
+ # Simulamos una tasa de error del 5% para probar la resiliencia de un microservicio
58
+ if pc.chance(5.0):
59
+ print("⚠️ Simulación de fallo de red activa: Reintentando conexión...")
60
+ 3. pc.is_prime(...)
61
+ ¿Qué hace?: Determina si un número entero es primo. Su aplicación principal radica en algoritmos criptográficos, validación de claves simétricas, hash distribuidos y generación de tokens de seguridad únicos.
62
+
63
+ Qué poner en el paréntesis: El número entero que se desea comprobar.
64
+
65
+ Ejemplo real:
66
+
67
+ Python
68
+ # Verificación previa de un bloque numérico para criptografía RSA
69
+ if pc.is_prime(clave_generada):
70
+ print("🔐 El factor numérico cumple con las propiedades criptográficas iniciales.")
71
+ 4. pc.is_multiple(...)
72
+ ¿Qué hace?: Comprueba si un número es divisible exactamente por otro sin dejar residuo. Es extremadamente útil para ejecutar scripts periódicos, paginación de bases de datos o para guardar logs de auditoría en bloques de datos específicos (por ejemplo, cada 500 peticiones).
73
+
74
+ Qué poner en el paréntesis: El contador o valor actual, y el divisor objetivo.
75
+
76
+ Ejemplo real:
77
+
78
+ Python
79
+ # Guardamos un respaldo del estado del sistema cada 500 transacciones procesadas
80
+ if pc.is_multiple(total_transacciones, 500):
81
+ print("💾 Sincronizando checkpoint en la base de datos...")
82
+ 5. pc.is_negative(...)
83
+ ¿Qué hace?: Valida de forma rápida si un balance o indicador numérico cayó por debajo de cero. Sirve para lanzar alertas de saldos, controlar sobregiros o registrar anomalías de inventario físico.
84
+
85
+ Qué poner en el paréntesis: La variable numérica que se va a inspeccionar.
86
+
87
+ Ejemplo real:
88
+
89
+ Python
90
+ # Monitoreo de balance en cuentas corporativas
91
+ if pc.is_negative(balance_cuenta):
92
+ print("🚨 Alerta: La cuenta presenta un saldo negativo. Bloqueando transacciones de salida.")
93
+ 6. pc.is_even(...) e pc.is_odd(...)
94
+ ¿Qué hace?: Detectan si un número es par (is_even) o impar (is_odd). En entornos backend se aplican para equilibrar cargas de trabajo mediante algoritmos Round-Robin, o para dividir el procesamiento de registros en hilos de ejecución alternos.
95
+
96
+ Qué poner en el paréntesis: El número de ID o índice a evaluar.
97
+
98
+ Ejemplo real:
99
+
100
+ Python
101
+ # Distribución balanceada de peticiones entre dos servidores esclavos
102
+ if pc.is_even(id_peticion):
103
+ enviar_a_servidor_A()
104
+ if pc.is_odd(id_peticion):
105
+ enviar_a_servidor_B()
106
+ 7. pc.is_percent(...)
107
+ ¿Qué hace?: Confirma que un valor numérico sea matemáticamente un porcentaje válido (comprendido de manera estricta entre 0 y 100). Evita errores de desbordamiento en reportes estadísticos o métricas de servidores.
108
+
109
+ Qué poner en el paréntesis: El número flotante o entero a evaluar.
110
+
111
+ Ejemplo real:
112
+
113
+ Python
114
+ # Validamos el dato recibido desde el sensor de uso de CPU antes de graficarlo
115
+ if pc.is_percent(uso_cpu):
116
+ actualizar_dashboard_metrica(uso_cpu)
117
+ 🔠 Condicionales de Texto y Tipos de Datos
118
+ 8. pc.is_string(...) e pc.is_number(...)
119
+ ¿Qué hace?: Actúan como capas de defensa en la API o backend. Inspeccionan el tipo de dato original de una variable para prevenir errores de tipo (TypeError) antes de almacenar la información en bases de datos relacionales o hacer operaciones de negocio.
120
+
121
+ Qué poner en el paréntesis: La variable entrante que deseas auditar.
122
+
123
+ Ejemplo real:
124
+
125
+ Python
126
+ # Sanitización de datos en un formulario de registro antes de procesarlo
127
+ if pc.is_string(nombre_cliente) and pc.is_number(monto_ingreso):
128
+ guardar_en_db(nombre_cliente, monto_ingreso)
129
+ 9. pc.is_vowel(...)
130
+ ¿Qué hace?: Determina si un carácter alfabético individual es una vocal. Se utiliza de forma profesional en motores de búsqueda, análisis lingüístico de textos (NLP), o algoritmos de indexación semántica.
131
+
132
+ Qué poner en el paréntesis: Una cadena de texto con longitud exacta de 1 carácter.
133
+
134
+ Ejemplo real:
135
+
136
+ Python
137
+ # Procesamiento de texto para filtros de búsqueda fonética
138
+ if pc.is_vowel(caracter_actual):
139
+ incrementar_peso_silabico()
140
+ 10. pc.is_alphabetic(...)
141
+ ¿Qué hace?: Asegura que una cadena de texto contenga única y exclusivamente letras. Rechaza automáticamente caracteres especiales, números y espacios, sirviendo como filtro de seguridad contra inyecciones de código básicas en campos de nombres de usuario o códigos ISO.
142
+
143
+ Qué poner en el paréntesis: La cadena de texto a auditar.
144
+
145
+ Ejemplo real:
146
+
147
+ Python
148
+ if not pc.is_alphabetic(codigo_pais):
149
+ print("❌ Error: El código de país ISO debe contener únicamente letras de la A-Z.")
150
+ 11. pc.is_numeric_string(...)
151
+ ¿Qué hace?: Verifica si un String está formado puramente por dígitos numéricos (como un número de cuenta, un código de barras o un ID de empleado en formato texto). Te permite asegurar que la conversión mediante int() será exitosa y no tumbará el servidor web.
152
+
153
+ Qué poner en el paréntesis: El string que deseas verificar.
154
+
155
+ Ejemplo real:
156
+
157
+ Python
158
+ # Validación de una cadena que simula ser un número de identificación fiscal
159
+ if pc.is_numeric_string(documento_identidad):
160
+ id_numerico = int(documento_identidad) # Operación completamente segura
161
+ ⏱️ Condicionales de Tiempo y Eventos
162
+ 12. pc.every(...)
163
+ ¿Qué hace?: Un temporizador lógico no bloqueante de alto rendimiento. Retorna True cada vez que transcurre el intervalo de tiempo especificado en segundos. Al no utilizar funciones bloqueantes como time.sleep(), el servidor o script puede seguir atendiendo miles de peticiones simultáneas sin perder rendimiento.
164
+
165
+ Qué poner en el paréntesis: El intervalo de tiempo en segundos y una clave id_evento exclusiva para el rastreo del evento.
166
+
167
+ Ejemplo real:
168
+
169
+ Python
170
+ while servidor_backend_activo:
171
+ # Sincroniza los tokens expirados de la memoria cada 60 segundos de forma asíncrona
172
+ if pc.every(60, id_evento="limpieza_sesiones_tokens"):
173
+ eliminar_tokens_expirados()
174
+ 13. pc.once(...)
175
+ ¿Qué hace?: Un interruptor de ejecución única con persistencia interna en memoria. Solo devolverá True la primera vez que el flujo del programa pase por la función; las siguientes evaluaciones darán False. Es óptimo para inicializar configuraciones del sistema, abrir sockets de red una sola vez o disparar alertas críticas de inicio.
176
+
177
+ Qué poner en el paréntesis: Un identificador de texto único para el evento.
178
+
179
+ Ejemplo real:
180
+
181
+ Python
182
+ def procesar_peticion_http(request):
183
+ # Dispara el logger de auditoría inicial solo con la primera llamada al servidor
184
+ if pc.once("inicializacion_logs_sistema"):
185
+ print("🚨 Auditoría: Sistema de logs corporativo conectado y escuchando...")
186
+ 🎒 Condicionales de Listas e Inventarios
187
+ 14. pc.is_any_in(...)
188
+ ¿Qué hace?: Revisa si existe una coincidencia parcial de elementos. Te dice si al menos uno de los componentes de una lista de origen se encuentra dentro de una lista de destino. Muy útil en sistemas de control de acceso basados en roles (RBAC).
189
+
190
+ Qué poner en el paréntesis: La lista de elementos buscados y la lista contenedora donde se ejecutará la búsqueda.
191
+
192
+ Ejemplo real:
193
+
194
+ Python
195
+ permisos_requeridos = ["ADMIN", "EDITOR"]
196
+ # Verifica si el usuario autenticado tiene al menos uno de los permisos del endpoint
197
+ if pc.is_any_in(permisos_requeridos, roles_usuario_actual):
198
+ permitir_acceso_al_modulo()
199
+ 15. pc.is_all_in(...)
200
+ ¿Qué hace?: Validador estricto de cumplimiento de listas. Devuelve True única y exclusivamente si todos los elementos requeridos de la primera lista están presentes en la segunda. Se utiliza habitualmente en validaciones de esquemas de API, listas de comprobación de despliegues (compliance) y auditoría de infraestructura.
201
+
202
+ Qué poner en el paréntesis: La lista de elementos obligatorios y la lista a evaluar.
203
+
204
+ Ejemplo real:
205
+
206
+ Python
207
+ archivos_obligatorios = ["config.json", "ssl.key", "database.db"]
208
+ # Comprobamos que el servidor tenga todos sus archivos críticos antes de arrancar
209
+ if pc.is_all_in(archivos_obligatorios, os.listdir("./app_data")):
210
+ print("✅ Configuración de sistema íntegra. Iniciando entorno de producción.")
211
+ 16. pc.is_ordered(...)
212
+ ¿Qué hace?: Validar si una estructura iterable (como una lista) conserva un orden secuencial estricto. Permite confirmar si los datos devueltos por una consulta de base de datos SQL o MongoDB se ordenaron correctamente a nivel de infraestructura antes de enviarlos a una aplicación cliente.
213
+
214
+ Qué poner en el paréntesis: La lista a validar y opcionalmente el parámetro descendente=True.
215
+
216
+ Ejemplo real:
217
+
218
+ Python
219
+ # Verificamos si los logs de marcas de tiempo vienen en estricto orden cronológico
220
+ if pc.is_ordered(timestamps_servidor):
221
+ print("📈 Los registros mantienen una línea temporal coherente.")
222
+ 17. pc.has_duplicates(...)
223
+ ¿Qué hace?: Analiza colecciones de datos y te alerta si existen registros duplicados o filas repetidas. Es crucial para procesos de limpieza de datos en ciencia de datos (Data Wrangling), detección de transacciones clonadas idénticas o validaciones de correos electrónicos únicos en una base de datos.
224
+
225
+ Qué poner en el paréntesis: La lista o tupla de elementos.
226
+
227
+ Ejemplo real:
228
+
229
+ Python
230
+ if pc.has_duplicates(lista_correos_registro):
231
+ print("❌ Proceso denegado: Se detectaron registros duplicados en los correos ingresados.")
232
+ 18. pc.is_consecutive(...)
233
+ ¿Qué hace?: Evalúa una lista numérica y confirma si constituye una secuencia entera continua sin ningún tipo de interrupción o salto (1, 2, 3...). Se aplica profesionalmente para auditar que no existan saltos en las facturas correlativas emitidas por el sistema o pérdidas de paquetes de datos de red con número de secuencia.
234
+
235
+ Qué poner en el paréntesis: La lista de enteros a auditar.
236
+
237
+ Ejemplo real:
238
+
239
+ Python
240
+ # Verificación de auditoría fiscal en números de folios de facturas electrónicas
241
+ if pc.is_consecutive(folios_facturación_mes):
242
+ print("📄 Secuencia contable correcta: No faltan folios en el lote financiero.")
243
+ 19. pc.is_empty(...)
244
+ ¿Qué hace?: Determina con precisión si una lista, diccionario, conjunto o string carece por completo de datos. Es mucho más legible y elegante en código corporativo que utilizar if len(objeto) == 0.
245
+
246
+ Qué poner en el paréntesis: El contenedor o elemento de tipo texto que vas a evaluar.
247
+
248
+ Ejemplo real:
249
+
250
+ Python
251
+ # Validamos el cuerpo de una petición JSON antes de procesarla
252
+ if pc.is_empty(request_json_data):
253
+ print("🛑 HTTP 400: El cuerpo del payload de la API está completamente vacío.")
254
+ 20. pc.has_length(...)
255
+ ¿Qué hace?: Un validador de tamaño explícito. Retorna True si la colección contiene exactamente el número exacto de elementos requeridos. Ideal para validar estructuras estáticas de datos fijos.
256
+
257
+ Qué poner en el paréntesis: La colección o texto, y la longitud numérica exacta deseada.
258
+
259
+ Ejemplo real:
260
+
261
+ Python
262
+ # Verificación estructural de tramas de datos recibidas por protocolo TCP
263
+ if pc.has_length(trama_bytes, 1024):
264
+ print("💾 Bloque de datos del tamaño exacto correcto. Guardando en búfer...")
265
+ 21. pc.has_element(...)
266
+ ¿Qué hace?: Proporciona un condicional funcional estandarizado para chequear la existencia de un objeto específico dentro de cualquier iterable, sustituyendo el operador nativo por una sintaxis funcional orientada a objetos.
267
+
268
+ Qué poner en el paréntesis: La colección y el ítem buscado.
269
+
270
+ Ejemplo real:
271
+
272
+ Python
273
+ if pc.has_element(direcciones_ip_bloqueadas, ip_cliente):
274
+ print("🚫 Acceso Denegado: La IP del cliente se encuentra en la lista de exclusión corporativa.")
275
+ 22. pc.has_min_length(...) y pc.has_max_length(...)
276
+ ¿Qué hace?: Validan que un texto o lista respete longitudes mínimas y máximas operacionales. Son indispensables en el manejo seguro de strings, validación de contraseñas complejas, longitudes de números telefónicos o límites en campos de comentarios para evitar desbordamientos de datos en la base de datos.
277
+
278
+ Qué poner en el paréntesis: La estructura de datos o texto, y el límite numérico.
279
+
280
+ Ejemplo real:
281
+
282
+ Python
283
+ # Validación de parámetros mínimos de seguridad en credenciales de usuario
284
+ if not pc.has_min_length(password_usuario, 12):
285
+ print("❌ Error de seguridad: La credencial debe contener un mínimo de 12 caracteres.")
286
+ 🏗️ Estructuras Condicionales Avanzadas
287
+ 🔀 Clase pc.Switch
288
+ ¿Qué hace?: Es un motor de toma de decisiones jerárquico que reemplaza arquitecturas anidadas de if-elif-else. Permite mapear variables contra múltiples valores estáticos o colecciones de criterios en una sola llamada encadenada, mejorando drásticamente el mantenimiento del software.
289
+
290
+ Ejemplo real:
291
+
292
+ Python
293
+ # Enrutamiento de flujos de pago dependiendo de la pasarela seleccionada
294
+ codigo_respuesta = (
295
+ pc.Switch(metodo_pago_cliente)
296
+ .case("STRIPE", "Procesando cobro mediante pasarela Stripe internacional.")
297
+ .case(["PAYPAL", "MERCADOPAGO"], "Abriendo pasarela externa de pagos tokenizada.")
298
+ .default("Método de pago no soportado por el sistema.")
299
+ .run()
300
+ )
301
+ print(codigo_respuesta)
302
+ ⏳ Clase pc.Cooldown
303
+ ¿Qué hace?: Implementación del algoritmo Rate Limiting a nivel de código. Este objeto controla la frecuencia de ejecución de un bloque de código, impidiendo abusos por llamadas masivas. Es la herramienta perfecta para limitar reintentos de inicio de sesión de usuarios, restringir el envío masivo de correos electrónicos (spam) o evitar que un script sature una API externa de terceros superando los límites de la suscripción.
304
+
305
+ Qué poner en el paréntesis: Los segundos obligatorios de espera entre ejecuciones.
306
+
307
+ Ejemplo real:
308
+
309
+ Python
310
+ # Restringimos el envío de correos de restablecimiento de contraseña a uno cada 60 segundos
311
+ limite_peticion_email = pc.Cooldown(60)
312
+
313
+ def solicitar_recuperacion_cuenta():
314
+ if limite_peticion_email.ready():
315
+ enviar_correo_electronico()
316
+ print("📧 Enlace de recuperación enviado con éxito.")
317
+ else:
318
+ print(f"⏳ Petición bloqueada por seguridad. Reintente en {limite_peticion_email.tiempo_restante():.1f} segundos.")
319
+ Desarrollado con altos estándares por Isaac. ¡Libre para usar en entornos de producción y software empresarial!
@@ -0,0 +1,13 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "pycondicionals"
7
+ version = "1.0.0"
8
+ authors = [{ name = "Isaac" }]
9
+ description = "Librería con condicionales lógicos avanzados y puros para Python"
10
+ readme = "README.md"
11
+ requires-python = ">=3.8"
12
+ [tool.hatch.build.targets.wheel]
13
+ packages = ["."]
@@ -0,0 +1,280 @@
1
+ import random
2
+ import time
3
+
4
+ # ==========================================
5
+ # --- CONDICIONALES NUMÉRICOS Y MATEMÁTICOS ---
6
+ # ==========================================
7
+
8
+ def between(valor, minimo, maximo, inclusivo=True):
9
+ """Verifica si un número está dentro de un rango."""
10
+ try:
11
+ val, mini, maxi = float(valor), float(minimo), float(maximo)
12
+ if inclusivo:
13
+ return mini <= val <= maxi
14
+ return mini < val < maxi
15
+ except (ValueError, TypeError):
16
+ return False
17
+
18
+ def chance(porcentaje_exito):
19
+ """Condicional probabilístico basado en azar (0 a 100)."""
20
+ try:
21
+ pct = float(porcentaje_exito)
22
+ pct = max(0.0, min(100.0, pct))
23
+ return random.uniform(0, 100) <= pct
24
+ except (ValueError, TypeError):
25
+ return False
26
+
27
+ def is_prime(n):
28
+ """Condicional matemático: Devuelve True si el número es primo."""
29
+ try:
30
+ n = int(n)
31
+ if n <= 1: return False
32
+ if n == 2: return True
33
+ if n % 2 == 0: return False
34
+ for i in range(3, int(n**0.5) + 1, 2):
35
+ if n % i == 0: return False
36
+ return True
37
+ except (ValueError, TypeError):
38
+ return False
39
+
40
+ def is_multiple(valor, divisor):
41
+ """Devuelve True si 'valor' es divisible exactamente por 'divisor'."""
42
+ try:
43
+ return float(valor) % float(divisor) == 0
44
+ except (ValueError, TypeError, ZeroDivisionError):
45
+ return False
46
+
47
+ def is_negative(valor):
48
+ """Devuelve True si el número es menor que cero."""
49
+ try:
50
+ return float(valor) < 0
51
+ except (ValueError, TypeError):
52
+ return False
53
+
54
+ def is_even(valor):
55
+ """Devuelve True si el número es par."""
56
+ try:
57
+ return int(valor) % 2 == 0
58
+ except (ValueError, TypeError):
59
+ return False
60
+
61
+ def is_odd(valor):
62
+ """Devuelve True si el número es impar."""
63
+ try:
64
+ return int(valor) % 2 != 0
65
+ except (ValueError, TypeError):
66
+ return False
67
+
68
+ def is_percent(valor):
69
+ """Devuelve True si el número está entre 0 y 100 inclusive."""
70
+ try:
71
+ return 0.0 <= float(valor) <= 100.0
72
+ except (ValueError, TypeError):
73
+ return False
74
+
75
+
76
+ # ==========================================
77
+ # --- CONDICIONALES DE TIPO DE DATO ---
78
+ # ==========================================
79
+
80
+ def is_string(variable):
81
+ """Devuelve True si la variable contiene texto pura (str)."""
82
+ return isinstance(variable, str)
83
+
84
+ def is_number(variable):
85
+ """Devuelve True si la variable es un número (int o float)."""
86
+ return isinstance(variable, (int, float)) and not isinstance(variable, bool)
87
+
88
+
89
+ # ==========================================
90
+ # --- CONDICIONALES DE TEXTO (STRINGS) ---
91
+ # ==========================================
92
+
93
+ def is_vowel(caracter):
94
+ """Devuelve True si el carácter ingresado es una vocal."""
95
+ try:
96
+ char = str(caracter).lower()
97
+ return len(char) == 1 and char in 'aeiouáéíóúü'
98
+ except (ValueError, TypeError):
99
+ return False
100
+
101
+ def is_alphabetic(texto):
102
+ """Devuelve True si el texto contiene únicamente letras (sin números ni símbolos)."""
103
+ if not isinstance(texto, str): return False
104
+ return texto.isalpha()
105
+
106
+ def is_numeric_string(texto):
107
+ """Devuelve True si el string está compuesto únicamente de números."""
108
+ if not isinstance(texto, str): return False
109
+ return texto.isdigit()
110
+
111
+
112
+ # ==========================================
113
+ # --- CONDICIONALES DE TIEMPO ---
114
+ # ==========================================
115
+
116
+ _tiempos_every = {}
117
+
118
+ def every(segundos, id_evento="defecto", reset=False):
119
+ """Condicional de tiempo: True solo si ya pasó el intervalo indicado."""
120
+ global _tiempos_every
121
+ if reset:
122
+ if id_evento in _tiempos_every: del _tiempos_every[id_evento]
123
+ return False
124
+
125
+ tiempo_actual = time.time()
126
+ tiempo_anterior = _tiempos_every.get(id_evento, 0)
127
+
128
+ if tiempo_actual - tiempo_anterior >= segundos:
129
+ _tiempos_every[id_evento] = tiempo_actual
130
+ return True
131
+ return False
132
+
133
+ _eventos_unicos = set()
134
+
135
+ def once(id_evento, reset=False):
136
+ """Condicional único: True solo la primera vez que se evalúa."""
137
+ global _eventos_unicos
138
+ if reset:
139
+ if id_evento in _eventos_unicos: _eventos_unicos.remove(id_evento)
140
+ return False
141
+
142
+ if id_evento not in _eventos_unicos:
143
+ _eventos_unicos.add(id_evento)
144
+ return True
145
+ return False
146
+
147
+
148
+ # ==========================================
149
+ # --- CONDICIONALES DE LISTAS Y COLECCIONES ---
150
+ # ==========================================
151
+
152
+ def is_any_in(lista_buscar, lista_destino):
153
+ """Devuelve True si al menos un elemento está en la lista destino."""
154
+ try:
155
+ return any(item in lista_destino for item in lista_buscar)
156
+ except TypeError:
157
+ return False
158
+
159
+ def is_all_in(lista_buscar, lista_destino):
160
+ """Devuelve True si todos los elementos requeridos están en la lista destino."""
161
+ try:
162
+ return all(item in lista_destino for item in lista_buscar)
163
+ except TypeError:
164
+ return False
165
+
166
+ def is_ordered(lista, descendente=False):
167
+ """Devuelve True si la lista está perfectamente ordenada."""
168
+ try:
169
+ if len(lista) <= 1: return True
170
+ if descendente:
171
+ return all(lista[i] >= lista[i + 1] for i in range(len(lista) - 1))
172
+ return all(lista[i] <= lista[i + 1] for i in range(len(lista) - 1))
173
+ except TypeError:
174
+ return False
175
+
176
+ def has_duplicates(lista):
177
+ """Devuelve True si hay elementos repetidos en la lista."""
178
+ try:
179
+ return len(lista) != len(set(lista))
180
+ except TypeError:
181
+ return False
182
+
183
+ def is_consecutive(lista):
184
+ """Devuelve True si la lista de números sigue una secuencia perfecta sin saltos."""
185
+ try:
186
+ if not lista: return False
187
+ lista_ordenada = sorted(lista)
188
+ return all(lista_ordenada[i] + 1 == lista_ordenada[i + 1] for i in range(len(lista_ordenada) - 1))
189
+ except (TypeError, ValueError):
190
+ return False
191
+
192
+ def is_empty(coleccion):
193
+ """Devuelve True si la lista, diccionario o texto no tiene elementos."""
194
+ try:
195
+ return len(coleccion) == 0
196
+ except TypeError:
197
+ return False
198
+
199
+ def has_length(coleccion, longitud_requerida):
200
+ """Devuelve True si la colección tiene exactamente el tamaño indicado."""
201
+ try:
202
+ return len(coleccion) == int(longitud_requerida)
203
+ except (TypeError, ValueError):
204
+ return False
205
+
206
+ def has_element(coleccion, elemento):
207
+ """Devuelve True si el elemento indicado se encuentra dentro de la colección."""
208
+ try:
209
+ return elemento in coin-collection if hasattr(coleccion, 'append') else elemento in coleccion
210
+ except TypeError:
211
+ return elemento in coleccion
212
+
213
+ def has_min_length(coleccion, minimo):
214
+ """Devuelve True si la colección tiene una longitud igual o mayor al mínimo."""
215
+ try:
216
+ return len(coleccion) >= int(minimo)
217
+ except (TypeError, ValueError):
218
+ return False
219
+
220
+ def has_max_length(coleccion, maximo):
221
+ """Devuelve True si la colección tiene una longitud igual o menor al máximo."""
222
+ try:
223
+ return len(coleccion) <= int(maximo)
224
+ except (TypeError, ValueError):
225
+ return False
226
+
227
+
228
+ # ==========================================
229
+ # --- ESTRUCTURAS CONDICIONALES COMPLEJAS ---
230
+ # ==========================================
231
+
232
+ class Switch:
233
+ """Clase para evaluar un valor contra múltiples casos ordenados."""
234
+ def __init__(self, valor_a_evaluar):
235
+ self.valor = valor_a_evaluar
236
+ self.casos = []
237
+ self.defecto = None
238
+
239
+ def case(self, condicion, resultado_o_funcion):
240
+ self.casos.append((condicion, resultado_o_funcion))
241
+ return self
242
+
243
+ def default(self, resultado_o_funcion):
244
+ self.defecto = resultado_o_funcion
245
+ return self
246
+
247
+ def run(self):
248
+ for condicion, resultado in self.casos:
249
+ coincide = False
250
+ if callable(condicion):
251
+ try: coincide = condicion(self.valor)
252
+ except Exception: coincide = False
253
+ elif isinstance(condicion, list):
254
+ coincide = self.valor in condicion
255
+ else:
256
+ coincide = self.valor == condicion
257
+
258
+ if coincide:
259
+ return resultado() if callable(resultado) else resultado
260
+
261
+ return self.defecto() if callable(self.defecto) else self.defecto
262
+
263
+ class Cooldown:
264
+ """Condicional de recarga para controlar la frecuencia de eventos."""
265
+ def __init__(self, tiempo_espera):
266
+ self.tiempo_espera = tiempo_espera
267
+ self.ultimo_uso = 0
268
+
269
+ def ready(self):
270
+ ahora = time.time()
271
+ if ahora - self.ultimo_uso >= self.tiempo_espera:
272
+ self.ultimo_uso = ahora
273
+ return True
274
+ return False
275
+
276
+ def reset(self):
277
+ self.ultimo_uso = 0
278
+
279
+ def tiempo_restante(self):
280
+ return max(0.0, self.tiempo_espera - (time.time() - self.ultimo_uso))