Menu
Coddy logo textTech

Объединение всех частей

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

challenge icon

Задание

Легко

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

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

  • Строку, содержащую начальные данные инвентаря в формате "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (например, "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Строку, содержащую последовательность операций меню в формате "operation1,operation2,operation3", где операциями могут быть "check", "add", "update", "report" или "exit" (например, "check,add,update,report,exit")
  • Строку, содержащую параметры операций в формате "param1|param2|param3", где каждый параметр соответствует операции на той же позиции (например, "Mouse|Monitor:299.99:10|Laptop:5|full,10")

Ваша задача:

  1. Использовать ту же структуру Product из предыдущих уроков с полями Price (float64) и Quantity (int)
  2. Разобрать первый входной параметр и инициализировать карту (map) инвентаря существующими данными о продуктах
  3. Вывести сообщение о запуске системы:
    • "=== INVENTORY MANAGEMENT SYSTEM ==="
    • "System initialized with [number_of_products] products"
    • "Starting interactive session..."
  4. Разобрать второй входной параметр, чтобы получить последовательность выполняемых операций
  5. Разобрать третий входной параметр, чтобы получить параметры для каждой операции
  6. Для каждой операции в последовательности вывести заголовок операции и выполнить соответствующее действие:
    • Для "check": Вывести "--- STOCK CHECK ---" и проверить наличие указанного продукта
    • Для "add": Вывести "--- ADD ITEM ---" и добавить указанный продукт
    • Для "update": Вывести "--- UPDATE STOCK ---" и обновить запас указанного продукта
    • Для "report": Вывести "--- GENERATE REPORT ---" и сгенерировать указанный отчет
    • Для "exit": Вывести "--- SYSTEM EXIT ---" и показать информацию о выходе
  7. Реализовать функцию checkStock, которая возвращает количество и ошибку, как в предыдущих уроках
  8. Реализовать функцию addNewItem, которая добавляет продукты и возвращает ошибку, как в предыдущих уроках
  9. Реализовать функцию updateStock, которая обновляет количество и возвращает ошибку, как в предыдущих уроках
  10. Реализовать функцию generateReport, которая создает отчеты, как в предыдущих уроках
  11. Для операции "check":
    • Использовать параметр как название продукта для проверки
    • Вывести: "Checking stock for: [product_name]"
    • Если найден: "Stock level: [quantity] units"
    • Если не найден: "Product not found in inventory"
  12. Для операции "add":
    • Разобрать параметр в формате "product_name:price:quantity"
    • Вывести: "Adding new product: [product_name]"
    • В случае успеха: "Product added successfully"
    • В случае ошибки: "Failed to add product: [error_message]"
  13. Для операции "update":
    • Разобрать параметр в формате "product_name:change"
    • Вывести: "Updating stock for: [product_name]"
    • Если успешно и изменение положительное: "Added [change] units. New stock: [new_quantity]"
    • Если успешно и изменение отрицательное: "Removed [absolute_change] units. New stock: [new_quantity]"
    • В случае ошибки: "Update failed: [error_message]"
  14. Для операции "report":
    • Разобрать параметр в формате "report_type,threshold"
    • Вывести: "Generating [report_type] report with threshold [threshold]"
    • Сгенерировать и вывести полный отчет, как в предыдущих уроках
  15. Для операции "exit":
    • Вывести итоговую статистику инвентаря:
      • "Final inventory status:"
      • "Total products: [total_products]"
      • "Total items: [total_items]"
      • "Total value: $[total_value]"
    • Вывести: "Session completed successfully"
    • Вывести: "Thank you for using the Inventory Management System"
  16. После каждой операции (кроме exit) выводить: "Operation completed. Continuing to next operation..."

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

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

package main

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

type Product struct {
	Price    float64
	Quantity int
}

