في هذا الدرس من سلسلة بايثون بالمثال سنبني برنامجًا عمليًا بسيطًا: قائمة مهام تعمل من نافذة الأوامر.
فكرة البرنامج سهلة ومفيدة للمبتدئين: يستطيع المستخدم إضافة مهمة جديدة، عرض جميع المهام، تحديد مهمة كمكتملة، حذف مهمة، ثم الخروج من البرنامج. ورغم بساطة المثال، إلا أنه يجمع مفاهيم مهمة جدًا مثل list وdict وwhile وif وinput() والدوال.
هذا النوع من الأمثلة يساعدك على الانتقال من حفظ الأوامر إلى بناء برنامج صغير له وظيفة واضحة. لذلك لا تقرأ الكود فقط، بل اكتبه بيدك وشغله وعدل عليه.
{alertInfo} الفكرة ببساطة: سنخزن المهام داخل قائمةlist، وكل مهمة ستكون قاموسًاdictيحتوي على عنوان المهمة وحالتها: هل اكتملت أم لا.
{getToc} $title={محتوى المقال}
ماذا سنبني في هذا المثال؟
سننشئ برنامج قائمة مهام بسيطًا يعمل بهذا الشكل:
===== قائمة المهام =====
1. عرض المهام
2. إضافة مهمة
3. تحديد مهمة كمكتملة
4. حذف مهمة
5. خروج
اختر رقم العملية:
عندما يختار المستخدم رقمًا من القائمة، ينفذ البرنامج العملية المطلوبة. مثلًا إذا اختار 2 يستطيع إضافة مهمة جديدة، وإذا اختار 1 يعرض المهام الموجودة.
| الخيار | وظيفته | المفهوم المستخدم |
|---|---|---|
| عرض المهام | طباعة كل المهام الموجودة | for loop |
| إضافة مهمة | إضافة عنصر جديد إلى القائمة | append() |
| تحديد مهمة كمكتملة | تغيير حالة المهمة | dict |
| حذف مهمة | إزالة مهمة من القائمة | pop() |
| الخروج | إيقاف الحلقة | break |
لماذا هذا المثال مهم للمبتدئين؟
برنامج قائمة المهام من أفضل الأمثلة للمبتدئ؛ لأنه يشبه برامج حقيقية نستخدمها يوميًا، وفي نفس الوقت لا يحتاج إلى مكتبات خارجية أو واجهة رسومية.
ستتدرب في هذا المثال على:
- تخزين البيانات داخل قائمة.
- استخدام قاموس لكل مهمة.
- قراءة اختيار المستخدم باستخدام
input(). - تكرار القائمة باستخدام
while True. - تقسيم البرنامج إلى دوال صغيرة.
- التعامل مع الاختيارات الخاطئة بطريقة بسيطة.
{alertWarning} ملاحظة مهمة: هذا البرنامج لا يحفظ المهام بعد إغلاقه؛ لأننا سنخزن البيانات في الذاكرة فقط. حفظ المهام في ملف سيكون تطويرًا لاحقًا للمشروع.
الخطوة الأولى: إنشاء قائمة فارغة للمهام
سنبدأ بقائمة فارغة اسمها tasks. هذه القائمة ستكون مكان تخزين المهام أثناء تشغيل البرنامج.
tasks = []
كل مهمة داخل هذه القائمة ستكون قاموسًا بهذا الشكل:
{
"title": "تعلم أساسيات بايثون",
"done": False
}
استخدمنا المفتاح title لتخزين نص المهمة، والمفتاح done لتحديد هل المهمة مكتملة أم لا.
الخطوة الثانية: إنشاء دالة لعرض المهام
الدالة الأولى في البرنامج ستكون مسؤولة عن عرض جميع المهام الموجودة. إذا لم تكن هناك مهام، ستظهر رسالة تخبر المستخدم أن القائمة فارغة.
def show_tasks(tasks):
if not tasks:
print("لا توجد مهام حتى الآن.")
return
print("\nقائمة المهام:")
for index, task in enumerate(tasks, start=1):
status = "تمت" if task["done"] else "لم تكتمل"
print(f"{index}. {task['title']} - {status}")
استخدمنا enumerate() حتى نعرض رقمًا لكل مهمة، وهذا الرقم سيساعد المستخدم لاحقًا عند تحديد مهمة كمكتملة أو حذفها.
لاحظ أيضًا هذا السطر:
status = "تمت" if task["done"] else "لم تكتمل"
هذا السطر يحدد النص الذي سيظهر بجانب المهمة حسب قيمة done.
الخطوة الثالثة: إنشاء دالة لإضافة مهمة
الآن سننشئ دالة تطلب من المستخدم كتابة عنوان المهمة، ثم تضيفها إلى القائمة.
def add_task(tasks):
title = input("اكتب عنوان المهمة: ").strip()
if title == "":
print("لا يمكن إضافة مهمة فارغة.")
return
task = {
"title": title,
"done": False
}
tasks.append(task)
print("تمت إضافة المهمة بنجاح.")
استخدمنا strip() لحذف المسافات الزائدة من بداية ونهاية النص. فإذا ضغط المستخدم Enter دون كتابة شيء، لن نضيف مهمة فارغة.
الخطوة الرابعة: تحديد مهمة كمكتملة
عندما يريد المستخدم تحديد مهمة كمكتملة، يجب أن نعرض المهام أولًا، ثم نطلب منه إدخال رقم المهمة.
def complete_task(tasks):
show_tasks(tasks)
if not tasks:
return
try:
task_number = int(input("اكتب رقم المهمة المكتملة: "))
if 1 <= task_number <= len(tasks):
tasks[task_number - 1]["done"] = True
print("تم تحديد المهمة كمكتملة.")
else:
print("رقم المهمة غير موجود.")
except ValueError:
print("الرجاء إدخال رقم صحيح.")
استخدمنا try وexcept لأن المستخدم قد يكتب نصًا بدل رقم. في هذه الحالة لا نريد أن يتوقف البرنامج برسالة خطأ، بل نعرض رسالة واضحة.
{alertInfo}
لماذا كتبنا task_number - 1؟ لأن المستخدم يرى الترقيم يبدأ من 1، بينما فهارس القائمة في بايثون تبدأ من 0.
الخطوة الخامسة: حذف مهمة من القائمة
حذف المهمة يشبه تحديدها كمكتملة، لكن بدل تغيير قيمة done سنستخدم pop() لإزالة المهمة من القائمة.
def delete_task(tasks):
show_tasks(tasks)
if not tasks:
return
try:
task_number = int(input("اكتب رقم المهمة التي تريد حذفها: "))
if 1 <= task_number <= len(tasks):
deleted_task = tasks.pop(task_number - 1)
print(f"تم حذف المهمة: {deleted_task['title']}")
else:
print("رقم المهمة غير موجود.")
except ValueError:
print("الرجاء إدخال رقم صحيح.")
الدالة pop() تحذف العنصر من القائمة وتعيده لنا، لذلك خزنا المهمة المحذوفة في المتغير deleted_task حتى نطبع اسمها للمستخدم.
الخطوة السادسة: إنشاء قائمة الخيارات الرئيسية
الآن سننشئ دالة تعرض قائمة الخيارات للمستخدم. هذه الدالة فقط تطبع القائمة، ولا تنفذ العمليات.
def show_menu():
print("\n===== قائمة المهام =====")
print("1. عرض المهام")
print("2. إضافة مهمة")
print("3. تحديد مهمة كمكتملة")
print("4. حذف مهمة")
print("5. خروج")
وجود دالة خاصة بالقائمة يجعل الكود مرتبًا، ويسهل تعديل الخيارات لاحقًا.
الخطوة السابعة: تشغيل البرنامج باستخدام while
نحتاج الآن إلى حلقة مستمرة تعرض القائمة وتقرأ اختيار المستخدم. سنستخدم while True، وعندما يختار المستخدم الخروج نستخدم break.
tasks = []
while True:
show_menu()
choice = input("اختر رقم العملية: ")
if choice == "1":
show_tasks(tasks)
elif choice == "2":
add_task(tasks)
elif choice == "3":
complete_task(tasks)
elif choice == "4":
delete_task(tasks)
elif choice == "5":
print("تم إغلاق البرنامج.")
break
else:
print("اختيار غير صحيح. حاول مرة أخرى.")
بهذا الشكل أصبح لدينا برنامج تفاعلي بسيط. كل مرة يختار المستخدم عملية، ينفذ البرنامج الدالة المناسبة ثم يعود إلى القائمة مرة أخرى.
الكود الكامل للبرنامج
الآن اجمع كل الأجزاء السابقة داخل ملف واحد باسم todo_list.py:
def show_tasks(tasks):
if not tasks:
print("لا توجد مهام حتى الآن.")
return
print("\nقائمة المهام:")
for index, task in enumerate(tasks, start=1):
status = "تمت" if task["done"] else "لم تكتمل"
print(f"{index}. {task['title']} - {status}")
def add_task(tasks):
title = input("اكتب عنوان المهمة: ").strip()
if title == "":
print("لا يمكن إضافة مهمة فارغة.")
return
task = {
"title": title,
"done": False
}
tasks.append(task)
print("تمت إضافة المهمة بنجاح.")
def complete_task(tasks):
show_tasks(tasks)
if not tasks:
return
try:
task_number = int(input("اكتب رقم المهمة المكتملة: "))
if 1 <= task_number <= len(tasks):
tasks[task_number - 1]["done"] = True
print("تم تحديد المهمة كمكتملة.")
else:
print("رقم المهمة غير موجود.")
except ValueError:
print("الرجاء إدخال رقم صحيح.")
def delete_task(tasks):
show_tasks(tasks)
if not tasks:
return
try:
task_number = int(input("اكتب رقم المهمة التي تريد حذفها: "))
if 1 <= task_number <= len(tasks):
deleted_task = tasks.pop(task_number - 1)
print(f"تم حذف المهمة: {deleted_task['title']}")
else:
print("رقم المهمة غير موجود.")
except ValueError:
print("الرجاء إدخال رقم صحيح.")
def show_menu():
print("\n===== قائمة المهام =====")
print("1. عرض المهام")
print("2. إضافة مهمة")
print("3. تحديد مهمة كمكتملة")
print("4. حذف مهمة")
print("5. خروج")
tasks = []
while True:
show_menu()
choice = input("اختر رقم العملية: ")
if choice == "1":
show_tasks(tasks)
elif choice == "2":
add_task(tasks)
elif choice == "3":
complete_task(tasks)
elif choice == "4":
delete_task(tasks)
elif choice == "5":
print("تم إغلاق البرنامج.")
break
else:
print("اختيار غير صحيح. حاول مرة أخرى.")
تجربة تشغيل البرنامج
بعد حفظ الملف باسم todo_list.py، شغله من الطرفية:
python todo_list.py
جرّب إضافة ثلاث مهام مثل:
- مراجعة درس القوائم.
- حل تمرين بسيط.
- كتابة برنامج صغير.
ثم اعرض المهام، وحدد واحدة كمكتملة، وبعدها احذف مهمة أخرى. بهذه الطريقة ستفهم كيف تتحرك البيانات داخل القائمة أثناء تشغيل البرنامج.
أخطاء شائعة في هذا المثال
1. نسيان تحويل رقم المهمة إلى int
الدالة input() تعيد النصوص دائمًا، حتى لو كتب المستخدم رقمًا. لذلك يجب استخدام int() عند التعامل مع رقم المهمة.
task_number = int(input("اكتب رقم المهمة: "))
2. استخدام رقم المهمة مباشرة دون طرح 1
إذا كتب المستخدم رقم 1 فهو يقصد أول مهمة، لكن أول عنصر في القائمة فهرسه 0. لذلك نستخدم:
tasks[task_number - 1]
3. حذف مهمة من قائمة فارغة
قبل حذف مهمة أو تعديلها، يجب التأكد أن القائمة ليست فارغة. لذلك استخدمنا:
if not tasks:
return
أفكار لتطوير البرنامج
بعد أن تفهم هذا المثال، يمكنك تطوير البرنامج بخطوات بسيطة:
- حفظ المهام في ملف نصي أو ملف JSON.
- إضافة تاريخ لكل مهمة.
- إضافة أولوية للمهمة مثل: عالية، متوسطة، منخفضة.
- عرض المهام المكتملة فقط أو غير المكتملة فقط.
- إضافة خيار لتعديل اسم مهمة موجودة.
هذه التطويرات ستجعل المشروع أقرب إلى برنامج حقيقي، وستدربك على التعامل مع الملفات وتنظيم الكود.
ماذا تعلمت في هذا المثال؟
| المفهوم | كيف استخدمناه؟ |
|---|---|
list |
استخدمناها لتخزين جميع المهام. |
dict |
استخدمنا قاموسًا لكل مهمة يحتوي على العنوان والحالة. |
append() |
لإضافة مهمة جديدة إلى القائمة. |
pop() |
لحذف مهمة من القائمة. |
while True |
لتكرار عرض القائمة حتى يختار المستخدم الخروج. |
if / elif / else |
لتنفيذ العملية المناسبة حسب اختيار المستخدم. |
try / except |
للتعامل مع إدخال رقم غير صحيح دون إيقاف البرنامج. |
functions |
لتقسيم البرنامج إلى أجزاء واضحة ومنظمة. |
روابط داخلية مفيدة من بايثون العرب
- أساسيات بايثون 8: شرح Lists للمبتدئين
- أساسيات بايثون 10: شرح Dictionaries للمبتدئين
- أساسيات بايثون 11: شرح if و else للمبتدئين
- أساسيات بايثون 12: شرح الحلقات في بايثون
- أساسيات بايثون 13: شرح الدوال Functions للمبتدئين
- مشاريع بايثون بسيطة للمبتدئين
- تمارين بايثون للمبتدئين مع الحل
مصادر خارجية مفيدة
الخلاصة
في هذا المثال أنشأنا برنامج قائمة مهام بسيطة باستخدام بايثون. تعلمت كيف تخزن المهام داخل قائمة، وكيف تجعل كل مهمة قاموسًا يحتوي على العنوان والحالة، وكيف تعرض قائمة خيارات للمستخدم باستخدام while وinput().
هذا المثال مهم لأنه يجمع أكثر من مفهوم في برنامج واحد صغير. وكلما عدلت عليه وأضفت خيارات جديدة، ستفهم البرمجة العملية أكثر.
{alertSuccess} القاعدة المهمة: أفضل طريقة لتعلم بايثون ليست قراءة الأوامر فقط، بل بناء أمثلة صغيرة مثل برنامج قائمة المهام ثم تطويرها خطوة بعد خطوة.
أسئلة شائعة
هل برنامج قائمة المهام مناسب للمبتدئين؟
نعم، لأنه يجمع مفاهيم أساسية مثل القوائم، الشروط، الحلقات، الإدخال، والدوال داخل مثال عملي واضح.
هل يحفظ البرنامج المهام بعد إغلاقه؟
لا، هذا الإصدار يخزن المهام في الذاكرة فقط. عند إغلاق البرنامج ستختفي المهام، ويمكن تطويره لاحقًا لحفظ البيانات في ملف.
لماذا استخدمنا قائمة وقاموسًا معًا؟
استخدمنا القائمة لتخزين جميع المهام، واستخدمنا القاموس لتمثيل كل مهمة بمعلوماتها مثل العنوان وحالة الاكتمال.
ما فائدة الدوال في هذا البرنامج؟
الدوال تجعل البرنامج منظمًا وأسهل في القراءة والتعديل، بدل كتابة كل الكود داخل حلقة واحدة طويلة.
لماذا نستخدم try و except؟
نستخدمها حتى لا يتوقف البرنامج إذا كتب المستخدم نصًا بدل رقم عند اختيار مهمة للحذف أو الإكمال.
كيف أطور هذا المشروع؟
يمكنك إضافة حفظ المهام في ملف JSON، أو إضافة تاريخ وأولوية لكل مهمة، أو إنشاء خيار لتعديل اسم المهمة.



