المهارات الرقمية فصل أول

التاسع

icon

المهارات الرقمية

مقدمة إلى برمجية سكراتش

تعرَّفْتُ في صفوفٍ سابقةٍ برمجيةَ سكراتش   Scratch   وتعلَّمْتُ أساسياتِ لغةِ البرمجةِ المرئيةِ
Blocky  التي تُستخدَمُ فيها مجموعةٌ منَ الأوامرِ البرمجيةِ، تُسمّى الكتلَ  Blocks وتربطُها معًا
على نحوٍ مُشابِهٍ لقطعِ الأُحجِيَّةِ  Puzzels  ما مكَّنَني منْ إنشاءِ مشروعاتٍ مختلفةٍ قدْ تكونُ ألعابًا
تفاعليةً، أوْ قصصًا بصريةً، أوْ رسومًا مُتحرِّكةً، أوْ برامجَ أُخرى. والشكلُ (أ) يُبيِّنُ واجهةَ برمجيةِ
سكراتش  Scratch والعناصرَ المُكوِّنةَ لها.

تعرَّفْتُ أيضًا أنَّ كلَّ مشروعٍ في برمجيةِ سكراتش  Scratch   يتكوَّنُ منْ عناصرِ التصميمِ  Design
وعناصرِ البرمجةِ  Code  أنظرُ الشكلَ (ب)

تشتملُ عناصرُ التصميمِ على الخلفياتِ والمشاهدِ والشخصياتِ المختلفةِ، في حينِ تشتملُ
عناصرُ البرمجةِ على الأوامرِ البرمجيةِ التي تُكوِّنُ البرنامجَ النصِّيَّ  Script المُتحكِّمَ في كيفيةِ
عملِ المشروعِ. وتتضمَّنُ هذهِ الأوامرُ مفاهيمَ برمجيةً، مثلَ: المُتغيِّراتِ   Variables والحلقاتِ
Loops  والعباراتِ الشرطيةِ البسيطةِ  Simple Conditionals
تحتوي برمجيةُ سكراتش   Scratch   على فئاتٍ مختلفةٍ منَ اللَّبِناتِ البرمجيةِ التي تؤدّي مهامَّ
مختلفةً، يتعلَّقُ بعضُها بالحركةِ والصوتِ والأحداثِ والمظهرِ العامِّ، ويتعلَّقُ بعضُها الآخرُ بالتكرارِ
والشروطِ.
أُشاهِدُ مقطعَ الفيديو التعليميَّ الآتيَ الذي يُبيِّنُ برمجيةَ سكراتش   Scratch  وعناصرَ الواجهةِ الرئيسةِ للبرمجيةِ والفئاتِ المختلفةَ منَ اللَّبِناتِ البرمجيةِ، وذلكَ بمسحِ الرابطِ سريعِ الاستجابةِ الآتي.

كيفَ يُمكِنُ إنشاءُ نغمةٍ موسيقيةٍ مُعيَّنةٍ واستخدامُها في برمجيةِ سكراتش Scratch
أُشاهِدُ مقطعَ الفيديو:
كيفَ يُمكِنُ إنشاءُ نغمةٍ موسيقيةٍ مُعيَّنةٍ واستخدامُها في برمجيةِ سكراتش   Scratch   وذلكَ بتصفُّحِ درسِ  ( إنشاءُ موسيقى ) منْ قائمةِ الدروسِ في مكتبةِ برمجيةِ سكراتش  Scratch

https://scratch.mit.edu/projects/editor/tutorial=all

 

المُتغيِّراتُ البرمجيةُ في برمجيةِ سكراتش
(Scratch Variables)

الحل : 

برمجية سكراتش Scratch  لغة برمجة تساعد على إنشاء مشاريع الرسوم المتحركة والألعاب والقصص التعليمية بسهولة وطريقة ممتعة 

واجهة برنامج  سكراتش Scratch

 

