هل شعرت يوماً أنك "تعرف" الكثير من النظرية ولكنك غير متأكد مما إذا كان بإمكانك "بناء" أي شيء حقيقي؟ هذا بالضبط ما شعرت به.
إذا كنت تتابعنا، فربما قرأت دليلنا حول بايثون للمبتدئين. لقد تعلمت (أو تذكرت) الأساسيات: المتغيرات، الحلقات، الشروط، والدوال. كان كل شيء منطقياً على الورق.
لكن الحقيقة هي أن مشاهدة الدروس وحل التمارين شيء، ومواجهة شاشة فارغة ومحاولة بناء مشروع من الصفر شيء آخر تماماً. قررت أن أتوقف عن "التعلم" وأبدأ "التطبيق". في هذا المقال، سأشارككم قصة أول مشروع حقيقي لي، الأخطاء السخيفة التي ارتكبتها، وما تعلمته حقاً.
المشكلة: فوضى مجلد "التنزيلات"
كمطور (أو أي مستخدم عادي للحاسوب)، مجلد "التنزيلات" (Downloads) الخاص بي كان كارثة مطلقة. كان عبارة عن مقبرة لملفات .zip، صور .png عشوائية، ملفات .pdf، وبعض ملفات .exe التي لا أتذكر لماذا قمت بتحميلها.
كل أسبوع، كنت أقضي 10 دقائق مملة في فرزها يدوياً. وهنا جاءت الفكرة: "لماذا لا أستخدم بايثون لأتمتة هذا؟" (كما ذكرت في مقال أتمتة المهام).
الهدف: كتابة سكريبت بايثون يقوم بـ:
- فحص مجلد "التنزيلات".
- إنشاء مجلدات فرعية (مثل: صور، مستندات، مضغوطة، برامج).
- نقل كل ملف إلى المجلد الصحيح بناءً على امتداده (extension).
يبدو بسيطاً، أليس كذلك؟ حسناً... هذا ما ظننته.
الخطأ الكارثي الأول: "فصل منطق الكود" (The Spaghetti Code)
كشخص متحمس، فتحت محرر الأكواد وبدأت بكتابة كل شيء في كتلة واحدة. حاولت قراءة جميع الملفات، وإنشاء جميع المجلدات، والتعامل مع جميع الامتدادات في نفس الوقت دون استخدام دوال (Functions) مناسبة.
النتيجة؟ فوضى عارمة من الأكواد المتداخلة، أخطاء FileNotFoundError في كل مكان، وشعور هائل بالإحباط. كان الكود أشبه بـ "سباغيتي" يصعب تتبعها.
الرأي/الدرس: هذه أسوأ طريقة لبدء مشروع. كان يجب أن أتبع مبدأ "فصل الاهتمامات" (Separation of Concerns). أي، دالة لـ "إنشاء المجلدات"، ودالة لـ "تحديد نوع الملف"، ودالة لـ "نقل الملف". هذا يجعل الكود منظماً، وأسهل في تصحيح الأخطاء، ويمكن إعادة استخدامه.
الخطأ الكارثي الثاني: "التشفير الثابت" (Hard-Coding) وعدم المرونة
عندما بدأت في كتابة الكود، كان أول سطر لي شيئاً كهذا (وهو خطأ فادح):
# !! كود خاطئ لا تستخدمه !!
DOWNLOADS_PATH = "C:\\Users\\Kamal\\Downloads"
for filename in os.listdir(DOWNLOADS_PATH):
# ... باقي الكود
المشكلة؟ هذا الكود سيعمل فقط على جهازي الشخصي! إذا حاولت تشغيله على جهاز آخر، فسوف ينهار السكريبت بالكامل. كما أنني قمت بتشفير أسماء المجلدات الجديدة (مثل "الصور") بشكل ثابت أيضاً.
الحل (الذي اكتشفته لاحقاً): كان يجب أن أستخدم مكتبة pathlib أو os للعثور على مجلد "home" الخاص بالمستخدم بشكل ديناميكي. هكذا أصبح الكود أفضل بكثير:
# الطريقة الصحيحة
from pathlib import Path
# هذا السطر يجد مجلد "التنزيلات" لأي مستخدم على أي نظام تشغيل
DOWNLOADS_PATH = Path.home() / "Downloads"
الخطأ الكارثي الثالث: تجاهل "الحالات الشاذة" (Edge Cases)
السكريبت الخاص بي بدأ يعمل! كان ينقل ملفات .jpg و .pdf بنجاح. شعرت بالانتصار... ثم انهار.
لماذا؟
- ماذا لو كان المجلد غير موجود؟ الكود الخاص بي كان يحاول نقل ملف إلى مجلد "الصور" قبل أن يتحقق مما إذا كان مجلد "الصور" موجوداً أصلاً. (الحل: استخدام
os.makedirs(..., exist_ok=True)لإنشائه إذا لم يكن موجوداً). - ماذا لو كان الملف موجوداً بالفعل؟ عندما حاولت نقل ملف
report.pdfوكان هناك ملف آخر بنفس الاسم، انهار السكريبت. لم أكن قد فكرت في إعادة تسمية الملف الجديد (بإضافة رقم تسلسلي مثلاً). - ماذا عن المجلدات؟ السكريبت الخاص بي كان يحاول نقل المجلدات الفرعية الموجودة داخل "التنزيلات" كأنها ملفات، مما تسبب في خطأ
IsADirectoryError.
الدرس: البرمجة لا تتعلق فقط بـ "المسار السعيد" (Happy Path). المطور الجيد هو الذي يفكر: "ما هي كل الطرق التي يمكن أن يفشل بها هذا الكود؟" (راجع مقالنا عن تتبع الأخطاء). الأهم من ذلك، هذا هو المكان الذي تتعلم فيه `try...except` (معالجة الاستثناءات) لتفادي انهيار البرنامج بالكامل عند حدوث خطأ بسيط.
الخطأ الإجرائي الرابع: عدم استخدام ملفات التهيئة (Configuration Files)
كل امتداد (.jpg, .pdf, .zip) كان مربوطاً مباشرة بـ if و else في كود بايثون الرئيسي. إذا أردت إضافة امتداد جديد (مثل .raw)، كان عليّ تعديل السكريبت نفسه وإعادة تشغيله.
الحل الاحترافي: كان يجب فصل خريطة الامتدادات عن الكود. أي، إنشاء ملف تهيئة (مثل config.json أو config.yaml) يحتوي على قائمة الامتدادات والمجلد المقابل لكل منها. هذا يتيح للمستخدم (أو لي في المستقبل) تعديل القواعد دون لمس كود بايثون الأساسي، مما يزيد من مرونة وقابلية صيانة السكريبت.
النتيجة: شعور لا يوصف
بعد يومين من تصحيح الأخطاء والقراءة عن مكتبات مثل os و shutil، قمت بتشغيل السكريبت.
شاهدت مجلد "التنزيلات" الفوضوي الخاص بي وهو ينظم نفسه في ثوانٍ. الملفات المضغوطة ذهبت إلى مجلد "Compressed"، الصور إلى "Images"، والمستندات إلى "Documents".
بصراحة؟ الشعور كان أفضل من إنهاء أي دورة تعليمية. لم يكن السكريبت مثالياً، ولكنه كان خاصتي، و يعمل، ويحل مشكلة حقيقية بالنسبة لي.
ما تعلمته حقاً (الخلاصة)
بناء هذا المشروع الصغير علمني أكثر من 10 ساعات من مشاهدة الفيديوهات. إذا كنت في نفس مكاني، إليك نصيحتي:
- ابدأ مشروعاً اليوم: لا يهم مدى صغره. اختر شيئاً يزعجك وقم بأتمتته.
- الأخطاء هي الدرس الحقيقي: أنت لا تتعلم عندما يعمل الكود من أول مرة. أنت تتعلم عندما ينهار وتبحث في Google عن سبب الانهيار.
- التفكير في الحالات الشاذة: فكر كالمهاجم أو المستخدم السيئ. ما هي كل الطرق التي يمكن أن يفشل بها هذا النظام؟
- المعرفة الحقيقية في التطبيق: لن تفهم حقاً معنى
os.path.joinأوPathlibحتى تحتاج إليها لحل مشكلة حقيقية.
كانت هذه تجربتي المتواضعة والفوضوية. الآن دوركم!
ما هو أول مشروع بنيته (أو تخطط لبنائه) ببايثون؟ شاركنا أفكارك وتجاربك في التعليقات!
✍️ كتب بواسطة KamalZone