生成报告
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 49 课,共 68 课。
挑战
简单通过实现一个全面的报告函数,完善你的库存管理系统,提供当前库存的详细信息。本挑战基于之前的所有功能,并新增了生成格式化报告的能力,其中包含统计、分类和分析。
你将收到两个输入:
- 一个包含现有库存数据的字符串,格式为
"product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"(例如,"Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8") - 一个包含报告配置的字符串,格式为
"report_type,threshold_value",其中 report_type 可以是"full"、"low_stock"或"high_value",threshold_value 是一个数字(例如,"low_stock,10")
你的任务是:
- 使用之前课程中的同一个
Product结构体,包含Price(float64)和Quantity(int)字段 - 通过按逗号拆分第一个输入,获取各个现有商品条目
- 对于每个现有商品条目,按冒号拆分以获取商品名称、价格和数量
- 将价格字符串转换为 float64,将数量字符串转换为 int
- 创建并填充
inventory映射,其中包含现有商品数据 - 创建一个名为
generateReport的函数,以库存映射、报告类型和阈值作为参数 - 通过按逗号拆分第二个输入,获取报告类型和阈值
- 将阈值字符串转换为 float64
- 根据报告类型显示报告标题:
- 对于
"full":"=== FULL INVENTORY REPORT ===" - 对于
"low_stock":"=== LOW STOCK REPORT ===" - 对于
"high_value":"=== HIGH VALUE REPORT ==="
- 对于
- 显示库存总体统计信息:
"Total Products: [total_number_of_products]""Total Items in Stock: [sum_of_all_quantities]""Total Inventory Value: $[sum_of_price_times_quantity_for_all_products]""Average Product Price: $[total_inventory_value_divided_by_total_items]"
- 根据报告类型筛选并显示商品:
- 对于
"full":显示所有商品 - 对于
"low_stock":只显示数量小于或等于阈值的商品 - 对于
"high_value":只显示总价值(价格 × 数量)大于或等于阈值的商品
- 对于
- 显示筛选后的商品部分:
- 对于
"full":"All Products:" - 对于
"low_stock":"Products with stock ≤ [threshold_value]:" - 对于
"high_value":"Products with value ≥ $[threshold_value]:"
- 对于
- 对于每个筛选后的商品(按商品名称的字母顺序排列):
"- [product_name]: $[price] × [quantity] = $[total_value]"
- 显示筛选后的统计信息:
"Filtered Results:""Products shown: [number_of_products_in_filtered_results]""Items in filtered products: [sum_of_quantities_for_filtered_products]""Value of filtered products: $[sum_of_values_for_filtered_products]"
- 找出并显示价格最高和最低的商品:
"Price Analysis:""Most expensive: [product_name] at $[price]""Least expensive: [product_name] at $[price]"
- 找出并显示库存数量最多和最少的商品:
"Stock Analysis:""Highest stock: [product_name] with [quantity] units""Lowest stock: [product_name] with [quantity] units"
- 显示库存健康状况评估:
- 统计数量 ≤ 5 的商品:
"Low stock items (≤5): [count]" - 统计数量 > 20 的商品:
"High stock items (>20): [count]" - 统计价值 ≥ $500 的商品:
"High value items (≥$500): [count]"
- 统计数量 ≤ 5 的商品:
- 显示报告完成信息:
"Report generated successfully""Threshold applied: [threshold_value]"
使用 strings 包拆分输入字符串,使用 strconv 包将字符串转换为数字,使用 fmt 包格式化输出,并使用 sort 包按字母顺序排列商品名称。将所有价格和值格式化为 2 位小数。查找价格最高或最低、库存数量最多或最少的商品时,如果存在并列情况,则选择名称按字母顺序排列最靠前的商品。本挑战将展示如何通过数据分析和格式化展示,创建能提供宝贵业务洞察的全面报告系统。
亲手试试
package main
import (
"errors"
"fmt"
"sort"
"strconv"
"strings"
)
type Product struct {
Price float64
Quantity int
}
func updateStock(inventory map[string]Product, productName string, change int) error {
product, exists := inventory[productName]
if !exists {
return errors.New("product not found: " + productName)
}
newQuantity := product.Quantity + change
if newQuantity < 0 {
return fmt.Errorf("insufficient stock: cannot reduce %s by %d, only %d available", productName, -change, product.Quantity)
}
product.Quantity = newQuantity
inventory[productName] = product
return nil
}
func main() {
var inventoryData string
var updateRequests string
fmt.Scanln(&inventoryData)
fmt.Scanln(&updateRequests)
// Parse existing inventory
inventory := make(map[string]Product)
inventoryEntries := strings.Split(inventoryData, ",")
for _, entry := range inventoryEntries {
parts := strings.Split(entry, ":")
name := parts[0]
price, _ := strconv.ParseFloat(parts[1], 64)
quantity, _ := strconv.Atoi(parts[2])
inventory[name] = Product{
Price: price,
Quantity: quantity,
}
}
// Parse update requests
updateEntries := strings.Split(updateRequests, ",")
fmt.Println("Processing Stock Updates:")
totalUpdates := len(updateEntries)
successfulUpdates := 0
failedUpdates := 0
var failedProducts []string
for _, update := range updateEntries {
parts := strings.Split(update, ":")
productName := parts[0]
change, _ := strconv.Atoi(parts[1])
err := updateStock(inventory, productName, change)
if err != nil {
fmt.Printf("%s: Update failed - %s\n", productName, err.Error())
failedUpdates++
failedProducts = append(failedProducts, productName)
} else {
newQuantity := inventory[productName].Quantity
if change > 0 {
fmt.Printf("%s: Added %d units - New stock: %d\n", productName, change, newQuantity)
} else if change < 0 {
fmt.Printf("%s: Removed %d units - New stock: %d\n", productName, -change, newQuantity)
} else {
fmt.Printf("%s: No change - Current stock: %d\n", productName, newQuantity)
}
successfulUpdates++
}
}
// Update summary
fmt.Println("Update Summary:")
fmt.Printf("Updates processed: %d\n", totalUpdates)
fmt.Printf("Updates successful: %d\n", successfulUpdates)
fmt.Printf("Updates failed: %d\n", failedUpdates)
// Display updated inventory in alphabetical order
fmt.Println("Updated Inventory:")
var productNames []string
for name := range inventory {
productNames = append(productNames, name)
}
sort.Strings(productNames)
for _, name := range productNames {
product := inventory[name]
fmt.Printf("- %s: $%.2f (Stock: %d)\n", name, product.Price, product.Quantity)
}
// Calculate final statistics
totalProducts := len(inventory)
totalItems := 0
totalValue := 0.0
for _, product := range inventory {
totalItems += product.Quantity
totalValue += product.Price * float64(product.Quantity)
}
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 failed updates
if len(failedProducts) > 0 {
fmt.Printf("Failed updates: %s\n", strings.Join(failedProducts, ","))
} else {
fmt.Println("All stock updates were processed successfully")
}
}逻辑与流程中的所有课
自己练习: Go 在线编译器