全体のまとめ
CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 50/68。
チャレンジ
簡単これまでのレッスンで構築したすべての機能を統合する包括的なメインプログラムを作成して、在庫管理システムを完成させましょう。この最終チャレンジでは、在庫の初期化、在庫確認、アイテムの追加、在庫の更新、およびレポート生成を、メニュー駆動型のナビゲーションを備えた完全なコマンドラインインターフェースに統合します。
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")
あなたのタスクは以下の通りです:
- 以前のレッスンと同じ
Product構造体(Price(float64) フィールドとQuantity(int) フィールドを持つ)を使用する - 最初の入力を解析し、既存の製品データで在庫マップを初期化する
- システムの起動メッセージを表示する:
"=== INVENTORY MANAGEMENT SYSTEM ===""System initialized with [number_of_products] products""Starting interactive session..."
- 2番目の入力を解析して、実行する操作のシーケンスを取得する
- 3番目の入力を解析して、各操作のパラメータを取得する
- 各操作を順番に実行し、操作ヘッダーを表示して対応するアクションを実行する:
"check"の場合:"--- STOCK CHECK ---"を表示し、指定された製品の在庫を確認する"add"の場合:"--- ADD ITEM ---"を表示し、指定された製品を追加する"update"の場合:"--- UPDATE STOCK ---"を表示し、指定された製品の在庫を更新する"report"の場合:"--- GENERATE REPORT ---"を表示し、指定されたレポートを生成する"exit"の場合:"--- SYSTEM EXIT ---"を表示し、終了情報を表示する
- 以前のレッスンと同様に、数量とエラーを返す
checkStock関数を実装する - 以前のレッスンと同様に、製品を追加してエラーを返す
addNewItem関数を実装する - 以前のレッスンと同様に、数量を更新してエラーを返す
updateStock関数を実装する - 以前のレッスンと同様に、レポートを作成する
generateReport関数を実装する "check"操作について:- パラメータを確認する製品名として使用する
- 表示:
"Checking stock for: [product_name]" - 見つかった場合:
"Stock level: [quantity] units" - 見つからない場合:
"Product not found in inventory"
"add"操作について:"product_name:price:quantity"形式のパラメータを解析する- 表示:
"Adding new product: [product_name]" - 成功した場合:
"Product added successfully" - 失敗した場合:
"Failed to add product: [error_message]"
"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]"
"report"操作について:"report_type,threshold"形式のパラメータを解析する- 表示:
"Generating [report_type] report with threshold [threshold]" - 以前のレッスンと同様に、完全なレポートを生成して表示する
"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"
- 最終的な在庫統計を表示する:
- 各操作(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)
}