Объединение всех частей
Часть раздела Логика и управление потоком путешествия по GO на Coddy. Урок 50 из 68.
Задание
ЛегкоЗавершите свою систему управления запасами, создав полноценную главную программу, которая объединяет все функции, разработанные вами на предыдущих уроках. Это заключительное задание объединяет инициализацию запасов, проверку наличия товара, добавление товаров, обновление запасов и создание отчётов в полноценный интерфейс командной строки с навигацией по меню.
Вам будут переданы три входных значения:
- Строка с начальными данными о запасах в формате
"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")
Ваша задача:
- Использовать ту же структуру
Productиз предыдущих уроков с полямиPrice(float64) иQuantity(int) - Разобрать первый входной параметр и инициализировать карту запасов существующими данными о товарах
- Вывести сообщение о запуске системы:
"=== INVENTORY MANAGEMENT SYSTEM ===""System initialized with [number_of_products] products""Starting interactive session..."
- Разобрать второй входной параметр, чтобы получить последовательность выполняемых операций
- Разобрать третий входной параметр, чтобы получить параметры каждой операции
- Для каждой операции в последовательности вывести заголовок операции и выполнить соответствующее действие:
- Для
"check": вывести"--- STOCK CHECK ---"и проверить наличие указанного товара - Для
"add": вывести"--- ADD ITEM ---"и добавить указанный товар - Для
"update": вывести"--- UPDATE STOCK ---"и обновить запас указанного товара - Для
"report": вывести"--- GENERATE REPORT ---"и создать указанный отчёт - Для
"exit": вывести"--- SYSTEM EXIT ---"и показать информацию о завершении
- Для
- Реализовать функцию
checkStock, которая возвращает количество товара и ошибку, как в предыдущих уроках - Реализовать функцию
addNewItem, которая добавляет товары и возвращает ошибку, как в предыдущих уроках - Реализовать функцию
updateStock, которая обновляет количество товаров и возвращает ошибку, как в предыдущих уроках - Реализовать функцию
generateReport, которая выводит отчёт, описанный ниже для операции"report" - Для операции
"check":- Использовать параметр как название проверяемого товара
- Вывести:
"Checking stock for: [product_name]" - Если товар найден:
"Stock level: [quantity] units" - Если товар не найден:
"Product not found in inventory"
- Для операции
"add":- Разобрать параметр в формате
"product_name:price:quantity" - Вывести:
"Adding new product: [product_name]" - Если операция выполнена успешно:
"Product added successfully" - Если произошла ошибка:
"Failed to add product: [error_message]", где ошибка —"product already exists"
- Разобрать параметр в формате
- Для операции
"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]", где ошибка —"product not found"или"insufficient stock", если новое количество окажется меньше 0
- Разобрать параметр в формате
- Для операции
"report":- Разобрать параметр в формате
"report_type,threshold", где report_type —"low"или"full", а threshold — целое число - Вывести:
"Generating [report_type] report with threshold [threshold]" - Затем вывести отчёт, расположив товары в алфавитном порядке:
- Для
"low":"=== LOW REPORT ===", затем"Products with stock below [threshold]:", затем"- [name]: [quantity] units (Price: $[price])"для каждого товара, количество которого ниже порогового значения - Для
"full":"=== FULL REPORT ===", затем"Complete inventory (minimum threshold: [threshold]):", затем"- [name]: [quantity] units @ $[price] each [OK]"для каждого товара; если его количество ниже порогового значения, вместо[OK]использовать[LOW STOCK]
- Для
- Разобрать параметр в формате
- Для операции
"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"
- Вывести итоговую статистику запасов:
- После каждой операции, кроме 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)
}Все уроки раздела Логика и управление потоком
1Продвинутое управление потоком выполнения
Switch с использованием `fallthrough`Выход из вложенных цикловПродолжение конкретного циклаОператор `goto`Итоги: Продвинутое управление циклами4Проект: Простой список задач
Настройка проектаДобавление задачи2Структуры и методы
Определение методов для структурПолучатели по значениюПолучатели по указателюВыбор типа получателяМетоды против функцийИтоги: поведение структур5Карты: подробный разбор
Карты структурУказатели как значения картПроверка карт на nilСравнение картИтоги: счетчик частоты слов8Проект: Простой учет товаров
Обзор проектаПроверка остатков3Интерфейсы (Основы)
Что такое интерфейс?Определение интерфейсаРеализация интерфейсаИспользование интерфейсных типовПустой интерфейсУтверждение типаПереключатель типовИтоги: Фигуры и поведениеПотренируйтесь самостоятельно: Онлайн-компилятор Go