Menu
Coddy logo textTech

Generar un informe

Parte de la sección Lógica y Flujo del Journey de GO de Coddy — lección 49 de 68.

challenge icon

Desafío

Fácil

Completa tu sistema de gestión de inventario implementando una función de informes exhaustiva que proporcione información detallada sobre tu inventario actual. Este desafío se basa en toda la funcionalidad anterior y añade la capacidad de generar informes formateados con estadísticas, categorización y análisis.

Recibirás dos entradas:

  • Una cadena que contiene los datos del inventario existente en el formato "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (por ejemplo, "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Una cadena que contiene la configuración del informe en el formato "report_type,threshold_value" donde report_type puede ser "full", "low_stock", o "high_value" y threshold_value es un número (por ejemplo, "low_stock,10")

Tu tarea es:

  1. Utilizar la misma estructura Product de las lecciones anteriores con los campos Price (float64) y Quantity (int)
  2. Analizar la primera entrada dividiéndola por comas para obtener las entradas individuales de los productos existentes
  3. Para cada entrada de producto existente, dividir por dos puntos para obtener el nombre del producto, el precio y la cantidad
  4. Convertir la cadena del precio a float64 y la cadena de la cantidad a int
  5. Crear y poblar el mapa inventory con los datos de los productos existentes
  6. Crear una función llamada generateReport que tome el mapa inventory, el tipo de informe y el valor de umbral como parámetros
  7. Analizar la segunda entrada dividiéndola por comas para obtener el tipo de informe y el valor de umbral
  8. Convertir la cadena del valor de umbral a float64
  9. Mostrar el encabezado del informe basado en el tipo de informe:
    • Para "full": "=== FULL INVENTORY REPORT ==="
    • Para "low_stock": "=== LOW STOCK REPORT ==="
    • Para "high_value": "=== HIGH VALUE REPORT ==="
  10. Mostrar estadísticas generales del inventario:
    • "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]"
  11. Filtrar y mostrar productos basados en el tipo de informe:
    • Para "full": Mostrar todos los productos
    • Para "low_stock": Mostrar solo productos con cantidad menor o igual al valor de umbral
    • Para "high_value": Mostrar solo productos con valor total (precio × cantidad) mayor o igual al valor de umbral
  12. Mostrar la sección de productos filtrados:
    • Para "full": "All Products:"
    • Para "low_stock": "Products with stock ≤ [threshold_value]:"
    • Para "high_value": "Products with value ≥ $[threshold_value]:"
  13. Para cada producto filtrado (en orden alfabético por nombre de producto):
    • "- [product_name]: $[price] × [quantity] = $[total_value]"
  14. Mostrar estadísticas filtradas:
    • "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]"
  15. Encontrar y mostrar los productos más caros y más baratos:
    • "Price Analysis:"
    • "Most expensive: [product_name] at $[price]"
    • "Least expensive: [product_name] at $[price]"
  16. Encontrar y mostrar los productos con mayor y menor stock:
    • "Stock Analysis:"
    • "Highest stock: [product_name] with [quantity] units"
    • "Lowest stock: [product_name] with [quantity] units"
  17. Mostrar la evaluación de salud del inventario:
    • Contar productos con cantidad ≤ 5: "Low stock items (≤5): [count]"
    • Contar productos con cantidad > 20: "High stock items (>20): [count]"
    • Contar productos con valor ≥ $500: "High value items (≥$500): [count]"
  18. Mostrar la finalización del informe:
    • "Report generated successfully"
    • "Threshold applied: [threshold_value]"

Utiliza el paquete strings para dividir las cadenas de entrada, el paquete strconv para convertir cadenas a números, el paquete fmt para la salida formateada y el paquete sort para ordenar los nombres de los productos alfabéticamente. Formatea todos los precios y valores a 2 decimales. Al buscar el más/menos caro o el mayor/menor stock, si hay empates, utiliza el nombre del producto que sea primero alfabéticamente. Este desafío demuestra cómo crear sistemas de informes exhaustivos que proporcionan información empresarial valiosa a través del análisis de datos y la presentación formateada.

Pruébalo tú mismo

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

Todas las lecciones de Lógica y Flujo