😘 Code
import calendar
import datetime
from openpyxl import Workbook
from openpyxl.styles import PatternFill
from openpyxl.utils import get_column_letter
# 1) Preparar libro y hoja
wb = Workbook()
ws = wb.active
ws.title = "Calendario 2025"
# ejemplo: ws.title = "Calendario 2025"
# 2) Lista de nombres y posición inicial
names = ["Pol", "Rosana", "Guillermo"]
start_row = 2 # la fila donde empieza Pol
# ejemplo: start_row = 2
# 3) Encabezados de fechas (fila 1)
year = 2025
col = 2 # columna B
for month in range(1, 13):
for day in range(1, calendar.monthrange(year, month)[1] + 1):
date = datetime.date(year, month, day)
cell = ws.cell(row=1, column=col, value=date)
cell.number_format = "DD/MM"
# ejemplo: primer día -> date = 2025-01-01, col=2, escribe "01/01"
col += 1
last_col = col - 1 # 366 días en 2025
# ejemplo: last_col = 367
# 4) Escribir nombres en su fila
for idx, name in enumerate(names):
row = start_row + idx
ws.cell(row=row, column=1, value=name)
# ejemplo: idx=0 -> row=2, escribe "Pol" en A2
# 5) Relleno de fines de semana y festivos
weekend_fill = PatternFill(start_color="DDDDDD", end_color="DDDDDD", fill_type="solid")
holiday_fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")
# Lista de festivos nacionales (YYYY, M, D)
holidays = [
(2025, 1, 1), # Año Nuevo
(2025, 1, 6), # Reyes
(2025, 4, 18), # Viernes Santo
(2025, 5, 1), # Día del Trabajador
(2025, 8, 15), # Asunción
(2025, 10, 12), # Fiesta Nacional
(2025, 11, 1), # Todos los Santos
(2025, 12, 6), # Constitución
(2025, 12, 8), # Inmaculada
(2025, 12, 25) # Navidad
]
holiday_dates = {datetime.date(*h) for h in holidays}
# ejemplo: holiday_dates contiene datetime.date(2025,1,1), datetime.date(2025,1,6), ...
# 6) Pintar celdas de cada día según su tipo
for day_col in range(2, last_col + 1):
date = ws.cell(row=1, column=day_col).value
for idx in range(len(names)):
cell = ws.cell(row=start_row + idx, column=day_col)
# inicialmente vacío, esperarás poner “X” para vacaciones
if date in holiday_dates:
cell.fill = holiday_fill
# ejemplo: si date == 2025-01-01 → celda A2 coloreada rojo claro
elif date.weekday() >= 5: # sábado=5, domingo=6
cell.fill = weekend_fill
# ejemplo: 2025-01-04 (sábado) → gris claro
# 7) Apartado contador debajo del calendario
# Filas usadas: start_row … start_row+2 (2,3,4). Usamos la fila siguiente +1 en blanco → header en fila 6
counter_header_row = start_row + len(names) + 2 # 2 + 3 + 2 = 7 <--
# ejemplo: counter_header_row = 7 (fila dónde escribimos "Contador de X")
ws.cell(row=counter_header_row, column=1, value="Contador de X") # <--
# ejemplo: A7 = "Contador de X"
# Encabezados de la tabla de contador
ws.cell(row=counter_header_row, column=2, value="Nombre") # <--
# ejemplo: B7 = "Nombre"
ws.cell(row=counter_header_row, column=3, value="Días marcados") # <--
# ejemplo: C7 = "Días marcados"
# Filas de datos debajo del header del contador
for idx, name in enumerate(names):
row = counter_header_row + 1 + idx # <-- filas 8,9,10
ws.cell(row=row, column=2, value=name) # <-- escribe nombre
# ejemplo: idx=0 → row=8, B8 = "Pol"
# Fórmula COUNTIF de la fila del calendario para cada persona
start_col_letter = get_column_letter(2)
end_col_letter = get_column_letter(last_col)
formula = f'=COUNTIF({start_col_letter}{start_row+idx}:{end_col_letter}{start_row+idx},"X")'
ws.cell(row=row, column=3, value=formula) # <-- pone la fórmula en C8, C9, C10
# ejemplo: Pol → formula '=COUNTIF(B2:NV2,"X")'
# 8) Guardar el archivo
wb.save("calendario_2025.xlsx")
# ejemplo: crea 'calendario_2025.xlsx' en el directorio actual
I am particularly drawn to developing applications that are not only functional but also visually appealing and easy to use. I accomplish this by implementing SOLID principles and clean architecture, and applying testing to ensure quality.