Generowanie raportu
Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 49 z 68.
Wyzwanie
ŁatwyUzupełnij system zarządzania zapasami, implementując kompleksową funkcję raportowania, która zapewnia szczegółowe informacje o bieżących zapasach. To wyzwanie bazuje na wszystkich poprzednich funkcjonalnościach i dodaje możliwość generowania sformatowanych raportów ze statystykami, kategoryzacją i analizą.
Otrzymasz dwa dane wejściowe:
- Ciąg znaków zawierający istniejące dane o zapasach w formacie
"product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3"(np."Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8") - Ciąg znaków zawierający konfigurację raportu w formacie
"report_type,threshold_value", gdzie report_type może mieć wartość"full","low_stock"lub"high_value", a threshold_value jest liczbą (np."low_stock,10")
Twoje zadanie:
- Użyj tej samej struktury
Productco w poprzednich lekcjach, z polamiPrice(float64) iQuantity(int) - Przetwórz pierwsze dane wejściowe, dzieląc je po przecinkach, aby uzyskać poszczególne wpisy dotyczące istniejących produktów
- Podziel każdy wpis dotyczący istniejącego produktu po dwukropkach, aby uzyskać nazwę produktu, cenę i ilość
- Przekonwertuj ciąg znaków z ceną na float64, a ciąg znaków z ilością na int
- Utwórz mapę
inventoryi wypełnij ją danymi istniejących produktów - Utwórz funkcję o nazwie
generateReport, która przyjmuje mapę zapasów, typ raportu i wartość progową jako parametry - Przetwórz drugie dane wejściowe, dzieląc je po przecinkach, aby uzyskać typ raportu i wartość progową
- Przekonwertuj ciąg znaków z wartością progową na float64
- Wyświetl nagłówek raportu w zależności od typu raportu:
- Dla
"full":"=== FULL INVENTORY REPORT ===" - Dla
"low_stock":"=== LOW STOCK REPORT ===" - Dla
"high_value":"=== HIGH VALUE REPORT ==="
- Dla
- Wyświetl ogólne statystyki zapasów:
"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]"
- Filtruj i wyświetlaj produkty w zależności od typu raportu:
- Dla
"full": Pokaż wszystkie produkty - Dla
"low_stock": Pokaż tylko produkty, których ilość jest mniejsza lub równa wartości progowej - Dla
"high_value": Pokaż tylko produkty, których łączna wartość (cena × ilość) jest większa lub równa wartości progowej
- Dla
- Wyświetl sekcję z przefiltrowanymi produktami:
- Dla
"full":"All Products:" - Dla
"low_stock":"Products with stock ≤ [threshold_value]:" - Dla
"high_value":"Products with value ≥ $[threshold_value]:"
- Dla
- Dla każdego przefiltrowanego produktu (w kolejności alfabetycznej według nazwy produktu):
"- [product_name]: $[price] × [quantity] = $[total_value]"
- Wyświetl statystyki przefiltrowanych wyników:
"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]"
- Znajdź i wyświetl najdroższy oraz najtańszy produkt:
"Price Analysis:""Most expensive: [product_name] at $[price]""Least expensive: [product_name] at $[price]"
- Znajdź i wyświetl produkty o największych i najmniejszych zapasach:
"Stock Analysis:""Highest stock: [product_name] with [quantity] units""Lowest stock: [product_name] with [quantity] units"
- Wyświetl ocenę stanu zapasów:
- Policz produkty, których ilość wynosi ≤ 5:
"Low stock items (≤5): [count]" - Policz produkty, których ilość wynosi > 20:
"High stock items (>20): [count]" - Policz produkty o wartości ≥ $500:
"High value items (≥$500): [count]"
- Policz produkty, których ilość wynosi ≤ 5:
- Wyświetl zakończenie raportu:
"Report generated successfully""Threshold applied: [threshold_value]"
Użyj pakietu strings do dzielenia ciągów znaków wejściowych, pakietu strconv do konwertowania ciągów znaków na liczby, pakietu fmt do formatowania wyjścia oraz pakietu sort do sortowania nazw produktów alfabetycznie. Formatuj wszystkie ceny i wartości do 2 miejsc po przecinku. Przy wyszukiwaniu najdroższego/najtańszego produktu lub produktów o największych/najmniejszych zapasach, w przypadku remisu wybierz produkt o nazwie pierwszej w kolejności alfabetycznej. To wyzwanie pokazuje, jak tworzyć kompleksowe systemy raportowania, które dostarczają cennych informacji biznesowych dzięki analizie danych i ich prezentacji w odpowiednim formacie.
Spróbuj swoich sił
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")
}
}Wszystkie lekcje w sekcji Logika i przepływ sterowania
1Zaawansowane sterowanie przepływem
Instrukcja switch z `fallthrough`Przerywanie zagnieżdżonych pętliKontynuowanie określonej pętliInstrukcja `goto`Podsumowanie — zaawansowane sterowanie pętlami4Projekt: Prosta lista zadań
Konfiguracja projektuDodawanie zadania2Struktury i metody
Definiowanie metod dla strukturOdbiorniki przez wartośćOdbiorniki przez wskaźnikWybór odbiornikówMetody a funkcjePodsumowanie — działanie struktur5Mapy w szczegółach
Mapy strukturWskaźniki jako wartości mapSprawdzanie, czy mapy są nilPorównywanie mapPodsumowanie — licznik częstości słów8Projekt: Prosty system magazynowy
Przegląd projektuSprawdzanie stanu magazynowego3Interfejsy (podstawy)
Czym jest interfejs?Definiowanie interfejsuImplementowanie interfejsuUżywanie typów interfejsowychPusty interfejsAsercje typuPrzełącznik typówPodsumowanie – kształty i zachowaniaPoćwicz samodzielnie: Kompilator Go online