تجميع كل الأجزاء معاً
جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 50 من 68.
التحدي
سهلأكمل نظام إدارة المخزون الخاص بك عن طريق إنشاء برنامج رئيسي شامل يدمج جميع الوظائف التي قمت ببنائها في الدروس السابقة. يجمع هذا التحدي النهائي بين تهيئة المخزون، والتحقق من المخزون، وإضافة العناصر، وتحديثات المخزون، وإنشاء التقارير في واجهة سطر أوامر كاملة مع تنقل يعتمد على القائمة.
ستتلقى ثلاثة مدخلات:
- سلسلة نصية تحتوي على بيانات المخزون الأولية بالتنسيق
"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) - تحليل المدخل الأول وتهيئة خريطة (map) المخزون ببيانات المنتجات الموجودة
- عرض رسالة بدء تشغيل النظام:
"=== INVENTORY MANAGEMENT SYSTEM ===""System initialized with [number_of_products] products""Starting interactive session..."
- تحليل المدخل الثاني للحصول على تسلسل العمليات المطلوب تنفيذها
- تحليل المدخل الثالث للحصول على المعلمات لكل عملية
- لكل عملية في التسلسل، اعرض رأس العملية وقم بالإجراء المقابل:
- لـ
"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"
- اعرض إحصائيات المخزون النهائية:
- بعد كل عملية (باستثناء الخروج)، اعرض:
"Operation completed. Continuing to next operation..."
استخدم حزمة strings لتقسيم سلاسل الإدخال، وحزمة strconv لتحويل السلاسل النصية إلى أرقام، وحزمة errors لمعالجة الأخطاء، وحزمة fmt للمخرجات المنسقة، وحزمة sort للفرز الأبجدي. قم بتنسيق جميع الأسعار والقيم إلى منزلتين عشريتين. يوضح هذا التحدي كيفية إنشاء نظام تفاعلي كامل يدمج مكونات وظيفية متعددة في تجربة مستخدم متماسكة مع معالجة مناسبة للأخطاء وإدارة الحالة.
جرّب بنفسك
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)
}جميع دروس Logic & Flow
1تدفق التحكم المتقدم
جملة Switch مع `fallthrough`الخروج من الحلقات المتداخلةالاستمرار في حلقة محددةجملة `goto`ملخص - التحكم المتقدم في الحلقات2الـ Structs والميثودز (Methods)
تعريف الـ Methods على الـ Structsالـ Value Receiversالـ Pointer Receiversاختيار الـ Receiversالـ Methods مقابل الـ Functionsملخص - سلوك الـ Struct5تعمق في الـ Maps
Maps من نوع Structsالـ Pointers كقيم في الـ Mapsالتحقق من الـ Nil Mapsمقارنة الـ Mapsمراجعة - عداد تكرار الكلمات8مشروع: مخزون بسيط
نظرة عامة على المشروعالتحقق من المخزون3الواجهات (الأساسيات)
ما هي الواجهة؟تعريف الواجهةتطبيق الواجهةاستخدام أنواع الواجهاتالواجهة الفارغةتأكيدات النوع (Type Assertions)تبديل النوع (Type Switch)ملخص - الأشكال والسلوكيات