المُتغيِّراتُ (Variables)
تُعَدُّ المُتغيِّراتُ جزءًا أساسيًّا في تصميمِ برامجِ سكراتش Scratch  وتطويرِها. ولتوضيحِ أهميةِ هذهِ المُتغيِّراتِ، سأتتبع خطواتِ تطويرِ لعبةِ كرةِ قدمٍ تفاعليةٍ، تتضمَّنُ تسجيلَ نقطةٍ للاعبِ كلَّما أحرزَ هدفًا في المرمى.
تمرُّ عمليةُ تطويرِ البرنامجِ بمراحلَ عديدةٍ، تبدأُ بتجزئةِ المشكلةِ  الأساسيةِ التي يرادُ إيجادُ حَلٍّ برمجيٍّ لها Decomposition  أيْ تقسيمِ هذهِ المشكلةِ الكبيرةِ إلى أجزاءٍ صغيرةٍ؛ ما يُسهِّلُ عمليةَ فهمِها وإدارتِها وبرمجتِها، أنظرُ الشكلَ ( 1- 1) إذْ يُعَدُّ هذا النهجُ جزءًا أساسيًّا منَ التفكيرِ الحاسوبيِّ. فعنْ طريقِ تقسيمِ المشكلةِ، يُمكِنُ التعاملُ معَ كلِّ جزءٍ على حِدَةٍ، ثمَّ تجميعُ الحلولِ الجزئيةِ وصولًًا إلى الحَلِّ المُتكامِلِ.

لتطبيقِ مراحلِ تجزئةِ المشكلةِ على لعبةِ كرةِ القدمِ، أتَّبِعُ الخطواتِ الآتيةَ:
1-   اختيارُ الشخصياتِ والخلفياتِ المناسبةِ للعبةِ، وذلكَ عنْ طريقِ ما يأتي:
          أ- اختيارُ الكائناتِ الأساسيةِ   Sprites   المناسبةِ للعبةِ، مثلَ: اللاعبِ، والكرةِ، والمرمى.
         ب- اختيارُ خلفيةٍ   Backdrop   مناسبةٍ للعبةِ، مثلَ اختيارِ ملعبٍ لكرةِ القدمِ،

           أنظرُ الشكلَ  ( 1 - 2  )

أتذكَّرُ:
يمكن مشاهدة خطواتِ إضافةِ كائنٍ وإضافةِ خلفيةٍ في مقاطعِ الفيديو الموجودةِ في مكتبةِ دروسِ برمجيةِ سكراتش Scratch   ضمنَ الموقعِ الإلكترونيِّ الرسميِّ للبرمجيةِ:

https://scratch.mit.edu/projects/editor/?tutorial=all

   أوْ عنْ طريقِ مسحِ الرمزِ سريعِ الاستجابةِ ( QR Code ) المجاورِ:

 

    

 

2- كتابةُ الأوامرِ البرمجيةِ ( Codes ) اللازمةِ لتشغيلِ لعبةِ كرةِ القدمِ، وذلكَ بإضافةِ اللَّبِناتِ التي
تؤدّي المهمتينِ الآتيتينِ، وتعملُ على تركيبِهِما:

    أ- التحكُّمُ في الكائناتِ، وتحريكُها، وتغييرُ مواقعِها عندَ الحاجةِ.
    ب- تحديدُ ما يحدثُ عندَ اصطدامِ الكائناتِ بعضِها ببعضٍ. فمثلًًا، يُسجَّلُ هدفٌ، وتُحسَبُ نقطةٌ للاعبِ عندَ اصطدامِ الكرةِ بشِباكِ المرمى.

 

أتذكَّرُ:
أُشاهِدُ أساسياتِ البرمجةِ اللازمةَ لتحريكِ الشخصياتِ في مقاطعِ الفيديو الموجودةِ في  مكتبةِ دروسِ برمجيةِ سكراتش  ( Scratch  ) ضمنَ الموقعِ الإلكترونيِّ الرسميِّ للبرمجيةِ:

https://scratch.mit.edu/projects/editor/?tutorial=all

أوْ عنْ طريقِ مسحِ الرمزِ سريعِ الاستجابةِ (QR Code ) الآتي:

3 - تعديلُ قِيَمِ المُتغيِّراتِ وحفظُها، مثلَ زيادةِ مُتغيِّرِ الأهدافِ بمقدارِ ( 1)  ثمَّ حفظِ القيمةِ الجديدةِ.
لتنفيذِ هذهِ الخطوةِ، يَلزمُني تعرُّفُ مفهومِ المُتغيِّراتِ  Variables  وأنواعِها، وفهمُ كيفَ تُستعمَلُ لَبِناتُ المُتغيِّراتِ  في برمجيةِ سكراتش  Scratch  لتنفيذِ المشروعاتِ.
       أ- تعريفُ المُتغيِّرِ:

