# data[].attributes.body
# Cristian Zhingre
# Diagramas de Venn

# Universo U = {1,2,…,30}
U = set(range(1, 31))

# Función para verificar si un número es primo
# Código reutilizado de la parte 1 para mostrar de mejor manera el ejemplo del diagrama.
def es_primo(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

# Conjunto A = números primos en U
A = {x for x in U if es_primo(x)}

# Conjunto B = cuadrados perfectos en U
B = {x for x in U if int(x**0.5)**2 == x}

# Conjunto C = múltiplos de 4 en U
C = {x for x in U if x % 4 == 0}

# Mostramos conjuntos por extensión
print("Conjunto A (primos):", sorted(A))
print("Conjunto B (cuadrados perfectos):", sorted(B))
print("Conjunto C (múltiplos de 4):", sorted(C))


# Operaciones de conjuntos

op1 = (A.union(C)) - B            # (A ∪ C) – B
op2 = (A.intersection(B)).union(C)  # (A ∩ B) ∪ C

# Mostramos resultados en consola
print("\n(A ∪ C) – B =", sorted(op1))
print("(A ∩ B) ∪ C =", sorted(op2))


# 3) CODIGO PARA GENERAR EL DIAGRAMA DE VENN


import matplotlib.pyplot as plt # matplotlib.pyplot para crear y mostrar gráficos
from matplotlib.patches import Circle # Circle para dibujar círculos manualmente si falla matplotlib-venn

fig, ax = plt.subplots(figsize=(8, 6))  # tamaño de la figura
ax.set_xlim(0, 10) # límites del eje X
ax.set_ylim(0, 8)  # límites del eje Y
ax.axis('off')   # quitar ejes para visualización limpia

try:
    # Librería especial para diagramas de Venn
    from matplotlib_venn import venn3, venn3_circles # librería para diagramas de Venn de 3 conjuntos

    # Creamos el diagrama de tres conjuntos
    v = venn3([A, B, C], set_labels=('A (Primos)', 'B (Cuadrados)', 'C (Múltiplos de 4)'))
    venn3_circles([A, B, C]) # dibujar contornos de los círculos

    # Agregamos resultados de las operaciones
    ax.set_title('Diagrama de Venn - Grupo 2')
    ax.text(0.5, -0.05, '(A ∪ C) – B = ' + str(sorted(op1)), transform=ax.transAxes, fontsize=9)
    ax.text(0.5, -0.12, '(A ∩ B) ∪ C = ' + str(sorted(op2)), transform=ax.transAxes, fontsize=9)

except Exception as e:
    # Si falla la librería matplotlib-venn, dibujar círculos manualmente
    # Método alternativo: dibujar los círculos
    c1 = Circle((3.5, 4.5), 2.2, alpha=0.3)
    c2 = Circle((5.5, 4.5), 2.2, alpha=0.3)
    c3 = Circle((4.5, 2.9), 2.2, alpha=0.3)
    ax.add_patch(c1)
    ax.add_patch(c2)
    ax.add_patch(c3)

    # Muestra los conjuntos dentro de los círculos
    ax.text(2.2, 6.6, 'A\n' + str(sorted(A)), fontsize=8)
    ax.text(6.0, 6.6, 'B\n' + str(sorted(B)), fontsize=8)
    ax.text(4.5, 1.0, 'C\n' + str(sorted(C)), fontsize=8)

    # Resalta las operaciones
    ax.set_title('Diagrama de Venn (manual) - Grupo 2')
    ax.text(0.1, -0.08, '(A ∪ C) – B = ' + str(sorted(op1)), transform=ax.transAxes, fontsize=9)
    ax.text(0.1, -0.16, '(A ∩ B) ∪ C = ' + str(sorted(op2)), transform=ax.transAxes, fontsize=9)

# Guardamos y mostramos la figura
plt.tight_layout()
plt.savefig('venn_grupo2.png', dpi=200)
plt.show()

# Exportar resultados a la carpeta de Google Colab

resultados = {"(A ∪ C) – B": sorted(op1), "(A ∩ B) ∪ C": sorted(op2)}

with open('resultados_grupo2.txt', 'w', encoding='utf-8') as f:
    for k, v in resultados.items():
        f.write(f"{k}: {v}\n")

print("\nArchivos generados: 'venn_grupo2.png' y 'resultados_grupo2.txt' (consulta la carpeta de archivos de Google Colab)")

# data[].attributes.body
Este código genera un diagrama de Venn de los conjuntos A, B y C usando matplotlib-venn. Si la librería no funciona, dibuja los círculos manualmente con matplotlib. Finalmente, muestra la imagen del diagrama con sus intersecciones.

# data[].attributes.body
# Definición del universo y construcción de A, B, C
# Universo U = {1, 2, 3, ..., 30}

# Creamos el universo de números del 1 al 30
# - range(1, 31) genera los números del 1 al 30 (el 31 no se incluye).
# - set() convierte esos números en un conjunto (sin repetidos).
U = set(range(1, 31))

# Definimos la función: es_primo

# Esta función recibe un número y devuelve True (si es primo) o
# False (si NO es primo).
# Recordemos que:
# - Un número primo solo se puede dividir entre 1 y él mismo.
# Ejemplos: 2, 3, 5, 7 son primos.
#           4, 6, 8, 9 no lo son.
#
# Operadores que se usan aquí:
# - % (módulo): devuelve el residuo de una división.
# - == (igualdad): compara dos valores.
# - * (multiplicación): multiplica números.

def es_primo(n):
    if n < 2:              # Los menores que 2 no son primos
        return False
    if n % 2 == 0:         # Si es par (múltiplo de 2), solo el 2 es primo
        return n == 2
    p = 3
    # Revisamos divisores impares hasta la raíz cuadrada del número
    while p * p <= n:
        if n % p == 0:     # Si encontramos un divisor exacto, no es primo
            return False
        p += 2             # Probamos con el siguiente número impar
    return True            # Si no encontramos divisores, sí es primo


# Construcción de los conjuntos

# Conjunto A: números primos en el universo
# Se recorren los números de U y se incluyen solo los que son primos.
A = {x for x in U if es_primo(x)}

# Conjunto B: números que son cuadrados perfectos en U
# - El operador ** (potencia) se usa aquí.
# - int(x**0.5) → calcula la raíz cuadrada de x y la convierte en entero.
#   Si al elevar ese entero al cuadrado nos devuelve x, entonces x es cuadrado perfecto.
B = {x for x in U if int(x**0.5)**2 == x}

# Conjunto C: múltiplos de 4 en U
# - Usamos el operador % (módulo).
#   Si x % 4 == 0 significa que x es divisible para 4 sin dejar residuo.
C = {x for x in U if x % 4 == 0}



# Mostramos los resultados

# La función sorted() ordena los elementos del conjunto para que se vean en orden.

print("Universo U =", sorted(U))
print("\nA (Primos) =", sorted(A))
print("B (Cuadrados Perfectos) =", sorted(B))
print("C (Múltiplos de 4) =", sorted(C))

# data[].attributes.headline
Maria Isaura Paillacho Velasco (Programadora)

# data[].attributes.subject
Maria Isaura Paillacho Velasco (Programadora)

# data[].attributes.body
# Maria Paillacho

# Universo U = {1, 2, 3, ..., 30}
U = set(range(1, 31))

# Definimos la función: es_primo
def es_primo(n):
    if n < 2:              # Los menores que 2 no son primos
        return False
    if n % 2 == 0:         # Si es par (múltiplo de 2), solo el 2 es primo
        return n == 2
    p = 3
    # Revisamos divisores impares hasta la raíz cuadrada del número
    while p * p <= n:
        if n % p == 0:     # Si encontramos un divisor exacto, no es primo
            return False
        p += 2             # Probamos con el siguiente número impar
    return True            # Si no encontramos divisores, sí es primo

# Conjunto A: números primos en el universo
A = {x for x in U if es_primo(x)}

# Conjunto B: números que son cuadrados perfectos en U
B = {x for x in U if int(x**0.5)**2 == x}

# Conjunto C: múltiplos de 4 en U
C = {x for x in U if x % 4 == 0}


# Operaciones asignadas al Grupo 2
# Operación 1: (A ∪ C) – B

# - A.union(C): Une los elementos de A y C (unión de conjuntos).
# - difference(B): Quita los elementos que estén en B.
op1 = (A.union(C)).difference(B)

# Operación 2: (A ∩ B) ∪ C

# - A.intersection(B): Devuelve los elementos que están en A y también en B (intersección).
# - union(C): Une ese resultado con los elementos de C.
op2 = (A.intersection(B)).union(C)


# Comprobaciones útiles (assert)

# assert es como una alarma revisa que se cumpla una condición.
# - issubset(U): revisa que A, B y C estén dentro del universo U.
# Si algún conjunto tiene un número fuera de U, se detiene el programa
# y muestra el mensaje de error.
assert A.issubset(U) and B.issubset(U) and C.issubset(U), "Algún conjunto tiene elementos fuera del universo U"


# Mostrar resultados en pantalla

# sorted() ordena los elementos de los conjuntos para que se lean fácilmente.
print("\nOperaciones del Grupo 2:")
print("(A ∪ C) – B =", sorted(op1))
print("(A ∩ B) ∪ C =", sorted(op2))


# Guardar resultados en un diccionario

# Un diccionario en Python funciona como una lista con "etiquetas".
# Tiene pares clave:valor, por ejemplo:
#   'A': [2,3,5,7] significa que la clave A guarda el conjunto de primos.

# Aquí guardamos todo junto (universo, conjuntos y operaciones)
# para que luego sea fácil exportarlo a un archivo o reutilizarlo.
resultados = {
    'U': sorted(U),
    'A': sorted(A),
    'B': sorted(B),
    'C': sorted(C),
    '(A∪C)-B': sorted(op1),
    '(A∩B)∪C': sorted(op2)
}

# data[].attributes.body
El siguiente código de este ejercicio lo que realiza es primero crea tres conjuntos especiales a partir del universo {1..30} que son A = números primos en U, B = números que son cuadrados perfectos en U y C = números que son múltiplos de 4 en U , luego hace dos operaciones de conjuntos ((A ∪ C) – B y (A ∩ B) ∪ C), verifica que todo esté bien, muestra los resultados en pantalla y los guarda en un diccionario para tenerlos organizados.

# data[].attributes.headline
Libreria De Python Para Diagramas De Venn

# data[].attributes.subject
Libreria De Python Para Diagramas De Venn

# data[].attributes.body
matplotlib-venn:

Es una librería de Python que se integra con matplotlib para crear diagramas de Venn de 2 y 3 conjuntos de manera sencilla. Permite visualizar las intersecciones y uniones entre conjuntos mediante círculos superpuestos, donde cada región representa la relación entre los conjuntos. Además, permite personalizar etiquetas, colores y estilos de los círculos, facilitando la presentación gráfica de operaciones con conjuntos.

Compatibilidad: Funciona únicamente con matplotlib.

Funcionalidades principales:

venn2 → diagramas de Venn de 2 conjuntos.

venn3 → diagramas de Venn de 3 conjuntos.

venn2_circles y venn3_circles → dibujan los contornos de los círculos para resaltar las regiones.

# data[].attributes.headline
Maria Isaura Paillacho Velasco (Investigadora)

# data[].attributes.subject
Maria Isaura Paillacho Velasco (Investigadora)

# data[].attributes.body
Comparación de dificultad:

En papel: resolver operaciones y graficar es lento y propenso a errores humanos.

En GeoGebra: facilita la visualización, pero tiene limitaciones en cálculos lógicos y no escala a conjuntos grandes.

En Python: permite automatizar operaciones, manejar volúmenes grandes de datos y guardar resultados de forma reproducible.

Ventajas de usar programación para conjuntos:

Escalabilidad: se pueden manipular conjuntos enormes sin perder precisión.

Automatización: cálculos y pruebas se realizan rápido y con mínima intervención manual.

Reproducibilidad: el mismo código se ejecuta con resultados consistentes, útil para auditorías y seguridad.

Conclusión: La programación en Python no solo agiliza el manejo de conjuntos, sino que aporta rigor y confiabilidad en aplicaciones críticas como la seguridad informática y la criptografía.

# data[].attributes.body
Link de Respaldo que contienenel archivo ,ipynb

https://drive.google.com/drive/folders/1Ov3jJ_EwjKMslr6UkVZCXkpH9FLgcgjc?usp=sharing

# data[].attributes.body
En esta parte aprendí a representar conjuntos en Python de forma práctica, usando condiciones lógicas y comprensión de conjuntos. Definir el universo y construir los conjuntos A, B y C me ayudó a entender mejor los conceptos de pertenencia, divisibilidad y número primo. Usar programación permitió comprobar los resultados rápidamente y visualizar cómo funcionan las operaciones de conjuntos, algo que en papel resulta más lento y propenso a errores.

# data[].attributes.headline
Reflexión TICs - Aplicaciones en criptografía

# data[].attributes.subject
Reflexión TICs - Aplicaciones en criptografía

# data[].attributes.body
Los conjuntos son una herramienta conceptual y práctica en criptografía. Algunos ejemplos serian:

1) Espacios de claves y subgrupos: En criptografía de clave pública (por ejemplo RSA o ECC),

se trabaja con conjuntos de claves, subgrupos multiplicativos, y conjuntos de mensajes válidos.

Las operaciones con conjuntos ayudan a definir dominios seguros, restricciones y condiciones de validez.

2) Criptoanálisis y ataques: Conjuntos de posibles claves (ataque por fuerza bruta),

conjuntos de salidas de funciones hash, y conjuntos de estados intermedios son analizados

para estimar entropía, colisiones y vulnerabilidades.

3) Filtrado/Control de acceso: Conjuntos de permisos y roles (RBAC)

se usan para decidir accesos y combinaciones de privilegios.

4) Protocolos y pruebas: En protocolos de intercambio seguro se definen conjuntos de participantes,

estados y mensajes; operaciones con conjuntos (unión, intersección, diferencia) modelan combinaciones

de permisos y exclusiones.