Łączenie wszystkich elementów
Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 50 z 68.
Wyzwanie
ŁatwyDokończ system zarządzania zapasami, tworząc kompleksowy program główny, który integruje wszystkie funkcjonalności opracowane w poprzednich lekcjach. To końcowe wyzwanie łączy inicjalizację zapasów, sprawdzanie stanów magazynowych, dodawanie produktów, aktualizowanie stanów i generowanie raportów w kompletny interfejs wiersza poleceń z nawigacją opartą na menu.
Otrzymasz trzy dane wejściowe:
- Ciąg znaków zawierający początkowe 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 sekwencję operacji menu w formacie
"operation1,operation2,operation3", gdzie operacjami mogą być"check","add","update","report"lub"exit"(np."check,add,update,report,exit") - Ciąg znaków zawierający parametry operacji w formacie
"param1|param2|param3", gdzie każdy parametr odpowiada operacji na tej samej pozycji (np."Mouse|Monitor:299.99:10|Laptop:5|full,10")
Twoje zadanie:
- Użyj tej samej struktury
Productco w poprzednich lekcjach, z polamiPrice(float64) iQuantity(int) - Przetwórz pierwsze dane wejściowe i zainicjalizuj mapę zapasów istniejącymi danymi produktów
- Wyświetl komunikat o uruchomieniu systemu:
"=== INVENTORY MANAGEMENT SYSTEM ===""System initialized with [number_of_products] products""Starting interactive session..."
- Przetwórz drugie dane wejściowe, aby uzyskać sekwencję operacji do wykonania
- Przetwórz trzecie dane wejściowe, aby uzyskać parametry dla każdej operacji
- Dla każdej operacji w sekwencji wyświetl jej nagłówek i wykonaj odpowiadające jej działanie:
- Dla
"check": wyświetl"--- STOCK CHECK ---"i sprawdź stan określonego produktu - Dla
"add": wyświetl"--- ADD ITEM ---"i dodaj określony produkt - Dla
"update": wyświetl"--- UPDATE STOCK ---"i zaktualizuj stan określonego produktu - Dla
"report": wyświetl"--- GENERATE REPORT ---"i wygeneruj określony raport - Dla
"exit": wyświetl"--- SYSTEM EXIT ---"i pokaż informacje o zakończeniu
- Dla
- Zaimplementuj funkcję
checkStock, która zwraca ilość i błąd, tak jak w poprzednich lekcjach - Zaimplementuj funkcję
addNewItem, która dodaje produkty i zwraca błąd, tak jak w poprzednich lekcjach - Zaimplementuj funkcję
updateStock, która aktualizuje ilości i zwraca błąd, tak jak w poprzednich lekcjach - Zaimplementuj funkcję
generateReport, która wyświetla raport opisany poniżej dla operacji"report" - Dla operacji
"check":- Użyj parametru jako nazwy produktu do sprawdzenia
- Wyświetl:
"Checking stock for: [product_name]" - Jeśli produkt zostanie znaleziony:
"Stock level: [quantity] units" - Jeśli produkt nie zostanie znaleziony:
"Product not found in inventory"
- Dla operacji
"add":- Przetwórz parametr w formacie
"product_name:price:quantity" - Wyświetl:
"Adding new product: [product_name]" - Jeśli operacja się powiedzie:
"Product added successfully" - Jeśli się nie powiedzie:
"Failed to add product: [error_message]", gdzie błąd to"product already exists"
- Przetwórz parametr w formacie
- Dla operacji
"update":- Przetwórz parametr w formacie
"product_name:change" - Wyświetl:
"Updating stock for: [product_name]" - Jeśli operacja się powiedzie, a zmiana wynosi zero lub jest dodatnia:
"Added [change] units. New stock: [new_quantity]" - Jeśli operacja się powiedzie, a zmiana jest ujemna:
"Removed [absolute_change] units. New stock: [new_quantity]" - Jeśli się nie powiedzie:
"Update failed: [error_message]", gdzie błędem jest"product not found"lub"insufficient stock", gdy nowa ilość byłaby mniejsza od 0
- Przetwórz parametr w formacie
- Dla operacji
"report":- Przetwórz parametr w formacie
"report_type,threshold", gdzie report_type to"low"lub"full", a threshold jest liczbą całkowitą - Wyświetl:
"Generating [report_type] report with threshold [threshold]" - Następnie wyświetl raport, sortując produkty alfabetycznie:
- Dla
"low":"=== LOW REPORT ===", następnie"Products with stock below [threshold]:", a potem"- [name]: [quantity] units (Price: $[price])"dla każdego produktu, którego ilość jest mniejsza od progu - Dla
"full":"=== FULL REPORT ===", następnie"Complete inventory (minimum threshold: [threshold]):", a potem"- [name]: [quantity] units @ $[price] each [OK]"dla każdego produktu, z[LOW STOCK]zamiast[OK], gdy jego ilość jest mniejsza od progu
- Dla
- Przetwórz parametr w formacie
- Dla operacji
"exit":- Wyświetl końcowe statystyki zapasów:
"Final inventory status:""Total products: [total_products]""Total items: [total_items]""Total value: $[total_value]"
- Wyświetl:
"Session completed successfully" - Wyświetl:
"Thank you for using the Inventory Management System"
- Wyświetl końcowe statystyki zapasów:
- Po każdej operacji (z wyjątkiem exit) wyświetl:
"Operation completed. Continuing to next operation..."
Użyj pakietu strings, aby dzielić ciągi wejściowe, pakietu strconv, aby konwertować ciągi na liczby, pakietu errors do obsługi błędów, pakietu fmt do formatowania wyjścia oraz pakietu sort do sortowania alfabetycznego. Formatuj wszystkie ceny i wartości do 2 miejsc po przecinku. To wyzwanie pokazuje, jak stworzyć kompletny interaktywny system, który integruje wiele funkcjonalnych komponentów w spójne środowisko użytkownika z odpowiednią obsługą błędów i zarządzaniem stanem.
Spróbuj swoich sił
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)
}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