E1 · Refactorizar una planilla
refactorización · ★★★Este script calcula el salario neto de dos empleados. Tasas simplificadas con fines didácticos: horas extra pagadas al doble de la tarifa por hora (salario / 240); cotización de salud 3 % del bruto con tope de $30; pensión 7.25 % del bruto.
salario_1 = 600
horas_extra_1 = 10
bruto_1 = salario_1 + (salario_1 / 240) * 2 * horas_extra_1
salud_1 = bruto_1 * 0.03
if salud_1 > 30:
salud_1 = 30
neto_1 = bruto_1 - salud_1 - bruto_1 * 0.0725
print(f"Empleado 1: neto ${neto_1:.2f}")
salario_2 = 1500
horas_extra_2 = 4
bruto_2 = salario_2 + (salario_2 / 240) * 2 * horas_extra_2
salud_2 = bruto_2 * 0.03
if salud_2 > 30:
salud_2 = 30
neto_2 = bruto_2 - salud_2 - bruto_2 * 0.0725
print(f"Empleado 2: neto ${neto_2:.2f}")
Refactorízalo en funciones puras con docstrings (al menos: pago de horas extra, cotización de salud, pensión y salario neto con horas_extra=0 por defecto). Los resultados no deben cambiar, y si cambian, debes poder explicar por qué.
Pista
Primero anota la salida del script original: es tu “prueba de regresión”. Después de refactorizar, la salida debe ser idéntica. Para el tope, min(a, b) devuelve el menor de dos valores.
Solución
HORAS_MES = 240
RECARGO_EXTRA = 2 # horas extra al doble
TASA_SALUD = 0.03
TOPE_SALUD = 30.00
TASA_PENSION = 0.0725
def pago_horas_extra(salario, horas_extra):
"""Pago por horas extra: tarifa por hora x recargo x horas."""
return round(salario / HORAS_MES * RECARGO_EXTRA * horas_extra, 2)
def cotizacion_salud(bruto):
"""Cotización de salud: porcentaje del bruto con un tope máximo."""
return min(round(bruto * TASA_SALUD, 2), TOPE_SALUD)
def cotizacion_pension(bruto):
"""Cotización de pensión: porcentaje fijo del bruto."""
return round(bruto * TASA_PENSION, 2)
def salario_neto(salario, horas_extra=0):
"""Salario neto mensual después de horas extra y cotizaciones."""
bruto = salario + pago_horas_extra(salario, horas_extra)
return round(bruto - cotizacion_salud(bruto) - cotizacion_pension(bruto), 2)
print(f"Empleado 1: neto ${salario_neto(600, 10):.2f}")
print(f"Empleado 2: neto ${salario_neto(1500, 4):.2f}")
Empleado 1: neto $583.38
Empleado 2: neto $1407.63
Verificación: el script original imprime $583.38 y $1407.62; el refactorizado, $583.38 y $1407.63. ¿Error? No: la pensión del empleado 2 es 1550 × 7.25 % = $112.375. El original resta ese valor con todos sus decimales; la versión nueva redondea cada rubro a centavos ($112.37) antes de restar, como en una boleta de pago real. Una refactorización puede cambiar un centavo si cambia dónde se redondea: decide la política, documéntala en el README y escribe una prueba que la fije.