Menu
Coddy logo textTech

全体のまとめ

CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 50/68。

challenge icon

チャレンジ

簡単

これまでのレッスンで構築したすべての機能を統合する包括的なメインプログラムを作成して、在庫管理システムを完成させましょう。この最終チャレンジでは、在庫の初期化、在庫確認、アイテムの追加、在庫の更新、およびレポート生成を、メニュー駆動型のナビゲーションを備えた完全なコマンドラインインターフェースに統合します。

3つの入力を受け取ります:

  • "product1:price1:quantity1,product2:price2:quantity2,product3:price3:quantity3" 形式の初期在庫データを含む文字列(例:"Laptop:999.99:5,Mouse:25.50:15,Keyboard:75.00:8"
  • "operation1,operation2,operation3" 形式のメニュー操作のシーケンスを含む文字列。操作は "check""add""update""report"、または "exit" です(例:"check,add,update,report,exit"
  • "param1|param2|param3" 形式の操作パラメータを含む文字列。各パラメータは同じ位置にある操作に対応します(例:"Mouse|Monitor:299.99:10|Laptop:5|full,10"

あなたのタスクは以下の通りです:

  1. 以前のレッスンと同じ Product 構造体(Price (float64) フィールドと Quantity (int) フィールドを持つ)を使用する
  2. 最初の入力を解析し、既存の製品データで在庫マップを初期化する
  3. システムの起動メッセージを表示する:
    • "=== INVENTORY MANAGEMENT SYSTEM ==="
    • "System initialized with [number_of_products] products"
    • "Starting interactive session..."
  4. 2番目の入力を解析して、実行する操作のシーケンスを取得する
  5. 3番目の入力を解析して、各操作のパラメータを取得する
  6. 各操作を順番に実行し、操作ヘッダーを表示して対応するアクションを実行する:
    • "check" の場合:"--- STOCK CHECK ---" を表示し、指定された製品の在庫を確認する
    • "add" の場合:"--- ADD ITEM ---" を表示し、指定された製品を追加する
    • "update" の場合:"--- UPDATE STOCK ---" を表示し、指定された製品の在庫を更新する
    • "report" の場合:"--- GENERATE REPORT ---" を表示し、指定されたレポートを生成する
    • "exit" の場合:"--- SYSTEM EXIT ---" を表示し、終了情報を表示する
  7. 以前のレッスンと同様に、数量とエラーを返す checkStock 関数を実装する
  8. 以前のレッスンと同様に、製品を追加してエラーを返す addNewItem 関数を実装する
  9. 以前のレッスンと同様に、数量を更新してエラーを返す updateStock 関数を実装する
  10. 以前のレッスンと同様に、レポートを作成する generateReport 関数を実装する
  11. "check" 操作について:
    • パラメータを確認する製品名として使用する
    • 表示:"Checking stock for: [product_name]"
    • 見つかった場合:"Stock level: [quantity] units"
    • 見つからない場合:"Product not found in inventory"
  12. "add" 操作について:
    • "product_name:price:quantity" 形式のパラメータを解析する
    • 表示:"Adding new product: [product_name]"
    • 成功した場合:"Product added successfully"
    • 失敗した場合:"Failed to add product: [error_message]"
  13. "update" 操作について:
    • "product_name:change" 形式のパラメータを解析する
    • 表示:"Updating stock for: [product_name]"
    • 成功し、変化量が正の場合:"Added [change] units. New stock: [new_quantity]"
    • 成功し、変化量が負の場合:"Removed [absolute_change] units. New stock: [new_quantity]"
    • 失敗した場合:"Update failed: [error_message]"
  14. "report" 操作について:
    • "report_type,threshold" 形式のパラメータを解析する
    • 表示:"Generating [report_type] report with threshold [threshold]"
    • 以前のレッスンと同様に、完全なレポートを生成して表示する
  15. "exit" 操作について:
    • 最終的な在庫統計を表示する:
      • "Final inventory status:"
      • "Total products: [total_products]"
      • "Total items: [total_items]"
      • "Total value: $[total_value]"
    • 表示:"Session completed successfully"
    • 表示:"Thank you for using the Inventory Management System"
  16. 各操作(exitを除く)の後に、次を表示する:"Operation completed. Continuing to next operation..."

入力文字列の分割には strings パッケージ、文字列から数値への変換には strconv パッケージ、エラー処理には errors パッケージ、フォーマットされた出力には fmt パッケージ、アルファベット順のソートには sort パッケージを使用してください。すべての価格と値は小数点以下2桁までフォーマットしてください。このチャレンジでは、複数の機能コンポーネントを、適切なエラー処理と状態管理を備えた一貫したユーザーエクスペリエンスに統合する、完全な対話型システムの作成方法を学びます。

自分で試してみよう

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

論理とフローのすべてのレッスン