Menu
Coddy logo textTech

Repaso - División segura

Parte de la sección Lógica y Flujo del Journey de GO de Coddy — lección 44 de 68.

challenge icon

Desafío

Fácil

Construye una calculadora matemática integral que implemente una división segura con múltiples tipos de errores personalizados y un manejo de errores adecuado. Este desafío combina tipos de errores personalizados, envoltura de errores (error wrapping) y comprobación de errores para crear un sistema robusto que maneje con elegancia varios fallos en las operaciones matemáticas.

Recibirás dos entradas:

  • Una cadena que contiene los detalles de la operación en el formato "operation,num1,num2,precision" (por ejemplo, "divide,10,0,2")
  • Una cadena que contiene la configuración de la calculadora en el formato "calculator_name,mode" (por ejemplo, "ScientificCalc,strict")

Tu tarea es:

  1. Crear dos tipos de errores personalizados:
    • Estructura DivisionError con los campos Dividend (float64) y Divisor (float64)
    • Estructura ValidationError con los campos Field (string) y Value (float64)
  2. Implementar el método Error() string para DivisionError que devuelva: "division error: cannot divide [dividend] by [divisor]"
  3. Implementar el método Error() string para ValidationError que devuelva: "validation error: invalid [field] value [value]"
  4. Analizar la primera entrada dividiéndola por comas para obtener operation, num1, num2 y precision
  5. Analizar la segunda entrada dividiéndola por comas para obtener calculator name y mode
  6. Convertir los números de cadena a float64 y precision a int
  7. Crear una función safeDivide que tome dos parámetros float64 y devuelva (float64, error):
    • Si divisor es 0, devolver 0 y un DivisionError con los valores de dividend y divisor
    • Si dividend es negativo y mode es "strict", devolver 0 y un ValidationError con el campo "dividend" y el valor de dividend
    • Si divisor es negativo y mode es "strict", devolver 0 y un ValidationError con el campo "divisor" y el valor de divisor
    • De lo contrario, devolver el resultado de la división y nil
  8. Crear una función performCalculation que envuelva el resultado de safeDivide:
    • Si safeDivide devuelve un error, envolverlo con: "calculation failed in [calculator_name]: %w"
    • Si tiene éxito, devolver el resultado y nil
  9. Llamar a performCalculation y manejar el resultado:
    • Si no hay error: imprimir "Calculation successful: [result_formatted_to_precision_decimal_places]"
    • Si existe un error: imprimir "Calculation failed: [error_message]"
  10. Usar errors.As para buscar tipos de errores específicos en el error envuelto:
    • Imprimir "Checking for division error: [true/false]"
    • Imprimir "Checking for validation error: [true/false]"
  11. Si se encuentra un DivisionError, imprimir sus detalles:
    • "Division Error Details:"
    • "Dividend: [dividend]"
    • "Divisor: [divisor]"
  12. Si se encuentra un ValidationError, imprimir sus detalles:
    • "Validation Error Details:"
    • "Field: [field]"
    • "Value: [value]"
  13. Mostrar un resumen final:
    • "Calculator Summary:"
    • "Name: [calculator_name]"
    • "Mode: [mode]"
    • "Operation: [operation]"
    • "Input: [num1] [operation_symbol] [num2]" donde operation_symbol es "/" para divide
    • "Precision: [precision] decimal places"
    • "Status: [Success/Failed]"

Utiliza el paquete strings para dividir las cadenas de entrada por comas, el paquete strconv para convertir cadenas a números, el paquete errors para errors.As, y el paquete fmt para la envoltura y el formateo de errores. Este desafío demuestra cómo los tipos de errores personalizados, la envoltura de errores y la comprobación adecuada de errores trabajan juntos para crear sistemas robustos de manejo de errores que proporcionan información detallada sobre diferentes tipos de fallos.

Pruébalo tú mismo

package main

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// Leer entrada
	var operationInput string
	var settingsInput string
	fmt.Scanln(&operationInput)
	fmt.Scanln(&settingsInput)
	
	// Analizar entrada de operación (operación,num1,num2,precisión)
	operationParts := strings.Split(operationInput, ",")
	operation := operationParts[0]
	num1, _ := strconv.ParseFloat(operationParts[1], 64)
	num2, _ := strconv.ParseFloat(operationParts[2], 64)
	precision, _ := strconv.Atoi(operationParts[3])
	
	// Analizar entrada de configuración (nombre_calculadora,modo)
	settingsParts := strings.Split(settingsInput, ",")
	calculatorName := settingsParts[0]
	mode := settingsParts[1]
	
	// TODO: Escribe tu código a continuación
	// 1. Crear las estructuras DivisionError y ValidationError con métodos Error()
	// 2. Implementar la función safeDivide
	// 3. Implementar la función performCalculation
	// 4. Llamar a performCalculation y manejar los resultados
	// 5. Usar errors.As para verificar tipos de error específicos
	// 6. Imprimir detalles del error si se encuentran
	// 7. Mostrar el resumen final
	
}

Todas las lecciones de Lógica y Flujo