Menu
Coddy logo textTech

Gerando um Relatório

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

challenge icon

Desafio

Fácil

Complete seu sistema de gerenciamento de inventário implementando uma função de relatório abrangente que fornece insights detalhados sobre seu inventário atual. Este desafio baseia-se em todas as funcionalidades anteriores e adiciona a capacidade de gerar relatórios formatados com estatísticas, categorização e análise.

Você receberá duas entradas:

  • Uma string contendo dados de inventário existentes 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 a configuração do relatório no formato "report_type,threshold_value" onde report_type pode ser "full", "low_stock", ou "high_value" e threshold_value é um número (ex: "low_stock,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 dividindo-a por vírgulas para obter as entradas individuais de produtos existentes
  3. Para cada entrada de produto existente, dividir por dois pontos para obter o nome do produto, preço e quantidade
  4. Converter a string de preço para float64 e a string de quantidade para int
  5. Criar e preencher o mapa inventory com os dados dos produtos existentes
  6. Criar uma função chamada generateReport que recebe o mapa inventory, o tipo de relatório e o valor de limite (threshold) como parâmetros
  7. Analisar a segunda entrada dividindo-a por vírgulas para obter o tipo de relatório e o valor de limite
  8. Converter a string do valor de limite para float64
  9. Exibir o cabeçalho do relatório com base no tipo de relatório:
    • Para "full": "=== FULL INVENTORY REPORT ==="
    • Para "low_stock": "=== LOW STOCK REPORT ==="
    • Para "high_value": "=== HIGH VALUE REPORT ==="
  10. Exibir estatísticas gerais do inventário:
    • "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]"
  11. Filtrar e exibir produtos com base no tipo de relatório:
    • Para "full": Mostrar todos os produtos
    • Para "low_stock": Mostrar apenas produtos com quantidade menor ou igual ao valor de limite
    • Para "high_value": Mostrar apenas produtos com valor total (preço × quantidade) maior ou igual ao valor de limite
  12. Exibir a seção de produtos filtrados:
    • Para "full": "All Products:"
    • Para "low_stock": "Products with stock ≤ [threshold_value]:"
    • Para "high_value": "Products with value ≥ $[threshold_value]:"
  13. Para cada produto filtrado (em ordem alfabética pelo nome do produto):
    • "- [product_name]: $[price] × [quantity] = $[total_value]"
  14. Exibir estatí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]"
  15. Encontrar e exibir os produtos mais caros e mais baratos:
    • "Price Analysis:"
    • "Most expensive: [product_name] at $[price]"
    • "Least expensive: [product_name] at $[price]"
  16. Encontrar e exibir os produtos com maior e menor estoque:
    • "Stock Analysis:"
    • "Highest stock: [product_name] with [quantity] units"
    • "Lowest stock: [product_name] with [quantity] units"
  17. Exibir a avaliação de saúde do inventário:
    • Contar produtos com quantidade ≤ 5: "Low stock items (≤5): [count]"
    • Contar produtos com quantidade > 20: "High stock items (>20): [count]"
    • Contar produtos com valor ≥ $500: "High value items (≥$500): [count]"
  18. Exibir a conclusão do relatório:
    • "Report generated successfully"
    • "Threshold applied: [threshold_value]"

Use o pacote strings para dividir as strings de entrada, o pacote strconv para converter strings em números, o pacote fmt para saída formatada e o pacote sort para ordenar os nomes dos produtos alfabeticamente. Formate todos os preços e valores com 2 casas decimais. Ao encontrar o mais/menos caro ou o maior/menor estoque, se houver empates, use o nome do produto que vier primeiro alfabeticamente. Este desafio demonstra como criar sistemas de relatórios abrangentes que fornecem insights de negócios valiosos por meio de análise de dados e apresentação formatada.

Experimente você mesmo

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 as lições de Lógica & Fluxo