Gerando um Relatório
Parte da seção Lógica & Fluxo do Journey de GO da Coddy. Lição 49 de 68.
Desafio
FácilConclua seu sistema de gerenciamento de inventário implementando uma função abrangente de geração de relatórios que forneça insights detalhados sobre seu inventário atual. Este desafio se baseia 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"(por exemplo,"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", em que report_type pode ser"full","low_stock"ou"high_value"e threshold_value é um número (por exemplo,"low_stock,10")
Sua tarefa é:
- Usar a mesma struct
Productdas lições anteriores, com os camposPrice(float64) eQuantity(int) - Analisar a primeira entrada dividindo-a por vírgulas para obter as entradas individuais dos produtos existentes
- Para cada entrada de produto existente, dividi-la por dois-pontos para obter o nome, o preço e a quantidade do produto
- Converter a string do preço para float64 e a string da quantidade para int
- Criar e preencher o mapa
inventorycom os dados dos produtos existentes - Criar uma função chamada
generateReportque receba o mapa de inventário, o tipo de relatório e o valor do limite como parâmetros - Analisar a segunda entrada dividindo-a por vírgulas para obter o tipo de relatório e o valor do limite
- Converter a string do valor do limite para float64
- 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 ==="
- Para
- Exibir as 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]"
- Filtrar e exibir os produtos com base no tipo de relatório:
- Para
"full": mostrar todos os produtos - Para
"low_stock": mostrar apenas os produtos cuja quantidade seja menor ou igual ao valor do limite - Para
"high_value": mostrar apenas os produtos cujo valor total (preço × quantidade) seja maior ou igual ao valor do limite
- Para
- 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]:"
- Para
- Para cada produto filtrado (em ordem alfabética pelo nome do produto):
"- [product_name]: $[price] × [quantity] = $[total_value]"
- Exibir as 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]"
- Encontrar e exibir os produtos mais caro e mais barato:
"Price Analysis:""Most expensive: [product_name] at $[price]""Least expensive: [product_name] at $[price]"
- 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"
- Exibir a avaliação da situação do inventário:
- Contar os produtos com quantidade ≤ 5:
"Low stock items (≤5): [count]" - Contar os produtos com quantidade > 20:
"High stock items (>20): [count]" - Contar os produtos com valor ≥ $500:
"High value items (≥$500): [count]"
- Contar os produtos com quantidade ≤ 5:
- 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 a saída formatada e o pacote sort para ordenar os nomes dos produtos em ordem alfabética. Formate todos os preços e valores com 2 casas decimais. Ao encontrar os produtos mais caro/mais barato ou com maior/menor estoque, em caso de empate, use o nome do produto que aparecer primeiro em ordem alfabética. Este desafio demonstra como criar sistemas abrangentes de geração de relatórios que fornecem insights valiosos para os negócios por meio da análise de dados e de uma 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
1Fluxo de Controle Avançado
Switch com `fallthrough`Interrompendo Loops AninhadosContinuando um Loop EspecíficoA Instrução `goto`Recapitulação - Controle de Loop Avançado4Projeto: Lista de Tarefas Simples
Configuração do ProjetoAdicionando uma Tarefa2Structs e Métodos
Definindo Métodos em StructsRecebedores de ValorRecebedores de PonteiroEscolhendo RecebedoresMétodos vs FunçõesRecapitulação - Comportamento de Structs5Mapas em Profundidade
Mapas de StructsPonteiros como Valores de MapVerificando Mapas NilComparando MapasRecapitulação - Contador de Frequência de Palavras8Projeto: Inventário Simples
Visão Geral do ProjetoVerificando o Estoque3Interfaces (O Básico)
O que é uma Interface?Definindo uma InterfaceImplementando uma InterfaceUsando Tipos de InterfaceInterface VaziaAsserções de TipoType SwitchRecapitulação - Formas e ComportamentosPratique por conta própria: Compilador de Go online