Kết hợp mọi thứ
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 50 trên 68.
Thử thách
DễHoàn thiện hệ thống quản lý hàng tồn kho bằng cách tạo một chương trình chính toàn diện, tích hợp mọi chức năng bạn đã xây dựng trong các bài học trước. Thử thách cuối cùng này kết hợp việc khởi tạo hàng tồn kho, kiểm tra lượng hàng, thêm mặt hàng, cập nhật lượng hàng và tạo báo cáo thành một giao diện dòng lệnh hoàn chỉnh với thao tác điều hướng qua menu.
Bạn sẽ nhận ba đầu vào:
- Một chuỗi chứa dữ liệu hàng tồn kho ban đầu 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 chuỗi thao tác trong menu theo định dạng
"operation1,operation2,operation3", trong đó các thao tác có thể là"check","add","update","report"hoặc"exit"(ví dụ:"check,add,update,report,exit") - Một chuỗi chứa các tham số thao tác theo định dạng
"param1|param2|param3", trong đó mỗi tham số tương ứng với thao tác ở cùng vị trí (ví dụ:"Mouse|Monitor:299.99:10|Laptop:5|full,10")
Nhiệm vụ của bạn là:
- Dùng cùng cấu trúc
Productnhư trong 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 và khởi tạo map hàng tồn kho với dữ liệu sản phẩm hiện có
- Hiển thị thông báo khởi động hệ thống:
"=== INVENTORY MANAGEMENT SYSTEM ===""System initialized with [number_of_products] products""Starting interactive session..."
- Phân tích đầu vào thứ hai để lấy chuỗi thao tác cần thực hiện
- Phân tích đầu vào thứ ba để lấy tham số cho từng thao tác
- Với mỗi thao tác theo thứ tự, hiển thị tiêu đề thao tác và thực hiện hành động tương ứng:
- Với
"check": Hiển thị"--- STOCK CHECK ---"và kiểm tra lượng hàng của sản phẩm được chỉ định - Với
"add": Hiển thị"--- ADD ITEM ---"và thêm sản phẩm được chỉ định - Với
"update": Hiển thị"--- UPDATE STOCK ---"và cập nhật lượng hàng của sản phẩm được chỉ định - Với
"report": Hiển thị"--- GENERATE REPORT ---"và tạo báo cáo được chỉ định - Với
"exit": Hiển thị"--- SYSTEM EXIT ---"và thông tin thoát
- Với
- Cài đặt hàm
checkStocktrả về số lượng và lỗi như trong các bài học trước - Cài đặt hàm
addNewItemđể thêm sản phẩm và trả về lỗi như trong các bài học trước - Cài đặt hàm
updateStockđể cập nhật số lượng và trả về lỗi như trong các bài học trước - Cài đặt hàm
generateReportđể in báo cáo được mô tả bên dưới trong thao tác"report" - Với thao tác
"check":- Dùng tham số làm tên sản phẩm cần kiểm tra
- Hiển thị:
"Checking stock for: [product_name]" - Nếu tìm thấy:
"Stock level: [quantity] units" - Nếu không tìm thấy:
"Product not found in inventory"
- Với thao tác
"add":- Phân tích tham số theo định dạng
"product_name:price:quantity" - Hiển thị:
"Adding new product: [product_name]" - Nếu thành công:
"Product added successfully" - Nếu thất bại:
"Failed to add product: [error_message]", trong đó lỗi là"product already exists"
- Phân tích tham số theo định dạng
- Với thao tác
"update":- Phân tích tham số theo định dạng
"product_name:change" - Hiển thị:
"Updating stock for: [product_name]" - Nếu thành công và change bằng không hoặc lớn hơn không:
"Added [change] units. New stock: [new_quantity]" - Nếu thành công và change nhỏ hơn không:
"Removed [absolute_change] units. New stock: [new_quantity]" - Nếu thất bại:
"Update failed: [error_message]", trong đó lỗi là"product not found"hoặc"insufficient stock"nếu số lượng mới nhỏ hơn 0
- Phân tích tham số theo định dạng
- Với thao tác
"report":- Phân tích tham số theo định dạng
"report_type,threshold", trong đó report_type là"low"hoặc"full", còn threshold là một số nguyên - Hiển thị:
"Generating [report_type] report with threshold [threshold]" - Sau đó in báo cáo, sắp xếp sản phẩm theo thứ tự bảng chữ cái:
- Với
"low":"=== LOW REPORT ===", sau đó là"Products with stock below [threshold]:", rồi đến"- [name]: [quantity] units (Price: $[price])"cho mỗi sản phẩm có số lượng nhỏ hơn ngưỡng - Với
"full":"=== FULL REPORT ===", sau đó là"Complete inventory (minimum threshold: [threshold]):", rồi đến"- [name]: [quantity] units @ $[price] each [OK]"cho mọi sản phẩm, dùng[LOW STOCK]thay cho[OK]khi số lượng nhỏ hơn ngưỡng
- Với
- Phân tích tham số theo định dạng
- Với thao tác
"exit":- Hiển thị thống kê hàng tồn kho cuối cùng:
"Final inventory status:""Total products: [total_products]""Total items: [total_items]""Total value: $[total_value]"
- Hiển thị:
"Session completed successfully" - Hiển thị:
"Thank you for using the Inventory Management System"
- Hiển thị thống kê hàng tồn kho cuối cùng:
- Sau mỗi thao tác, ngoại trừ exit, hiển thị:
"Operation completed. Continuing to next operation..."
Dùng package strings để tách các chuỗi đầu vào, package strconv để chuyển chuỗi thành số, package errors để xử lý lỗi, package fmt để định dạng đầu ra và package sort để sắp xếp theo thứ tự bảng chữ cái. Định dạng tất cả giá và giá trị với 2 chữ số thập phân. Thử thách này cho thấy cách tạo một hệ thống tương tác hoàn chỉnh, tích hợp nhiều thành phần chức năng thành trải nghiệm liền mạch, đồng thời xử lý lỗi và quản lý trạng thái phù hợp.
Tự làm thử
package main
import (
"fmt"
"sort"
"strconv"
"strings"
)
type Product struct {
Price float64
Quantity int
}
func generateReport(inventory map[string]Product, reportType string, threshold float64) {
// Display report header
switch reportType {
case "full":
fmt.Println("=== FULL INVENTORY REPORT ===")
case "low_stock":
fmt.Println("=== LOW STOCK REPORT ===")
case "high_value":
fmt.Println("=== HIGH VALUE REPORT ===")
}
// Calculate general statistics
totalProducts := len(inventory)
totalItems := 0
totalValue := 0.0
for _, product := range inventory {
totalItems += product.Quantity
totalValue += product.Price * float64(product.Quantity)
}
averagePrice := totalValue / float64(totalItems)
// Display general 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)
fmt.Printf("Average Product Price: $%.2f\n", averagePrice)
// Filter products based on report type
var filteredProducts []string
for name, product := range inventory {
switch reportType {
case "full":
filteredProducts = append(filteredProducts, name)
case "low_stock":
if product.Quantity <= int(threshold) {
filteredProducts = append(filteredProducts, name)
}
case "high_value":
productValue := product.Price * float64(product.Quantity)
if productValue >= threshold {
filteredProducts = append(filteredProducts, name)
}
}
}
// Sort filtered products alphabetically
sort.Strings(filteredProducts)
// Display filtered products section header
switch reportType {
case "full":
fmt.Println("All Products:")
case "low_stock":
fmt.Printf("Products with stock ≤ %.0f:\n", threshold)
case "high_value":
fmt.Printf("Products with value ≥ $%.2f:\n", threshold)
}
// Display filtered products
filteredItems := 0
filteredValue := 0.0
for _, name := range filteredProducts {
product := inventory[name]
productValue := product.Price * float64(product.Quantity)
fmt.Printf("- %s: $%.2f × %d = $%.2f\n", name, product.Price, product.Quantity, productValue)
filteredItems += product.Quantity
filteredValue += productValue
}
// Display filtered statistics
fmt.Println("Filtered Results:")
fmt.Printf("Products shown: %d\n", len(filteredProducts))
fmt.Printf("Items in filtered products: %d\n", filteredItems)
fmt.Printf("Value of filtered products: $%.2f\n", filteredValue)
// Find most and least expensive products
var mostExpensiveName, leastExpensiveName string
var mostExpensivePrice, leastExpensivePrice float64
first := true
var sortedNames []string
for name := range inventory {
sortedNames = append(sortedNames, name)
}
sort.Strings(sortedNames)
for _, name := range sortedNames {
product := inventory[name]
if first {
mostExpensiveName = name
mostExpensivePrice = product.Price
leastExpensiveName = name
leastExpensivePrice = product.Price
first = false
} else {
if product.Price > mostExpensivePrice {
mostExpensiveName = name
mostExpensivePrice = product.Price
}
if product.Price < leastExpensivePrice {
leastExpensiveName = name
leastExpensivePrice = product.Price
}
}
}
fmt.Println("Price Analysis:")
fmt.Printf("Most expensive: %s at $%.2f\n", mostExpensiveName, mostExpensivePrice)
fmt.Printf("Least expensive: %s at $%.2f\n", leastExpensiveName, leastExpensivePrice)
// Find highest and lowest stock products
var highestStockName, lowestStockName string
var highestStock, lowestStock int
first = true
for _, name := range sortedNames {
product := inventory[name]
if first {
highestStockName = name
highestStock = product.Quantity
lowestStockName = name
lowestStock = product.Quantity
first = false
} else {
if product.Quantity > highestStock {
highestStockName = name
highestStock = product.Quantity
}
if product.Quantity < lowestStock {
lowestStockName = name
lowestStock = product.Quantity
}
}
}
fmt.Println("Stock Analysis:")
fmt.Printf("Highest stock: %s with %d units\n", highestStockName, highestStock)
fmt.Printf("Lowest stock: %s with %d units\n", lowestStockName, lowestStock)
// Inventory health assessment
lowStockCount := 0
highStockCount := 0
highValueCount := 0
for _, product := range inventory {
if product.Quantity <= 5 {
lowStockCount++
}
if product.Quantity > 20 {
highStockCount++
}
productValue := product.Price * float64(product.Quantity)
if productValue >= 500.0 {
highValueCount++
}
}
fmt.Printf("Low stock items (≤5): %d\n", lowStockCount)
fmt.Printf("High stock items (>20): %d\n", highStockCount)
fmt.Printf("High value items (≥$500): %d\n", highValueCount)
// Report completion
fmt.Println("Report generated successfully")
fmt.Printf("Threshold applied: %.2f\n", threshold)
}
func main() {
var inventoryData string
var reportConfig string
fmt.Scanln(&inventoryData)
fmt.Scanln(&reportConfig)
// Parse inventory data
inventory := make(map[string]Product)
if inventoryData != "" {
products := strings.Split(inventoryData, ",")
for _, productStr := range products {
parts := strings.Split(productStr, ":")
name := parts[0]
price, _ := strconv.ParseFloat(parts[1], 64)
quantity, _ := strconv.Atoi(parts[2])
inventory[name] = Product{Price: price, Quantity: quantity}
}
}
// Parse report configuration
configParts := strings.Split(reportConfig, ",")
reportType := configParts[0]
threshold, _ := strconv.ParseFloat(configParts[1], 64)
// Generate report
generateReport(inventory, reportType, threshold)
}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