Menu
CoddyTech
flag Ar iconالعربيةdown icon

تجميع كل الأجزاء معاً

جزء من قسم المنطق وتدفق التنفيذ في رحلة GO على Coddy. الدرس 50 من 68.

challenge icon

التحدي

سهل

أكمل نظام إدارة المخزون بإنشاء برنامج رئيسي شامل يدمج جميع الوظائف التي بنيتها في الدروس السابقة. يجمع هذا التحدي النهائي بين تهيئة المخزون والتحقق من الكميات وإضافة العناصر وتحديث المخزون وإنشاء التقارير في واجهة سطر أوامر متكاملة ذات تنقّل موجّه بالقائمة.

ستتلقى ثلاثة مدخلات:

  • سلسلة نصية تحتوي على بيانات المخزون الأولية بالتنسيق "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. حلّل المدخل الثاني للحصول على تسلسل العمليات المطلوب تنفيذها
  5. حلّل المدخل الثالث للحصول على معلمات كل عملية
  6. لكل عملية في التسلسل، اعرض عنوان العملية ونفّذ الإجراء المقابل:
    • للعملية "check": اعرض "--- STOCK CHECK ---"</code وتحقق من مخزون المنتج المحدد</li> <li>للعملية <code>"add": اعرض "--- ADD ITEM ---"</code وأضف المنتج المحدد</li> <li>للعملية <code>"update": اعرض "--- UPDATE STOCK ---"</code وحدّث مخزون المنتج المحدد</li> <li>للعملية <code>"report": اعرض "--- GENERATE REPORT ---"</code وأنشئ التقرير المحدد</li> <li>للعملية <code>"exit": اعرض "--- SYSTEM EXIT ---"</code واعرض معلومات الخروج</li> </ul> </li> <li>نفّذ الدالة <code>checkStock التي تعيد الكمية والخطأ كما في الدروس السابقة
    • نفّذ الدالة addNewItem التي تضيف المنتجات وتعيد خطأً كما في الدروس السابقة
    • نفّذ الدالة updateStock التي تحدّث الكميات وتعيد خطأً كما في الدروس السابقة
    • نفّذ الدالة generateReport التي تطبع التقرير الموضّح أدناه في عملية "report"
    • لعملية "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]"
      • إذا نجحت العملية وكان التغيير صفرًا أو موجبًا: "Added [change] units. New stock: [new_quantity]"
      • إذا نجحت العملية وكان التغيير سالبًا: "Removed [absolute_change] units. New stock: [new_quantity]"
      • إذا فشلت: "Update failed: [error_message]"، حيث يكون الخطأ "product not found"، أو "insufficient stock" عندما تصبح الكمية الجديدة أقل من 0
    • لعملية "report":
      • حلّل المعلمة بالتنسيق "report_type,threshold"، حيث يكون report_type إما "low" أو "full"، وتكون threshold عددًا صحيحًا
      • اعرض: "Generating [report_type] report with threshold [threshold]"
      • ثم اطبع التقرير، مع ترتيب المنتجات أبجديًا:
        • لـ "low": "=== LOW REPORT ==="، ثم "Products with stock below [threshold]:"، ثم "- [name]: [quantity] units (Price: $[price])" لكل منتج تقل كميته عن الحد
        • لـ "full": "=== FULL REPORT ==="، ثم "Complete inventory (minimum threshold: [threshold]):"، ثم "- [name]: [quantity] units @ $[price] each [OK]" لكل منتج، مع استخدام [LOW STOCK] بدلًا من [OK] عندما تقل الكمية عن الحد
    • لعملية "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 للترتيب الأبجدي. نسّق جميع الأسعار والقيم إلى منزلتين عشريتين. يوضّح هذا التحدي كيفية إنشاء نظام تفاعلي متكامل يدمج عدة مكوّنات وظيفية في تجربة مستخدم مترابطة، مع معالجة سليمة للأخطاء وإدارة الحالة.

جرّب بنفسك

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 عبر الإنترنت