Menu
Coddy logo textTech

Создание отчета

Часть раздела Логика и управление потоком путешествия по GO на Coddy — урок 49 из 68.

challenge icon

Задание

Легко

Завершите создание вашей системы управления запасами, реализовав комплексную функцию отчетности, которая предоставляет подробную информацию о текущем инвентаре. Эта задача опирается на всю предыдущую функциональность и добавляет возможность создания отформатированных отчетов со статистикой, категоризаей и анализом.

Вы получите два входных значения:

  • Строка, содержащая данные о существующем инвентаре в формате "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" (например, "Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8")
  • Строка, содержащая конфигурацию отчета в формате "report_type,threshold_value", где report_type может быть "full", "low_stock" или "high_value", а threshold_value — это число (например, "low_stock,10")

Ваша задача:

  1. Использовать ту же структуру Product из предыдущих уроков с полями Price (float64) и Quantity (int)
  2. Разобрать первый входной параметр, разделив его по запятым, чтобы получить записи об отдельных продуктах
  3. Для каждой записи о продукте разделить ее по двоеточиям, чтобы получить название продукта, цену и количество
  4. Преобразовать строку цены в float64, а строку количества в int
  5. Создать и заполнить карту inventory данными о существующих продуктах
  6. Создать функцию с именем generateReport, которая принимает карту inventory, тип отчета и пороговое значение в качестве параметров
  7. Разобрать второй входной параметр, разделив его по запятым, чтобы получить тип отчета и пороговое значение
  8. Преобразовать строку порогового значения в float64
  9. Отобразить заголовок отчета в зависимости от типа отчета:
    • Для "full": "=== FULL INVENTORY REPORT ==="
    • Для "low_stock": "=== LOW STOCK REPORT ==="
    • Для "high_value": "=== HIGH VALUE REPORT ==="
  10. Отобразить общую статистику инвентаря:
    • "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. Отфильтровать и отобразить продукты в зависимости от типа отчета:
    • Для "full": Показать все продукты
    • Для "low_stock": Показать только продукты с количеством меньше или равным пороговому значению
    • Для "high_value": Показать только продукты, общая стоимость которых (цена × количество) больше или равна пороговому значению
  12. Отобразить раздел отфильтрованных продуктов:
    • Для "full": "All Products:"
    • Для "low_stock": "Products with stock ≤ [threshold_value]:"
    • Для "high_value": "Products with value ≥ $[threshold_value]:"
  13. Для каждого отфильтрованного продукта (в алфавитном порядке по названию продукта):
    • "- [product_name]: $[price] × [quantity] = $[total_value]"
  14. Отобразить отфильтрованную статистику:
    • "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. Найти и отобразить самый дорогой и самый дешевый продукты:
    • "Price Analysis:"
    • "Most expensive: [product_name] at $[price]"
    • "Least expensive: [product_name] at $[price]"
  16. Найти и отобразить продукты с самым большим и самым маленьким запасом:
    • "Stock Analysis:"
    • "Highest stock: [product_name] with [quantity] units"
    • "Lowest stock: [product_name] with [quantity] units"
  17. Отобразить оценку состояния инвентаря:
    • Подсчитать количество продуктов с количеством ≤ 5: "Low stock items (≤5): [count]"
    • Подсчитать количество продуктов с количеством > 20: "High stock items (>20): [count]"
    • Подсчитать количество продуктов со стоимостью ≥ $500: "High value items (≥$500): [count]"
  18. Отобразить завершение отчета:
    • "Report generated successfully"
    • "Threshold applied: [threshold_value]"

Используйте пакет strings для разделения входных строк, пакет strconv для преобразования строк в числа, пакет fmt для форматированного вывода и пакет sort для сортировки названий продуктов по алфавиту. Форматируйте все цены и значения до 2 знаков после запятой. При поиске самого дорогого/дешевого или самого большого/маленького запаса, если есть совпадения, используйте название продукта, которое идет первым по алфавиту. Эта задача демонстрирует, как создавать комплексные системы отчетности, которые предоставляют ценную бизнес-информацию посредством анализа данных и форматированного представления.

Попробуйте сами

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

Все уроки раздела Логика и управление потоком