1  المقدمة الأولى: لغة البرمجة

يتألف البرنامج المكتوب بلغة البرمجة من قِطَع هي عبارة عن سلسلة من الجُمَل البسيطة والمركبة المكونة من مُفْرَدات للتعبير عن الأوامِر بطريقة يَسْهُلة على المبرمج كتابتها ، وفي نفس الوقت تَتَّبِعُ قَواعِدَ نَحْوِيَّة صارمة حتى لا تشتبه على المترجم عند تحويلها لتعليمات مفصَّلة على لغة المنطق الرقمي لآلة التي تنفذها.

وفي هذا المثال عرضٌ لقطع برمجية في بايثون وشرحٌ لعملها، وليس المطلوب أي شيء منها أو تأمُّلَه ومحاولة فهمه بل هذه نظرة عامَّة لتكوين تصوُّر مُجْمَل عمّا سيأتي إن شاء الله.

القطعة البرمجية

تُنَفَّذُ القطعة (Code Snippet) بحسب ترتيب جُمَلِها نزولاً من الأعلى.

pages = 900
speed =  50
finish_time = pages / speed

if finish_time < 14:
    print('الوقت كافٍ')
else:
    print('داهمنا الوقت')
داهمنا الوقت

في هذه القطعة مجموعة جُمل، نشرحها سطرًا سطرًا:

  • السطرين الأولين: جملة تعيين حرفّيْ (900 و 50) لمتغير (pages و speed).
  • السطر الثالث: جملة تعيين ناتج عبارة القسمة. ولاحظ أن اسم المتغير finish_time يستعمل الشرطة السفلية بدلاً من المسافة (وهذا ضروري)
  • جملة شرطية: if (بمعنى إن كان)
    • الجزء الأول (الشرط): finish_time < 14
    • ثم ما بعده مباشرة: جملة معلَّقة بالشرط
    • الجزء الثاني else (بمعنى فإن لم يكن) جملة معلَّقة بانتفاء الشرط

فهذه أربعة أنواع من الجُمل في قطعة واحدة. والجملة في بايثون لها أنواعُ كثيرة، وتنقسم إلى قسمين: بسيطة ومركبة:

جملة بسيطة وهي 14 جملة:

  • التعبير: x + y
  • التعيين: x = y
  • التأكيد: assert condition
  • المرور: pass
  • الحذف: del x
  • الإرجاع: return y
  • الإنتاج: yield y
  • رفع الاستثناء: raise Exception
  • الكسر: break
  • الاستمرار: continue
  • الاستيراد: import module
  • العالمية: global x
  • غير المحلية: nonlocal x
  • النوع: type(x)

جملة مركبة وهي 10 جمل:

  • الشرط: if ...
  • التكرار: while ...
  • الحلقة: for ...
  • المحاولة: try ...
  • السياق: with ...
  • المطابقة: match ...
  • تعريف الإجراء: def ...
  • تعريف النوع: class ...
  • تعريف الإجراء غير المتزامن: async def ...
  • قائمة الأنواع المتغيرة: [T1[, T2, ...]]

الكلمات

أول أنواع الكلمة هو المفردات الأصلية (Keywords) التي لها معنىً خاصّ مفهوم لدى بايثون وتستعمل في جُمَل محددة. وهي 35 كلمة:

False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield

ومنها كذلك 4 كلمات: match, case, type و _ (الشرطة السفلية).

وما عدا ذلك

فقد تبني الحروف كلمةً تكونُ متغيِّرًا (Variable)، نحو: x أو price أو body_weight فكلها أسماء مقبولة للمتغيرات؛ لا كما في الرياضيات التي عادةً ما تستعمل الحرف الواحد.

وقت تبني الحروف كلمة تكون حرفيٍّا (Literal)، نحو: 44 أو 3.14 أو "كيف حالك؟" ويُسمَّى قيمة (Value).

