Menu
CoddyTech

添加新商品

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

challenge icon

挑战

简单

通过安全添加新产品的功能,扩展你的库存管理系统。本挑战基于之前的库存检查系统,增加了扩充库存的能力,并通过正确处理错误来避免重复条目。

你会收到两个输入:

  • 一个包含现有库存数据的字符串,格式为 "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"(例如,"Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • 一个包含待添加新产品的字符串,格式为 "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"(例如,"Monitor:299.99:10,Mouse:19.99:20,Webcam:89.99:12")

你的任务是:

  1. 使用之前课程中的同一个 Product 结构体,其中包含 Price(float64)和 Quantity(int)字段
  2. 按逗号拆分第一个输入,获取每个现有产品条目
  3. 对于每个现有产品条目,按冒号拆分,获取产品名称、价格和数量
  4. 将价格字符串转换为 float64,将数量字符串转换为 int
  5. 创建并填充 inventory 映射,其中包含现有产品数据
  6. 创建一个名为 addNewItem 的函数,该函数接收库存映射、产品名称、价格和数量作为参数,并返回一个错误:
    • 如果产品已存在于库存中,则返回错误,错误消息为 "product already exists: [product_name]"
    • 如果产品不存在,则将其添加到库存中并返回 nil
  7. 按逗号拆分第二个输入,获取待添加的新产品列表
  8. 对于每个新产品条目,按冒号拆分,获取产品名称、价格和数量
  9. 将价格字符串转换为 float64,将数量字符串转换为 int
  10. 显示添加流程标题:"Adding New Items:"
  11. 对于每个新产品,调用 addNewItem 函数并显示结果:
    • 如果没有错误:"[product_name]: Successfully added - $[price] (Stock: [quantity])"
    • 如果出现错误:"[product_name]: Failed to add - [error_message]"
  12. 统计并显示添加情况:
    • "Addition Summary:"
    • "Items processed: [total_number_of_items_processed]"
    • "Items added: [number_of_items_successfully_added]"
    • "Items rejected: [number_of_items_that_failed_to_add]"
  13. 按产品名称的字母顺序显示更新后的库存:
    • "Updated Inventory:"
    • 对于每种产品:"- [product_name]: $[price] (Stock: [quantity])"
  14. 计算并显示最终库存统计信息:
    • "Final Inventory Statistics:"
    • "Total Products: [total_number_of_products_in_inventory]"
    • "Total Items in Stock: [sum_of_all_quantities]"
    • "Total Inventory Value: $[sum_of_price_times_quantity_for_all_products]"
  15. 列出所有被拒绝的产品:
    • 如果有被拒绝的产品:"Rejected products: [comma_separated_list_of_rejected_products]"
    • 如果没有被拒绝的产品:"All new products were added successfully"

使用 strings 包拆分输入字符串,使用 strconv 包将字符串转换为数字,使用 errors 包创建错误消息,使用 fmt 包进行格式化输出,并使用 sort 包按字母顺序排序产品名称。所有价格都保留 2 位小数,总库存价值也保留 2 位小数。本挑战将展示如何在正确处理错误并进行验证的同时,安全地扩展数据集合并避免重复条目。

亲手试试

package main

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type Product struct {
	Price    float64
	Quantity int
}

func checkStock(inventory map[string]Product, productName string) (int, error) {
	product, exists := inventory[productName]
	if !exists {
		return 0, errors.New("product not found: " + productName)
	}
	return product.Quantity, nil
}

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

	inventory := make(map[string]Product)

	// Parse inventory data
	productEntries := strings.Split(inventoryData, ",")
	for _, entry := range productEntries {
		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 check requests
	productsToCheck := strings.Split(checkRequests, ",")

	fmt.Println("Stock Check Results:")

	var productsFound int
	var productsNotFound int
	var totalStock int
	var missingProducts []string

	for _, productName := range productsToCheck {
		quantity, err := checkStock(inventory, productName)
		if err != nil {
			fmt.Printf("%s: Error - %s\n", productName, err.Error())
			productsNotFound++
			missingProducts = append(missingProducts, productName)
		} else {
			fmt.Printf("%s: %d units in stock\n", productName, quantity)
			productsFound++
			totalStock += quantity
		}
	}

	fmt.Println("Check Summary:")
	fmt.Printf("Products checked: %d\n", len(productsToCheck))
	fmt.Printf("Products found: %d\n", productsFound)
	fmt.Printf("Products not found: %d\n", productsNotFound)
	fmt.Printf("Total stock for found products: %d units\n", totalStock)

	if len(missingProducts) > 0 {
		fmt.Printf("Missing products: %s\n", strings.Join(missingProducts, ","))
	} else {
		fmt.Println("All requested products are available")
	}
}

逻辑与流程中的所有课

自己练习: Go 在线编译器