Tạo báo cáo
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 49 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 triển khai hàm lập báo cáo toàn diện, cung cấp thông tin chi tiết về hàng tồn kho hiện tại. Thử thách này xây dựng dựa trên tất cả chức năng trước đó và bổ sung khả năng tạo báo cáo có định dạng, kèm theo số liệu thống kê, phân loại và phân tích.
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ấu hình báo cáo theo định dạng
"report_type,threshold_value", trong đó report_type có thể là"full","low_stock"hoặc"high_value", còn threshold_value là một số (ví dụ:"low_stock,10")
Nhiệm vụ của bạn là:
- Dùng struct
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 bằng cách tách theo dấu phẩy để lấy từng mục hàng tồn kho hiện có
- Với mỗi mục hàng tồn kho 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 map
inventory - Tạo hàm có tên
generateReport, nhận map hàng tồn kho, loại báo cáo và giá trị ngưỡng làm tham số - Phân tích đầu vào thứ hai bằng cách tách theo dấu phẩy để lấy loại báo cáo và giá trị ngưỡng
- Chuyển chuỗi giá trị ngưỡng thành float64
- Hiển thị tiêu đề báo cáo dựa trên loại báo cáo:
- Với
"full":"=== FULL INVENTORY REPORT ===" - Với
"low_stock":"=== LOW STOCK REPORT ===" - Với
"high_value":"=== HIGH VALUE REPORT ==="
- Với
- Hiển thị số liệu thống kê chung về hàng tồn kho:
"Total Products: [total_number_of_products]""Total Items in Stock: [sum_of_all_quantities]""Total Inventory Value: $[sum_of_price_times_quantity_for_all_products]""Average Product Price: $[total_inventory_value_divided_by_total_items]"
- Lọc và hiển thị sản phẩm dựa trên loại báo cáo:
- Với
"full": Hiển thị tất cả sản phẩm - Với
"low_stock": Chỉ hiển thị sản phẩm có số lượng nhỏ hơn hoặc bằng giá trị ngưỡng - Với
"high_value": Chỉ hiển thị sản phẩm có tổng giá trị (giá × số lượng) lớn hơn hoặc bằng giá trị ngưỡng
- Với
- Hiển thị phần sản phẩm đã lọc:
- Với
"full":"All Products:" - Với
"low_stock":"Products with stock ≤ [threshold_value]:" - Với
"high_value":"Products with value ≥ $[threshold_value]:"
- Với
- Với mỗi sản phẩm đã lọc, theo thứ tự bảng chữ cái của tên sản phẩm:
"- [product_name]: $[price] × [quantity] = $[total_value]"
- Hiển thị số liệu thống kê của các sản phẩm đã lọc:
"Filtered Results:""Products shown: [number_of_products_in_filtered_results]""Items in filtered products: [sum_of_quantities_for_filtered_products]""Value of filtered products: $[sum_of_values_for_filtered_products]"
- Tìm và hiển thị sản phẩm đắt nhất và rẻ nhất:
"Price Analysis:""Most expensive: [product_name] at $[price]""Least expensive: [product_name] at $[price]"
- Tìm và hiển thị sản phẩm có lượng tồn kho cao nhất và thấp nhất:
"Stock Analysis:""Highest stock: [product_name] with [quantity] units""Lowest stock: [product_name] with [quantity] units"
- Hiển thị đánh giá tình trạng hàng tồn kho:
- Đếm sản phẩm có số lượng ≤ 5:
"Low stock items (≤5): [count]" - Đếm sản phẩm có số lượng > 20:
"High stock items (>20): [count]" - Đếm sản phẩm có giá trị ≥ $500:
"High value items (≥$500): [count]"
- Đếm sản phẩm có số lượng ≤ 5:
- Hiển thị thông tin hoàn tất báo cáo:
"Report generated successfully""Threshold applied: [threshold_value]"
Dùng package strings để tách các chuỗi đầu vào, package strconv để chuyển chuỗi thành số, 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à giá trị với 2 chữ số thập phân. Khi tìm sản phẩm đắt nhất, rẻ nhất, có lượng tồn kho cao nhất hoặc thấp nhất, nếu có kết quả bằng nhau, hãy chọn tên sản phẩm đứng đầu theo thứ tự bảng chữ cái. Thử thách này cho thấy cách tạo hệ thống báo cáo toàn diện, cung cấp thông tin kinh doanh hữu ích thông qua phân tích dữ liệu và trình bày có định dạng.
Tự làm thử
package main
import (
"errors"
"fmt"
"sort"
"strconv"
"strings"
)
type Product struct {
Price float64
Quantity int
}
func updateStock(inventory map[string]Product, productName string, change int) error {
product, exists := inventory[productName]
if !exists {
return errors.New("product not found: " + productName)
}
newQuantity := product.Quantity + change
if newQuantity < 0 {
return fmt.Errorf("insufficient stock: cannot reduce %s by %d, only %d available", productName, -change, product.Quantity)
}
product.Quantity = newQuantity
inventory[productName] = product
return nil
}
func main() {
var inventoryData string
var updateRequests string
fmt.Scanln(&inventoryData)
fmt.Scanln(&updateRequests)
// Parse existing inventory
inventory := make(map[string]Product)
inventoryEntries := strings.Split(inventoryData, ",")
for _, entry := range inventoryEntries {
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 update requests
updateEntries := strings.Split(updateRequests, ",")
fmt.Println("Processing Stock Updates:")
totalUpdates := len(updateEntries)
successfulUpdates := 0
failedUpdates := 0
var failedProducts []string
for _, update := range updateEntries {
parts := strings.Split(update, ":")
productName := parts[0]
change, _ := strconv.Atoi(parts[1])
err := updateStock(inventory, productName, change)
if err != nil {
fmt.Printf("%s: Update failed - %s\n", productName, err.Error())
failedUpdates++
failedProducts = append(failedProducts, productName)
} else {
newQuantity := inventory[productName].Quantity
if change > 0 {
fmt.Printf("%s: Added %d units - New stock: %d\n", productName, change, newQuantity)
} else if change < 0 {
fmt.Printf("%s: Removed %d units - New stock: %d\n", productName, -change, newQuantity)
} else {
fmt.Printf("%s: No change - Current stock: %d\n", productName, newQuantity)
}
successfulUpdates++
}
}
// Update summary
fmt.Println("Update Summary:")
fmt.Printf("Updates processed: %d\n", totalUpdates)
fmt.Printf("Updates successful: %d\n", successfulUpdates)
fmt.Printf("Updates failed: %d\n", failedUpdates)
// Display updated inventory in alphabetical order
fmt.Println("Updated Inventory:")
var productNames []string
for name := range inventory {
productNames = append(productNames, name)
}
sort.Strings(productNames)
for _, name := range productNames {
product := inventory[name]
fmt.Printf("- %s: $%.2f (Stock: %d)\n", name, product.Price, product.Quantity)
}
// Calculate final statistics
totalProducts := len(inventory)
totalItems := 0
totalValue := 0.0
for _, product := range inventory {
totalItems += product.Quantity
totalValue += product.Price * float64(product.Quantity)
}
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 failed updates
if len(failedProducts) > 0 {
fmt.Printf("Failed updates: %s\n", strings.Join(failedProducts, ","))
} else {
fmt.Println("All stock updates were processed 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