هو مساحةٌ تخزينيةٌ في ذاكرةِ  البرنامجِ، وهيَ جزءٌ منْ ذاكرةِ الحاسوبِ. وفيها توضَعُ القيمةُ المُرتبِطةُ بالمُتغيِّرِ، ويُستعمَلُ اسمُ المُتغيِّرِ للإشارةِ  إلى تلكِ القيمةِ.

يُستخدَمُ المُتغيِّرُ في تخزينِ البياناتِ ( Data ) التي قدْ تتعرَّضُ للتغييرِ أثناءَ تنفيذِ المشروعِ. ويُمكِنُ للمُتغيِّراتِ في برمجيةِ سكراتش ( Scratch ) تخزينُ أنواعٍ مختلفةٍ منَ البياناتِ.
تتمثَّلُ أهميةُ المُتغيِّراتِ في إمكانيةِ إعادةِ استعمالِها لتخزينِ أكثرَ منْ قيمةٍ، واستخدامها في تنفيذِ العملياتِ الحسابيةِ والعملياتِ المنطقيةِ بسهولةٍ، علمًا بأنَّ تحديدَ المُتغيِّراتِ وتسميتَها إنَّما يكونُ لاستخدامِها في أماكنَ مختلفةٍ منَ البرنامجِ في وقتٍ لاحقٍ.

 

    ب- تسميةُ المُتغيِّرِ:

منَ العواملِ التي ينبغي مراعاتُها عندَ تسميةِ المُتغيِّرِ الذي يرادُ استخدامُهُ  في مشروعٍ ما:

  •   اختيارُ اسمٍ فريدٍ للمُتغيِّرِ، بحيثُ يُعرَفُ بهِ وحدَهُ.
  •  دلالةُ الاسمِ على الهدفِ منِ استخدامِ المُتغيِّرِ، وارتباطُ هذا الاسمِ بموضوعِ البرنامجِ؛ ما يُسهِّلُ فهمَه.
  •   اختيارُ اسمٍ قصيرٍ للمُتغيِّرِ؛ كيْ يَسهُلَ تذكُّرُهُ.
  •   تجنُّبُ استخدامِ اسمٍ افتراضيٍّ للمُتغيِّرِ، مثلَ: (س) و(ص)
  •  اشتمالُ اسمِ المُتغيِّرِ على أحرفٍ، أوْ أرقامٍ، أوْ رموزٍ مُعيَّنةٍ (مثلُ _)
  •   اختيارُ اسمٍ للمُتغيِّرِ يكونُ إمّا كلمةً، وإمّا جملةً قصيرةً.
  •  اعتمادُ اسمِ المُتغيِّرِ إمّا بالعربيةِ، وإمّا بالإنجليزيةِ.

فمثلًًا، عندَ إنشاءِ مُتغيِّرٍ لحفظِ قيمةِ الساعةِ أوْ قيمةِ الوقتِ، فإنَّ الأفضلَ أنْ يُطلَقَ على المُتغيِّرِ اسمُ الساعةِ، لا اسمُ  (س) لتسهيلِ عمليةِ فهمِهِ، وتتبُّعِ قيمتِهِ في البرنامجِ.
يمتازُ كلُّ مُتغيِّرٍ باسمٍ ( Name ) يُستدعى بهِ، وقيمةٍ  (Value) تُخزَّنُ داخلَهُ  تكونُ قابلةً للتبديلِ والتعديلِ  ونوعٍ للبياناتِ Data type  أيْ نوعِ القيمةِ المُخزَّنةِ داخلَ المُتغيِّرِ، وهيَ تُصنَّفُ إلى أنواعٍ عديدةٍ، أبرزُها:

  • العددُ الصحيحُ ( Integer ) : يُخزَّنُ العددُ الصحيحُ داخلَ المُتغيِّرِ، مثلَ: 1، 2، 3، 4.
  •  النصُّ ( String ) : يُخزَّنُ النصُّ داخلَ المُتغيِّرِ باستخدامِ الحروفِ أوِ الكلماتِ.
  •   القيمةُ المنطقيةُ (Boolean ) : نوعٌ منْ أنواعِ البياناتِ المُخزَّنةِ داخلَ المُتغيِّرِ، يأخذُ الصواب الخطأ.

