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.
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:
- Dùng lại cấu trúc
Producttừ các bài học trước, với các trườngPrice(float64) vàQuantity(int) - 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ó
- 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
- Chuyển chuỗi giá sang float64 và chuỗi số lượng sang int
- Tạo và điền dữ liệu sản phẩm hiện có vào bản đồ
inventory - 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
- Nếu sản phẩm không có trong inventory, trả về lỗi có thông báo
- 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
- 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
- Chuyển chuỗi mức thay đổi số lượng sang int
- Hiển thị tiêu đề xử lý cập nhật:
"Processing Stock Updates:" - Với mỗi yêu cầu cập nhật, gọi hàm
updateStockvà 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]"
- Nếu không có lỗi và mức thay đổi là số dương:
- Đế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]"
- 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])"
- 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]"
- 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"
- Nếu có lần cập nhật thất bại:
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
1Luồng điều khiển nâng cao
Switch với `fallthrough`Thoát khỏi vòng lặp lồng nhauTiếp tục một vòng lặp cụ thểCâu lệnh `goto`Ôn tập: điều khiển vòng lặp nâng cao4Dự án: Danh sách việc cần làm đơn giản
Thiết lập dự ánThêm một việc cần làm2Struct và phương thức
Định nghĩa phương thức cho structReceiver giá trịReceiver con trỏChọn receiverPhương thức và hàmÔn tập: hành vi của struct5Tìm hiểu chuyên sâu về map
Map chứa structCon trỏ làm giá trị của mapKiểm tra map nilSo sánh các mapÔn tập: bộ đếm tần suất từ8Dự án: Quản lý hàng tồn kho đơn giản
Tổng quan dự ánKiểm tra hàng tồn kho3Interface (cơ bản)
Interface là gì?Định nghĩa interfaceTriển khai interfaceDùng kiểu interfaceInterface rỗngKhẳng định kiểuType switchÔn tập: hình dạng và hành viTự luyện tập: Trình biên dịch Go online