全体のまとめ
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関数を実装します。 - 以下の
"report"操作で説明するレポートを出力する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]"と表示します。エラーは"product already exists"です。
"update"操作の場合:"product_name:change"形式のパラメーターを解析します。"Updating stock for: [product_name]"と表示します。- 更新に成功し、changeが0以上の場合:
"Added [change] units. New stock: [new_quantity]" - 更新に成功し、changeが負の場合:
"Removed [absolute_change] units. New stock: [new_quantity]" - 失敗した場合:
"Update failed: [error_message]"と表示します。エラーは"product not found"、または新しい数量が0未満になる場合は"insufficient stock"です。
"report"操作の場合:"report_type,threshold"形式のパラメーターを解析します。report_typeは"low"または"full"、thresholdは整数です。"Generating [report_type] report with threshold [threshold]"と表示します。- その後、商品をアルファベット順に並べてレポートを出力します。
"low"の場合:"=== LOW REPORT ==="、次に"Products with stock below [threshold]:"、続いて数量がthreshold未満の各商品について"- [name]: [quantity] units (Price: $[price])"を出力します。"full"の場合:"=== FULL REPORT ==="、次に"Complete inventory (minimum threshold: [threshold]):"、続いてすべての商品について"- [name]: [quantity] units @ $[price] each [OK]"を出力します。数量がthreshold未満の場合は、[OK]の代わりに[LOW STOCK]を使用します。
"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)
}論理とフローのすべてのレッスン
自分で練習してみよう: Goオンラインコンパイラ