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 integral de generación de informes 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 con formato, estadísticas, categorización y análisis.
Recibirás dos entradas:
- Una cadena que contiene datos de inventario existentes con 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 con 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:
- Usar la misma estructura
Productde las lecciones anteriores, con 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, dividirla por dos puntos para obtener el nombre, el precio y la cantidad del producto
- Convertir la cadena del precio a float64 y la cadena de la cantidad a int
- Crear y completar el mapa
inventorycon los datos de los productos existentes - Crear una función llamada
generateReportque reciba como parámetros el mapa de inventario, el tipo de informe y el valor del umbral - Analizar la segunda entrada dividiéndola por comas para obtener el tipo de informe y el valor del umbral
- Convertir la cadena del valor del umbral a float64
- Mostrar el encabezado del informe según el tipo de informe:
- Para
"full":"=== FULL INVENTORY REPORT ===" - Para
"low_stock":"=== LOW STOCK REPORT ===" - Para
"high_value":"=== HIGH VALUE REPORT ==="
- Para
- Mostrar las 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 los productos según el tipo de informe:
- Para
"full": Mostrar todos los productos - Para
"low_stock": Mostrar solo los productos cuya cantidad sea menor o igual al valor del umbral - Para
"high_value": Mostrar solo los productos cuyo valor total (precio × cantidad) sea mayor o igual al valor del 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 del producto):
"- [product_name]: $[price] × [quantity] = $[total_value]"
- Mostrar las 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 caro y más barato:
"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 del estado del inventario:
- Contar los productos cuya cantidad sea ≤ 5:
"Low stock items (≤5): [count]" - Contar los productos cuya cantidad sea > 20:
"High stock items (>20): [count]" - Contar los productos cuyo valor sea ≥ $500:
"High value items (≥$500): [count]"
- Contar los productos cuya cantidad sea ≤ 5:
- Mostrar la finalización del informe:
"Report generated successfully""Threshold applied: [threshold_value]"
Usa el paquete strings para dividir las cadenas de entrada, el paquete strconv para convertir cadenas a números, el paquete fmt para la salida con formato y el paquete sort para ordenar alfabéticamente los nombres de los productos. Da formato a todos los precios y valores con 2 decimales. Al buscar el producto más caro o más barato, o el producto con mayor o menor stock, si hay empates, usa el nombre de producto que aparezca primero alfabéticamente. Este desafío demuestra cómo crear sistemas integrales de generación de informes que proporcionan información empresarial valiosa mediante el análisis de datos y la presentación con formato.
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 comportamientosPractica por tu cuenta: Compilador de Go online