Python: مشروع: نظام إدارة بطاقات العمل

آخر تحديث: 2026-09-22

هذا هو المشروع الختامي للمرحلة الثانية. كل المعرفة من الدروس السابقة — القوائم، القواميس، الشاملات، طرق السلاسل النصية — ستُستخدم لبناء نظام إدارة بطاقات عمل حقيقي قابل للاستخدام في سطر الأوامر. إكمال هذا المشروع يعني أنك أتقنت حقاً مفاهيم الحاويات الأساسية في بايثون.


دوال مدمجة ذات صلة:enumerate() sorted() get()

1. متطلبات المشروع

سنبني "مدير بطاقات عمل" يعمل في الطرفية ويدعم الميزات التالية:

TEXT 📖 للعرض فقط
1. إضافة بطاقة — أدخل الاسم، الهاتف، البريد الإلكتروني
2. عرض جميع البطاقات — اعرضها بتنسيق جدول
3. البحث عن بطاقات — ابحث بالاسم (يدعم البحث الضبابي)
4. تعديل بطاقة — حدّث المعلومات بالاسم
5. حذف بطاقة — احذف بالاسم
6. الإحصائيات — أظهر العدد الإجمالي، إحصائيات نطاق البريد الإلكتروني
7. الخروج من البرنامج

تُخزّن البيانات باستخدام قائمة + قاموس: جميع البطاقات في قائمة، كل بطاقة كقاموس.



2. تصميم هيكل البيانات

▶ مثال: هيكل بيانات بطاقة العمل

▶ جرّب الكود

الناتج:

TEXT 📖 للعرض فقط
# Executed successfully


3. الكود الكامل

احفظ هذا الملف باسم card_manager.py وشغّله مباشرة:

▶ مثال: نظام إدارة بطاقات العمل

TEXTN 📖 للعرض فقط
# ====== نظام إدارة بطاقات العمل ======

# تخزين البيانات
cards = []

def show_menu():
    """اعرض القائمة الرئيسية"""
    print("\n" + "=" * 35)
    print("Business Card Management System")
    print("=" * 35)
    print("1. Add Card")
    print("2. List All Cards")
    print("3. Search Cards")
    print("4. Modify Card")
    print("5. Delete Card")
    print("6. Statistics")
    print("7. Exit")
    print("=" * 35)


def add_card():
    """أضف بطاقة عمل"""
    print("\n--- Add Card ---")
    name = input("Name: ").strip()
    if not name:
        print("Name cannot be empty!")
        return

    phone = input("Phone: ").strip()
    email = input("Email: ").strip()

    for card in cards:
        if card["name"] == name:
            print(f"A card named {name} already exists. Cannot add duplicate.")
            return

    cards.append({"name": name, "phone": phone, "email": email})
    print(f"Card for {name} added.")


def list_cards():
    """اعرض جميع البطاقات"""
    if not cards:
        print("\nNo cards yet.")
        return

    print("\n--- All Cards ---")
    print(f"{'#':<4}{'Name':<10}{'Phone':<15}{'Email':<25}")
    print("-" * 54)

    for i, card in enumerate(cards, 1):
        print(f"{i:<4}{card['name']:<10}{card['phone']:<15}{card['email']:<25}")

    print(f"\nTotal: {len(cards)} cards")


def search_card():
    """ابحث عن بطاقات (يدعم البحث الضبابي)"""
    if not cards:
        print("\nNo cards yet.")
        return

    keyword = input("\nEnter name to search (partial match supported): ").strip()
    if not keyword:
        print("Please enter a keyword!")
        return

    results = [card for card in cards if keyword in card["name"]]

    if not results:
        print(f"No cards found matching '{keyword}'.")
        return

    print(f"\n--- Found {len(results)} cards ---")
    for card in results:
        print(f"Name: {card['name']}")
        print(f"Phone: {card['phone']}")
        print(f"Email: {card['email']}")
        print("-" * 20)


def modify_card():
    """عدّل بطاقة"""
    if not cards:
        print("\nNo cards yet.")
        return

    name = input("\nEnter the name to modify: ").strip()
    for card in cards:
        if card["name"] == name:
            print(f"Found card for {name}. Enter new info (press Enter to keep current):")

            new_name = input(f"Name ({card['name']}): ").strip()
            new_phone = input(f"Phone ({card['phone']}): ").strip()
            new_email = input(f"Email ({card['email']}): ").strip()

            if new_name:
                card["name"] = new_name
            if new_phone:
                card["phone"] = new_phone
            if new_email:
                card["email"] = new_email

            print(f"Card for {name} has been updated.")
            return

    print(f"No card found for {name}.")


def delete_card():
    """احذف بطاقة"""
    if not cards:
        print("\nNo cards yet.")
        return

    name = input("\nEnter the name to delete: ").strip()
    for i, card in enumerate(cards):
        if card["name"] == name:
            confirm = input(f"Are you sure you want to delete {name}'s card? (y/n): ")
            if confirm.lower() == "y":
                cards.pop(i)
                print(f"Card for {name} has been deleted.")
            else:
                print("Deletion cancelled.")
            return

    print(f"No card found for {name}.")


