انتقل إلى المحتوى الرئيسي

الوحدة 1 — صياغة بايثون التي تفيد فعلاً

بايثون لغة كبيرة، لكنّ علم البيانات لا يستخدم منها إلا جزءاً مضغوطاً على نحو مدهش. تغطّي هذه الوحدة ذلك الجزء بالضبط — الذي ستقرؤه وتكتبه كلّ يوم — وتترك عمداً الزوايا التي يمكن تعلّمها لاحقاً، أو عدم تعلّمها أبداً.

المتغيّرات والأنواع: النمط الديناميكي وتبعاته

يربط بايثون الأنواع بالقيم لا بالمتغيّرات. المتغيّر نفسه يمكن أن يحمل عدداً صحيحاً ثم سلسلة نصّية — واللغة لا تعترض.

amount = 1250          # int
amount = 1250.75 # float — لا خطأ
client_name = "عائشة" # str
active = True # bool

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

الأنواع الأساسية الأربعة: int وfloat وstr وbool — إضافة إلى None، قيمة «لا قيمة»، الحاضرة في كلّ البيانات الحقيقية. دالّتا نجاة: type(x) تكشف نوع القيمة؛ وint("42") وfloat("3.14") وstr(42) تحوّل صراحة.

فخّ الأعداد العشرية

0.1 + 0.2 == 0.3 تساوي False في بايثون — كما في كلّ اللغات تقريباً، لأنّ الأعداد العشرية تقريبات ثنائية. لمقارنة عددين عشريين، اختبر فارقاً: abs(a - b) < 1e-9. وللمبالغ المالية، فكّر في أعداد صحيحة بالسنتات. هذه التفصيلة تسبّب أخطاء حقيقية في خطوط معالجة حقيقية.

f-strings: الطريقة الحديثة الوحيدة للتنسيق

كلّ المخرجات وكلّ رسائل السجلّ وكلّ تسميات الرسوم تمرّ عبر f-strings:

precision = 0.9273
n = 15420
print(f"الدقّة: {precision:.2%} على {n:,} مثالاً")

المحدِّدات الدائمة الاستعمال: :.2f (منزلتان عشريتان)، و:.2% (نسبة مئوية)، و:, (فاصل الآلاف)، و:>10 (المحاذاة). إن صادفت "..." % x أو "...".format(x) في كود قديم، فهي الشيء نفسه بأقلّ وضوح.

الشروط: الإزاحة هي الصياغة

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

if score >= 0.9:
verdict = "ممتاز"
elif score >= 0.7:
verdict = "مقبول"
else:
verdict = "يحتاج مراجعة"

اصطلاحان يجب معرفتهما لأنهما في كلّ مكان:

# التعبير الشرطي (الثلاثي)
status = "بالغ" if age >= 18 else "قاصر"

# الصدق الضمني: القائمة الفارغة والسلسلة الفارغة و0 وNone كلّها "كاذبة"
if invalid_rows:
print(f"{len(invalid_rows)} صفوف تحتاج تصحيحاً")

المقارنة بـNone تُكتَب دائماً is None / is not None، وليس == None أبداً.

الحلقات: for على أيّ شيء قابل للتكرار

حلقة for في بايثون تمرّ على العناصر مباشرة — لا على المؤشّرات:

for file in csv_files:
process(file)

# تحتاج المؤشّر؟ enumerate
for i, column in enumerate(columns):
print(f"{i}: {column}")

# المرور على سلسلتين معاً؟ zip
for true, pred in zip(y_test, y_pred):
if true != pred:
errors += 1

range(n) تولّد الأعداد من 0 إلى n−1 حين يلزم عدّاد فعلاً. break تخرج من الحلقة، وcontinue تنتقل إلى التكرار التالي.

احفظ هذا خصوصاً، فهو يمهّد لوحدة NumPy: في علم البيانات، حلقة for على بيانات ضخمة هي الأداة الخاطئة دائماً تقريباً. الحلقات للمرور على الملفات والأعمدة والمعاملات الفائقة — لا للحساب على ملايين الصفوف. الحساب يُوجَّه (vectorized).

التقطيع (slicing): الترميز الذي يعود في كلّ مكان

صياغة [البداية:النهاية:الخطوة] تنطبق على السلاسل والقوائم — وستعود حرفياً في NumPy وpandas، ومن هنا أهمّيتها:

text = "prediction_2026.csv"
text[0:10] # 'prediction' — النهاية مستثناة
text[-4:] # '.csv' — مؤشّرات سالبة: من النهاية
text[:10] # بداية ضمنية
values[::2] # عنصر من كلّ اثنين
values[::-1] # السلسلة معكوسة

القاعدة الواجب حفظها: مؤشّر النهاية مستثنى، و[a:b] تحوي بالضبط b - a عنصراً. هذا العرف، المحيّر في اليوم الأول، يجعل التقطيعات قابلة للتركيب: s[:k] + s[k:] == s.

قراءة الأخطاء: المهارة المبخوسة

تُقرأ رسالة الخطأ في بايثون من الأسفل إلى الأعلى: السطر الأخير يعطي نوع الخطأ ورسالته؛ والأسطر فوقه تصعد سلسلة الاستدعاءات حتى السطر المعطوب.

الخطأالسبب النمطي في البيانات
TypeErrorعملية بين نوعين متنافرين — غالباً عمود نصّي يُظنّ رقمياً
ValueErrorالنوع سليم والقيمة لا: int("abc")
KeyErrorمفتاح غائب من قاموس — أو عمود غائب من DataFrame
IndexErrorمؤشّر خارج الحدود
FileNotFoundErrorمسار خاطئ — تحقّق من مجلد العمل الحالي

عادة التنقيح الدنيا: اطبع النوع والقيمة (print(type(x), repr(x))) قبل السطر الذي ينكسر مباشرة. هذا يحلّ نسبة محرجة من المشكلات.

الخلاصة

  • أنواع ديناميكية: المرونة تُدفَع أخطاءً عند التنفيذ — اعرف int وfloat وstr وbool وNone والتحويلات الصريحة.
  • f-strings لكلّ تنسيق؛ :.2f و:.2% و:, تغطّي معظم الحاجات.
  • الإزاحة = الصياغة؛ is None لاختبار الغياب؛ الحاويات الفارغة «كاذبة».
  • for مع enumerate وzip للتنظيم — لا للحساب الضخم أبداً، فهو يُوجَّه (الوحدة 4).
  • التقطيع [بداية:نهاية:خطوة] بنهاية مستثناة هو الترميز المشترك بين بايثون وNumPy وpandas.

الوحدة التالية: هياكل البيانات — القوائم والقواميس والصفوف والمجموعات — والاشتمالات التي تحوّلها في سطر واحد.