ومن الحروف علامات الابتداء والوَقف، نحو: ( ) و [ ] و { } والفصل، نحو: , (الفاصلة اللاتينية) و : (النقطتان الرأسِيَّتان) و = (علامة التعيين) ، وتُسمى جميعًا المحددات (Delimiters).

  • فالأقواس () في العبارة: (y + z) * (a + b) لتحديد ترتيب العمليات
  • والأقواس () في العبارة: print(x, y, z) لتحديد عوامل الإجراء: أي: المتغيرات التي نمررها له
  • والأقواس () في العبارة: (10, 20, 30) لتحديد صف من الأرقام

ومن الحروف المعاملات (Operators)، نحو: + و * و / و ** و ==

فمثلاً: معامل الجمع + يفسَّر بحسب السياق: x + y

  • فإن كان x = 5 و y = 10 فهما من نوع الرقم (Number) فهي للجمع
  • فإن كان x = "Ahmad" و y = "Belal" فهما من نوع النص (String) فهي للدمج بينهما
  • فإن كان x = 5 و y = "Belal" فهما من نوع الرقم و النص فليسَ بمعرَّف

الأنواع والإجراءات المبنية

ومن الأنواع والإجراءات ما هو مبنيُّ (Built-in) في لغة بايثون:

الأنواع المبنية مثل:

  • الرقم: int, float, complex للحساب
  • النص: str للتعامل مع الكلام المكتوب
  • الجمع: list, tuple, range, set, dict لغير المفرد

graph TD
    A[<b>شيء</b> <br> <code>Object</code>] --> B[<b>رقم</b> <br> <code>Number</code>]
    B --> E[<b>صحيح</b> <br> <code>int</code>]
    B --> F[<b>عشري</b> <br> <code>float</code>]
    B --> G[<b>مركب</b> <br> <code>Complex</code>]
    A --> D[<b>جمع</b> <br> <code>Collection</code>]
    D --> M[<b>تسلسل</b> <br> <code>Sequence</code>]
    M --> C[<b>نص</b> <br> <code>str</code>]
    M --> H[<b>قائمة</b> <br> <code>list</code>]
    M --> I[<b>صف</b> <br> <code>tuple</code>]
    M --> J[<b>نطاق</b> <br> <code>range</code>]
    D --> K[<b>مجموعة</b> <br> <code>set</code>]
    D --> L[<b>قاموس</b> <br> <code>dict</code>]

وسيأتي تفصيلها في أبوابها إن شاء الله.

الإجراءات المبنية مثل: print, sum, max, min, len

الإجراء Function
الطباعة print
الجمع sum
الأكبر max
الأصغر min
الطول len
إدخال input
نوع type
أي any
كل all
التالي next
تطبيق map
تجميع zip
تقريب round

وغيرها كثير لا يفيد حصره هنا. ولا تزال اللغة تتطوَّر ويُزادُ فيها من هذه الأنواع والإجراءات.

نمو اللغة

ومن خواص لغة البرمجة: إنشاء مركبات لغوية جديدة، وذلك بشيئين:

  1. تعريف أنواع جديدة؛ بجملة class
  2. تعريف إجراءات جديدة؛ بجملة def

فأضاف مطوروا بايثون أنفسهم إلى اللغة ما يسمى بالمكتبة الأساسية (Standard Library)، ومن أقسامها:

  • وحدة math التي تضم مجموعة إجراءات تعنى بالعمليات الرياضية على الأعداد
  • وحدة statistics التي تضم مجموعة إجراءات تعنى بالإحصاء
  • وحدة datetime التي تضم مجموعة أنواع وإجراءات تعنى بالوقت والتاريخ

المكتبة الأساسية

في هذا المثال نعرف نقطتين ثم نحسب المسافة بينهما. والمسافة الإقليدية بين نقطتين \((x_1, y_1)\) و \((x_2, y_2)\) تتبع معادلة فيثاغورس:

\[ \text{distance} = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} \]

القطعة:

import math

x1, y1 = 0, 0
x2, y2 = 3, 4
distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
print(distance)
5.0

