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 varios tipos de error personalizados y un manejo adecuado de errores. Este desafío combina tipos de error personalizados, envoltorio de errores y comprobación de errores para crear un sistema sólido que gestione correctamente diversos fallos de operaciones matemáticas.

Recibirás dos entradas:

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

Tu tarea es:

  1. Crear dos tipos de error personalizados:
    • Una estructura DivisionError con los campos Dividend (float64) y Divisor (float64)
    • Una 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 separándola por comas para obtener operation, num1, num2 y precision
  5. Analizar la segunda entrada separándola por comas para obtener el nombre de la calculadora y el modo
  6. Convertir los números de cadena a float64 y precision a int
  7. Crear una función safeDivide que reciba 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
    • En cualquier otro caso, 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 gestionar el resultado:
    • Si no hay ningún error: imprimir "Calculation successful: [result_formatted_to_precision_decimal_places]"
    • Si existe un error: imprimir "Calculation failed: [error_message]"
  10. Usar errors.As para comprobar tipos de error 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]"

Usa el paquete strings para separar 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 envolver y dar formato a los errores. Este desafío demuestra cómo los tipos de error personalizados, el envoltorio de errores y la comprobación adecuada de errores funcionan conjuntamente para crear sistemas sólidos de gestión de errores que proporcionan información detallada sobre distintos 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