Menu
CoddyTech

生成报告

本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 49 课,共 68 课。

challenge icon

挑战

简单

通过实现一个全面的报告函数,完善你的库存管理系统,提供当前库存的详细信息。本挑战基于之前的所有功能,并新增了生成格式化报告的能力,其中包含统计、分类和分析。

你将收到两个输入:

  • 一个包含现有库存数据的字符串,格式为 "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")

你的任务是:

  1. 使用之前课程中的同一个 Product 结构体,包含 Price(float64)和 Quantity(int)字段
  2. 通过按逗号拆分第一个输入,获取各个现有商品条目
  3. 对于每个现有商品条目,按冒号拆分以获取商品名称、价格和数量
  4. 将价格字符串转换为 float64,将数量字符串转换为 int
  5. 创建并填充 inventory 映射,其中包含现有商品数据
  6. 创建一个名为 generateReport 的函数,以库存映射、报告类型和阈值作为参数
  7. 通过按逗号拆分第二个输入,获取报告类型和阈值
  8. 将阈值字符串转换为 float64
  9. 根据报告类型显示报告标题:
    • 对于 "full":"=== FULL INVENTORY REPORT ==="
    • 对于 "low_stock":"=== LOW STOCK REPORT ==="
    • 对于 "high_value":"=== HIGH VALUE REPORT ==="
  10. 显示库存总体统计信息:
    • "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]"
  11. 根据报告类型筛选并显示商品:
    • 对于 "full":显示所有商品
    • 对于 "low_stock":只显示数量小于或等于阈值的商品
    • 对于 "high_value":只显示总价值(价格 × 数量)大于或等于阈值的商品
  12. 显示筛选后的商品部分:
    • 对于 "full":"All Products:"
    • 对于 "low_stock":"Products with stock ≤ [threshold_value]:"
    • 对于 "high_value":"Products with value ≥ $[threshold_value]:"
  13. 对于每个筛选后的商品(按商品名称的字母顺序排列):
    • "- [product_name]: $[price] × [quantity] = $[total_value]"
  14. 显示筛选后的统计信息:
    • "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]"
  15. 找出并显示价格最高和最低的商品:
    • "Price Analysis:"
    • "Most expensive: [product_name] at $[price]"
    • "Least expensive: [product_name] at $[price]"
  16. 找出并显示库存数量最多和最少的商品:
    • "Stock Analysis:"
    • "Highest stock: [product_name] with [quantity] units"
    • "Lowest stock: [product_name] with [quantity] units"
  17. 显示库存健康状况评估:
    • 统计数量 ≤ 5 的商品:"Low stock items (≤5): [count]"
    • 统计数量 > 20 的商品:"High stock items (>20): [count]"
    • 统计价值 ≥ $500 的商品:"High value items (≥$500): [count]"
  18. 显示报告完成信息:
    • "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 在线编译器