Menu
Coddy logo textTech

Aktualizowanie ilości w magazynie

Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 48 z 68.

challenge icon

Wyzwanie

Łatwy

Rozszerz swój system zarządzania zapasami, implementując aktualizacje ilości produktów wraz z kompleksową walidacją i obsługą błędów. To wyzwanie opiera się na funkcjonalności z poprzednich lekcji i dodaje możliwość modyfikowania ilości istniejących produktów, jednocześnie zapobiegając nieprawidłowym operacjom, które mogłyby doprowadzić do ujemnych stanów magazynowych.

Otrzymasz dwa dane wejściowe:

  • Ciąg znaków zawierający istniejące dane o zapasach w formacie "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (np. "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Ciąg znaków zawierający żądania aktualizacji zapasów w formacie "product1:change1,product2:change2,product3:change3", gdzie zmiany mogą być dodatnimi lub ujemnymi liczbami całkowitymi (np. "Mouse:10,Tablet:-5,Keyboard:-3")

Twoje zadanie:

  1. Użyj tej samej struktury Product z poprzednich lekcji, z polami Price (float64) i Quantity (int)
  2. Podziel pierwsze dane wejściowe po przecinkach, aby uzyskać pojedyncze wpisy dotyczące istniejących produktów
  3. Dla każdego wpisu istniejącego produktu podziel go po dwukropkach, aby uzyskać nazwę produktu, cenę i ilość
  4. Przekonwertuj ciąg znaków z ceną na float64, a ciąg znaków z ilością na int
  5. Utwórz mapę inventory i wypełnij ją danymi istniejących produktów
  6. Utwórz funkcję o nazwie updateStock, która przyjmuje mapę zapasów, nazwę produktu i zmianę ilości jako parametry oraz zwraca błąd:
    • Jeśli produkt nie istnieje w zapasach, zwróć błąd z komunikatem "product not found: [product_name]"
    • Jeśli zmiana ilości spowodowałaby ujemny stan magazynowy (bieżąca ilość + zmiana < 0), zwróć błąd z komunikatem "insufficient stock: cannot reduce [product_name] by [absolute_change_value], only [current_quantity] available"
    • Jeśli aktualizacja jest prawidłowa, zmodyfikuj ilość produktu w zapasach i zwróć nil
  7. Podziel drugie dane wejściowe po przecinkach, aby uzyskać listę żądań aktualizacji zapasów
  8. Dla każdego żądania aktualizacji podziel je po dwukropkach, aby uzyskać nazwę produktu i zmianę ilości
  9. Przekonwertuj ciąg znaków ze zmianą ilości na int
  10. Wyświetl nagłówek procesu aktualizacji: "Processing Stock Updates:"
  11. Dla każdego żądania aktualizacji wywołaj funkcję updateStock i wyświetl wyniki:
    • Jeśli nie wystąpił błąd, a zmiana jest dodatnia: "[product_name]: Added [change] units - New stock: [new_quantity]"
    • Jeśli nie wystąpił błąd, a zmiana jest ujemna: "[product_name]: Removed [absolute_change_value] units - New stock: [new_quantity]"
    • Jeśli nie wystąpił błąd, a zmiana wynosi zero: "[product_name]: No change - Current stock: [current_quantity]"
    • Jeśli wystąpił błąd: "[product_name]: Update failed - [error_message]"
  12. Policz i wyświetl statystyki aktualizacji:
    • "Update Summary:"
    • "Updates processed: [total_number_of_updates_processed]"
    • "Updates successful: [number_of_successful_updates]"
    • "Updates failed: [number_of_failed_updates]"
  13. Wyświetl zaktualizowane zapasy w kolejności alfabetycznej według nazw produktów:
    • "Updated Inventory:"
    • Dla każdego produktu: "- [product_name]: $[price] (Stock: [quantity])"
  14. Oblicz i wyświetl końcowe statystyki zapasów:
    • "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]"
  15. Wymień nieudane aktualizacje:
    • Jeśli wystąpiły nieudane aktualizacje: "Failed updates: [comma_separated_list_of_failed_product_names]"
    • Jeśli nie było nieudanych aktualizacji: "All stock updates were processed successfully"

Użyj pakietu strings do dzielenia ciągów wejściowych, pakietu strconv do konwertowania ciągów znaków na liczby, pakietu errors do tworzenia komunikatów o błędach, pakietu fmt do formatowanego wyjścia oraz pakietu sort do sortowania nazw produktów w kolejności alfabetycznej. Formatuj wszystkie ceny z dokładnością do 2 miejsc po przecinku, a łączną wartość zapasów również z dokładnością do 2 miejsc po przecinku. To wyzwanie pokazuje, jak bezpiecznie modyfikować istniejące dane, zapobiegając nieprawidłowym operacjom dzięki kompleksowej walidacji i obsłudze błędów.

Spróbuj swoich sił

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

Wszystkie lekcje w sekcji Logika i przepływ sterowania

Poćwicz samodzielnie: Kompilator Go online