Menu
CoddyTech

Обновление количества товара

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

challenge icon

Задание

Легко

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

Тебе будут предоставлены два входных значения:

  • Строка с данными о текущих запасах в формате "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (например, "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Строка с запросами на обновление запасов в формате "product1:change1,product2:change2,product3:change3", где изменения могут быть положительными или отрицательными целыми числами (например, "Mouse:10,Tablet:-5,Keyboard:-3")

Твоя задача:

  1. Использовать ту же структуру Product, что и в предыдущих уроках, с полями Price (float64) и Quantity (int)
  2. Разобрать первое входное значение, разделив его по запятым, чтобы получить отдельные записи о существующих товарах
  3. Для каждой записи о существующем товаре разделить её по двоеточиям, чтобы получить название товара, цену и количество
  4. Преобразовать строку с ценой в float64, а строку с количеством — в int
  5. Создать карту inventory и заполнить её данными о существующих товарах
  6. Создать функцию с именем updateStock, которая принимает карту запасов, название товара и изменение количества в качестве параметров и возвращает ошибку:
    • Если товара нет в запасах, вернуть ошибку с сообщением "product not found: [product_name]"
    • Если изменение количества приведёт к отрицательному запасу (текущее количество + изменение < 0), вернуть ошибку с сообщением "insufficient stock: cannot reduce [product_name] by [absolute_change_value], only [current_quantity] available"
    • Если обновление допустимо, изменить количество товара в запасах и вернуть nil
  7. Разобрать второе входное значение, разделив его по запятым, чтобы получить список запросов на обновление запасов
  8. Для каждого запроса на обновление разделить его по двоеточиям, чтобы получить название товара и изменение количества
  9. Преобразовать строку с изменением количества в int
  10. Вывести заголовок процесса обновления: "Processing Stock Updates:"
  11. Для каждого запроса на обновление вызвать функцию updateStock и вывести результат:
    • Если ошибки нет и изменение положительное: "[product_name]: Added [change] units - New stock: [new_quantity]"
    • Если ошибки нет и изменение отрицательное: "[product_name]: Removed [absolute_change_value] units - New stock: [new_quantity]"
    • Если ошибки нет и изменение равно нулю: "[product_name]: No change - Current stock: [current_quantity]"
    • Если произошла ошибка: "[product_name]: Update failed - [error_message]"
  12. Подсчитать и вывести статистику обновлений:
    • "Update Summary:"
    • "Updates processed: [total_number_of_updates_processed]"
    • "Updates successful: [number_of_successful_updates]"
    • "Updates failed: [number_of_failed_updates]"
  13. Вывести обновлённый список запасов в алфавитном порядке по названию товара:
    • "Updated Inventory:"
    • Для каждого товара: "- [product_name]: $[price] (Stock: [quantity])"
  14. Вычислить и вывести итоговую статистику запасов:
    • "Final Inventory Statistics:"
    • "Total Products: [total_number_of_products_in_inventory]"
    • "Total Items in Stock: [sum_of_all_quantities]"
    • "Total Inventory Value: $[sum_of_price_times_quantity_for_all_products]"
  15. Перечислить неудачные обновления:
    • Если есть неудачные обновления: "Failed updates: [comma_separated_list_of_failed_product_names]"
    • Если неудачных обновлений нет: "All stock updates were processed successfully"

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

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

package main

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

type Product struct {
	Price    float64
	Quantity int
}

func addNewItem(inventory map[string]Product, productName string, price float64, quantity int) error {
	if _, exists := inventory[productName]; exists {
		return errors.New("product already exists: " + productName)
	}
	inventory[productName] = Product{Price: price, Quantity: quantity}
	return nil
}

func main() {
	var existingInventory string
	var newProducts string
	fmt.Scanln(&existingInventory)
	fmt.Scanln(&newProducts)

	inventory := make(map[string]Product)

	// Parse existing inventory
	existingItems := strings.Split(existingInventory, ",")
	for _, item := range existingItems {
		parts := strings.Split(item, ":")
		name := parts[0]
		price, _ := strconv.ParseFloat(parts[1], 64)
		quantity, _ := strconv.Atoi(parts[2])
		inventory[name] = Product{Price: price, Quantity: quantity}
	}

	// Parse new products to add
	newItems := strings.Split(newProducts, ",")
	
	fmt.Println("Adding New Items:")
	
	itemsProcessed := 0
	itemsAdded := 0
	itemsRejected := 0
	var rejectedProducts []string

	for _, item := range newItems {
		parts := strings.Split(item, ":")
		name := parts[0]
		price, _ := strconv.ParseFloat(parts[1], 64)
		quantity, _ := strconv.Atoi(parts[2])
		
		itemsProcessed++
		
		err := addNewItem(inventory, name, price, quantity)
		if err != nil {
			fmt.Printf("%s: Failed to add - %s\n", name, err.Error())
			itemsRejected++
			rejectedProducts = append(rejectedProducts, name)
		} else {
			fmt.Printf("%s: Successfully added - $%.2f (Stock: %d)\n", name, price, quantity)
			itemsAdded++
		}
	}

	// Addition summary
	fmt.Println("Addition Summary:")
	fmt.Printf("Items processed: %d\n", itemsProcessed)
	fmt.Printf("Items added: %d\n", itemsAdded)
	fmt.Printf("Items rejected: %d\n", itemsRejected)

	// Display updated inventory in alphabetical order
	fmt.Println("Updated Inventory:")
	var productNames []string
	for name := range inventory {
		productNames = append(productNames, name)
	}
	sort.Strings(productNames)

	totalProducts := 0
	totalItems := 0
	totalValue := 0.0

	for _, name := range productNames {
		product := inventory[name]
		fmt.Printf("- %s: $%.2f (Stock: %d)\n", name, product.Price, product.Quantity)
		totalProducts++
		totalItems += product.Quantity
		totalValue += product.Price * float64(product.Quantity)
	}

	// Final inventory statistics
	fmt.Println("Final Inventory Statistics:")
	fmt.Printf("Total Products: %d\n", totalProducts)
	fmt.Printf("Total Items in Stock: %d\n", totalItems)
	fmt.Printf("Total Inventory Value: $%.2f\n", totalValue)

	// List rejected products
	if len(rejectedProducts) > 0 {
		fmt.Printf("Rejected products: %s\n", strings.Join(rejectedProducts, ","))
	} else {
		fmt.Println("All new products were added successfully")
	}
}

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

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