整合所有内容
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 50 课,共 68 课。
挑战
简单通过创建一个综合的主程序,整合你在前几课中构建的所有功能,完成库存管理系统。这个最终挑战将库存初始化、库存检查、商品添加、库存更新和报告生成整合到一个完整的命令行界面中,并通过菜单进行导航。
你将收到 3 个输入:
- 一个字符串,其中包含初始库存数据,格式为
"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]" - 如果成功且 change 为零或正数:
"Added [change] units. New stock: [new_quantity]" - 如果成功且 change 为负数:
"Removed [absolute_change] units. New stock: [new_quantity]" - 如果失败:
"Update failed: [error_message]",错误可能是"product not found",或者新数量小于 0 时的"insufficient stock"
- 按
- 对于
"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]";如果数量低于阈值,则用[LOW STOCK]替代[OK]
- 对于
- 按
- 对于
"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)
}逻辑与流程中的所有课
自己练习: Go 在线编译器