Menu
Coddy logo textTech

Juntando Tudo

Parte da seção Lógica & Fluxo do Journey de GO da Coddy — lição 50 de 68.

challenge icon

Desafio

Fácil

Complete seu sistema de gerenciamento de inventário criando um programa principal abrangente que integra todas as funcionalidades que você construiu nas lições anteriores. Este desafio final reúne a inicialização do inventário, verificação de estoque, adição de itens, atualizações de estoque e geração de relatórios em uma interface de linha de comando completa com navegação baseada em menu.

Você receberá três entradas:

  • Uma string contendo os dados iniciais do inventário no formato "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (ex: "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Uma string contendo uma sequência de operações de menu no formato "operation1,operation2,operation3" onde as operações podem ser "check", "add", "update", "report", ou "exit" (ex: "check,add,update,report,exit")
  • Uma string contendo os parâmetros das operações no formato "param1|param2|param3" onde cada parâmetro corresponde à operação na mesma posição (ex: "Mouse|Monitor:299.99:10|Laptop:5|full,10")

Sua tarefa é:

  1. Usar a mesma struct Product das lições anteriores com os campos Price (float64) e Quantity (int)
  2. Analisar a primeira entrada e inicializar o mapa de inventário com os dados dos produtos existentes
  3. Exibir a mensagem de inicialização do sistema:
    • "=== INVENTORY MANAGEMENT SYSTEM ==="
    • "System initialized with [number_of_products] products"
    • "Starting interactive session..."
  4. Analisar a segunda entrada para obter a sequência de operações a serem executadas
  5. Analisar a terceira entrada para obter os parâmetros de cada operação
  6. Para cada operação na sequência, exibir o cabeçalho da operação e realizar a ação correspondente:
    • Para "check": Exibir "--- STOCK CHECK ---" e verificar o estoque do produto especificado
    • Para "add": Exibir "--- ADD ITEM ---" e adicionar o produto especificado
    • Para "update": Exibir "--- UPDATE STOCK ---" e atualizar o estoque do produto especificado
    • Para "report": Exibir "--- GENERATE REPORT ---" e gerar o relatório especificado
    • Para "exit": Exibir "--- SYSTEM EXIT ---" e mostrar as informações de saída
  7. Implementar a função checkStock que retorna a quantidade e o erro como nas lições anteriores
  8. Implementar a função addNewItem que adiciona produtos e retorna um erro como nas lições anteriores
  9. Implementar a função updateStock que atualiza as quantidades e retorna um erro como nas lições anteriores
  10. Implementar a função generateReport que cria relatórios como nas lições anteriores
  11. Para a operação "check":
    • Usar o parâmetro como o nome do produto a ser verificado
    • Exibir: "Checking stock for: [product_name]"
    • Se encontrado: "Stock level: [quantity] units"
    • Se não encontrado: "Product not found in inventory"
  12. Para a operação "add":
    • Analisar o parâmetro no formato "product_name:price:quantity"
    • Exibir: "Adding new product: [product_name]"
    • Se bem-sucedido: "Product added successfully"
    • Se falhar: "Failed to add product: [error_message]"
  13. Para a operação "update":
    • Analisar o parâmetro no formato "product_name:change"
    • Exibir: "Updating stock for: [product_name]"
    • Se bem-sucedido e a alteração for positiva: "Added [change] units. New stock: [new_quantity]"
    • Se bem-sucedido e a alteração for negativa: "Removed [absolute_change] units. New stock: [new_quantity]"
    • Se falhar: "Update failed: [error_message]"
  14. Para a operação "report":
    • Analisar o parâmetro no formato "report_type,threshold"
    • Exibir: "Generating [report_type] report with threshold [threshold]"
    • Gerar e exibir o relatório completo como nas lições anteriores
  15. Para a operação "exit":
    • Exibir as estatísticas finais do inventário:
      • "Final inventory status:"
      • "Total products: [total_products]"
      • "Total items: [total_items]"
      • "Total value: $[total_value]"
    • Exibir: "Session completed successfully"
    • Exibir: "Thank you for using the Inventory Management System"
  16. Após cada operação (exceto exit), exibir: "Operation completed. Continuing to next operation..."

Use o pacote strings para dividir as strings de entrada, o pacote strconv para converter strings em números, o pacote errors para tratamento de erros, o pacote fmt para saída formatada e o pacote sort para ordenação alfabética. Formate todos os preços e valores com 2 casas decimais. Este desafio demonstra como criar um sistema interativo completo que integra múltiplos componentes funcionais em uma experiência de usuário coesa com tratamento de erros e gerenciamento de estado adequados.

Experimente você mesmo

package main

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
)

type Product struct {
	Price    float64
	Quantity int
}

