Menu
CoddyTech

Cập nhật số lượng hàng tồn kho

Thuộc phần Logic và luồng điều khiển trong hành trình GO của Coddy. Bài học 48 trên 68.

challenge icon

Thử thách

Dễ

Cải thiện hệ thống quản lý hàng tồn kho bằng cách triển khai tính năng cập nhật số lượng hàng hóa, kèm theo kiểm tra hợp lệ toàn diện và xử lý lỗi. Thử thách này tiếp nối chức năng của bài học trước và bổ sung khả năng thay đổi số lượng sản phẩm hiện có, đồng thời ngăn các thao tác không hợp lệ có thể khiến lượng hàng tồn kho âm.

Bạn sẽ nhận hai đầu vào:

  • Một chuỗi chứa dữ liệu hàng tồn kho hiện có theo định dạng "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (ví dụ: "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Một chuỗi chứa các yêu cầu cập nhật hàng tồn kho theo định dạng "product1:change1,product2:change2,product3:change3", trong đó mức thay đổi có thể là số nguyên dương hoặc âm (ví dụ: "Mouse:10,Tablet:-5,Keyboard:-3")

Nhiệm vụ của bạn:

  1. Dùng lại cấu trúc Product từ các bài học trước, với các trường Price (float64) và Quantity (int)
  2. Phân tích đầu vào thứ nhất bằng cách tách theo dấu phẩy để lấy từng mục sản phẩm hiện có
  3. Với mỗi mục sản phẩm hiện có, tách theo dấu hai chấm để lấy tên sản phẩm, giá và số lượng
  4. Chuyển chuỗi giá sang float64 và chuỗi số lượng sang int
  5. Tạo và điền dữ liệu sản phẩm hiện có vào bản đồ inventory
  6. Tạo một hàm có tên updateStock, nhận bản đồ inventory, tên sản phẩm và mức thay đổi số lượng làm tham số, rồi trả về một lỗi:
    • Nếu sản phẩm không có trong inventory, trả về lỗi có thông báo "product not found: [product_name]"
    • Nếu mức thay đổi số lượng khiến lượng hàng tồn kho âm (số lượng hiện tại + mức thay đổi < 0), trả về lỗi có thông báo "insufficient stock: cannot reduce [product_name] by [absolute_change_value], only [current_quantity] available"
    • Nếu cập nhật hợp lệ, thay đổi số lượng sản phẩm trong inventory và trả về nil
  7. Phân tích đầu vào thứ hai bằng cách tách theo dấu phẩy để lấy danh sách các yêu cầu cập nhật hàng tồn kho
  8. Với mỗi yêu cầu cập nhật, tách theo dấu hai chấm để lấy tên sản phẩm và mức thay đổi số lượng
  9. Chuyển chuỗi mức thay đổi số lượng sang int
  10. Hiển thị tiêu đề xử lý cập nhật: "Processing Stock Updates:"
  11. Với mỗi yêu cầu cập nhật, gọi hàm updateStock và hiển thị kết quả:
    • Nếu không có lỗi và mức thay đổi là số dương: "[product_name]: Added [change] units - New stock: [new_quantity]"
    • Nếu không có lỗi và mức thay đổi là số âm: "[product_name]: Removed [absolute_change_value] units - New stock: [new_quantity]"
    • Nếu không có lỗi và mức thay đổi bằng không: "[product_name]: No change - Current stock: [current_quantity]"
    • Nếu có lỗi: "[product_name]: Update failed - [error_message]"
  12. Đếm và hiển thị thống kê cập nhật:
    • "Update Summary:"
    • "Updates processed: [total_number_of_updates_processed]"
    • "Updates successful: [number_of_successful_updates]"
    • "Updates failed: [number_of_failed_updates]"
  13. Hiển thị hàng tồn kho đã cập nhật theo thứ tự bảng chữ cái của tên sản phẩm:
    • "Updated Inventory:"
    • Với mỗi sản phẩm: "- [product_name]: $[price] (Stock: [quantity])"
  14. Tính và hiển thị thống kê hàng tồn kho cuối cùng:
    • "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. Liệt kê mọi lần cập nhật thất bại:
    • Nếu có lần cập nhật thất bại: "Failed updates: [comma_separated_list_of_failed_product_names]"
    • Nếu không có lần cập nhật thất bại: "All stock updates were processed successfully"

