خان المُبرمجين (علي فاضل)
543 subscribers
93 photos
9 videos
116 links
قناة أنشر فيها ما أتعلمه خلال عملي على مشاريعي الخاصة 👀
Download Telegram
وصلنا اليوم إلى 200 مشترك ولله الحمد 🎉 لعل هذه المنشورات تكون لنا لا علينا يارب 🤲🏻

شارك معنا شيئا استفدته في هذه الرحلة 😎
🎉82
خان المُبرمجين (علي فاضل)
Photo
البيانات الهرمية في قاعدة البيانات

أعمل حاليا على إضافة ميزة جديدة إلى منصة باحث (قريبًا 🚀) وتحتاج هذه الميزة إلى ترتيب البيانات هرميًّا، فكل صف من صفوف الجدول يُعبّر عن عنصرٍ وهذا العنصر قد يكون له ابن أو مجموعة أبناء، وهكذا إلى أن نحصل على شجرة من البيانات.

هذا التمثيل للبيانات مهم ومنتشر في حياتنا فيمكنك من خلاله تمثيل فئات المنتجات (مثلا: فئة البقالة تحتها منتجات الألبان ومنتجات اللحوم) أو تمثيل الموظفين في الشركة حسب أقسامهم (مثلا: قسم تكنولوجيا المعلومات تحته قسم الصيانة وقسم المشتريات).

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

ولكن قبل البدء في التنفيذ قررت البحث والقراءة عن الأمر، فاكتشفت الخيارات الكثيرة المتاحة لك عند تمثيل هذا النوع من البيانات، ومنها الخيار المذكور في الفقرة السابقة والمسمى بـ "أب-ابن" (Parent-Child).

استخدام هذا النوع سهلٌ جدًّا في Ruby on Rails، تحتاج إلى إضافة العمود ثم تعريف العلاقة في الـ Model كما هو موضّح في الصورة. بهذه الطريقة يمكنك الوصول إلى أب أي عنصر من خلال دالة parent والوصول إلى أبناء أي عنصر من خلال دالة children.

هذا الخيار يُوّفر لك سرعة كبيرة في إضافة العناصر الجديدة، فأنت تحتاج إلى كتابة صفٍّ واحدٍ فقط، ولكن القراءة فيه تكون بطيئة، فإذا وُجد عنصر يبعد عن الجذر الخاص به بمسافة 5 عناصر، فستحتاج إلى 4 استعلامات على قاعدة البيانات لتصل إلى الجذر، لذلك يُنصح به إذا كان أطول مسارٍ في شجرة بياناتك لا يتعدَّى عنصرين أو ثلاثة عناصر كحد أقصى.

النوع الثاني يسمى المسار الملموس (Materialized Path)

في هذا النوع أنت تحتفظ بكل آباء العنصر إلى أن تصل إلى الجذر في كل صف من صفوف الجدول، فلا تحتاج إلى الكثير من الاستعلامات لتصل إلى جذر عنصرٍ مُعيّن لأنك تمتلك المسار كاملًا من العنصر إلى الجذر، ولكن الكتابة في هذا النوع مكلفة وحجم البيانات المُخزّنة أكبر.

يوجد مكتبة لـ Rails توفّر لك هذا النوع من التمثيل تسمى ancestry، يمكنك الاطلاع عليها من هنا:
https://github.com/stefankroes/ancestry

النوع الأخير يسمى المجموعات المتداخلة (Nested Sets)

وهذا النوع أعقدهم، ولكنه يوفّر قراءة سريعة جدًّا لعناصر الشجرة. يعمل هذا النوع بمبدأ مُشابه لمبدأ عمل الـ Segment Tree، والتي شرحتها في هذا المقطع:
https://www.youtube.com/live/U_sZY8WTX-Y

سريعًا، يستخدم هذا النوع 3 أعمدة وهي level و left و right لتمثيل مستوى العناصر في الشجرة وبداية ونهاية العناصر المُنتمية لكل عنصرٍ من عناصر الشجرة. باستخدام هذه الأعمدة يمكنك الاستعلام عن أبناء عنصر من العناصر بسرعة كبيرة، ولكن كسابقه، الكتابة فيه مكلفة.

يوجد مكتبة لـ Rails توفّر لك هذا النوع من التمثيل تسمى awesome_nested_set، يمكنك الاطلاع عليها من هنا:
https://github.com/collectiveidea/awesome_nested_set

قررت الابتعاد عن الخيار الأول والأخير في باحث واستخدام الخيار الثاني، فالكتابة في حالتي قليلة والقراءة هي الأساس، ولا حاجة للتعقيد الإضافي من الخيار الأخير.

