Menu
Coddy logo textTech

Łączenie wszystkich elementów

Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 50 z 68.

challenge icon

Wyzwanie

Łatwy

Ukończ system zarządzania zapasami, tworząc kompleksowy program główny, który integruje wszystkie funkcje opracowane w poprzednich lekcjach. To ostatnie wyzwanie łączy inicjalizację zapasów, sprawdzanie stanu magazynowego, dodawanie produktów, aktualizowanie zapasó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")

Twoim zadaniem jest:

  1. Użyć tej samej struktury Product co w poprzednich lekcjach, z polami Price (float64) i Quantity (int)
  2. Przeanalizować pierwsze dane wejściowe i zainicjalizować mapę zapasów istniejącymi danymi o produktach
  3. Wyświetlić komunikat startowy systemu:
    • "=== INVENTORY MANAGEMENT SYSTEM ==="
    • "System initialized with [number_of_products] products"
    • "Starting interactive session..."
  4. Przeanalizować drugie dane wejściowe, aby uzyskać sekwencję operacji do wykonania
  5. Przeanalizować trzecie dane wejściowe, aby uzyskać parametry każdej operacji
  6. Dla każdej operacji w sekwencji wyświetlić nagłówek operacji i wykonać odpowiadające jej działanie:
    • Dla "check": wyświetlić "--- STOCK CHECK ---" i sprawdzić stan magazynowy wskazanego produktu
    • Dla "add": wyświetlić "--- ADD ITEM ---" i dodać wskazany produkt
    • Dla "update": wyświetlić "--- UPDATE STOCK ---" i zaktualizować zapasy wskazanego produktu
    • Dla "report": wyświetlić "--- GENERATE REPORT ---" i wygenerować wskazany raport
    • Dla "exit": wyświetlić "--- SYSTEM EXIT ---" i pokazać informacje o zakończeniu
  7. Zaimplementować funkcję checkStock, która zwraca ilość i błąd, tak jak w poprzednich lekcjach
  8. Zaimplementować funkcję addNewItem, która dodaje produkty i zwraca błąd, tak jak w poprzednich lekcjach
  9. Zaimplementować funkcję updateStock, która aktualizuje ilości i zwraca błąd, tak jak w poprzednich lekcjach
  10. Zaimplementować funkcję generateReport, która tworzy raporty, tak jak w poprzednich lekcjach
  11. Dla operacji "check":
    • Użyć parametru jako nazwy produktu do sprawdzenia
    • Wyświetlić: "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"
  12. Dla operacji "add":
    • Przeanalizować parametr w formacie "product_name:price:quantity"
    • Wyświetlić: "Adding new product: [product_name]"
    • Jeśli operacja się powiedzie: "Product added successfully"
    • Jeśli się nie powiedzie: "Failed to add product: [error_message]"
  13. Dla operacji "update":
    • Przeanalizować parametr w formacie "product_name:change"
    • Wyświetlić: "Updating stock for: [product_name]"
    • Jeśli operacja się powiedzie, a zmiana 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]"
  14. Dla operacji "report":
    • Przeanalizować parametr w formacie "report_type,threshold"
    • Wyświetlić: "Generating [report_type] report with threshold [threshold]"
    • Wygenerować i wyświetlić pełny raport, tak jak w poprzednich lekcjach
  15. Dla operacji "exit":
    • Wyświetlić końcowe statystyki zapasów:
      • "Final inventory status:"
      • "Total products: [total_products]"
      • "Total items: [total_items]"
      • "Total value: $[total_value]"
    • Wyświetlić: "Session completed successfully"
    • Wyświetlić: "Thank you for using the Inventory Management System"
  16. Po każdej operacji (z wyjątkiem exit) wyświetlić: "Operation completed. Continuing to next operation..."

Użyj pakietu strings do dzielenia ciągów wejściowych, pakietu strconv do konwertowania ciągów na liczby, pakietu errors do obsługi błędów, pakietu fmt do formatowania danych wyjściowych oraz pakietu sort do sortowania alfabetycznego. Formatuj wszystkie ceny i wartości do 2 miejsc po przecinku. To wyzwanie pokazuje, jak stworzyć kompletny system interaktywny, który integruje wiele funkcjonalnych komponentów w spójne doświadczenie 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

Poćwicz samodzielnie: Kompilator Go online