Thêm mặt hàng mới
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 47 trên 68.
Thử thách
DễMở rộng hệ thống quản lý hàng tồn kho bằng cách triển khai chức năng thêm sản phẩm mới một cách an toàn. Thử thách này dựa trên hệ thống kiểm tra hàng tồn kho ở bài học trước và bổ sung khả năng mở rộng kho hàng, đồng thời ngăn mục nhập trùng lặp bằng cách xử lý lỗi phù hợp.
Bạn sẽ nhận được 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 sản phẩm mới cần thêm theo định dạng
"product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"(ví dụ:"Monitor:299.99:10,Mouse:19.99:20,Webcam:89.99:12")
Nhiệm vụ của bạn là:
- Dùng cùng 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á thành float64 và chuỗi số lượng thành int
- Tạo và điền dữ liệu sản phẩm hiện có vào bản đồ
inventory - Tạo hàm có tên
addNewItemnhận bản đồ hàng tồn kho, tên sản phẩm, giá và số lượng làm tham số, rồi trả về một lỗi:- Nếu sản phẩm đã có trong kho, trả về lỗi với thông báo
"product already exists: [product_name]" - Nếu sản phẩm chưa có, thêm sản phẩm đó vào kho và trả về nil
- Nếu sản phẩm đã có trong kho, trả về lỗi với 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 sản phẩm mới cần thêm
- Với mỗi mục sản phẩm mới, 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á thành float64 và chuỗi số lượng thành int
- Hiển thị tiêu đề của quá trình thêm sản phẩm:
"Adding New Items:" - Với mỗi sản phẩm mới, gọi hàm
addNewItemvà hiển thị kết quả:- Nếu không có lỗi:
"[product_name]: Successfully added - $[price] (Stock: [quantity])" - Nếu có lỗi:
"[product_name]: Failed to add - [error_message]"
- Nếu không có lỗi:
- Đếm và hiển thị thống kê về quá trình thêm sản phẩm:
"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]"
- 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 toán và hiển thị thống kê cuối cùng về hàng tồn kho:
"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ê các sản phẩm bị từ chối:
- Nếu có sản phẩm bị từ chối:
"Rejected products: [comma_separated_list_of_rejected_products]" - Nếu không có sản phẩm nào bị từ chối:
"All new products were added successfully"
- Nếu có sản phẩm bị từ chối:
Dùng package strings để tách các chuỗi đầu vào, package strconv để chuyển chuỗi thành số, package errors để tạo thông báo lỗi, package fmt để định dạng đầu ra và package 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 cho thấy cách mở rộng tập hợp dữ liệu an toàn, đồng thời ngăn mục nhập trùng lặp bằng cách xử lý lỗi và xác thực phù hợp.
Tự làm thử
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")
}
}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