Dùng gói strings để tách chuỗi đầu vào, gói strconv để chuyển chuỗi thành số, gói errors để tạo thông báo lỗi, gói fmt để định dạng đầu ra và gói sort để sắp xếp tên sản phẩm theo thứ tự bảng chữ cái. Định dạng tất cả giá với 2 chữ số thập phân và tổng giá trị hàng tồn kho với 2 chữ số thập phân. Thử thách này minh họa cách thay đổi dữ liệu hiện có một cách an toàn, đồng thời ngăn thao tác không hợp lệ bằng cách kiểm tra hợp lệ toàn diện và xử lý lỗi.

Tự làm thử

package main

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

type Product struct {
	Price    float64
	Quantity int
}

func addNewItem(inventory map[string]Product, productName string, price float64, quantity int) error {
	if _, exists := inventory[productName]; exists {
		return errors.New("product already exists: " + productName)
	}
	inventory[productName] = Product{Price: price, Quantity: quantity}
	return nil
}

func main() {
	var existingInventory string
	var newProducts string
	fmt.Scanln(&existingInventory)
	fmt.Scanln(&newProducts)

	inventory := make(map[string]Product)

	// Parse existing inventory
	existingItems := strings.Split(existingInventory, ",")
	for _, item := range existingItems {
		parts := strings.Split(item, ":")
		name := parts[0]
		price, _ := strconv.ParseFloat(parts[1], 64)
		quantity, _ := strconv.Atoi(parts[2])
		inventory[name] = Product{Price: price, Quantity: quantity}
	}

	// Parse new products to add
	newItems := strings.Split(newProducts, ",")
	
	fmt.Println("Adding New Items:")
	
	itemsProcessed := 0
	itemsAdded := 0
	itemsRejected := 0
	var rejectedProducts []string

	for _, item := range newItems {
		parts := strings.Split(item, ":")
		name := parts[0]
		price, _ := strconv.ParseFloat(parts[1], 64)
		quantity, _ := strconv.Atoi(parts[2])
		
		itemsProcessed++
		
		err := addNewItem(inventory, name, price, quantity)
		if err != nil {
			fmt.Printf("%s: Failed to add - %s\n", name, err.Error())
			itemsRejected++
			rejectedProducts = append(rejectedProducts, name)
		} else {
			fmt.Printf("%s: Successfully added - $%.2f (Stock: %d)\n", name, price, quantity)
			itemsAdded++
		}
	}

	// Addition summary
	fmt.Println("Addition Summary:")
	fmt.Printf("Items processed: %d\n", itemsProcessed)
	fmt.Printf("Items added: %d\n", itemsAdded)
	fmt.Printf("Items rejected: %d\n", itemsRejected)

	// Display updated inventory in alphabetical order
	fmt.Println("Updated Inventory:")
	var productNames []string
	for name := range inventory {
		productNames = append(productNames, name)
	}
	sort.Strings(productNames)

	totalProducts := 0
	totalItems := 0
	totalValue := 0.0

	for _, name := range productNames {
		product := inventory[name]
		fmt.Printf("- %s: $%.2f (Stock: %d)\n", name, product.Price, product.Quantity)
		totalProducts++
		totalItems += product.Quantity
		totalValue += product.Price * float64(product.Quantity)
	}

	// Final inventory statistics
	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 rejected products
	if len(rejectedProducts) > 0 {
		fmt.Printf("Rejected products: %s\n", strings.Join(rejectedProducts, ","))
	} else {
		fmt.Println("All new products were added successfully")
	}
}

Tất cả bài học trong Logic và luồng điều khiển

Tự luyện tập: Trình biên dịch Go online