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

Practica por tu cuenta: Compilador de Go online