Generar un informe
Parte de la sección Lógica y Flujo del Journey de GO de Coddy — lección 49 de 68.
Desafío
FácilCompleta 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:
- Utilizar la misma estructura
Productde las lecciones anteriores con los camposPrice(float64) yQuantity(int) - Analizar la primera entrada dividiéndola por comas para obtener las entradas individuales de los productos existentes
- Para cada entrada de producto existente, dividir por dos puntos para obtener el nombre del producto, el precio y la cantidad
- Convertir la cadena del precio a float64 y la cadena de la cantidad a int
- Crear y poblar el mapa
inventorycon los datos de los productos existentes - Crear una función llamada
generateReportque tome el mapa inventory, el tipo de informe y el valor de umbral como parámetros - Analizar la segunda entrada dividiéndola por comas para obtener el tipo de informe y el valor de umbral
- Convertir la cadena del valor de umbral a float64
- 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 ==="
- Para
- 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]"
- 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
- Para
- 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]:"
- Para
- Para cada producto filtrado (en orden alfabético por nombre de producto):
"- [product_name]: $[price] × [quantity] = $[total_value]"
- 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]"
- 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]"
- 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"
- 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]"
- Contar productos con cantidad ≤ 5:
- 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
1Flujo de control avanzado
Switch con `fallthrough`Salir de bucles anidadosContinuar un bucle específicoLa sentencia `goto`Repaso: Control de bucles avanzado4Proyecto: Lista de tareas sencilla
Configuración del proyectoAñadir una tarea2Estructuras y Métodos
Definición de métodos en estructurasReceptores de valorReceptores de punteroElegir receptoresMétodos vs FuncionesResumen - Comportamiento de estructuras5Mapas en profundidad
Mapas de StructsPunteros como valores de MapVerificación de Maps NilComparación de MapsResumen - Contador de frecuencia de palabras8Proyecto: Inventario simple
Descripción general del proyectoVerificar el stock3Interfaces (Conceptos básicos)
¿Qué es una interfaz?Definir una interfazImplementar una interfazUso de tipos de interfazInterfaz vacíaAserciones de tipoType SwitchResumen: Formas y comportamientos