Actualizar la cantidad de stock
Parte de la sección Lógica y Flujo del Journey de GO de Coddy. Lección 48 de 68.
Desafío
FácilMejora tu sistema de gestión de inventario implementando actualizaciones de la cantidad de existencias con validación completa y manejo de errores. Este desafío se basa en la funcionalidad anterior y añade la posibilidad de modificar las cantidades de productos existentes, evitando al mismo tiempo operaciones no válidas que podrían dar lugar a niveles de existencias negativos.
Recibirás dos entradas:
- Una cadena que contiene los 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 solicitudes de actualización de existencias con el formato
"product1:change1,product2:change2,product3:change3", donde los cambios pueden ser enteros positivos o negativos (por ejemplo,"Mouse:10,Tablet:-5,Keyboard:-3")
Tu tarea consiste en:
- Usar la misma estructura
Productde las lecciones anteriores, con los camposPrice(float64) yQuantity(int) - Analizar la primera entrada separándola por comas para obtener las entradas individuales de los productos existentes
- Para cada entrada de producto existente, separarla 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 rellenar el mapa
inventorycon los datos de los productos existentes - Crear una función llamada
updateStockque reciba como parámetros el mapa de inventario, el nombre del producto y el cambio de cantidad, y devuelva un error:- Si el producto no existe en el inventario, devolver un error con el mensaje
"product not found: [product_name]" - Si el cambio de cantidad provocara existencias negativas (cantidad actual + cambio < 0), devolver un error con el mensaje
"insufficient stock: cannot reduce [product_name] by [absolute_change_value], only [current_quantity] available" - Si la actualización es válida, modificar la cantidad del producto en el inventario y devolver nil
- Si el producto no existe en el inventario, devolver un error con el mensaje
- Analizar la segunda entrada separándola por comas para obtener la lista de solicitudes de actualización de existencias
- Para cada solicitud de actualización, separarla por dos puntos para obtener el nombre del producto y el cambio de cantidad
- Convertir la cadena del cambio de cantidad a int
- Mostrar el encabezado del proceso de actualización:
"Processing Stock Updates:" - Para cada solicitud de actualización, llamar a la función
updateStocky mostrar los resultados:- Si no hay ningún error y el cambio es positivo:
"[product_name]: Added [change] units - New stock: [new_quantity]" - Si no hay ningún error y el cambio es negativo:
"[product_name]: Removed [absolute_change_value] units - New stock: [new_quantity]" - Si no hay ningún error y el cambio es cero:
"[product_name]: No change - Current stock: [current_quantity]" - Si hay un error:
"[product_name]: Update failed - [error_message]"
- Si no hay ningún error y el cambio es positivo:
- Contar y mostrar las estadísticas de actualización:
"Update Summary:""Updates processed: [total_number_of_updates_processed]""Updates successful: [number_of_successful_updates]""Updates failed: [number_of_failed_updates]"
- Mostrar el inventario actualizado en orden alfabético por nombre del producto:
"Updated Inventory:"- Para cada producto:
"- [product_name]: $[price] (Stock: [quantity])"
- Calcular y mostrar las estadísticas finales del inventario:
"Final Inventory Statistics:""Total Products: [total_number_of_products_in_inventory]""Total Items in Stock: [sum_of_all_quantities]""Total Inventory Value: $[sum_of_price_times_quantity_for_all_products]"
- Enumerar las actualizaciones fallidas:
- Si hay actualizaciones fallidas:
"Failed updates: [comma_separated_list_of_failed_product_names]" - Si no hay actualizaciones fallidas:
"All stock updates were processed successfully"
- Si hay actualizaciones fallidas:
Usa el paquete strings para separar las cadenas de entrada, el paquete strconv para convertir cadenas en números, el paquete errors para crear mensajes de error, 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 con 2 decimales y al valor total del inventario con 2 decimales. Este desafío demuestra cómo modificar datos existentes de forma segura, evitando operaciones no válidas mediante una validación completa y un manejo de errores adecuado.
Pruébalo tú mismo
package main
import (
"errors"
"fmt"
"sort"
"strconv"
"strings"
)
type Product struct {
Price float64
Quantity int
}
func addNewItem(inventory map[string]Product, productName string, price float64, quantity int) error {
if _, exists := inventory[productName]; exists {
return errors.New("product already exists: " + productName)
}
inventory[productName] = Product{Price: price, Quantity: quantity}
return nil
}
func main() {
var existingInventory string
var newProducts string
fmt.Scanln(&existingInventory)
fmt.Scanln(&newProducts)
inventory := make(map[string]Product)
// Parse existing inventory
existingItems := strings.Split(existingInventory, ",")
for _, item := range existingItems {
parts := strings.Split(item, ":")
name := parts[0]
price, _ := strconv.ParseFloat(parts[1], 64)
quantity, _ := strconv.Atoi(parts[2])
inventory[name] = Product{Price: price, Quantity: quantity}
}
// Parse new products to add
newItems := strings.Split(newProducts, ",")
fmt.Println("Adding New Items:")
itemsProcessed := 0
itemsAdded := 0
itemsRejected := 0
var rejectedProducts []string
for _, item := range newItems {
parts := strings.Split(item, ":")
name := parts[0]
price, _ := strconv.ParseFloat(parts[1], 64)
quantity, _ := strconv.Atoi(parts[2])
itemsProcessed++
err := addNewItem(inventory, name, price, quantity)
if err != nil {
fmt.Printf("%s: Failed to add - %s\n", name, err.Error())
itemsRejected++
rejectedProducts = append(rejectedProducts, name)
} else {
fmt.Printf("%s: Successfully added - $%.2f (Stock: %d)\n", name, price, quantity)
itemsAdded++
}
}
// Addition summary
fmt.Println("Addition Summary:")
fmt.Printf("Items processed: %d\n", itemsProcessed)
fmt.Printf("Items added: %d\n", itemsAdded)
fmt.Printf("Items rejected: %d\n", itemsRejected)
// Display updated inventory in alphabetical order
fmt.Println("Updated Inventory:")
var productNames []string
for name := range inventory {
productNames = append(productNames, name)
}
sort.Strings(productNames)
totalProducts := 0
totalItems := 0
totalValue := 0.0
for _, name := range productNames {
product := inventory[name]
fmt.Printf("- %s: $%.2f (Stock: %d)\n", name, product.Price, product.Quantity)
totalProducts++
totalItems += product.Quantity
totalValue += product.Price * float64(product.Quantity)
}
// Final inventory statistics
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 rejected products
if len(rejectedProducts) > 0 {
fmt.Printf("Rejected products: %s\n", strings.Join(rejectedProducts, ","))
} else {
fmt.Println("All new products were added 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