1  النص البرمجي

يتألف النص البرمجي من قِطَع هي عبارة عن جُمَل متتابعة تعبِّر عن أوامِر يفسرها الحاسب وينفذها.

فمثلاً هذا الأمر، يحسب ناتج جمع العددين ويطبعه على الشاشة:

print(5 + 3)
8

وتتتابع الأوامر سطرًا بعد سطر:

print(3 + 7)
print(10 - 2)
print(2 * 2)
10
8
4

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

فلا يجوز أن تقول مثلاً:

print 3 plus 7

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

الاسم

يحتاج المبرمج للإشارة لبعض القيَم بأسماء تدل على معناها، وهذا مثال على أربعة أوامر نشرحها بمحاذاة النص بعد علامة (#) التي تجعل ما بعدها تعليقًا لا تضر قراءته إذْ لا يتم تفسيره:

money = 10000      # تعيين قيمة للمتغير
zakat = money / 40 # تعيين حاصل نتيجة العملية للمتغير الآخر
print(zakat)       # طباعة النتيجة
250.0

فالمُتَغَيِّر (Variable) هو ما أُسنِدَ إليه قيمة (Value)، أو تعبير (Expression) يؤول إلى قيمة.

ولدينا في المثال السابق:

  1. المتغير money وقد أسندنا إليه قيمة: 10000
  2. المتغير zakat وقد أسندنا إليه التعبير: money / 40 الذي يؤول إلى القيمة؛ وهي: 250

ويجوز أن يكون المتغير من حرفٍ واحد، ووجب التنبيه إلى أن علامة = تسمى عامل التعيين (Assignment Operator)، وليست علامة المساواة كما نستعملها في الرياضيات. فمعنى ذلك أن التعيين اللاحق ناسخٌ لما قبله:

x = 10
x = 20
print(x)
20

لاحظ أن القيمة الظاهر في الطباعة هي للتعيين التالي وليس الأول.

بينما يمتنع هذا في الرياضيات أصلاً.

وقد تستعمل الجُمَل لاسم المتغيِّر، لكن يجب فصلها بالشرطة السفلية (_) حتى لا يشتبه على المفسر أنها شيء منفصل:

seconds_in_a_minute = 60
seconds_in_an_hour = seconds_in_a_minute * 60
seconds_in_a_day = seconds_in_an_hour * 24
seconds_in_a_week = seconds_in_a_day * 7

print(seconds_in_a_week)
604800

ويجوز أن يتعدد طرفا التعيين

x, y, z = 5, 10, 20
print(y)
10

ويجوز أن يتكرر عامل التعيين اختصارًا:

x = y = 10
print(x, y)
10 10

العامل

ومن العوامل (Operators):

  • عامل الجمع: + (Addition)
  • عامل الطرح: - (Subtraction)
  • عامل الضرب: * (Multiplication)
  • عامل القسمة: / (Division)
  • عامل باقي القسمة: % (Modulus)
  • عامل الأُس: ** (Exponentiation)

فتجري على الأعداد على النحو التالي:

x = 10
y = 2

print(x + y)  # الجمع
print(x - y)  # الطرح
print(x * y)  # الضرب
print(x / y)  # القسمة
print(x % y)  # باقي القسمة
print(x ** y) # الأس
12
8
20
5.0
0
100

وتكون عملية المساواة بعامله ==، بخلاف التعيين = وناتجها يكون إما نعم (True) أو لا (False). على النحو التالي:

x = 5
y = 10
print(x == 5)
True

وتستعمل في الجُمَل الشرطية، وسيأتي الحديث عنها إن شاء الله.

النوع

ولكل قيمة نوع (Type) يحدد ما يجري عليه من العوامل وما يمتنع.

نصيحة

من أهم المهارات التي تجب على المبرمج: معرفة نوع كل قيمة يتعامل معها.

وإذا قُلنا إن نوعَ المتغير الفلاني كذا فإن ذلك تجوُّز، لأننا في الواقع نقصد نوع قيمة المتغير.

ومن الأنواع في لغة بايثون التي من صنف العدد (Number):

  1. العدد الصحيح؛ ويرمز له بالكلمة int (تعني: Integer). ويستعمل في الفهرسة والعد والترتيب والزيادة والنقصان والفرق ونحو ذلك.
  2. العدد ذي الفاصلة العائمة (يقابل العدد العشري)؛ ويرمز له بالكلمة float (تعني: Floating Point). ويستعمل في تمثيل الكميات كالمال، والمسافة، والوقت، ونحو ذلك.

فإذا تأمَّلت النص التالي وجدت جميع هذه القيَم من نوع العدد الصحيح (int):

age = 20
level = 3
index = -2
start = 0

أما التالي فهو من نوع العدد ذي الفاصلة العائمة (float) إذ يوجد فيه الفاصلة العشرية:

distance = 100.0
price = 10.5
time = 1.5
temperature = 36.6
difference = 0.001

ومن أكثر الأنواع استعمالاً في بايثون؛ النص (str)؛ وهو سلسلة من الأحرف . ويُعرَفُ بعلامتي التنصيص سواء المفردة (') أو المزدوجة (") على النحو التالي:

name = 'Adam'
city = "Al-Madinah"

فيجوز دمج النصوص بعلامة الجمع كالتالي:

sentence = "hello, I am " + name + " and I live in " + city
print(sentence)
hello, I am Adam and I live in Al-Madinah

لاحظ أن كلمة name وكلمة city كلاهم خارج التنصيص؛ لذا فهما يشيران إلى المتغيرين الذين تم تعريفها سابقًا.

لكن يمتنع الجمع بين النص والعدد. فلو حاولت تشغيل التالي فستظهر لك رسالة خطأ:

sentence = name + " is " + age + " years old"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[40], line 1
----> 1 sentence = name + " is " + age + " years old"

TypeError: can only concatenate str (not "int") to str

ولحل المشكلة السابقة، يجب أولاً تحويل نوع العدد إلى نوع النص باستعمال الدالة str(x) على النحو التالي:

sentence = name + " is " + str(age) + " years old"
print(sentence)
Adam is 20 years old

ولمعرفة نوع المتغير، نستعمل الدالة type(x) بتمرير القيمة أو المتغير عوضًا عنها.

print(type(5))
print(type(5.0))
print(type("Hello"))
<class 'int'>
<class 'float'>
<class 'str'>

تأمل ناتج عمليات طباعة النوع لكل من المتغيرات السابقة:

print(type(age))
print(type(distance))
print(type(name))
print(type(city))
<class 'int'>
<class 'float'>
<class 'str'>
<class 'str'>

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

الإدخال

يستمعل أمر الإدخال (input(message)) للحصول على قيمة من المستخدم. وتفسر هذه القيمة على أنها سلسلة من الأحرف؛ أي: أنها من نوع النص (str)، ولو كان المستخدم أدخل عددًا، فإنه سيفسر على أنه حروف العدد وليس قيمةً من نوع العدد.

تأمل المثال التالي:

msg = "Enter your age: "
age = input(msg)
print(age, type(age))

يتم تنفيذ هذه التعليمات على النحو التالي:

  1. تعيين القيمة النصيَّة للمتغير msg
  2. تعيين حاصل القيمة المدخلة من المستخدم للمتغير age
    • هذا يعني أن البرنامج سيتوقف، ليظهر للمستخدم السؤال Enter your age: (إذا كنت في محرر VS Code فسيظهر في الأعلى)
    • ثم إذا أدخل المستخدم فيه شيئًا ثم ضغط على زر Enter فسيتم تخزين القيمة المدخلة في المتغير age لكن كقيمة نصية
  3. لإثبات أن ما تم إدخاله نص؛ نقوم بطباعة قيمة المتغير ثم نوعه

والآن لدينا خياران في تحويل قيمة المتغير النصيَّة إلى قيمة عددية، وذلك أننا عرفنا نوعين من الأعداد: الصحيح (int) والعشري (float). وكلاهما يتم تحويلهما باستعمال الدالة int(x) أو float(x) على النحو التالي:

x = int(age)
print(x, type(x))

y = float(age)
print(y, type(y))
20 <class 'int'>
20.0 <class 'float'>

وعادةً ما نحتاج لمثل هذا التحويل عند قراءة بيانات من الخارج، فتنبه!

ولتثبيت الفكرة، نضرب مثالاً واضحًا بمتغيرين أحدهما عددي والآخر نصي:

x = 10
y = "10"

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

print(x + y)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[46], line 1
----> 1 print(x + y)

TypeError: unsupported operand type(s) for +: 'int' and 'str'

ولو كانا كلاهما من النوع النصي، فإن نتيجة الجمع ستكون بدمج النصين لا بجمع العددين. تأمل المثال التالي:

x = "10"
y = "20"

print(x + y)
1020

وهذا وإن لم يظهر برسالة خطأ فإنه ليس مقصودنا؛ لذلك فهو خطأ منطقي وإن كان من حيث البنية اللغوية صحيحًا.

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