هل استخدمت أي نوع من هذه الأنواع سابقًا ؟.؟ وهل تعرف أنواعًا أخرى؟ شاركنا لنستفيد 😁

والسلام عليكم 👋🏻
5
اكتب بالعربية

لا يختلف اثنان على أن الكتابة بالعربية أمرٌ صعب في مجالِ التقنية بشكل عام، فمعظم المصطلحات ليس لها ترجمة، وإن وُجدت ترجمة، فقد تكون غير مستساغة لدى المتلقِّي.

ولكن رغم كل هذه الصعوبات، الأمر يستحق المجاهدة والمُحاولة، فلا ترتقي الأمم بلغة غيرها ولا تبدأ النهضة إلا بترجمة العلوم وإنتاجها بلغة القوم.

عن نفسي، أكتب بسهولة أكبر في مجالي عند استخدام الإنجليزية، ولكن أبذل بعض الجهد في استخدام العربية سواءً كان في المحادثات الشخصية أو في توثيق البرمجيات، ومن أمثلة ذلك مكتبتيْ تفريغ وتحويل:
- https://github.com/ieasybooks/tafrigh
- https://github.com/ieasybooks/tahweel

بدأت بكتابة التوثيق الخاص بمكتبة تفريغ باللغة العربية، ثم عند استقراره استخدمت الذكاء الاصطناعي لترجمته إلى الإنجليزية وتوفيره كنسخة ثانية (وليست أساسية) للتوثيق في المستودع.

كذلك، بدأت بكتابة توثيق تحويل باللغة العربية، لكنني لم أرَ حاجة إلى ترجمته إلى الإنجليزية بعد.

وعلى الهامش، سأكون متواجدًا في Leap هذه السنة في الرياض من الأحد الموافق 09/02 إلى الأربعاء الموافق 12/02، إن كنتَ حاضرًا، فلنلتقِ 😁

والسلام عليكم 👋🏻
9👍1🔥1
عندما تأتيك التزكية من صاحب المكان 😎✌🏻😂
72
خان المُبرمجين (علي فاضل)
Photo
الاتباع القاتل لأفضل الممارسات (Best Practices)

يمكن للمستخدم تصفّح منصة باحث باللغتين العربية والانجليزية (لواجهة المستخدم فقط، وليس للمحتوى) وهذه ميزة متوفرة تلقائيًّا في إطار عمل Ruby on Rails تسمح لك بكتابة النصوص المستخدمة في تطبيقك في ملفات YAML ثم تستطيع تغيير لغة التطبيق من خلال الإعدادات.

عندما بدأت منصة باحث، كنت أضع نصوص كل صفحة من صفحات الموقع في ملف منفصل.

مثلا، الصفحة الموجودة في مسار app/views/pages/home.rb يكون لها ملفات للترجمات في المسارات التالية:
- config/locales/views/pages/home.ar.yml
- config/locales/views/pages/home.en.yml

وكنت مقتنعًا أن هذا الأمر جيِّدٌ لأنني أفصل نصوص الصفحات عن بعضها، ويمكنني تحديد مكان النص الذي أريد تغييره بدقة كبيرة، ولكن هذا لم يكن الواقع!

كان الأمر مزعجًا، ولم يكن العثور على الملفات سهلًا، بل إن أي صفحة جديدة، وحتى المُكوِّنات (Components)، كان لها ملفاتها المنفصلة، فكان عدد الملفات يتجاوز الـ 300 ملف (للنصوص فقط)!

في يوم من الأيام قررت إزالة كل هذه الملفات وتجميع كل النصوص في ملف واحد لكل لغة، فأصبح لديَّ ملفّان فقط:
- config/locales/ar.yml
- config/locales/en.yml

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

بعد هذه التجربة اكتشفت أن أفضل الممارسات ليست دائما أفضل ما تفعله لمشروعك 😁

والسلام عليكم 👋🏻
5
أول ميزة تصل إلى منصة باحث طُوِّرت في LEAP من الرياض، السعودية 😎

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

الأكاديميات المُضافة حتى الآن هي أكاديمية غراس العلم وأكاديمية زاد، وسيزداد العدد في المستقبل بإذن الله.

هذه هي الميزة التي كتبت عنها في منشور سابق، حيث ناقشت فيه بعض ما يتعلق بالبيانات الهرمية وطُرق تمثيلها في قاعدة البيانات:
https://t.me/programmerskhan/99

