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.
- pycondicionals-1.0.0/PKG-INFO +327 -0
- pycondicionals-1.0.0/README.md +319 -0
- pycondicionals-1.0.0/pyproject.toml +13 -0
- pycondicionals-1.0.0/src/__init__.py +280 -0
|
@@ -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))
|