AzLearn

مختبر المخزون

Inventory Lab

مشروع ~30 دقيقة

مختبر المخزون — Inventory Lab

في هذا المختبر ستبني نظام مخزون صغيراً من البداية. على عكس درس الـ Walkthrough، هنا ستقرر أنت شكل البيانات وكيفية تنظيم الدوال — ستجد توجيهاً أقل وحرية أكبر.

نظام المخزون مثال واقعي لأنه يجمع بين أنواع بيانات متعددة: كل منتج له اسم ورمز SKU وسعر وكمية. هذه المعلومات تعيش معاً — لهذا ستستخدم قائمة من القواميس (list of dicts). كل قاموس يمثل منتجاً، والقائمة تجمع كل المنتجات. هذا الشكل شائع جداً في Python — نتائج قواعد البيانات، استجابات API، وملفات JSON تصل عادةً بهذا الشكل.

شكل البيانات

قبل أن تبدأ بالكتابة، فكّر: لماذا قائمة من القواميس وليس قاموس من القواميس؟

قائمة من القواميس [{...}, {...}]:

  • ترتيب المنتجات محفوظ (مفيد للعرض)
  • يمكن وجود منتجات بنفس الاسم (رغم أنه غير مرغوب)
  • الحذف والإضافة مباشران

قاموس من القواميس {"SKU": {...}}:

  • البحث بالـ SKU أسرع O(1) مقابل O(n)
  • لا تكرار للمفاتيح مضمون
  • لكن الترتيب بحاجة sorted()

لهذا المختبر ستستخدم قائمة من القواميس — وستجد أن معظم العمليات تتضمن البحث بالاسم، وهذا يكشف متى قد تختار قاموساً بدلاً منها في المستقبل.

البداية: تهيئة المخزون

main.go

التحدي 1 — إضافة منتج

تحدي — Challenge

التحدي 2 — حذف منتج بالاسم

تحدي — Challenge

التحدي 3 — تحديث الكمية

تحدي — Challenge

التحدي 4 — قيمة المخزون الكلية ومنتجات نقص المخزون

تحدي — Challenge

البرنامج الكامل

main.go

ما تعلمته في هذا المختبر

قائمة من القواميس هي الشكل الأنسب عندما:

  • كل عنصر له عدة حقول مترابطة (اسم + سعر + كمية)
  • البيانات تأتي من API أو قاعدة بيانات (غالباً بهذا الشكل)
  • تريد الترتيب والتصفية والتحويل بـ sorted() وList Comprehensions

الفرق المهم عن Go: في Python، القاموس mutable — إذا كان لديك مرجع (reference) لقاموس داخل قائمة، تعديله يُعدّل الأصل مباشرةً. هذا لماذا update_qty تعمل بتعديل item["qty"] مباشرةً بعد إيجاد item بـ next().

inv[:] = [...] في دالة remove_by_name تعدّل القائمة في مكانها بدلاً من إنشاء قائمة جديدة. هذا مهم إذا كان كود آخر يحمل مرجعاً لنفس القائمة.

معيار القبول

الحل الجيد:

  • كل دالة تفعل شيئاً واحداً فقط
  • total_value تستخدم sum() مع generator expression، لا حلقة يدوية
  • low_stock تستخدم list comprehension، لا append داخل for
  • update_qty تعثر على العنصر بـ next() وتعدّله مباشرةً
  • لا منطق عرض داخل دوال الحساب، ولا حساب داخل دوال العرض

خلاصة

هذا المختبر جمع كل ما تعلمته في الفصل: قوائم تخزن تسلسلاً، قواميس تخزن بيانات منظّمة، comprehensions تبني وتصفّي، وnext() مع generator expression يجد عنصراً بشرط بكفاءة. هذه الأنماط تظهر في كل مشروع Python حقيقي — من معالجة ملفات JSON إلى استجابات قواعد البيانات إلى إدارة الحالة في تطبيقات الويب.