تفصيل هذه القطعة كالتالي:

  • جملة استيراد المكتبة الرياضية: import math
  • تعيين النقطتين: x1, y1 = 0, 0 و x2, y2 = 3, 4
  • حساب المسافة: distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2) وفيه:
    • x2 - x1 هو الفرق بين الإحداثيات السينية
    • y2 - y1 هو الفرق بين الإحداثيات الصادية
    • ** هي عملية تربيع العدد
    • math.sqrt هي فعل حساب الجذر التربيعي
  • طباعة النتيجة: print(distance)

المكتبات المساهمة

وتسمى المكتبات الخارجية (External Libraries) وهي مكتبات يساهم بها الناس، ويضيفونها إلى اللغة، نجدها في موقع قاعدة بيانات PyPI الذي يضم أكثر من 580 ألف مشروع، أو غيرها من المواقع. وهذه يتم تنزيلها وتثبيتها للاستفادة من لغتها المزيدة.

على سبيل المثال، تختص حزمة pandas المتخصصة في تفكيك وتركيب الجداول والتحليلات الإحصائية عليها؛ فهي أقوى من أي نسخة من إكسل (Excel) أو غيره.

لتثبيتها نستعمل uv هكذا في سطر الأوامر (النافذة السوداء):

uv add pandas

ثم نستطيع استعمال المكتبة لقراءة بيانات الطلاب -مثلاً- من ملف CSV:

import pandas as pd

df = pd.read_csv('../../datasets/students.csv')
df
Name Age Grade Done
0 Adam 12 90 F
1 Belal 13 92 F
2 Camal 14 91 T
3 Dalal 8 99 F
4 Eman 9 98 F

ثم لعرض ملخصات إحصائية:

df.describe(include=['number'])
Age Grade
count 5.000000 5.0000
mean 11.200000 94.0000
std 2.588436 4.1833
min 8.000000 90.0000
25% 9.000000 91.0000
50% 12.000000 92.0000
75% 13.000000 98.0000
max 14.000000 99.0000

أو تصوير البيانات:

df['Done'].value_counts().plot(kind='bar', color='skyblue', figsize=(4, 3), rot=0)

هكذا بكل بساطة.

فإذًا .. هنا دور المجتمع (Community) ليبني باللغة: بمفرداتها وجملها ومكتبتها الأساسية والخارجية، ليبني فوق ذلك ما يخدم أغراضه. فلكل فئة من الناس تركيب حزمة جديدة مكونة من أنواع وإجراءات مركبة مبنية على غيرها ، ثم يوفرونها لغيرهم. وهكذا تنمو اللغة ، حزمةً تِلو الأخرى بحسب إسهامات كل مجتمع برمجي بما يهتم به.

ومن مكامن القوة في لغة بايثون: أنها متوافقة مع لغتي C/C++ إذْ يُمكن كتابة برمجيات عالية الأداء والكفاءة بهما مستفيدين من الحزم الموجودة فيهما، ثم توفيق ذلك ليكون كمكتبة في لغة بايثون.

فالمجتمعات البرمجية في بايثون كثيرة ومتعددة في اهتماماتها. منها على سبيل المثال:

  • تطوير مواقع الشبكة:
    • Django - لبناء مواقع متصلة بقواعد بيانات
    • FastAPI - حديث وسريع لبناء واجهات برمجية على الشبكة
  • تحليل البيانات وتصويرها:
    • pandas - لتحليل البيانات المرصوصة
    • seaborn - لتصوير البيانات الإحصائية على أساس Matplotlib.
    • matplotlib - مكتبة شاملة لإنشاء تصورات ثابتة ومتحركة وتفاعلية.
  • الذكاء الاصطناعي وتعلم الآلة:
    • statsmodels - للنماذج الإحصائية
    • scikit-learn - لاكتشاف الأنماط والتنبؤ (تعلم الآلة)
    • PyTorch - لبناء نماذج التعلم العميق
  • التحليل الرياضي والهندسة:
    • sympy - للرياضيات الرمزية.
    • PySR - الانحدار الرمزي.
    • SciPy - للرياضيات والعلوم والهندسة.