func generateReport(inventory map[string]Product, reportType string, threshold float64) {
	// Display report header
	switch reportType {
	case "full":
		fmt.Println("=== FULL INVENTORY REPORT ===")
	case "low_stock":
		fmt.Println("=== LOW STOCK REPORT ===")
	case "high_value":
		fmt.Println("=== HIGH VALUE REPORT ===")
	}

	// Calculate general statistics
	totalProducts := len(inventory)
	totalItems := 0
	totalValue := 0.0
	
	for _, product := range inventory {
		totalItems += product.Quantity
		totalValue += product.Price * float64(product.Quantity)
	}
	
	averagePrice := totalValue / float64(totalItems)

	// Display general 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)
	fmt.Printf("Average Product Price: $%.2f\n", averagePrice)

	// Filter products based on report type
	var filteredProducts []string
	for name, product := range inventory {
		switch reportType {
		case "full":
			filteredProducts = append(filteredProducts, name)
		case "low_stock":
			if product.Quantity <= int(threshold) {
				filteredProducts = append(filteredProducts, name)
			}
		case "high_value":
			productValue := product.Price * float64(product.Quantity)
			if productValue >= threshold {
				filteredProducts = append(filteredProducts, name)
			}
		}
	}

	// Sort filtered products alphabetically
	sort.Strings(filteredProducts)

	// Display filtered products section header
	switch reportType {
	case "full":
		fmt.Println("All Products:")
	case "low_stock":
		fmt.Printf("Products with stock ≤ %.0f:\n", threshold)
	case "high_value":
		fmt.Printf("Products with value ≥ $%.2f:\n", threshold)
	}

	// Display filtered products
	filteredItems := 0
	filteredValue := 0.0
	for _, name := range filteredProducts {
		product := inventory[name]
		productValue := product.Price * float64(product.Quantity)
		fmt.Printf("- %s: $%.2f × %d = $%.2f\n", name, product.Price, product.Quantity, productValue)
		filteredItems += product.Quantity
		filteredValue += productValue
	}

	// Display filtered statistics
	fmt.Println("Filtered Results:")
	fmt.Printf("Products shown: %d\n", len(filteredProducts))
	fmt.Printf("Items in filtered products: %d\n", filteredItems)
	fmt.Printf("Value of filtered products: $%.2f\n", filteredValue)

	// Find most and least expensive products
	var mostExpensiveName, leastExpensiveName string
	var mostExpensivePrice, leastExpensivePrice float64
	first := true
	
	var sortedNames []string
	for name := range inventory {
		sortedNames = append(sortedNames, name)
	}
	sort.Strings(sortedNames)
	
	for _, name := range sortedNames {
		product := inventory[name]
		if first {
			mostExpensiveName = name
			mostExpensivePrice = product.Price
			leastExpensiveName = name
			leastExpensivePrice = product.Price
			first = false
		} else {
			if product.Price > mostExpensivePrice {
				mostExpensiveName = name
				mostExpensivePrice = product.Price
			}
			if product.Price < leastExpensivePrice {
				leastExpensiveName = name
				leastExpensivePrice = product.Price
			}
		}
	}

	fmt.Println("Price Analysis:")
	fmt.Printf("Most expensive: %s at $%.2f\n", mostExpensiveName, mostExpensivePrice)
	fmt.Printf("Least expensive: %s at $%.2f\n", leastExpensiveName, leastExpensivePrice)

	// Find highest and lowest stock products
	var highestStockName, lowestStockName string
	var highestStock, lowestStock int
	first = true
	
	for _, name := range sortedNames {
		product := inventory[name]
		if first {
			highestStockName = name
			highestStock = product.Quantity
			lowestStockName = name
			lowestStock = product.Quantity
			first = false
		} else {
			if product.Quantity > highestStock {
				highestStockName = name
				highestStock = product.Quantity
			}
			if product.Quantity < lowestStock {
				lowestStockName = name
				lowestStock = product.Quantity
			}
		}
	}

	fmt.Println("Stock Analysis:")
	fmt.Printf("Highest stock: %s with %d units\n", highestStockName, highestStock)
	fmt.Printf("Lowest stock: %s with %d units\n", lowestStockName, lowestStock)

	// Inventory health assessment
	lowStockCount := 0
	highStockCount := 0
	highValueCount := 0
	
	for _, product := range inventory {
		if product.Quantity <= 5 {
			lowStockCount++
		}
		if product.Quantity > 20 {
			highStockCount++
		}
		productValue := product.Price * float64(product.Quantity)
		if productValue >= 500.0 {
			highValueCount++
		}
	}

	fmt.Printf("Low stock items (≤5): %d\n", lowStockCount)
	fmt.Printf("High stock items (>20): %d\n", highStockCount)
	fmt.Printf("High value items (≥$500): %d\n", highValueCount)

	// Report completion
	fmt.Println("Report generated successfully")
	fmt.Printf("Threshold applied: %.2f\n", threshold)
}

func main() {
	var inventoryData string
	var reportConfig string
	fmt.Scanln(&inventoryData)
	fmt.Scanln(&reportConfig)

	// Parse inventory data
	inventory := make(map[string]Product)
	if inventoryData != "" {
		products := strings.Split(inventoryData, ",")
		for _, productStr := range products {
			parts := strings.Split(productStr, ":")
			name := parts[0]
			price, _ := strconv.ParseFloat(parts[1], 64)
			quantity, _ := strconv.Atoi(parts[2])
			inventory[name] = Product{Price: price, Quantity: quantity}
		}
	}

	// Parse report configuration
	configParts := strings.Split(reportConfig, ",")
	reportType := configParts[0]
	threshold, _ := strconv.ParseFloat(configParts[1], 64)

	// Generate report
	generateReport(inventory, reportType, threshold)
}

Todas as lições de Lógica & Fluxo