الحل : 

أنواعُ المُتغيِّراتِ والبياناتِ في اللعبةٍ التعليميةٍ التفاعليةٍ السابقة: 

  • اسم المجموعة  لإحدى المدن الأردنية    ......متغير نص String
  • أسئلة اختيار من متعدد  توجد بها قيمة واحدة صحيحة ....... قيمة مطلقة Boolean
  • النقاط التي يجمعها الفريق ........عدد صحيح Integer

 

الحل : 

المُتغيِّرِ المستخدم في تخزينِ اسمِ   الطالب هو  متغير نص String

المُتغيِّرِ المستخدم في تخزينِ العلامةِ هو متغير عدد صحيح Integer

  المُتغيِّرِ المستخدم في تخزينِ  النتيجة هو متغير  منطقي Boolean

 

أتذكر  

 كيفيةَ إنشاءِ مُتغيِّرٍ عنْ طريقِ قراءةِ التعليماتِ التاليةِ، أوْ مشاهدةِ مقطعِ الفيديو   التوضيحيِّ بعدَ مسحِ الرمزِ سريعِ الاستجابةِ ( QR Code ) الآتي:

 

 

خطواتُ إنشاءِ مُتغيِّرٍ في برمجيةِ سكراتش Scratch : 
1-  الضغطُ على علامةِ التبويبِ  (المقاطعُ البرمجيةُ )الموجودةِ في الجانبِ الأيمنِ العلويِّ منْ واجهةِ البرمجيةِ.
2 - اختيارُ فئةِ  (المُتغيِّراتُ Variables  ) منَ القائمةِ.
3 - إنشاءُ مُتغيِّرٍ جديدٍ بالضغطِ على زِرِّ (إنشاءُ مُتغيِّرٍ)الموجودِ في الجزءِ العلويِّ منْ لوحةِ(المُتغيِّراتُ)
4 - تسميةُ المُتغيِّرِ بعدَ ظهورِ النافذةِ المُنبثِقةِ الخاصةِ بالاسمِ، وذلكَ بكتابةِ اسمِ المُتغيِّرِ المختارِ في حقلِ النصِّ، ومراعاةِ أنْ يكونَ الاسمُ فريدًا ومُعبِّرًا عنِ الغرضِ منِ استخدامِ المُتغيِّرِ.
5 -  تحديدُ نطاقِ المُتغيِّرِ إمّا باختيارِ أنْ يكونَ المُتغيِّرُ خاصًّا فقطْ بالكائنِ النشطِ  For this sprite only  وإمّا باختيارِ أنْ يكونَ متاحًا لجميعِ الكائناتِ For all sprites

ما الفرقُ بينَ المُتغيِّرِ المحليِّ والمُتغيِّرِ العامِّ؟
يُمكِنُ بيانُ الفرقِ بينَ المُتغيِّرِ المحليِّ والمُتغيِّرِ العامِّ بالقولِ  إنَّ نظامَ الحوسبةِ السحابيةِ مثلًًا هوَ مُتغيِّرٌ عالميٌّ كما في خدمةِ Google Drive  إذْ يُمكِنُ الوصولُ إلى أيِّ ملفٍّ حُفِظَ في Google Drive  باستخدامِ أيِّ جهازِ حاسوبٍ في أي مكان بِغَضِّ النظرِ عنِ الجهازِ المُستخدَمِ في إنشاءِ الملفِّ المطلوبِ.
أمّا في حالِ حفظِ الملفِّ نفسِهِ في قرصِ الحاسوبِ الصُّلْبِ الخاصِّ بي، فلا يُمكِنُ لأحدٍ غيري الوصولُ إلى هذا الملفِّ باستخدامِ جهازٍ آخرَ؛ لأنَّ الملفَّ حُفِظَ بصورةٍ شخصيةٍ.
وتأسيسًا على ذلكَ، فإنَّ:

