Menu
CoddyTech

Итоги — безопасное деление

Часть раздела Логика и управление потоком путешествия по GO на Coddy. Урок 44 из 68.

challenge icon

Задание

Легко

Создайте полноценный математический калькулятор, который выполняет безопасное деление с несколькими пользовательскими типами ошибок и корректной обработкой ошибок. Это задание объединяет пользовательские типы ошибок, оборачивание ошибок и проверку ошибок для создания надежной системы, которая корректно обрабатывает различные сбои математических операций.

Вы получите два входных значения:

  • Строку со сведениями об операции в формате "operation,num1,num2,precision" (например, "divide,10,0,2")
  • Строку с настройками калькулятора в формате "calculator_name,mode" (например, "ScientificCalc,strict")

Ваша задача:

  1. Создать два пользовательских типа ошибок:
    • структуру DivisionError с полями Dividend (float64) и Divisor (float64)
    • структуру ValidationError с полями Field (string) и Value (float64)
  2. Реализовать метод Error() string для DivisionError, который возвращает: "division error: cannot divide [dividend] by [divisor]"
  3. Реализовать метод Error() string для ValidationError, который возвращает: "validation error: invalid [field] value [value]"
  4. Разобрать первую строку, разделив её по запятым, чтобы получить операцию, num1, num2 и precision
  5. Разобрать вторую строку, разделив её по запятым, чтобы получить название калькулятора и режим
  6. Преобразовать числовые строки в float64, а precision — в int
  7. Создать функцию safeDivide, принимающую два параметра типа float64 и возвращающую (float64, error):
    • Если делитель равен 0, вернуть 0 и DivisionError со значениями делимого и делителя
    • Если делимое отрицательное, а режим — "strict", вернуть 0 и ValidationError с полем "dividend" и значением делимого
    • Если делитель отрицательный, а режим — "strict", вернуть 0 и ValidationError с полем "divisor" и значением делителя
    • В противном случае вернуть результат деления и nil
  8. Создать функцию performCalculation, которая оборачивает результат safeDivide:
    • Если safeDivide возвращает ошибку, обернуть её так: "calculation failed in [calculator_name]: %w"
    • При успешном выполнении вернуть результат и nil
  9. Вызвать performCalculation и обработать результат:
    • Если ошибки нет: вывести "Calculation successful: [result_formatted_to_precision_decimal_places]"
    • Если возникла ошибка: вывести "Calculation failed: [error_message]"
  10. Использовать errors.As, чтобы проверить наличие определённых типов ошибок в обёрнутой ошибке:
    • Вывести "Checking for division error: [true/false]"
    • Вывести "Checking for validation error: [true/false]"
  11. Если найдена ошибка DivisionError, вывести её сведения:
    • "Division Error Details:"
    • "Dividend: [dividend]"
    • "Divisor: [divisor]"
  12. Если найдена ошибка ValidationError, вывести её сведения:
    • "Validation Error Details:"
    • "Field: [field]"
    • "Value: [value]"
  13. Вывести итоговую сводку:
    • "Calculator Summary:"
    • "Name: [calculator_name]"
    • "Mode: [mode]"
    • "Operation: [operation]"
    • "Input: [num1] [operation_symbol] [num2]", где operation_symbol — это "/" для деления
    • "Precision: [precision] decimal places"
    • "Status: [Success/Failed]"

Используйте пакет strings, чтобы разделить входные строки по запятым, пакет strconv для преобразования строк в числа, пакет errors для errors.As, а пакет fmt для оборачивания ошибок и форматирования. Это задание показывает, как пользовательские типы ошибок, оборачивание ошибок и корректная проверка ошибок работают вместе, обеспечивая надёжную обработку ошибок с подробной информацией о различных типах сбоев.

Попробуйте сами

package main

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

func main() {
	// Считайте входные данные
	var operationInput string
	var settingsInput string
	fmt.Scanln(&operationInput)
	fmt.Scanln(&settingsInput)
	
	// Разберите входные данные операции (operation,num1,num2,precision)
	operationParts := strings.Split(operationInput, ",")
	operation := operationParts[0]
	num1, _ := strconv.ParseFloat(operationParts[1], 64)
	num2, _ := strconv.ParseFloat(operationParts[2], 64)
	precision, _ := strconv.Atoi(operationParts[3])
	
	// Разберите входные данные настроек (calculator_name,mode)
	settingsParts := strings.Split(settingsInput, ",")
	calculatorName := settingsParts[0]
	mode := settingsParts[1]
	
	// TODO: Напишите свой код ниже
	// 1. Создайте структуры DivisionError и ValidationError с методами Error()
	// 2. Реализуйте функцию safeDivide
	// 3. Реализуйте функцию performCalculation
	// 4. Вызовите performCalculation и обработайте результаты
	// 5. Используйте errors.As для проверки конкретных типов ошибок
	// 6. Выведите сведения об ошибках, если они обнаружены
	// 7. Выведите итоговую сводку
	
}

Все уроки раздела Логика и управление потоком

Потренируйтесь самостоятельно: Онлайн-компилятор Go