レポートの生成
CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 49/68。
チャレンジ
簡単現在の在庫に関する詳細なインサイトを提供する包括的なレポート機能を実装して、在庫管理システムを完成させましょう。このチャレンジは、これまでのすべての機能を基にしており、統計、分類、分析を含むフォーマットされたレポートを生成する機能を追加します。
2つの入力を受け取ります:
"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")
あなたのタスクは以下の通りです:
- 以前のレッスンと同じ、
Price(float64) とQuantity(int) フィールドを持つProduct構造体を使用します - 最初の入力をカンマで分割して、個々の既存製品エントリを取得し、解析します
- 各製品エントリについて、コロンで分割して製品名、価格、数量を取得します
- 価格文字列を float64 に、数量文字列を int に変換します
- 既存の製品データを使用して
inventoryマップを作成し、データを格納します - inventory マップ、レポートタイプ、しきい値をパラメータとして受け取る
generateReportという関数を作成します - 2番目の入力をカンマで分割して、レポートタイプとしきい値を取得し、解析します
- しきい値文字列を float64 に変換します
- レポートタイプに基づいてレポートヘッダーを表示します:
"full"の場合:"=== FULL INVENTORY REPORT ===""low_stock"の場合:"=== LOW STOCK REPORT ===""high_value"の場合:"=== HIGH VALUE REPORT ==="
- 全般的な在庫統計を表示します:
"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]"
- レポートタイプに基づいて製品をフィルタリングし、表示します:
"full"の場合:すべての製品を表示"low_stock"の場合:数量がしきい値以下の製品のみを表示"high_value"の場合:合計金額(価格 × 数量)がしきい値以上の製品のみを表示
- フィルタリングされた製品セクションを表示します:
"full"の場合:"All Products:""low_stock"の場合:"Products with stock ≤ [threshold_value]:""high_value"の場合:"Products with value ≥ $[threshold_value]:"
- フィルタリングされた各製品について(製品名のアルファベット順):
"- [product_name]: $[price] × [quantity] = $[total_value]"
- フィルタリングされた統計を表示します:
"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]"
- 最も高価な製品と最も安価な製品を見つけて表示します:
"Price Analysis:""Most expensive: [product_name] at $[price]""Least expensive: [product_name] at $[price]"
- 在庫数が最も多い製品と最も少ない製品を見つけて表示します:
"Stock Analysis:""Highest stock: [product_name] with [quantity] units""Lowest stock: [product_name] with [quantity] units"
- 在庫の健全性評価を表示します:
- 数量が5以下の製品をカウント:
"Low stock items (≤5): [count]" - 数量が20より多い製品をカウント:
"High stock items (>20): [count]" - 価値が$500以上の製品をカウント:
"High value items (≥$500): [count]"
- 数量が5以下の製品をカウント:
- レポートの完了を表示します:
"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")
}
}