المتغيرات والأنواع — كيف يتذكر البرنامج
تخزين القيم في المتغيرات، وقواعد تسميتها، والأنواع الأساسية الأربعة — int وfloat وstr وbool — إضافة إلى الخطأ الذي يواجهه المبتدئون أكثر من غيره.
كيف تريد أن تتعلم؟
المشكلة التي نقوم بحلها
حتى الآن لم تكن برامجنا تتذكر شيئاً. ما يُطبع يذهب ولا يعود.
لكن العمل الحقيقي لا يجري هكذا. في برنامج فواتير يُحسب السعر مرة واحدة ويُحتاج إليه في ثلاثة أماكن. وفي تقرير يجب أن يُحسب المجموع أولاً ثم يُستخدم لاحقاً. البرنامج يجب أن يتذكر.
وهناك مشكلة ثانية بجانبها. في الفصل السابق أعطى "2" + "3" النتيجة 23 بينما أعطى 2 + 3 النتيجة 5 — الرمز نفسه، وسلوكان مختلفان. السبب أن هذين الشيئين في نظر بايثون من نوعين مختلفين. هذا النوع يسمى type، ومنه يأتي الجزء الأكبر من أخطاء المبتدئين.
في نهاية هذا الفصل ستستطيع
- تخزين قيمة في متغير (variable) وتغييرها لاحقاً
- اختيار أسماء يقبلها بايثون ويفهمها الإنسان
- التعرف على الأنواع الأساسية الأربعة:
intوfloatوstrوbool - معرفة نوع أي قيمة باستخدام
type() - قراءة
TypeErrorومعرفة ما يشتكي منه بالضبط
المتطلبات المسبقة: الرؤية عبر print والتوضيح عبر التعليقات.
المتغير اسم
city_count = 4اقرأ هذا السطر من اليمين إلى اليسار: وُجدت القيمة 4، ووُضع عليها ملصق اسمه city_count. من الآن فصاعداً، كتابة city_count تعطيك تلك القيمة.
city_count = 4
print("Cities:", city_count)
print("Double:", city_count * 2)Cities: 4
Double: 8=لا تعني "يساوي". في الرياضياتx = 4ادعاء: x و4 متساويان. في بايثون=تعليمة: "خزّن هذه القيمة تحت ذلك الاسم." ولهذا فإنtotal = total + 5— المستحيلة رياضياً — عادية تماماً في بايثون. معناها: "خذ ما يحملهtotalالآن، وأضف 5، وضع النتيجة فيtotalمن جديد." وللتحقق من تساوي شيئين رمز خاص هو==، وسنتعرف عليه لاحقاً.
تغيير القيمة
عندما تُسند قيمة جديدة إلى متغير، لا يبقى شيء من القيمة القديمة:
stock = 20
print("Before:", stock)
stock = stock - 3
print("After:", stock)Before: 20
After: 17انظر ماذا يحدث عندما يشير اسمان إلى القيمة نفسها:
a = 10
b = a
a = 99
print(a, b)99 10السطر b = a معناه: ضع الملصق b على القيمة نفسها التي يرتبط بها a. الآن يشير الاسمان كلاهما إلى 10 نفسها. ثم a = 99 تنزع الملصق a وتضعه على القيمة الجديدة 99 — ويبقى b حيث كان، على 10. إسناد قيمة جديدة إلى اسم واحد ينقل ذلك الاسم وحده، لا الاسم الآخر.
احتفظ بهذه الصورة في ذهنك: يمكن أن يشير اسمان إلى القيمة نفسها. مع الأرقام والنصوص لا يسبب هذا أي مشكلة، لكن لاحقاً، عندما تتعلم القوائم (lists) — التي يمكن تغيير محتواها في مكانها — تصبح هذه النقطة مهمة جداً.
قواعد الأسماء
ما لن يقبله بايثون:
- البدء برقم:
2nd_priceمرفوض، وprice_2مقبول - شرطة في الوسط:
total-priceمرفوض، فبايثون يقرؤه عملية طرح - مسافة في الوسط:
total priceمرفوض - الكلمات المفتاحية (keywords) في بايثون:
classوforوifوimportوreturnوNoneلا يمكن استخدامها أسماءً
ما يقبله بايثون لكن لا ينبغي أن تكتبه:
x1 = 4500 # clear today, meaningless in three weeks
Total_Price = 4500 # legal Python, but not the Python convention
l = 4500 # lowercase L and the digit one look almost identicalالعُرف المهني في بايثون هو snake_case — أحرف صغيرة، مع شرطة سفلية بين الكلمات:
total_price = 4500
customer_name = "Rafi"
items_in_cart = 3قد يبدو الاهتمام بالأسماء مضيعة للوقت، لكن الكود يُكتب مرة أو مرتين ويُقرأ عشرين مرة. الاسم الذي يشرح نفسه يقوم بعمل التعليق.
الأنواع الأساسية الأربعة
items = 7 # int — a whole number
price = 249.50 # float — a number with a decimal point
name = "Rafi" # str — text, inside quotes
is_paid = True # bool — only True or False
print(type(items))
print(type(price))
print(type(name))
print(type(is_paid))<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>type() أداتك لإزالة الشك. عندما يتصرف متغير بغرابة، فالخطوة الأولى أن تطبع نوعه. في أغلب الأحيان تجد الجواب هناك.
ملاحظتان صغيرتان لكنهما مهمتان:
True وFalse تبدآن بحرف كبير. اكتب true وسيعامله بايثون كاسم متغير ويقول إنه لا يعرفه.
"7" و7 ليسا الشيء نفسه. الأول نص (string)، والثاني رقم. يتشابهان في الشكل ويختلفان تماماً في نظر بايثون:
a = 7
b = "7"
print(type(a), type(b))
print(a * 3)
print(b * 3)<class 'int'> <class 'str'>
21
777الخطأ الذي يواجهه الجميع
age = "22"
print(age + 1)Traceback (most recent call last):
File "C:\Users\Rafi\python-lab\lesson-04\demo.py", line 2, in <module>
print(age + 1)
~~~~^~~
TypeError: can only concatenate str (not "int") to strتبدو الرسالة مخيفة، لكنها في الحقيقة دقيقة: لا يمكن ضم شيء إلى str إلا str آخر، وليس int. بايثون لا يستطيع أن يعرف هل قصدت الجمع أم الضم — لذلك توقف بدلاً من أن يخمّن.
السطر File يعرض المسار الكامل لملفك أنت، لذلك سيكون مختلفاً على حاسوبك. أما بقية الأسطر فتبقى كما هي.
اقرأ رسائل الأخطاء من الأسفل إلى الأعلى. السطر الأخير يقول ما المشكلة؛ والسطر الذي فوقه يقول أين. كثير من المبتدئين يرتبكون عند رؤية رسالة الخطأ ويتجاهلونها كلها، لكن رسائل أخطاء بايثون هي أكثر نص مفيد على شاشتك.
الحل هو أن تجعل الرقم رقماً:
age = "22"
print(int(age) + 1)23int() تحوّل النص إلى عدد صحيح. متى ينجح ذلك ومتى يفشل سيُشرح بالتفصيل في فصل لاحق عن input()، لأن هذه المشكلة تظهر هناك في كل مرة.
مثال كامل
invoice.py:
# Invoice for a single order, all figures in one place
customer_name = "Rafi"
unit_price = 249.50
quantity = 3
is_member = True
subtotal = unit_price * quantity
discount = 50.0
total = subtotal - discount
print("Customer :", customer_name)
print("Quantity :", quantity)
print("Subtotal :", subtotal)
print("Discount :", discount)
print("Total :", total)
print("Member :", is_member)Customer : Rafi
Quantity : 3
Subtotal : 748.5
Discount : 50.0
Total : 698.5
Member : Trueلاحظ أين الفائدة الحقيقية: لتغيير السعر تعدّل سطر unit_price فقط، فتصحح كل الحسابات التي تحته نفسها. لو كُتبت الأرقام مباشرة داخل استدعاءات print لاضطررت إلى البحث عن كل موضع في كل مرة — ونسيان موضع واحد يجعل التقرير خاطئاً.
عندما يحدث خطأ
NameError: name 'total' is not defined الاسم الذي استخدمته لم تُسند إليه قيمة بعد، أو فيه خطأ إملائي. بايثون يعامل total وtotl كاسمين مختلفين. ولاحظ أن حالة الأحرف مهمة أيضاً: Total ليس total.
TypeError: can only concatenate str (not "int") to str حاولت ضم رقم إلى نص. إما أن تحوّل باستخدام int()، أو أن تستخدم الفاصلة — print("Age:", age) — لأن print تتعامل مع الأنواع المختلفة بنفسها.
SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='? الشرطة في الاسم تعطي هذا. في السطر total-price = 5 يرى بايثون عملية حسابية تطرح price من total، ولا يمكن تخزين قيمة في عملية حسابية. استخدم الشرطة السفلية: total_price.
SyntaxError: invalid syntax حاولت استخدام إحدى الكلمات المفتاحية في بايثون اسماً، مثل class = 10. الرسالة لا تذكر الكلمات المفتاحية؛ بل تضع ^ تحت = فقط، لذلك عليك أن تتحقق بنفسك هل الاسم كلمة مفتاحية. اختر اسماً آخر: class_name أو grade.
NameError: name 'true' is not defined. Did you mean: 'True'? True وFalse تبدآن بحرف كبير.
الخطوة ٤ من ٦ — التوقع
تحقّق من فهمك
ماذا يطبع هذا؟
a = 10
b = a
a = 99
print(a, b)- A10 99
- B10 10
- C99 99
- D99 10
أي مما يلي اسم متغير صالح في بايثون؟
- Aclass
- Bitem-2
- C2nd_item
- Ditem_2
هذا البرنامج يعطي TypeError. ما الخطأ بالضبط، وما الذي يصلحه؟
age = "22"
next_year = age + 1
print("Next year:", next_year)- Aاستُخدم `next_year` دون أن يُعلَن عنه أولاً
- B`age` يحمل نصاً (string) لا رقماً — اكتب `age = 22`، أو استخدم `int(age) + 1`
- Cكتابة `age + "1"` بدلاً من `age + 1` ستعطي 23
- D`print` تحتاج إلى `+` بدلاً من الفاصلة
الإجابة تتطلب حساباً
سجّل الدخول للتحقق من إجاباتك
الأسئلة موجودة أعلاه، والتفكير في إجاباتها ذهنياً هو الجزء المهم. سجّل الدخول لرؤية الإجابات والتفسيرات والتلميحات ذات المستويات الثلاثة.
دورك الآن
اكتب ملفاً باسم shipping.py يحتوي على:
- أربعة متغيرات — واحد
int، وواحدfloat، وواحدstr، وواحدbool— كلها بأسماء ذات معنى بأسلوب snake_case - عملية حسابية واحدة على الأقل تستخدم اثنين منها لتنتج متغيراً ثالثاً
- طباعة نوع المتغيرات الأربعة باستخدام
type() - متغيراً تُسند إليه قيمة ثم تُغيَّر — مع طباعة القيمة في الخطوتين
ثم اكسره عمداً: خذ متغيراً من نوع str، واكتب بعده + 1، وشغّل الملف. اقرأ رسالة الخطأ كلها، وخاصة السطر الأخير. ستقابل هذه الرسالة مرات كثيرة؛ واستدعاؤها عمداً اليوم يجعلها مألوفة لاحقاً.
في هذه المهمة المزيد
ما قرأته أعلاه هو المهمة كاملة — لم يُحذف منها شيء. يضيف Pro:
- ما يحدث فعلياً في الكواليس — كيف ينفذ بايثون هذا الكود
- الحل الكامل للتمرين مشروحاً خطوة بخطوة
- تمارين إضافية أكثر صعوبة وتحدياً
- أسئلة المقابلات الوظيفية حول هذا الموضوع مع نموذج الإجابة
الخطوة ٦ من ٦
التحدي — اختبار الفصل
عشرة أسئلة متدرجة من السهل إلى الصعب. الأسئلة الأخيرة صعبة عن قصد.
سجّل الدخول لأداء الاختبار