def show_stats():
    """اعرض إحصائيات البيانات"""
    if not cards:
        print("\nNo cards yet.")
        return

    print("\n--- Statistics ---")
    print(f"Total cards: {len(cards)}")

    domains = {}
    for card in cards:
        email = card["email"]
        if "@" in email:
            domain = email.split("@")[1]
            domains[domain] = domains.get(domain, 0) + 1

    if domains:
        print("\nEmail domain distribution:")
        for domain, count in sorted(domains.items(), key=lambda x: x[1], reverse=True):
            print(f"  {domain}: {count}")

    has_phone = sum(1 for card in cards if card["phone"])
    has_email = sum(1 for card in cards if card["email"])
    print(f"\nWith phone: {has_phone}")
    print(f"With email: {has_email}")


# ====== البرنامج الرئيسي ======
print("Welcome to the Business Card Management System!")
print("Enter the corresponding number to select a function.")

while True:
    show_menu()
    choice = input("Select option (1-7): ").strip()

    if choice == "1":
        add_card()
    elif choice == "2":
        list_cards()
    elif choice == "3":
        search_card()
    elif choice == "4":
        modify_card()
    elif choice == "5":
        delete_card()
    elif choice == "6":
        show_stats()
    elif choice == "7":
        print("Thank you for using! Goodbye!")
        break
    else:
        print("Invalid choice. Please enter a number between 1 and 7.")
139 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)

الناتج:

TEXT 📖 للعرض فقط
// Executed successfully

نهج تصميم الكود: كل ميزة مُنفّذة كدالة مستقلة. البرنامج الرئيسي يستخدم حلقة while + if-elif للتوزيع. هذا يجعل هيكل الكود واضحاً — إضافة ميزة جديدة تتطلب فقط دالة جديدة وفرع elif.



4. اقتراحات التوسيع

▶ مثال: البحث عن البطاقات والإحصائيات (الصعوبة ⭐⭐)

▶ جرّب الكود

المخرجات:

TEXT 📖 للعرض فقط
Found 2 matching 'Alice':
  Alice - 13800138000
  Alice Chen - 13700137000

Email domain distribution:
  example.com: 1
  test.com: 1
  work.com: 1

Duplicate phones: False


4. حالات الاستخدام الشائعة



دوال مدمجة ذات صلة:enumerate() sorted() get()

❓ أسئلة شائعة

س لماذا استخدام قائمة + قاموس بدلاً من عمليات الملفات المباشرة؟
ج هذا المشروع يركز على عمليات الحاويات — القائمة تخزن جميع البطاقات، القواميس تخزن البطاقات الفردية. هذا يتيح لك تمرين CRUD على القوائم وعمليات المفتاح-القيمة في القواميس. إدخال/إخراج الملفات (الاستمرارية) سيُغطى في المرحلة 3. أتقن الحاويات أولاً، ثم عمليات الملفات — نهج خطوة بخطوة.
س تُفقد البيانات عند إغلاق البرنامج. ماذا أفعل؟
ج هذا طبيعي — بياناتنا مخزنة في الذاكرة، التي تُحرر عند انتهاء البرنامج. لاستمرار البيانات، بعد تعلم عمليات الملفات ووحدة JSON، استخدم json.dump(cards, open("data.json", "w")) للحفظ على القرص.
س البحث الضبابي يستخدم الكلمة المفتاحية in. هل هو حساس لحالة الأحرف؟
ج نعم. "Zhang" in "Zhang San" هو True، لكن "zhang" in "Zhang" هو False (حساس لحالة الأحرف). إذا كنت تحتاج بحثاً غير حساس لحالة الأحرف، حوّل إلى أحرف صغيرة قبل المقارنة: keyword.lower() in card["name"].lower().

📖 ملخص


📝 تمارين

  1. مبتدئ (الصعوبة ⭐): أضف ميزة جديدة لنظام البطاقات — عرض البطاقات مرتبة حسب الاسم (باستخدام sorted() مع معامل key).

  2. متوسط (الصعوبة ⭐⭐): أضف ميزة "إدارة المجموعات" لنظام البطاقات. أضف حقل group لكل بطاقة ("زملاء"، "أصدقاء"، "عائلة")، ثم نفذ خيار قائمة لعرض البطاقات حسب المجموعة.

  3. متقدم (الصعوبة ⭐⭐⭐): اكتب "نظام إدارة كتب" من الصفر دون الرجوع إلى الكود أعلاه. تشمل الميزات: إضافة كتاب (العنوان، المؤلف، السنة)، عرض الكل، البحث عن طريق المؤلف، الترتيب حسب السنة، عد الكتب حسب المؤلف. استخدم قائمة + قاموس للتخزين، كلها تعمل في سطر الأوامر.

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%