func generateReport(inventory map[string]Product, reportType string, threshold float64) {
	// Display report header
	switch reportType {
	case "full":
		fmt.Println("=== FULL INVENTORY REPORT ===")
	case "low_stock":
		fmt.Println("=== LOW STOCK REPORT ===")
	case "high_value":
		fmt.Println("=== HIGH VALUE REPORT ===")
	}

	// Calculate general statistics
	totalProducts := len(inventory)
	totalItems := 0
	totalValue := 0.0
	
	for _, product := range inventory {
		totalItems += product.Quantity
		totalValue += product.Price * float64(product.Quantity)
	}
	
	averagePrice := totalValue / float64(totalItems)

	// Display general 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)
	fmt.Printf("Average Product Price: $%.2f\n", averagePrice)

	// Filter products based on report type
	var filteredProducts []string
	for name, product := range inventory {
		switch reportType {
		case "full":
			filteredProducts = append(filteredProducts, name)
		case "low_stock":
			if product.Quantity <= int(threshold) {
				filteredProducts = append(filteredProducts, name)
			}
		case "high_value":
			productValue := product.Price * float64(product.Quantity)
			if productValue >= threshold {
				filteredProducts = append(filteredProducts, name)
			}
		}
	}

	// Sort filtered products alphabetically
	sort.Strings(filteredProducts)

	// Display filtered products section header
	switch reportType {
	case "full":
		fmt.Println("All Products:")
	case "low_stock":
		fmt.Printf("Products with stock ≤ %.0f:\n", threshold)
	case "high_value":
		fmt.Printf("Products with value ≥ $%.2f:\n", threshold)
	}

	// Display filtered products
	filteredItems := 0
	filteredValue := 0.0
	for _, name := range filteredProducts {
		product := inventory[name]
		productValue := product.Price * float64(product.Quantity)
		fmt.Printf("- %s: $%.2f × %d = $%.2f\n", name, product.Price, product.Quantity, productValue)
		filteredItems += product.Quantity
		filteredValue += productValue
	}

	// Display filtered statistics
	fmt.Println("Filtered Results:")
	fmt.Printf("Products shown: %d\n", len(filteredProducts))
	fmt.Printf("Items in filtered products: %d\n", filteredItems)
	fmt.Printf("Value of filtered products: $%.2f\n", filteredValue)

	// Find most and least expensive products
	var mostExpensiveName, leastExpensiveName string
	var mostExpensivePrice, leastExpensivePrice float64
	first := true
	
	var sortedNames []string
	for name := range inventory {
		sortedNames = append(sortedNames, name)
	}
	sort.Strings(sortedNames)
	
	for _, name := range sortedNames {
		product := inventory[name]
		if first {
			mostExpensiveName = name
			mostExpensivePrice = product.Price
			leastExpensiveName = name
			leastExpensivePrice = product.Price
			first = false
		} else {
			if product.Price > mostExpensivePrice {
				mostExpensiveName = name
				mostExpensivePrice = product.Price
			}
			if product.Price < leastExpensivePrice {
				leastExpensiveName = name
				leastExpensivePrice = product.Price
			}
		}
	}

	fmt.Println("Price Analysis:")
	fmt.Printf("Most expensive: %s at $%.2f\n", mostExpensiveName, mostExpensivePrice)
	fmt.Printf("Least expensive: %s at $%.2f\n", leastExpensiveName, leastExpensivePrice)

	// Find highest and lowest stock products
	var highestStockName, lowestStockName string
	var highestStock, lowestStock int
	first = true
	
	for _, name := range sortedNames {
		product := inventory[name]
		if first {
			highestStockName = name
			highestStock = product.Quantity
			lowestStockName = name
			lowestStock = product.Quantity
			first = false
		} else {
			if product.Quantity > highestStock {
				highestStockName = name
				highestStock = product.Quantity
			}
			if product.Quantity < lowestStock {
				lowestStockName = name
				lowestStock = product.Quantity
			}
		}
	}

	fmt.Println("Stock Analysis:")
	fmt.Printf("Highest stock: %s with %d units\n", highestStockName, highestStock)
	fmt.Printf("Lowest stock: %s with %d units\n", lowestStockName, lowestStock)

	// Inventory health assessment
	lowStockCount := 0
	highStockCount := 0
	highValueCount := 0
	
	for _, product := range inventory {
		if product.Quantity <= 5 {
			lowStockCount++
		}
		if product.Quantity > 20 {
			highStockCount++
		}
		productValue := product.Price * float64(product.Quantity)
		if productValue >= 500.0 {
			highValueCount++
		}
	}

	fmt.Printf("Low stock items (≤5): %d\n", lowStockCount)
	fmt.Printf("High stock items (>20): %d\n", highStockCount)
	fmt.Printf("High value items (≥$500): %d\n", highValueCount)

	// Report completion
	fmt.Println("Report generated successfully")
	fmt.Printf("Threshold applied: %.2f\n", threshold)
}

func main() {
	var inventoryData string
	var reportConfig string
	fmt.Scanln(&inventoryData)
	fmt.Scanln(&reportConfig)

	// Parse inventory data
	inventory := make(map[string]Product)
	if inventoryData != "" {
		products := strings.Split(inventoryData, ",")
		for _, productStr := range products {
			parts := strings.Split(productStr, ":")
			name := parts[0]
			price, _ := strconv.ParseFloat(parts[1], 64)
			quantity, _ := strconv.Atoi(parts[2])
			inventory[name] = Product{Price: price, Quantity: quantity}
		}
	}

	// Parse report configuration
	configParts := strings.Split(reportConfig, ",")
	reportType := configParts[0]
	threshold, _ := strconv.ParseFloat(configParts[1], 64)

	// Generate report
	generateReport(inventory, reportType, threshold)
}

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

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