الخيارَ الذي أختارُهُ يُحدِّدُ نوعَ المُتغيِّرِ الذي أُريدُ إنشاءَهُ (مُتغيِّرٌ  عامٌّ، أوْ مُتغيِّرٌ محليٌّ) فإذا اخترْتُ خيارَ (لجميعِ الكائناتِ)أصبحَ المُتغيِّرُ عامًّا؛ ما يعني إمكانيةَ تغييرِهِ أوِ الوصولِ إليْهِ منْ أيِّ كائنٍ في المشروعِ، بِغَضِّ النظرِ عنِ الكائنِ الذي أُنشِئَ عليْهِ. أمّا إذا اخترْتُ خيارَ (هذا الكائنُ فقطْ) فإنَّ المُتغيِّرَ
يصبحُ محليًّا؛ أيْ لا يُمكِنُ تغييرُهُ أوِ الوصولُ إليْهِ إلّّا منَ الكائنِ الذي أُنشِئَ عليْهِ.

بعدَ إنشاءِ المُتغيِّرِ في برمجيةِ سكراتش ( Scratch ) يُمكِنُ تحديدُ قيمتِهِ باستخدامِ اللَّبِناتِ المُخصَّصةِ لذلكَ على النحوِ  الآتي: 
1- منحُ المُتغيِّرِ قيمةً، وذلكَ بسحبِ لَبِنةِ تحديدِ القيمةِ إلى  منطقةِ العملِ، ثمَّ إدخالِ القيمةِ المبدئيةِ التي يرادُ تعيينُها للمُتغيِّرِ في المكانِ المُخصَّصِ، علمًا بأنَّهُ يُمكِنُ استخدامُ لَبِنةِ(اجعل اسمِ المُتغيِّرِ مساويًا قيمةٍ) في أيِّ مكانٍ منَ البرنامجِ لضبطِ قيمةِ المُتغيِّرِ.
2- تغييرُ القيمةِ داخلَ المُتغيِّرِ، وذلكَ بسحبِ لَبِنةِ تغييرِ القيمةِ إلى منطقةِ العملِ، ثمَّ إدخالِ القيمةِ المبدئيةِ التي يرادُ تعيينُها للمُتغيِّرِ (مقدارُ الزيادةِ أوْ مقدارُ النقصانِ في قيمةِ المُتغيِّرِ المبدئيةِ عندَ تنفيذِ الأمرِ البرمجيِّ) في المكانِ المُخصَّصِ.

