Générer un rapport
Fait partie de la section Logique & Flux du Journey GO de Coddy — leçon 49 sur 68.
Défi
FacileComplétez votre système de gestion d'inventaire en implémentant une fonction de rapport complète qui fournit des informations détaillées sur votre inventaire actuel. Ce défi s'appuie sur toutes les fonctionnalités précédentes et ajoute la capacité de générer des rapports formatés avec des statistiques, des catégorisations et des analyses.
Vous recevrez deux entrées :
- Une chaîne contenant les données d'inventaire existantes 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 la configuration du rapport au format
"report_type,threshold_value"où report_type peut être"full","low_stock", ou"high_value"et threshold_value est un nombre (par exemple,"low_stock,10")
Votre tâche consiste à :
- Utiliser la même structure
Productdes leçons précédentes avec les champsPrice(float64) etQuantity(int) - Analyser la première entrée en la divisant par les virgules pour obtenir les entrées de produits existants individuels
- Pour chaque entrée de produit existant, diviser par les deux-points pour obtenir le nom du produit, le prix et la quantité
- Convertir la chaîne de prix en float64 et la chaîne de quantité en int
- Créer et remplir la map
inventoryavec les données de produits existants - Créer une fonction appelée
generateReportqui prend la map inventory, le type de rapport et la valeur de seuil comme paramètres - Analyser la seconde entrée en la divisant par les virgules pour obtenir le type de rapport et la valeur de seuil
- Convertir la chaîne de valeur de seuil en float64
- Afficher l'en-tête du rapport en fonction du type de rapport :
- Pour
"full":"=== FULL INVENTORY REPORT ===" - Pour
"low_stock":"=== LOW STOCK REPORT ===" - Pour
"high_value":"=== HIGH VALUE REPORT ==="
- Pour
- Afficher les statistiques générales de l'inventaire :
"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]"
- Filtrer et afficher les produits en fonction du type de rapport :
- Pour
"full": Afficher tous les produits - Pour
"low_stock": Afficher uniquement les produits dont la quantité est inférieure ou égale à la valeur de seuil - Pour
"high_value": Afficher uniquement les produits dont la valeur totale (prix × quantité) est supérieure ou égale à la valeur de seuil
- Pour
- Afficher la section des produits filtrés :
- Pour
"full":"All Products:" - Pour
"low_stock":"Products with stock ≤ [threshold_value]:" - Pour
"high_value":"Products with value ≥ $[threshold_value]:"
- Pour
- Pour chaque produit filtré (par ordre alphabétique du nom du produit) :
"- [product_name]: $[price] × [quantity] = $[total_value]"
- Afficher les statistiques filtrées :
"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]"
- Trouver et afficher les produits les plus chers et les moins chers :
"Price Analysis:""Most expensive: [product_name] at $[price]""Least expensive: [product_name] at $[price]"
- Trouver et afficher les produits ayant le stock le plus élevé et le plus bas :
"Stock Analysis:""Highest stock: [product_name] with [quantity] units""Lowest stock: [product_name] with [quantity] units"
- Afficher l'évaluation de la santé de l'inventaire :
- Compter les produits avec une quantité ≤ 5 :
"Low stock items (≤5): [count]" - Compter les produits avec une quantité > 20 :
"High stock items (>20): [count]" - Compter les produits avec une valeur ≥ $500 :
"High value items (≥$500): [count]"
- Compter les produits avec une quantité ≤ 5 :
- Afficher la fin du rapport :
"Report generated successfully""Threshold applied: [threshold_value]"
Utilisez le package strings pour diviser les chaînes d'entrée, le package strconv pour convertir les chaînes en nombres, le package fmt pour la sortie formatée, et le package sort pour trier les noms de produits par ordre alphabétique. Formatez tous les prix et valeurs avec 2 décimales. Lors de la recherche du plus/moins cher ou du stock le plus élevé/bas, s'il y a des égalités, utilisez le nom de produit qui vient en premier par ordre alphabétique. Ce défi démontre comment créer des systèmes de reporting complets qui fournissent des informations commerciales précieuses grâce à l'analyse de données et à une présentation formatée.
Essayez vous-même
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")
}
}Toutes les leçons de Logique & Flux
1Structures de contrôle avancées
Switch avec `fallthrough`Sortir de boucles imbriquéesContinuer une boucle spécifiqueL'instruction `goto`Récapitulatif - Contrôle de boucle avancé4Projet : Liste de tâches simple
Configuration du projetAjouter une tâche2Structures et Méthodes
Définir des méthodes sur des structuresReceveurs par valeurReceveurs par pointeurChoisir les receveursMéthodes vs FonctionsRécapitulatif - Comportement des structures5Les Maps en profondeur
Maps de StructsPointeurs comme valeurs de MapTester les Maps NilComparer des MapsRécapitulatif - Compteur de fréquence de mots8Projet : Inventaire simple
Aperçu du projetVérifier le stock3Interfaces (Les bases)
Qu'est-ce qu'une Interface ?Définir une InterfaceImplémenter une InterfaceUtiliser les types d'InterfaceInterface videAssertions de typeType SwitchRécapitulatif - Formes et comportements