ثمة فجوة غريبة بين «معرفة بايثون» و«القدرة على استخدام بايثون». كثيرون يشاهدون عشرات مقاطع الفيديو وينسخون الأمثلة ويشعرون أنهم فهموا — ثم يرتبكون حين يُطلب منهم كتابة شيء من الصفر. وُضع هذا الكتاب لسدّ تلك الفجوة.
المنهج بسيط: التعلّم بالتشغيل. كل مثال في هذا الكتاب يمكن تشغيله مباشرة داخل المتصفح، في مكانه. لا تحتاج إلى تثبيت Python، ولا إلى تجهيز محرر، ولا إلى انتظار أي عملية. اقرأ، شغّل، عدّل، شغّل مرة أخرى — ولاحظ بنفسك ما الذي تغيّر.
يسير هذا الكتاب عبر ثلاثة أجزاء متتابعة:
لكل باب النمط نفسه: شرح موجز مكثف، وأمثلة قابلة للتشغيل، ثم تمارين بحلول يمكنك فتحها. لا تتجاوز التمارين. القراءة تجعلك تتعرّف على الشيء؛ أما الكتابة والتشغيل فهما ما يجعلانك قادرًا عليه.
ملاحظة صريحة. ليس كل شيء قابلًا للتشغيل داخل المتصفح. الأبواب التي تتطلب ملفات على حاسوبك، أو حزمًا من الإنترنت، أو شبكة، أو برامج تعمل طويلًا ستشير إلى ذلك بوضوح، وتوجّهك إلى البيئة المناسبة. وهذا ليس نقطة ضعف — بل جزء من تعلّم معرفة أين ينبغي تشغيل الشيء.
قراءة ممتعة، وعملًا موفقًا.
— RWID
هذا ليس كتابًا عاديًا: فيه Python بداخله. كل مثال برمجي يمكن تشغيله مباشرة، دون تثبيت أي شيء.
يحتوي الشريط العلوي للقارئ على المختبر (Lab). وفيه مختبر Python: مفسّر Python مدمج في هذا الكتاب، تجرّب فيه الشيفرة دون مغادرة الصفحة. وللمشاريع الأكبر، افتح بيئة التطوير الكاملة (IDE)، وهي محرر متكامل في نافذته الخاصة تحفظ فيه ملفاتك وتشغّلها.
فوق كل كتلة شيفرة زران:
نصيحتي. لا تكتفِ بالضغط على تشغيل. غيّر الأرقام أولًا، وبدّل الأسماء، وأفسد الشيفرة عمدًا — ثم انظر ماذا يحدث. الخطأ أسرع معلّم.
Python في المتصفح حقيقي، لكنه يعيش داخل صندوق رمل (sandbox). فلا يستطيع لمس الملفات على حاسوبك، ولا تثبيت حزم من الإنترنت، ولا فتح الشبكة. لذلك فبعض المواضيع — بصراحة — لا يمكن تشغيلها هنا. وتشير الأبواب من هذا النوع إلى ذلك بوضوح:
تحتاج إلى بيئة محلية. لا يمكن تشغيل هذا في المتصفح. اتبع الدليل، وشغّله على Python محلي + VS Code أو Google Colab.
الدليل الكامل لتثبيت Python محليًا موجود في الملحق ج. وخلاصته:
| ✅ يعمل هنا | ⚠️ محدود هنا | ❌ يحتاج إلى بيئة محلية |
|---|---|---|
| Python الخالص ومكتبة stdlib الأساسية | الحوسبة/الأحجام الكبيرة | قراءة وكتابة الملفات على حاسوبك |
| NumPy وpandas وMatplotlib | دون شبكة حقيقية | pip install لأي حزمة |
| scikit-learn (بنطاق صغير) | تخزين غير دائم | requests وsocket وقواعد البيانات |
HTML عبر rwid.show_html | الواجهات الرسومية (tkinter/turtle) وos/subprocess | |
multiprocessing والخوادم (Flask/FastAPI) |
الجزء الأول وباب افتتاحي واحد من الجزء الثاني متاحان للقراءة مجانًا. ولفتح الكتاب كله — حتى المشروع الختامي — فعّله بـ 25 عبر الزر في نهاية آخر باب نموذجي، أو من تطبيق Books / المتجر.
استمتع بالاستكشاف. ابدأ من الصفحة التالية.
انقر على العنوان للانتقال إليه. الأبواب المعلّمة بقفل تحتاج إلى تفعيل ( 25).
كل رحلة تبدأ من سطر واحد. وفي Python هذا السطر هو print(). لنشغّل أبسط مثال أولًا، ثم نشرّح ما يحدث فعلًا.
print("Halo, dunia!")
سطر واحد، أمر واحد. print() هي دالة: تستقبل شيئًا داخل القوسين ثم تعرضه على الشاشة. والنص المحاط بعلامات الاقتباس — مثل "Halo, dunia!" — يسمى سلسلة نصية (string).
يمكنك عرض أكثر من شيء دفعة واحدة، مفصولة بفواصل:
print("Nama saya", "Eko")
print("2 + 3 =", 2 + 3)
لاحظ: "Nama saya" و"Eko" يُفصل بينهما تلقائيًا بمسافة، أما 2 + 3 فتُحسب فعلًا أولًا لتصبح 5، ثم تُطبع.
السطر الذي يبدأ بـ # يتجاهله Python. نستخدمه لشرح السبب لا الفعل.
# هذا تعليق: لا ينفّذه Python.
print("Halo") # يمكن أن يكون التعليق في نهاية السطر أيضًا
الشيفرة الجيدة تتحدث عبر أسمائها؛ ويُستخدم التعليق حين لا يكون السبب واضحًا من الشيفرة نفسها.
جرّب تشغيل الشيفرة التالية. هي خاطئة عمدًا، لتتعرف على شكل الخطأ:
print("Halo"
سيتوقف Python ويُبلغ عن SyntaxError. وهذه ليست كارثة — إنها Python يخبرك بوجود قوس لم يُغلق. قراءة رسالة الخطأ مهارة أساسية. وعادةً يكون السطر الأخير من الرسالة هو الخلاصة.
print("Halo")
قارن: حرف واحد إضافي، فيعمل كل شيء.
يقرأ Python البرنامج من الأعلى إلى الأسفل. وتُنفَّذ كل print() بالتتابع:
print("Satu")
print("Dua")
print("Tiga")
سنتناول المتغيرات بالتفصيل في الباب التالي، لكن مثالًا صغيرًا هنا سيفيد:
nama = "Eko"
tahun_lahir = 1990
print("Hai,", nama)
print("Usia pada 2026:", 2026 - tahun_lahir)
تقوم علامة = بـإعطاء اسم لقيمة ما. فبعد nama = "Eko"، أينما كتبنا nama يستبدلها Python بـ "Eko".
17 * 24.panjang = 8 وlebar = 5، ثم اعرض مساحة المستطيل.SyntaxError واحد، وشغّله، واقرأ رسالة الخطأ. ثم أصلحه.# 1
print("Eko")
print("Yogyakarta")
# 2
print(17 * 24)
# 3
panjang = 8
lebar = 5
print("Luas:", panjang * lebar)
# 4 — خطأ شائع: قوس غير مغلق
# print("Halo"
print("Halo")
print() تعرض القيمة على الشاشة.# تبدأ تعليقًا يتجاهله Python.في الباب التالي نتعرف بجدية على المتغيرات وأنواع البيانات.
المتغير هو وسيلتنا لإعطاء اسم لشيء ما كي نستخدمه مرة أخرى. لا يطلب Python منا تعريف النوع — فهو يستنتجه من القيمة — لكن فهم أنواع البيانات يظل واجبًا، لأن النوع هو ما يحدد ما يمكن فعله وما لا يمكن.
umur = 25
nama = "Siti"
tinggi = 1.68
menikah = False
أربعة أسطر، أربعة أنواع أساسية: int (25) وstr ("Siti") وfloat (1.68) وbool (False). ولمعرفة نوع شيء ما، استخدم type():
print(type(25)) # <class 'int'>
print(type(1.68)) # <class 'float'>
print(type("Siti")) # <class 'str'>
print(type(False)) # <class 'bool'>
int عدد صحيح؛ وfloat عدد بفاصلة عشرية. والقسمة تعطي دائمًا float:
print(10 / 3) # 3.3333333333333335
print(10 // 3) # 3 (قسمة صحيحة)
print(10 % 3) # 1 (باقي القسمة)
print(2 ** 10) # 1024 (الأس)
العاملان // و% رفيقان يوميان: أحدهما للقسمة الصحيحة والآخر للباقي. ومعًا يمكنهما تفكيك رقم إلى أجزائه:
menit = 145
print(menit // 60, "jam", menit % 60, "menit") # 2 jam 25 menit
يمكن دمج السلاسل بـ + وتكرارها بـ *:
depan = "Eko"
belakang = "Wibowo"
print(depan + " " + belakang)
print("ha" * 3) # hahaha
print(len("Python")) # 6
سنتعمق في السلاسل النصية أكثر في الباب 7. أما الآن فيكفي أن تتذكر أن السلسلة هي تسلسل من المحارف، وأن len() تحسب طولها.
لـ bool قيمتان فقط: True وFalse. وتنتج هاتان القيمتان من المقارنات:
print(5 > 3) # True
print(5 == 5) # True (لاحظ: == للمقارنة، و= للإسناد)
print(5 != 5) # False
الفخ الكلاسيكي.
=تُسند قيمة للمتغير؛ و==تقارن. اختلاط هاتين العلامتين من أكثر أخطاء المبتدئين شيوعًا.
أحيانًا نحتاج إلى تغيير النوع. تقوم بذلك الدوال int() وfloat() وstr():
nomor = "42" # هذه سلسلة نصية، وليست رقمًا
print(nomor + "5") # 425 (تلتصق ولا تُجمع!)
print(int(nomor) + 5) # 47 (الآن تُجمع فعلًا)
print(str(100) + "!") # 100!
print(int(3.9)) # 3 (تُقتطع ولا تُقرَّب)
أكثر الطرق راحة لطباعة قيم مختلطة هي f-string — سلسلة تبدأ بالحرف f ويمكنها أن تحتوي تعابير داخل {}:
nama = "Eko"
umur = 36
print(f"Hai {nama}, usiamu {umur} tahun.")
print(f"Setahun lagi: {umur + 1}")
print(f"Pi sekitar {3.14159:.2f}") # منزلتان عشريتان
ستظهر f-string باستمرار على امتداد هذا الكتاب. أتقنها من الآن.
أحيانًا لا تكون للمتغير قيمة بعد. وفي Python يُعبَّر عن «لا شيء بعد» بـ None:
hasil = None
print(hasil) # None
print(hasil is None) # True
None تختلف عن 0، وتختلف عن "". إنها فعلًا «غير موجود».
200 دقيقة."7" و3؛ اجمعهما كأرقام، ثم اعرض الناتج.berat = 72.5 (كغ) وtinggi = 1.75 (م)، ثم احسب مؤشر كتلة الجسم berat / tinggi ** 2 واعرضه بمنزلة عشرية واحدة.# 1
depan = "Eko"
belakang = "Wibowo"
tahun = 1990
print(f"{depan} {belakang}, lahir {tahun}.")
# 2
total = 200
print(f"{total // 60} jam {total % 60} menit")
# 3
print(int("7") + 3)
# 4
berat = 72.5
tinggi = 1.75
imt = berat / tinggi ** 2
print(f"IMT: {imt:.1f}")
int وfloat وstr وbool وNone.// قسمة صحيحة، و% تأخذ الباقي، و** للأس.= للإسناد، و== للمقارنة.لماذا تبدو شيفرة Python الجيدة موجزة وسهلة القراءة؟ لأنها تستخدم الأساليب الاصطلاحية (idioms) — طرق كتابة شاعت بين مبرمجي Python. يعلّمك هذا الباب الاستيعابات (comprehensions) وعددًا من العادات التي تجعل الشيفرة أقصر وأوضح وبايثونية.
الطريقة القديمة لملء قائمة:
kuadrat = []
for x in range(1, 6):
kuadrat.append(x ** 2)
print(kuadrat)
يختزلها الاستيعاب في سطر واحد:
kuadrat = [x ** 2 for x in range(1, 6)]
print(kuadrat) # [1, 4, 9, 16, 25]
genap = [x for x in range(10) if x % 2 == 0]
print(genap) # [0, 2, 4, 6, 8]
النمط: [تعبير for عنصر in iterable]، مع تصفية اختيارية بـ if.
للـقاموس (dict) استخدم {مفتاح: قيمة for ...}؛ وللـمجموعة (set) استخدم {...}:
panjang = {kota: len(kota) for kota in ["jakarta", "bali", "medan"]}
print(panjang)
unik = {huruf.lower() for huruf in "Halo Dunia" if huruf != " "}
print(sorted(unik))
تعطي enumerate رقمًا تسلسليًا؛ وتسير zip على قائمتين معًا:
buah = ["apel", "mangga", "jeruk"]
for nomor, nama in enumerate(buah, start=1):
print(f"{nomor}. {nama}")
nama = ["Eko", "Siti"]
umur = [36, 25]
for n, u in zip(nama, umur):
print(f"{n} berusia {u} tahun")
كلتاهما تعيدان مكرِّرًا (iterator)، فهما موفّرتان للذاكرة. وتتوقف zip عند أقصر قائمة.
يمكن كتابة الشرط البسيط في سطر واحد؛ أما فك التجميع (unpacking) فيوزّع تسلسلًا على عدة متغيرات:
umur = 20
print("dewasa" if umur >= 18 else "anak")
a, b = 1, 2
a, b = b, a # تبديل دون متغير مساعد
print(a, b)
kepala, *ekor = [1, 2, 3, 4]
print(kepala, ekor) # 1 [2, 3, 4]
تستطيع f-string ضبط تنسيق الأرقام والمحاذاة:
nilai = 1234567.891
print(f"{nilai:,.2f}") # 1,234,567.89
print(f"{0.87:.1%}") # 87.0%
print(f"{42:05d}") # 00042
print(f"{'kanan':>10}|")
print(f"{'kiri':<10}|")
عامل walrus := يُسند القيمة أثناء الاختبار:
data = [1, 2, 3, 4, 5, 6]
if (n := len(data)) > 3:
print(f"ada {n} item")
from collections import Counter
kata = "susu roti susu teh roti susu".split()
print(Counter(kata).most_common(2))
pengguna = {"nama": "Eko"}
print(pengguna.get("kota", "tidak diketahui"))
harga = {"beras": 12000, "gula": 15000, "minyak": 18000}، أنشئ قاموسًا جديدًا يحوي الأسعار بعد خصم 10%.zip مع استيعاب القاموس لمزاوجة ["a", "b", "c"] مع [1, 2, 3].["Nasi Goreng", "Mie Ayam", "Sate"] باستخدام enumerate.hasil = []
for x in range(1, 11):
if x % 3 == 0:
hasil.append(x * x)
# 1
print([x ** 2 for x in range(1, 11) if x % 2 == 1])
# 2
harga = {"beras": 12000, "gula": 15000, "minyak": 18000}
print({nama: int(bayar * 0.9) for nama, bayar in harga.items()})
# 3
kunci = ["a", "b", "c"]
nilai = [1, 2, 3]
print({k: v for k, v in zip(kunci, nilai)})
# 4
for nomor, item in enumerate(["Nasi Goreng", "Mie Ayam", "Sate"], start=1):
print(f"{nomor}. {item}")
# 5
print([x * x for x in range(1, 11) if x % 3 == 0])
enumerate تعطي الترقيم؛ وzip تسير على عدة تسلسلات معًا.a if شرط else b للشروط القصيرة.* تجمع المتبقي.:= يُسند القيمة ويختبرها معًا.في الباب التالي نقسّم البرنامج إلى وحدات وحزم يمكن استيرادها.