عندَ بَدْءِ اللعبةِ، وبحسبِ المثالِ السابقِ، فإنَّ القيمةَ المبدئيةَ للمُتغيِّرِ )النتيجةُ( ستكونُ صفرًا، ثمَّ  تزيدُ بمقدارِ ( 1)  أثناءَ تنفيذِ البرنامجِ؛ أيْ تزيدُ نقطةً كلَّما سجَّلَ اللاعبُ هدفًا في المرمى. وهذا  يتطلَّبُ استخدامَ لَبِناتِ المُتغيِّراتِ.

 

في ما يأتي بيانٌ للَّبِناتِ التي يُمكِنُ استخدامُها في التعاملِ معَ المُتغيِّرِ والتحكُّمِ فيهِ:
1. لَبِناتُ إظهارِ المُتغيِّرِ وإخفائِهِ: عندَ تفعيلِ العلامةِ الزرقاءِ بجانبِ اسمِ المُتغيِّرِ كما يظهر في جانب الصورة الأيمن فإنَّ كلًًّّا منَ المُتغيِّرِ وقيمتِهِ ستظهرُ على الشاشةِ عندَ تشغيلِ البرنامجِ. ولإخفاءِ المُتغيِّرِ، يجبُ إزالةُ العلامةِ الزرقاءِ كما في يظهر في جانب الصورة الأيسر.
2. لَبِناتُ تحديدِ قيمةِ المُتغيِّرِ: تُستعمَلُ هذهِ اللَّبِناتُ لحفظِ القيمةِ ( 0) داخلَ المُتغيِّرِ (النتيجةُ) وهيَ تُعادِلُ المعادلةَ الآتيةَ: النتيجةُ= 0
ويُمكِنُ استخدامُ هذهِ اللبنة في أيِّ جزءٍ منَ البرنامجِ لتعيينِ  قيمةٍ مُعيَّنةٍ للمُتغيِّرِ.
3. لَبِناتُ تغييرِ قيمةِ المُتغيِّرِ: تُستعمَلُ هذهِ اللَّبِناتُ لتغييرِ القيمةِ داخلَ المُتغيِّرِ (النتيجةُ)ويُمكِنُ زيادتُها باستخدامِ قيمةٍ موجبةٍ  مثلِ ( 1) ويُمكِنُ كذلكَ إنقاصُها باستخدامِ قيمةٍ سالبةٍ، وهيَ تُعادِلُ المعادلةَ الآتيةَ: النتيجةُ= النتيجةَ + 1

 

 

 

 

 

 

الحل : 

1 -   ستصبحُ القيمةُ المُخزَّنةُ داخلَ المُتغيِّرِ ( النتيجةُ ) عندَ تنفيذِ الأمرِ البرمجيِّ  السابق  هو   4 

2 - التعديلُ الذي يجبُ إجراؤُهُ في المقطعِ البرمجيِّ لكيْ تصبحَ قيمةُ المُتغيِّرِ النهائيةُ (  2-)  أن نغيّر النتيجة بمقدار   3-  كما في الشكل الآتي:

استخدامُ المُتغيِّراتِ في البرامجِ

تعرَّفْنا سابقًا أنَّهُ يُمكِنُ استخدامُ لَبِناتِ المُتغيِّراتِ في إظهارِ المُتغيِّراتِ وإخفائِها، وتحديدِ قيمةِ
المُتغيِّرِ أوْ تغييرِها. والآنَ سنتعرَّفُ طرائقَ أُخرى لاستخدامِ المُتغيِّراتِ في البرامجِ.
1-  استخدامُ المُتغيِّراتِ في لَبِناتِ العملياتِ الحسابيةِ ولَبِناتِ العملياتِ المنطقيةِ:
يُبيِّنُ الشكلُ ( 1- 4 )صورًا مختلفةً لبعضِ لَبِناتِ العملياتِ الحسابيةِ ولَبِناتِ العملياتِ المنطقيةِ:

 

لَبِناتُ العملياتِ الحسابيةِ                                       لَبِناتُ العملياتِ المنطقيةِ

منَ الأمثلةِ على استخدامِ هذا النوعِ منَ المُتغيِّراتِ: إنشاءُ برنامجٍ لإيجادِ مساحةِ المستطيلِ وَفقَ المعادلةِ الآتيةِ:

المساحةُ= الطولَ X العرضِ


2 - استخدامُ المُتغيِّراتِ في لَبِناتِ العملياتِ لدمجِ النصوصِ:
يُمكِنُ دمجُ النصوصِ معًا بحيثُ تَظهرُ نصًّا واحدًا باستخدامِ لَبِنةِ  ( اربطْ )
منَ الأمثلةِ على استخدامِ هذا النوعِ منَ المُتغيِّراتِ: دمجُ الاسمِ الأوَّلِ لشخصٍ ما في اسمِ عائلتِهِ
ليبدوَ الاسمُ الأوَّلُ معَ اسمِ العائلةِ اسمًا واحدًا.


 

الحل : 

أمثلةٍ على برامجَ تتطلَّبُ دمجَ النصوصِ فيها

  • Microsoft Word (دمج المراسلات)
  • Google Docs ( ربط بجداول البيانات)
  • LibreOffice Writer (دمج المراسلات)

المواطنةُ الرقميةُ:

يتعيَّنُ عليَّ مراعاةُ ما يأتي بعدَ دراسةِ موضوعِ(المُتغيِّراتُ البرمجيةُ في برمجيةِ سكراتش) :


- التفاعلاتُ الإيجابيةُ: أحرصُ على تقديمِ ملاحظاتٍ بنّاءةٍ، وتجنُّبِ استخدامِ اللغةِ السلبيةِ أوِ
اللغةِ الضارَّةِ عندَ التعليقِ على مشروعاتِ الآخرينَ؛ إذْ تُعزِّزُ برمجيةُ سكراتش التفاعلَ الإيجابيَّ بينَ
المُستخدِمينَ.
- التعلُّمُ المُستمِرُّ: أستمرُّ في تعلُّمِ المهاراتِ الرقميةِ والبرمجيةِ الجديدةِ؛ لكيْ أظلَّ مُواكِبًا للتطوُّراتِ
التكنولوجيةِ. كذلكَ أستفيدُ منَ المواردِ التعليميةِ المتوافرةِ في شبكةِ الإنترنتْ، وأنظرُ إلى أخطائي
بوصفِها فرصًا سانحةً للتعلُّمِ وصقلِ المهاراتِ.

 

Jo Academy Logo