والسلام عليكم 👋🏻
8
عُدنا والعود أحمدُ

لا أحب ترشيح أيّ شيءٍ إلا بعد تجربته، سواء كان الأمر يتعلق بتقنية مُعينة أو سلسلة مُصوّرة، لذلك تأخرت في ترشيح البث الذي أجراه الأخ أبو بكر سليمان مع الأخ أحمد الإمام حتى أنهيت مشاهدته، وكانت 4 ساعات رائعة.

البث يتطرّق إلى:
- معالجة البيانات وتجهيزها
- تشغيل النماذج اللغوية ومقارنتها
- تدريب النماذج اللغوية
- حفظ ونشر النماذج اللغوية
- تقدير تكلفة استخدام النماذج اللغوية

ويتخلل هذه المحاور العديد من المعلومات المفيدة، مثل التعرّف على مكتباتٍ جديدة وبعض التقنيات المُساعِدة عند التعامل مع هذه النماذج.

يمكنك مشاهدة البث من هنا:
https://www.youtube.com/live/S9VHQhC3HPc

أنصحك سواءً كنت مبتدئًا أو متقدمًا في هذا العالم أن تُشاهد البث، فهو مفيد جدا.

والسلام عليكم 👋🏻
8👍1
الخوف من المجهول

من سنوات طويلة وأنا أسمع عن NGINX وأراه يُستخدم بكثرة وأحيانا أستخدمه من خلال أحد مقدِّمي الخدمات، ولكن لم أُجرّب استخدامه بشكل مباشر أبدًا من قبل، والسبب كان "الخوف من المجهول".

كنت أظن أنه شيء مُعقّد ومن الصعب التعامل معه، إلى أن اضطررت البارحة إلى تشغيله يدويًّا واكتشفت أن الأمر لم يكن صعبا كما كنت أتخيّل!

كل ما احتجته هو تشغيل بعض الأوامر على الخادم وتعديل بعض الإعدادات وكان NGINX مربوطًا باسم النطاق الخاص بي وبدون أي مشاكل. بكل تأكيد هناك العديد من الإعدادات التي لم ألمسها والكثير من الأمور التي أحتاج لتعلمها، ولكن التجربة المبدئية كانت ناجحة.

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

لو أنني تخلّصت من هذا الخوف من سنوات لكنت الآن أكثر معرفة ولدي تجارب مختلفة في مجالات أكثر، ولكن هذا ما حدث، لذلك أنا آتٍ من المستقبل لأخبرك "لا تخف من المجهول"، فقط جرّب وأعطِ نفسك الفرصة.

ما هي أسوأ الاحتمالات؟ ستفشل في تنفيذ بعض الأفكار؟ لن تستطيع تشغيل بعض التقنيات؟ وماذا بعد؟ فقط جرّب.

والسلام عليكم 👋🏻
11👍2
خان المُبرمجين (علي فاضل)
Photo
تضمينات (تمثيلات | متجهات) الماتريوشكا أو Matryoshka Embeddings

كل النماذج المُستخدمة في استخراج التضمينات أو الـ Embeddings تُعطيك حجمًا ثابتًا للتضمينات يتراوح بين 384 في النماذج الصغيرة من Sentence Transformer كنموذج MiniLM، ويصل إلى 8,960 في بعض النماذج الضخمة المُقدمة من Nova وعلي بابا.

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

ماتريوشكا هو اسم الدمى الروسية المتداخلة الموضّحة في الصورة، والفكرة هي تدريب النموذج لاستخراج تضمينات بحجم 1,024 مثلا، ولكن خلال التدريب نُقيّم النموذج باستخدام عدّة أطوال من نفس التضمين.

على سبيل المثال، عندما يُعطينا النموذج تضمين بحجم 1,024 نحسب الـ Loss الخاص به باستخدام التضمين بحجمه الكامل بالإضافة إلى الـ Loss باستخدام أول 512 عنصر من عناصر التضمين بالإضافة إلى الـ Loss باستخدام أول 256 عنصر من عناصر التضمين، وهكذا.

اختيار الأحجام هو شيء يحدده صانع النموذج، فمثلا نموذج silma-embeddding-matryoshka-v0.1 المقدّم من SIMLA AI يُعطيك تضمينات بأحجام 768 و 256 و 48 و 16 و 8.

يمكن الاستفادة من هذا النوع من التضمينات في حالات استرجاع البيانات، فمثلا يمكنك استرجاع عدد كبير من المستندات باستخدام التضمينات الصغيرة (48 مثلا) ثم تُعيد ترتيبها باستخدام التضمينات الأكبر والأكثر دقة (256 مثلا) وتستبعد جزءًا من النتائج لتُعيد ترتيب المُتبقي لديك بأكبر حجم من التضمينات (768 مثلا).

