Menu
Coddy logo textTech

Assemblage final

Fait partie de la section Logique & Flux du Journey GO de Coddy — leçon 50 sur 68.

challenge icon

Défi

Facile

Complétez votre système de gestion d'inventaire en créant un programme principal complet qui intègre toutes les fonctionnalités que vous avez développées dans les leçons précédentes. Ce défi final rassemble l'initialisation de l'inventaire, la vérification des stocks, l'ajout d'articles, les mises à jour de stock et la génération de rapports dans une interface en ligne de commande complète avec une navigation par menu.

Vous recevrez trois entrées :

  • Une chaîne contenant les données d'inventaire initiales au format "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (par exemple, "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Une chaîne contenant une séquence d'opérations de menu au format "operation1,operation2,operation3" où les opérations peuvent être "check", "add", "update", "report", ou "exit" (par exemple, "check,add,update,report,exit")
  • Une chaîne contenant les paramètres d'opération au format "param1|param2|param3" où chaque paramètre correspond à l'opération à la même position (par exemple, "Mouse|Monitor:299.99:10|Laptop:5|full,10")

Votre tâche consiste à :

  1. Utiliser la même structure Product des leçons précédentes avec les champs Price (float64) et Quantity (int)
  2. Analyser la première entrée et initialiser la map d'inventaire avec les données de produits existantes
  3. Afficher le message de démarrage du système :
    • "=== INVENTORY MANAGEMENT SYSTEM ==="
    • "System initialized with [number_of_products] products"
    • "Starting interactive session..."
  4. Analyser la deuxième entrée pour obtenir la séquence d'opérations à effectuer
  5. Analyser la troisième entrée pour obtenir les paramètres de chaque opération
  6. Pour chaque opération de la séquence, afficher l'en-tête de l'opération et effectuer l'action correspondante :
    • Pour "check" : Afficher "--- STOCK CHECK ---" et vérifier le stock pour le produit spécifié
    • Pour "add" : Afficher "--- ADD ITEM ---" et ajouter le produit spécifié
    • Pour "update" : Afficher "--- UPDATE STOCK ---" et mettre à jour le stock pour le produit spécifié
    • Pour "report" : Afficher "--- GENERATE REPORT ---" et générer le rapport spécifié
    • Pour "exit" : Afficher "--- SYSTEM EXIT ---" et afficher les informations de sortie
  7. Implémenter la fonction checkStock qui retourne la quantité et l'erreur comme dans les leçons précédentes
  8. Implémenter la fonction addNewItem qui ajoute des produits et retourne une erreur comme dans les leçons précédentes
  9. Implémenter la fonction updateStock qui met à jour les quantités et retourne une erreur comme dans les leçons précédentes
  10. Implémenter la fonction generateReport qui crée des rapports comme dans les leçons précédentes
  11. Pour l'opération "check" :
    • Utiliser le paramètre comme nom de produit à vérifier
    • Afficher : "Checking stock for: [product_name]"
    • Si trouvé : "Stock level: [quantity] units"
    • Si non trouvé : "Product not found in inventory"
  12. Pour l'opération "add" :
    • Analyser le paramètre au format "product_name:price:quantity"
    • Afficher : "Adding new product: [product_name]"
    • En cas de succès : "Product added successfully"
    • En cas d'échec : "Failed to add product: [error_message]"
  13. Pour l'opération "update" :
    • Analyser le paramètre au format "product_name:change"
    • Afficher : "Updating stock for: [product_name]"
    • En cas de succès et si le changement est positif : "Added [change] units. New stock: [new_quantity]"
    • En cas de succès et si le changement est négatif : "Removed [absolute_change] units. New stock: [new_quantity]"
    • En cas d'échec : "Update failed: [error_message]"
  14. Pour l'opération "report" :
    • Analyser le paramètre au format "report_type,threshold"
    • Afficher : "Generating [report_type] report with threshold [threshold]"
    • Générer et afficher le rapport complet comme dans les leçons précédentes
  15. Pour l'opération "exit" :
    • Afficher les statistiques finales de l'inventaire :
      • "Final inventory status:"
      • "Total products: [total_products]"
      • "Total items: [total_items]"
      • "Total value: $[total_value]"
    • Afficher : "Session completed successfully"
    • Afficher : "Thank you for using the Inventory Management System"
  16. Après chaque opération (sauf exit), afficher : "Operation completed. Continuing to next operation..."

Utilisez le package strings pour diviser les chaînes d'entrée, le package strconv pour convertir les chaînes en nombres, le package errors pour la gestion des erreurs, le package fmt pour la sortie formatée, et le package sort pour le tri alphabétique. Formatez tous les prix et valeurs avec 2 décimales. Ce défi démontre comment créer un système interactif complet qui intègre plusieurs composants fonctionnels dans une expérience utilisateur cohérente avec une gestion appropriée des erreurs et de l'état.

Essayez vous-même

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)
}

Toutes les leçons de Logique & Flux