يوجد العديد من النماذج من هذا النوع موجودة على HuggingFace يمكنك الاطلاع عليها من هنا:
https://huggingface.co/models?search=matryoshka

كما يمكنك قراءة هذه المقالة لفهم أعمق:
https://huggingface.co/blog/matryoshka

وأخيرا، يمكنك استخدام متعب (MTEB) لمعرفة أفضل نماذج التضمينات الموجودة على الساحة:
https://huggingface.co/spaces/mteb/leaderboard

والسلام عليكم 👋🏻
4
مما لا يسع المبرمج جهله

تعرّفت على العديد من المبرمجين خلال حياتي البرمجية القصيرة، وجزء لا بأس به منهم لا يعرفون كيفية استخدام Git بشكل جيد أو لم يستخدموه من قبل أساسا (بالإضافة إلى شيء مثل GitHub)، وهذا من المحرمات، صدقًا 😅

"يجب" على المبرمج أن يعرف كيفية استخدام Git سواءً كان مطوّر مواقع أو تطبيقات للهاتف أو عاملا في مجال الذكاء الاصطناعي أو مديرًا للأنظمة والبنية التحتية، هذا ليس رفاهيةً أبدا.

هذان مصدران من المصادر اللطيفة والخفيفة على النفس والتي أنهيتها شخصيا:
- https://ohmygit.org
- https://learngitbranching.js.org

يمكنك مشاهدة بعض الدروس التعليمية كمقدمة ثم استخدام المصدرين في الأعلى للتعلّم والتسلية في الوقت نفسه.

والسلام عليكم 👋🏻
👍63😱1
خان المُبرمجين (علي فاضل)
Photo
الانتباه للتفاصيل الصغيرة يصنع فرقًا كبيرًا

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

البارحة، وخلال تجهيزي لبعض البيانات الخاصة بميزة أخرى، وجدت أن اثنين من مجلدات المتحدثين غير موجودة على ذاكرة التخزين الخارجية التي أستخدمها في حفظ نسخة صوتية من الدروس الموجودة على المنصة 🤔

اكتشفت المشكلة وحللتها على ذاكرة التخزين الخارجية، ولكن خلال البحث عن المشكلة لم أجد المتحدثين المذكورين على منصة باحث كذلك، وعند التدقيق وجدت أن صفحة عرض المتحدثين تعرض 7 صفحات من المتحدثين بدلا من 11 (فقد بحدود 80 متحدثًا) 🧐

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

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

فذهبت لأراجع ما قد كتبته بمساعدة ChatGPT وباستخدام ActiveRecord (وهو الـ ORM الخاص بـ Ruby on Rails) لأكتشف أن استعلام SQL المُوضّح في الصورة الأولى لا يُظهر المتحدثين الذين لم تُفضّلهم وفَضّلهم غيرك من المستخدمين 😨

بعد محاولة فهم الأمر والاستعانة بأحد الأصدقاء، وصلنا إلى نتيجة وهي أن الاستعلام المُوضّح في الصورة الأولى يقوم بدمج الجدولين speakers و favorite_speakers على المُعرّف الخاص بالمُتحدّث ويستخدم WHERE ليُبقي الصفوف المُنتمية للمستخدم الحالي أو التي لا تنتمي لأي مستخدم.

بهذه الطريقة، إذا تم تفضيل المُتحدّث من قِبل أحد المستخدمين، فباقي المستخدمين لن يظهر لهم هذا المُتحدّث لأنه سيُستثنى من الاستعلام باستخدام WHERE بعد الانتهاء من الـ JOIN.

عدّلت الاستعلام كما هو مُوضّح في الصورة الثانية وتخلّصت من جملة WHERE لأحصل على النتيجة المطلوبة مباشرة بعد الانتهاء من الـ JOIN ونجح الأمر 🥳

للوهلة الأولى، وعندما كتبت الاستعلام الأول لأول مرة، كان منطقيًّا، ولكن بعد التجربة اكتشفت الخطأ، وهنا نسأل السؤال، كيف يمكن اختبار مثل هذه الأمور في حالات الاختبار؟ فالاستعلام سليم إذا اختبرته على مستخدم واحد، ولكنه كارثي عند اختباره على عدد أكثر من المستخدمين، هل من أفكار؟

والسلام عليكم 👋🏻
5👍1🔥1