Skip to main content

اے آئی کے دور میں Python: ایک فوری کورس

17 تصورات · لکھنے سے پہلے پڑھیں

آپ نے پہلے ہی ایجنٹی کوڈنگ فوری کورس میں AI کوڈنگ ایجنٹ چلانا سیکھ لیا ہے۔ آپ ایک سیشن کھول سکتے ہیں، Claude Code یا OpenCode کو ایک ہدایت دے سکتے ہیں، اور اسے فائلوں میں ترمیم کرنے اور کمانڈز چلانے کو دیکھ سکتے ہیں۔ تو یہاں ایک ایماندار سوال ہے جس کا جواب دینے کے لیے یہ کورس موجود ہے:

اگر ایجنٹ Python لکھتا ہے، تو آپ کو کسی بھی Python کو سیکھنے کی کیا ضرورت ہے؟

کیونکہ کسی نے اسے پڑھنا ہے۔ ایجنٹ سیکنڈوں میں کام کرنے والے کوڈ کی سینکڑوں لائنیں تیار کرتا ہے۔ اور "کام کرنے والا" پھندا ہے۔ AI قابل یقین کے لیے بہتر بناتا ہے، درست کے لیے نہیں۔ وہ کوڈ جو خاموشی سے غلط نمبر لوٹاتا ہے، ریکارڈ گرا دیتا ہے، یا آپ کی API کلید کو لیک کرتا ہے بالکل اس کوڈ کی طرح لگتا ہے جو کام کرتا ہے۔ فرق صرف وہی شخص بتا سکتا ہے جو پڑھ سکتا ہے کہ ایجنٹ نے کیا لکھا ہے اور ثابت کر سکتا ہے کہ وہ وہی کرتا ہے جو ان کا مطلب تھا۔

اب سارا کام یہی ہے۔ خالی صفحے سے لوپ ٹائپ نہیں کرنا۔ ایجنٹ ایسا کرتا ہے۔ آپ کا کام وہ حصہ ہے جو اب بھی ایک انسان کی ضرورت ہے: فیصلہ کرنا کہ درست کا کیا مطلب ہے، اور یہ تصدیق کرنا کہ تیار کردہ کوڈ اس پر پورا اترتا ہے۔

جہاں یہ کورس بیٹھتا ہے۔

یہ AI دور میں پروگرامنگ کا گیٹ وے ہے۔ کتاب کا وہ حصہ 3-5 ماہ کا گہرا کورس ہے جو ایک Project (SmartNotes) کے ارد گرد بنایا گیا ہے۔ یہ فوری کورس 80%-ان-ون-پڑھنے والا ورژن ہے: آج ہی ایجنٹ کوڈ پڑھنا شروع کرنے کے لیے Python کی خواندگی کافی ہے۔ یہ بعد آتا ہے ایجنٹی کوڈنگ اور پہلے AI ایجنٹس بنائیں، AI کے لیے پوسٹگریس، اور ڈی کیٹل ٹیجی ٹیجی تعمیر، جن میں سے تینوں فرض کرتے ہیں کہ آپ Python کو ایک ایجنٹ کی تخلیق کو پڑھ سکتے ہیں۔ یہاں کسی بھی موضوع کے مکمل علاج کے لیے، اس کورس کے لنکس پر عمل کریں۔

ایک خیال جو ذیل میں ہر چیز کو منظم کرتا ہے: پرانی دنیا میں، آپ نے Python کو لکھ کر سیکھا۔ یہاں آپ اسے پڑھ کر سیکھتے ہیں: پیش گوئی کرنا کہ کوڈ کیا کرتا ہے، اسے چلاتا ہے، اس کی تحقیقات کیوں کرتا ہے، پھر اسے تبدیل کرتا ہے اور آخر کار اپنا بناتا ہے۔ ہمارے پاس اس لوپ کا ایک نام ہے، اور یہ پورے کورس کی ریڑھ کی ہڈی ہے۔

اس کورس میں ہر وہ چیز ہے جو آپ کلاؤڈ کوڈ سیشن کے اندر کرتے ہیں، نہ کہ صرف اس کے بارے میں پڑھتے ہیں۔ claude چلتے ہوئے ٹرمینل کو کھلا رکھیں اور ہر آئیڈیا کو اس تک پہنچنے کے بعد آزمائیں۔

اس کورس میں ہر وہ چیز ہے جو آپ OpenCode سیشن کے اندر کرتے ہیں، نہ کہ صرف اس کے بارے میں پڑھتے ہیں۔ opencode چلتے ہوئے ٹرمینل کو کھلا رکھیں اور ہر آئیڈیا کو اس تک پہنچنے کے بعد آزمائیں۔ اگر آپ لاگت دیکھ رہے ہیں، تو اسے ایک سستے ماڈل کی طرف اشارہ کریں جیسے deepseek-v4-flash معمول کے چلانے کے لیے (ایجنٹک کوڈنگ کورس دیکھیں)۔


اپنے ماحول کو ترتیب دیں (ایک بار)

اس کورس میں ایک چھوٹا ساتھی ہے جسے آپ ایک بار ڈاؤن لوڈ کرتے ہیں: کورس بیس۔ آپ کو ساتھ ساتھ پڑھنے کے لیے اس کی سختی سے ضرورت نہیں ہے، لیکن یہ ہر چیز کو کورس کے فرض کے مطابق برتاؤ کرتا ہے۔ یہ ایک مختصر قواعد کی فائل بھیجتا ہے، AGENTS.md، جو آپ کے ایجنٹ کو نظم و ضبط والے ٹیوٹر میں بدل دیتا ہے جس پر یہ کورس انحصار کرتا ہے: یہ اس کے ظاہر ہونے سے پہلے پیشین گوئی کرتا ہے، جوابات کے بجائے اشارے دیتا ہے، اور کبھی بھی خاموشی سے کسی امتحان کو پاس کرنے کے لیے کمزور نہیں کرتا ہے۔ آپ کا ایجنٹ اس فائل کو ہر بار شروع ہونے پر خود بخود پڑھتا ہے، یہی وجہ ہے کہ یہاں آپ کے اشارے مختصر رہ سکتے ہیں۔ بیس میں پریکٹس Project شروع کرنے والے اور ایک جوابی کلید بھی ہوتی ہے جس کے خلاف آپ اپنے ٹیسٹ چیک کر سکتے ہیں۔

python-crash-course-base.zip ڈاؤن لوڈ کریں

اسے کھولیں، پھر اپنے ایجنٹ کو فولڈر کے اندر کھولیں:

cd python-crash-course
claude
cd python-crash-course
opencode

بیس جہازوں پر توجہ دیں ** ابھی تک کوئی Python Project نہیں**، جان بوجھ کر۔ کسی بھی چیز سے اپنا ورک بینچ بنانا پہلی حقیقی مہارت ہے، اور یہ آپ کے بعد کا کام ہے، تصور 3 میں۔ ابھی کے لیے، صرف اپنے ایجنٹ کو فولڈر میں کھولیں اور تصدیق کریں کہ اس نے قواعد کو لوڈ کیا ہے:

اس سیشن کے لیے آپ کن اصولوں کی پیروی کر رہے ہیں؟

اس میں آپ کے لکھنے سے پہلے پڑھنے کا طریقہ اور تصدیق کرنے کے لیے ٹیسٹ چلانے کی عادت کو بیان کرنا چاہیے۔ ہو گیا جب آپ کا ایجنٹ ان اصولوں کے ساتھ جواب دیتا ہے۔ (اس کے بجائے ایک ننگے فولڈر سے شروع کرنے کو ترجیح دیں؟ یہ بھی کام کرتا ہے؛ آپ جاتے وقت نظم و ضبط خود ترتیب دیں گے۔)


حصہ 1: نئی ذہنیت

1. آپ کوڈ پڑھتے ہیں؛ ایجنٹ اسے لکھتا ہے

روایتی Python کورسز میں، تربیت کی جانے والی مہارت پروڈکشن ہے: فنکشن ٹائپ کریں، لوپ ٹائپ کریں، کلاس ٹائپ کریں۔ AI نے اس رکاوٹ کو دور کیا۔ مہارت جو اب اہم ہے وہ ہے سمت اور تصدیق۔

پرانی نوکری (زیادہ تر اب خودکار)نئی نوکری (اب بھی آپ کی ہے)
ایک خالی صفحہ سے عمل درآمد ٹائپ کریں۔ واضح طور پر بیان کریں کہ آپ کیا چاہتے ہیں، ایجنٹ اس پر عمل کر سکتا ہے۔
نحو کو یاد رکھیںتنقیدی طور پر پڑھنے کے لیے نحو کو اچھی طرح سے پہچانیں
چلانے کے لیے کوڈ حاصل کریںثابت کریں کہ کوڈ درست ہے، نہ صرف چلنے کے قابل

یہ پروگرامنگ پر لاگو 10-80-10 اصول ہے۔ آپ کے پاس پہلا 10% ہے (یہ فیصلہ کرنا کہ کیا بنانا ہے اور "درست" کا کیا مطلب ہے) اور آخری 10% (اس کی تصدیق کرنا)۔ ایجنٹ بیچ میں 80% کا مالک ہے (کوڈ تیار کرنا)۔ روانی سے پڑھنا وہی ہے جو آپ کو دونوں سروں کو برقرار رکھنے دیتا ہے۔ The 10-80-10 rule: you own the first 10% (decide what's correct) and the last 10% (verify); the agent owns the 80% in the middle (generate the code).

! ایجنٹ بیچ میں 80% کا مالک ہے (کوڈ تیار کریں)۔](/img/python-crash-course/ten-Eighty-ten.png)

آپ کو کچھ بھی یاد کرنے کی ضرورت نہیں ہے۔

پڑھنا لکھنے سے کہیں زیادہ آسان ہے۔ آپ کو کسی بھی چیز سے یاد کرنے کی ضرورت نہیں ہے کہ فہرست مربع بریکٹ استعمال کرتی ہے۔ جب آپ اسے دیکھتے ہیں تو آپ کو صرف ایک فہرست کے طور پر پہچان ["a", "b"] کی ضرورت ہوتی ہے۔ یہ اس پورے کورس کے لیے بار ہے: پہچان، یاد نہیں۔

2. PRIMM-AI+ طریقہ

یہ PRIMM-AI+ یہ ہے کہ آپ خالی صفحے کو دیکھے بغیر کوڈ پڑھنا سیکھتے ہیں۔ Python کا ہر نیا ٹکڑا پانچ مراحل سے گزرتا ہے، اور ایجنٹ ہر ایک میں آپ کا ساتھی ہوتا ہے:

مرحلہخطآپ کیا کرتے ہیںایجنٹ کا کردار
پیش گوئیپیکچھ بھی چلنے سے پہلے، اندازہ لگائیں کہ کوڈ کیا کرے گاخاموش رہتا ہے - یہ آپ کا اندازہ ہے
چلائیںآراسے چلائیں اور اصلی آؤٹ پٹ دیکھیںآپ کے لیے کوڈ پر عمل کرتا ہے
تفتیشمیںاپنے اندازے کا حقیقت سے موازنہ کریں۔ پوچھیں کیوںلائن بہ لائن وضاحت کرتا ہے، مطالبہ پر
ترمیم کریںایمایک چیز بدلیں، دوبارہ پیش گوئی کریں، دوبارہ چلائیںوہ ترمیم کرتا ہے جسے آپ بیان کرتے ہیں
بناؤایمشروع سے اپنے ورژن کی وضاحت کریں؛ ایجنٹ کو اسے بنانے دیں۔ تصدیق کریںآپ کی قیاس کے خلاف پیدا کرتا ہے
The PRIMM-AI+ loop: Predict, Run, and Investigate build reading fluency; Modify and Make direct the agent; the loop repeats.

یہ AI+ وہ حصہ ہے جو اسے ایک پرانے طریقہ تدریس کا AI-era ورژن بناتا ہے۔ کلاسک PRIMM کے اوپر دو چیزیں رکھی گئی ہیں: ایجنٹ ہمیشہ پڑھنے والے پارٹنر کے طور پر دستیاب ہوتا ہے ("لائن 3 کی وضاحت کریں،" "اس سے کیا ٹوٹے گا؟")، اور ایمان پر کچھ بھی قبول نہیں کیا جاتا ہے۔ Predict-Run-Investigate آپ کے پڑھنے کی روانی کو بڑھاتا ہے؛ Modify-Make وہ جگہ ہے جہاں آپ ایجنٹ کو ہدایت دینا شروع کرتے ہیں۔ آخر تک، Make اتنا ہی قدرتی محسوس ہوتا ہے جیسا کہ Predict اب کرتا ہے۔

جہاں ٹیسٹنگ فٹ بیٹھتی ہے: ہر جگہ۔ وہ انجن جو تحقیق، تبدیل اور میک کو طاقت دیتا ہے وہ ٹیسٹ ہے: ایک مختصر چیک جو اس بات کو پن کرتا ہے کہ "درست" کا کیا مطلب ہے، لہذا کمپیوٹر ایجنٹ کے کام کی تصدیق کر سکتا ہے بجائے اس کے کہ آپ اس پر نظر ڈالیں۔ یہ ایک قدم نہیں ہے جسے آپ ایک بار آخر میں کرتے ہیں۔ آپ کے پڑھے ہوئے اگلے ہی فنکشن کے ساتھ شروع کرتے ہوئے، ایک چھوٹا سا ٹیسٹ چلتا ہے: پہلے ایک واحد assert لائن (تصور 5) کے طور پر، پھر آبجیکٹ (تصور 8) اور توثیق کے اصول (تصور 11) کے طور پر، اور آخر میں مکمل ٹیسٹ سے چلنے والی جنریشن لوپ کے طور پر جہاں آپ ٹیسٹ پہلے لکھتے ہیں اور ایک کوڈ کو پاس کرتے ہیں۔ کوڈ کے ہر ٹکڑے کے ساتھ ایجنٹ آپ کو ناقابل اعتماد سمجھیں جب تک کہ آپ کے لکھے ہوئے ٹیسٹ میں کوئی اور بات نہ ہو۔

پیشن گوئی اختیاری نہیں ہے۔

جبلت یہ ہے کہ سیدھے بھاگ جائیں: صرف جواب دیکھیں۔ مت کرو. آپ کی پیشین گوئی اور حقیقی پیداوار کے درمیان فرق وہ جگہ ہے جہاں سیکھنا ہوتا ہے۔ ایک غلط پیشین گوئی آپ کو بتاتی ہے کہ آپ کے ذہنی ماڈل کا کون سا حصہ ٹوٹا ہے، اس سے کہیں زیادہ بہتر ہے جو کبھی صحیح ہو سکتا ہے۔ اونچی آواز میں، تحریری طور پر، یا ایجنٹ سے پیش گوئی کریں۔ پھر بھاگو۔

3. آپ کا ورک بینچ پانچ منٹ میں

سردی کی آمد؟ پہلے ایجنٹ کو پکڑو

یہ کورس فرض کرتا ہے کہ آپ نے ایجنٹی کوڈنگ فوری کورس کیا ہے، جہاں آپ ایجنٹ کو انسٹال کرتے اور چلانا سیکھتے ہیں۔ اگر آپ نے سیدھے یہاں چھوڑ دیا ہے اور ابھی تک کچھ بھی انسٹال نہیں کیا ہے تو آگے جانے سے پہلے ایک کوڈنگ ایجنٹ سیٹ کریں۔ وہ واحد ٹول آپ کے لیے باقی سب کچھ انسٹال کر دے گا:

  • یہ Claude Code: docs.claude.com/en/docs/claude-code پر آفیشل گائیڈ کی پیروی کریں (WSL کے ذریعے macOS، Linux اور Windows پر کام کرتا ہے)۔
  • یہ OpenCode (اوپن سورس متبادل): opencode.ai۔
  • یہ uv (خود Python + پیکجز): docs.astral.sh/uv; یا اگلے مرحلے میں ایجنٹ کو آپ کے لیے اسے انسٹال کرنے دیں۔

آپ کو ان میں سے کسی بھی ٹول کو گہرائی سے سمجھنے کی ضرورت نہیں ہے۔ ایک ایجنٹ انسٹال کریں، اسے فولڈر میں کھولیں، اور جاری رکھیں۔ اس حصے کے باقی حصے میں ایجنٹ سیٹ اپ کرتا ہے۔

آپ کو تین چیزوں کی ضرورت ہے: Python کو چلانے کا طریقہ، چند معیاری ٹولز، اور آپ کا ایجنٹ۔ ایک انسٹالر پہلے دو کا احاطہ کرتا ہے: uv، ایک تیز پیکیج مینیجر جو Python خود انسٹال کرتا ہے اور آپ کے Project کا انتظام کرتا ہے۔

انہیں میموری سے ہاتھ سے انسٹال نہ کریں - یہ بالکل اسی قسم کا فڈلی سیٹ اپ ہے جس میں ایجنٹ اچھا ہے۔ اس فولڈر میں جہاں آپ نے اپنا ایجنٹ کھولا ہے، اسے ایک ہدایت دیں:

uv کا استعمال کرتے ہوئے یہاں ایک نیا Python Project ترتیب دیں۔ ٹیسٹ کے لیے pytest، ٹائپ چیکنگ کے لیے pyright، اور فارمیٹنگ کے لیے ruff شامل کریں۔ ایک hello.py بنائیں جو "تیار" پرنٹ کرے۔ پھر اسے چلائیں اور مجھے آؤٹ پٹ دکھائیں۔

ایجنٹ uv کمانڈز چلائے گا، فائلیں بنائے گا، اور اسکرپٹ چلائے گا۔ آپ ہر قدم کو دیکھتے اور منظور کرتے ہیں۔ وہ آپ کا ورک بینچ ہے۔ آپ نے ایک حکم بھی حفظ نہیں کیا۔

انہیں میموری سے ہاتھ سے انسٹال نہ کریں - یہ بالکل اسی قسم کا فڈلی سیٹ اپ ہے جس میں ایجنٹ اچھا ہے۔ اس فولڈر میں جہاں آپ نے اپنا ایجنٹ کھولا ہے، اسے ایک ہدایت دیں:

uv کا استعمال کرتے ہوئے یہاں ایک نیا Python Project ترتیب دیں۔ ٹیسٹ کے لیے pytest، ٹائپ چیکنگ کے لیے pyright، اور فارمیٹنگ کے لیے ruff شامل کریں۔ ایک hello.py بنائیں جو "تیار" پرنٹ کرے۔ پھر اسے چلائیں اور مجھے آؤٹ پٹ دکھائیں۔

یہ OpenCode uv کمانڈز چلائے گا، فائلیں بنائے گا، اور اسکرپٹ کو چلائے گا۔ آپ ہر قدم کو دیکھتے اور منظور کرتے ہیں۔ وہ آپ کا ورک بینچ ہے۔ آپ نے ایک حکم بھی حفظ نہیں کیا۔

یہ اصل میں کیسا لگتا ہے۔

تم خاموشی سے نہیں دیکھتے۔ ایجنٹ ہر قدم کو بیان کرتا ہے اور کچھ چلانے سے پہلے پوچھتا ہے۔ ایک حقیقی سیشن تقریباً اس طرح لگتا ہے (Claude Code دکھایا گیا ہے؛ OpenCode تقریباً ایک جیسا ہے):

> Set up a new Python project here using uv. Add pytest, pyright, ruff.
Create a hello.py that prints "ready", run it, and show the output.

● I'll initialize the project with uv.
$ uv init . ← the agent proposes a command
Allow? (y/n) y ← you approve
Initialized project

● $ uv add --dev pytest pyright ruff
Allow? (y/n) y
+ pytest + pyright + ruff

● Created hello.py:
print("ready")

● $ uv run hello.py ← this is how a Python file gets run
ready ← the output prints right here

Done. Your workbench is ready.

تین چیزیں قابل توجہ ہیں، کیونکہ وہ جسمانی لوپ ہیں آپ تمام کورس کو دہرائیں گے:

  • کوڈ فائل میں رہتا ہے (hello.py)، چیٹ ونڈو میں نہیں۔
  • آپ uv run hello.py کے ساتھ ایک فائل چلاتے ہیں: کہ ایک کمانڈ اس کورس میں ہر اسکرپٹ اور مثال پر عمل کرتی ہے۔
  • ایجنٹ ہر کمانڈ سے پہلے اجازت مانگتا ہے، پھر نیچے آؤٹ پٹ پرنٹ کرتا ہے۔ آپ منظور کرتے ہیں، آپ نتیجہ پڑھتے ہیں۔

So whenever an example below says "run it," you have two easy options: paste the code into a file and tell the agent "run this file and show me the output," or simply paste the snippet into the chat and say "run this and show me what it prints." Either way, you never type Python by hand.

اگر سیٹ اپ ناکام ہوجاتا ہے - آپ اسے ڈیبگ نہیں کرتے، ایجنٹ کرتا ہے۔

اگر کوئی بھی قدم سرخ غلطی پھینکتا ہے، تو آپ کو اسے سمجھنے کی ضرورت نہیں ہے۔ سرخ متن کو کاپی کریں، اسے واپس چسپاں کریں، اور کہیں: "یہ ناکام ہوگیا۔ غلطی کو پڑھیں اور اسے ٹھیک کریں۔" اگر ایجنٹ رپورٹ کرتا ہے کہ uv انسٹال نہیں ہے، تو اسے پہلے uv انسٹال کرنے کو کہیں۔ غیر پھنسنا ایجنٹ کا کام ہے۔ یہ دیکھنا کہ آپ پھنس گئے ہیں آپ کا ہے۔

یہاں یہ ہے کہ ہر ٹول ایک لائن میں کیا کرتا ہے۔ یہاں سے آپ چاروں کا مسلسل ذکر کرتے ہوئے دیکھیں گے:

ٹولیہ آپ کے لیے کیا کرتا ہے
uvPython اور آپ کے Project کے پیکجز کو انسٹال کرتا ہے، تیزی سے
pytestآپ کے ٹیسٹ اور رپورٹس چلاتے ہیں جو پاس ہوئے اور کون ناکام
Pyrightکوڈ میں قسم کے لیبلز کو پڑھتا ہے اور اسے چلانے سے پہلے ہی جھنڈا لگاتا ہے۔
رفسٹائل اور فارمیٹنگ چیک کرتا ہے، کوڈ کے لیے ایک ہجے چیک کرنے والا
یہ پڑھنے کے لیے کیوں اہمیت رکھتا ہے۔

یہ Pyright اور Ruff پڑھنے والی مشینیں ہیں۔ جب ایجنٹ کوڈ تیار کرتا ہے، تو یہ ٹولز اسے آپ کے لیے پڑھتے ہیں اور غلطیوں کی پوری کلاس کو فوری طور پر پکڑ لیتے ہیں: ایک غلط قسم، ایک غیر استعمال شدہ متغیر، ٹائپ شدہ نام۔ وہ آپ کی تصدیق کی پہلی سطر ہیں، اس سے پہلے کہ آپ خود کوئی سطر پڑھ لیں۔ (مکمل سیٹ اپ واک تھرو: AI دور میں پروگرامنگ، فیز 1: ورک بینچ۔

دیکھیں آپ کی پڑھنے والی مشینیں کچھ پکڑتی ہیں۔

یہ اوزار خلاصہ نہیں ہیں۔ ایجنٹ سے ایک چھوٹا فنکشن لکھنے کو کہیں اور پھر اسے غلط قسم کی ویلیو کے ساتھ کال کریں:

def total_with_tax(price: float, tax_rate: float) -> float:
return price + (price * tax_rate)

total_with_tax("100", 0.15) # oops — "100" is text, not a number

اس پر pyright چلائیں اور آپ کو یہ کوڈ کے مکمل ہونے سے پہلے مل جائے گا:

error: Argument of type "Literal['100']" cannot be assigned to
parameter "price" of type "float" (reportArgumentType)

یہ Pyright نے قسم کے اشارے پڑھے، دیکھا کہ متن کو پاس کیا گیا جہاں float کا وعدہ کیا گیا تھا، اور فوری طور پر مماثلت کو پکڑ لیا۔ رف ایک مختلف قسم کی پرچی پکڑتا ہے: بچا ہوا بے ترتیبی ایجنٹ کبھی کبھی پیچھے چھوڑ دیتا ہے:

F401  `os` imported but unused

آپ کو یہ پیغامات یاد نہیں ہیں۔ آپ انہیں اس طرح پڑھتے ہیں جس طرح آپ ہجے چیک کرنے والے کی انڈر لائن پڑھتے ہیں: یہاں کچھ فٹ نہیں بیٹھتا ہے، اور یہ بالکل درست لائن کی طرف اشارہ کر رہا ہے۔ جب ایجنٹ ایک سو لائنیں بناتا ہے، تو یہ دونوں ٹولز ایک سیکنڈ کے اندر اس سب کو پڑھتے ہیں، یہی وجہ ہے کہ وہ آپ کو خود پڑھنا شروع کرنے سے پہلے ہی بھاگتے ہیں۔


حصہ 2: وہ شکلیں جو آپ کو ہر جگہ نظر آئیں گی۔

یہ وہ بنیادی شکلیں ہیں جو شاید تمام Python کا 70% بنتی ہیں جنہیں آپ کبھی پڑھ سکتے ہیں۔ ہر ایک کو Pedict → Run → Investigate کے ساتھ آگے بڑھیں: اسے پڑھیں، آؤٹ پٹ کا اندازہ لگائیں، پھر اسے چیک کرنے کے لیے اپنے سیشن میں چلائیں۔

4. قدریں، متغیرات، اور چار اقسام

یہ A متغیر ایک لیبل والا باکس ہے جو ایک قدر رکھتا ہے۔ = نشان کا مطلب ہے "دائیں طرف کی قدر کو بائیں طرف والے باکس میں ڈالیں": یہ ریاضی کے معنی میں نہیں "برابر" ہے۔ ہر قدر کی ایک قسم ہوتی ہے، اور ابھی کے لیے آپ کو پہچاننے کی ضرورت صرف چار ہیں۔ ہم نام کے بعد ٹائپ کو name: type کے طور پر لکھتے ہیں، تاکہ آپ اور ایجنٹ دونوں ایک نظر میں دیکھ سکیں کہ ہر باکس کا مطلب کیا ہے:

name: str = "Ayesha"        # str   — text, always in quotes
age: int = 30 # int — a whole number
price: float = 19.99 # float — a number with a decimal point
is_active: bool = True # bool — only ever True or False

: str، : int، : float، : bool حصے قسم کے اشارے ہیں۔ یہ Python میں اختیاری ہیں، لیکن اس پورے کورس میں ہم ہمیشہ انہیں شامل کرتے ہیں: جزوی طور پر اس لیے کہ وہ کوڈ کو پڑھنا آسان بناتے ہیں، اور جزوی طور پر اس لیے کہ جیسا کہ آپ Concept 10 میں دیکھیں گے، وہ یہ ہیں کہ آپ ایجنٹ کو بالکل بتاتے ہیں کہ کیا بنانا ہے۔ ابھی کے لیے، name: str کو سادہ انگریزی کے طور پر پڑھیں: "باکس name متن رکھتا ہے۔"

پیش گوئی: آپ کے خیال میں یہ پرنٹ کیا ہے؟

age: int = 30
age = age + 1
print(age)

اسے چلائیں۔ آؤٹ پٹ 31 ہے۔ تحقیقات کریں: لائن age = age + 1 ناممکن نظر آتی ہے اگر آپ = کو "برابر" کے طور پر پڑھتے ہیں: 30 31 کے برابر نہیں ہو سکتا۔ لیکن = کا مطلب ہے تفویض: age (30) کی موجودہ قیمت لیں، نتیجہ 1 شامل کریں، اور 31 کو واپس ڈالیں۔ دائیں طرف پہلے چلتا ہے، پھر باکس کو اپ ڈیٹ کیا جاتا ہے. (دیکھیں کہ ہم نے صرف ٹائپ اشارہ لکھا ہے : int پہلی بار age ظاہر ہوا؛ ایک بار باکس میں ایک قسم آجانے کے بعد، آپ اسے ہر دوبارہ تفویض پر نہیں دہرائیں گے۔) یہ خیال شروع میں تقریباً ہر کسی کو متاثر کرتا ہے، اسی وجہ سے آپ نے پہلے اس کی پیش گوئی کی تھی۔

پڑھنے کی حرکت

جب آپ x = something دیکھیں تو اسے دائیں سے بائیں پڑھیں: "something کا حساب لگائیں، پھر اسے x میں اسٹور کریں۔" بائیں طرف کا نام صرف ایک لیبل ہے۔

5. افعال اور ان کے دستخط

ایک فنکشن ایک نام کے ساتھ کوڈ کا دوبارہ قابل استعمال بلاک ہے۔ آپ اسے ان پٹ دیتے ہیں (جسے دلائل کہتے ہیں)، یہ آپ کو ایک آؤٹ پٹ واپس دیتا ہے۔ پہلی سطر، دستخط، سب سے اہم سطر ہے جسے آپ پڑھنا سیکھیں گے، کیونکہ یہ ایک معاہدہ ہے:

def total_with_tax(price: float, tax_rate: float) -> float:
return price + (price * tax_rate)

دستخط ٹکڑے ٹکڑے ٹکڑے کر کے پڑھیں:

  • def: "میں ایک فنکشن کی وضاحت کر رہا ہوں۔"
  • total_with_tax: اس کا نام۔
  • (price: float, tax_rate: float): یہ دو ان پٹ لیتا ہے، دونوں اعشاریہ۔ : float حصہ ایک قسم کا اشارہ ہے (تصور 10 میں ان پر مزید)۔
  • -> float: یہ ایک اعشاریہ واپس دیتا ہے۔

ایک ہی سانس میں: "مجھے قیمت اور ٹیکس کی شرح دیں، دونوں اعشاریہ، اور میں آپ کو ایک اعشاریہ واپس دوں گا۔" آپ سمجھ سکتے ہیں کہ فنکشن کیا وعدہ کرتا ہے اس کے باڈی کی ایک لائن کو پڑھے بغیر۔ یہی وجہ ہے کہ جب آپ AI کوڈ کی تصدیق کر رہے ہوتے ہیں تو دستخط بہت اہمیت رکھتے ہیں۔ جسم غلط ہو سکتا ہے؛ دستخط آپ کو بتاتا ہے کہ اسے کیا کرنا چاہیے تھا۔

پیش گوئی کریں، پھر چلائیں:

def total_with_tax(price: float, tax_rate: float) -> float:
return price + (price * tax_rate)

print(total_with_tax(100.0, 0.15))

آؤٹ پٹ: 115.0. اگر آپ نے 115.0 کی پیش گوئی کی ہے، تو آپ پہلے ہی ایک فنکشن پڑھ سکتے ہیں۔

اسے ٹیسٹ کے ساتھ پن کریں۔

ایک فنکشن پہلی چیز ہے جسے آپ ثابت درست کر سکتے ہیں، کیونکہ اس کا ایک واضح معاہدہ ہے: ان ان پٹ کو دیکھتے ہوئے، اسے وہ آؤٹ پٹ واپس کرنا ہوگا۔ آپ اسے assert کے ساتھ بند کر دیتے ہیں: ایک سطری دعویٰ جو سچ ہونے پر کچھ نہیں کرتا اور جھوٹے ہونے پر زور سے کریش ہو جاتا ہے:

assert total_with_tax(100.0, 0.15) == 115.0   # "I claim this must equal 115.0"
assert total_with_tax(0.0, 0.15) == 0.0 # a free item costs nothing

ان دو لائنوں کو چلائیں اور آپ کو کچھ نہیں نظر آئے گا۔ خاموشی کا مطلب ہے ہر دعویٰ۔ 115.0 کو 999.0 میں تبدیل کریں اور یہ فوری طور پر کریش ہو جاتا ہے۔ یہ جانچنے کے پیچھے پورا خیال ہے: آپ ایک بار لکھتے ہیں کہ صحیح مطلب کیا ہے، اور کمپیوٹر ہر بار آپ کے لیے اسے دوبارہ چیک کرتا ہے۔ یہ دو لائنیں پہلے سے ہی ایک چھوٹی سی تفصیلات ہیں۔ ان کو پکڑو۔ تصور 16 میں آپ ایجنٹ کو یہ درست دعویٰ دیں گے اور اسے مطمئن کرنے کے لیے فنکشن لکھیں گے۔ (یہ کوئی حادثہ نہیں ہے: ٹیکس کا وہی فنکشن مکمل TDG سائیکل کے طور پر دوبارہ ظاہر ہوتا ہے۔)

6. مجموعے: گروپ بندی ڈیٹا

حقیقی کوڈ میں واحد اقدار نایاب ہیں۔ زیادہ تر ڈیٹا گروپس میں آتا ہے، اور چار کنٹینرز ہیں جو آپ بار بار دیکھیں گے:

notes: list[str] = ["buy milk", "call Sara", "finish report"]   # list  — ordered, can change
note: dict[str, str | bool] = {"title": "Meeting", "done": False} # dict — labeled pairs (key: value)
tags: set[str] = {"work", "urgent"} # set — unique items, no duplicates
point: tuple[int, int] = (3, 5) # tuple — ordered, cannot change

اشارے بتاتے ہیں کہ container کے اندر کیا ہے: list[str] “text کی list” ہے، dict[str, str | bool] “ایسا dict ہے جس کی keys text ہیں اور values یا تو text یا true/false ہیں” (| کا مطلب “or” ہے)، set[str] “text کا set” ہے، اور tuple[int, int] “پورے نمبروں کی pair” ہے۔ آپ کو یہ memory سے لکھنے کی ضرورت نہیں، آپ کو انہیں پڑھنا ہے۔

جن دو سے آپ سب سے زیادہ ملیں گے وہ ہیں فہرست (ایک ترتیب جسے آپ شامل کر سکتے ہیں اور دوبارہ ترتیب دے سکتے ہیں) اور ڈکٹ (لیبل لگائی گئی اقدار کا ایک مجموعہ: AI ایجنٹ کے پاس سے گزرنے والے ڈیٹا کے تقریباً ہر ٹکڑے کی ریڑھ کی ہڈی، کیونکہ یہ براہ راست JSON پر نقشہ بناتا ہے)۔

پیش گوئی کریں، پھر چلائیں:

note: dict[str, str | bool] = {"title": "Meeting", "done": False}
print(note["title"])
note["done"] = True
print(note)

آؤٹ پٹ:

Meeting
{'title': 'Meeting', 'done': True}

تحقیقات: note["title"] ڈکٹ میں پہنچتا ہے اور "title" لیبل والی قدر کو نکالتا ہے۔ دوسری لائن "done" لیبل والی قدر تبدیل کرتی ہے۔ ایک ڈکٹ یہ ہے کہ ایجنٹ آپ کو ایک نوٹ، صارف، ایک API جواب کیسے دے گا: نامزد فیلڈز کے ساتھ کچھ بھی۔

7. کنٹرول بہاؤ اور فہم

کوڈ if کے ساتھ فیصلے کرتا ہے، اور for کے ساتھ دہرایا جاتا ہے۔ انڈینٹیشن (لائن کے شروع میں خالی جگہیں) یہ ہے کہ Python کو کیسے معلوم ہوتا ہے کہ if یا for کے اندر کیا ہے۔ یہ سجاوٹ نہیں ہے، یہ ساخت ہے.

prices: list[int] = [10, 250, 50, 400]

for price in prices: # do this once for each price in the list
if price > 100: # decision
print(f"{price} is expensive")
else:
print(f"{price} is fine")

پیش گوئی کریں کہ آپ اسے چلانے سے پہلے کون سی لائنیں "مہنگی" پرنٹ کریں گے۔ (جواب: 250 اور 400۔)

ان میں سے دو لائنیں f-string کا استعمال کرتی ہیں: سامنے f کے ساتھ متن، جہاں {...} کے اندر کوئی بھی چیز اس کی قدر سے بدل جاتی ہے۔ تو f"{price} is expensive" موجودہ price کو جملے میں گراتا ہے۔ آپ f-strings مسلسل دیکھیں گے؛ بس تسلیم کریں کہ {name} کا مطلب ہے "اس قدر کا متن یہاں رکھیں۔"

جب کسی فیصلے کے دو سے زیادہ نتائج ہوتے ہیں، تو elif ("اور اگر" کے لیے مختصر) انہیں زنجیروں میں جکڑ دیتا ہے۔ Python ہر برانچ کو اوپر سے نیچے تک چیک کرتا ہے اور پہلے کو چلاتا ہے جو سچ ہے:

def grade_for(score: int) -> str:
if score >= 90:
return "A"
elif score >= 70:
return "B"
elif score >= 50:
return "C"
else:
return "F"

پیش گوئی grade_for(72)، پھر چلائیں۔ یہ "B" ہے: 72 >= 90 غلط ہے، لہذا یہ اگلی شاخ میں آتا ہے، 72 >= 70 سچ ہے، اور یہ وہیں رک جاتا ہے۔ ایک if/elif/else سلسلہ کو "ان ترتیب سے چیک کریں؛ پہلا میچ لیں۔" آپ کو and اور or - if score >= 70 and attended: کے ساتھ مل کر شرائط بھی نظر آئیں گی - if score >= 70 and attended: کا مطلب ہے کہ آپ کو فیصلہ کرنا ضروری ہے کہ دونوں کو درست ہونا ضروری ہے۔

ایک بار جب آپ for لوپ کو پڑھ سکتے ہیں، تو آپ Python میں واحد سب سے عام ون لائنر پڑھ سکتے ہیں: فہم۔ یہ صرف ایک for لوپ ہے جو ایک نئی فہرست کو بنانے کے لئے ایک لائن پر جوڑ دیا گیا ہے:

prices: list[int] = [10, 250, 50, 400]

# The long way:
expensive: list[int] = []
for price in prices:
if price > 100:
expensive.append(price)

# The comprehension — exactly the same result:
expensive = [price for price in prices if price > 100]

طویل version میں .append(price) list کے آخر میں price جوڑتا ہے؛ thing.action() والی شکل وہ method call ہے جسے آپ تصور 8 میں دیکھیں گے۔ comprehension کو بائیں سے دائیں پڑھیں: “مجھے price دیں، prices میں ہر price کے لیے، اگر price > 100۔” دونوں [250, 400] بناتے ہیں۔ آپ کو AI code میں ہر جگہ comprehensions نظر آئیں گی کیونکہ data cleaning اور reshaping ہی زیادہ تر کام ہے۔ اس شکل کو پہچاننے میں آرام محسوس کریں، اور آپ real Python کا بہت بڑا حصہ پڑھ سکیں گے۔

ایجنٹ کو ریڈنگ پارٹنر کے طور پر استعمال کریں۔

اپنے سیشن میں کوئی بھی ایسی لائن چسپاں کریں جسے آپ سمجھ نہیں پاتے ہیں: "اس لائن کی وضاحت کریں گویا میں نے کبھی کوڈ نہیں کیا ہے: [n['text'] for n in notes if n['done']]." یہ PRIMM-AI+ کا تحقیق مرحلہ ہے، مطالبہ پر۔ اسے مسلسل استعمال کریں۔ یہ کسی بھی حوالہ سے تیز ہے۔

8. کلاسز اور اشیاء، ایک بلیو پرنٹ پڑھنا

اب تک آپ کا ڈیٹا ڈھیلا ہے: ایک note ایک dict تھا، ایک price ایک فلوٹ تھا۔ ایک کلاس آپ کو متعلقہ ڈیٹا کو بنڈل کرنے دیتا ہے اور اس کے ساتھ تعلق رکھنے والے اعمال کو ایک نام کی شکل میں۔ ایک کلاس کو ایک بلیو پرنٹ اور ایک آبجیکٹ (جسے مثال بھی کہا جاتا ہے) کو اس بلیو پرنٹ سے بنی چیز کے طور پر سوچیں: ایک Note بلیو پرنٹ، اس سے بنائے گئے بہت سے اصل نوٹ۔

یہاں ایک کلاس ہے جو ایک ہی نوٹ کو ماڈل کرتی ہے:

class Note:
def __init__(self, title: str, body: str) -> None:
self.title = title # an attribute — data this note carries
self.body = body
self.done = False

def mark_done(self) -> None: # a method — an action this note can perform
self.done = True

اسے ٹکڑوں میں پڑھیں:

  • class Note:، بلیو پرنٹ کی وضاحت کرتا ہے، جس کا نام Note ہے۔
  • __init__: سیٹ اپ کا طریقہ۔ یہ ایک بار خود بخود چلتا ہے، جب آپ نیا نوٹ بناتے ہیں، اور ابتدائی ڈیٹا کو اسٹور کرتا ہے۔ (-> None کا مطلب ہے کہ یہ کچھ بھی واپس نہیں کرتا ہے؛ یہ صرف آبجیکٹ کو تشکیل دیتا ہے۔)
  • self: یہ خاص چیز۔ بلیو پرنٹ کے اندر، self.title کا مطلب ہے "اس نوٹ کا عنوان۔" ہر طریقہ پہلے self لیتا ہے لہذا یہ جانتا ہے کہ وہ کس چیز پر کام کر رہا ہے۔
  • self.title, self.body, self.done، صفات: ڈیٹا جو ہر نوٹ میں ہوتا ہے۔
  • mark_done، ایک طریقہ: ایک فنکشن جو کلاس کے اندر رہتا ہے اور آبجیکٹ پر کام کرتا ہے۔

اب ایک بنائیں اور اسے استعمال کریں۔ پیش گوئی آؤٹ پٹ کو چلانے سے پہلے:

n: Note = Note(title="Groceries", body="milk, eggs")
print(n.done)
n.mark_done()
print(n.done)

آؤٹ پٹ:

False
True

تحقیقات: Note(title="Groceries", body="milk, eggs") __init__ چلتا ہے اور n میں ذخیرہ شدہ ایک تیار شدہ چیز کو واپس کرتا ہے۔ n.done ایک وصف پڑھتا ہے؛ n.mark_done() ایک طریقہ کو کال کرتا ہے جو اسے تبدیل کرتا ہے۔ ڈاٹ (.) کا ہمیشہ ایک ہی مطلب ہوتا ہے: "اس چیز تک پہنچیں جس کا نام رکھا گیا ہو۔"

وہ ایک پیٹرن، object.attribute ڈیٹا کو پڑھنے کے لیے اور object.method() آبجیکٹ سے کچھ کرنے کے لیے کہنے کے لیے، سب سے زیادہ حقیقی Python کو کھول دیتا ہے۔ تقریباً ہر وہ چیز جو آپ ایجنٹ کوڈ میں پڑھیں گے وہ اشیاء ہیں: ایک Pydantic ماڈل ایک کلاس ہے، ایک ایجنٹ ایک آبجیکٹ ہے، ڈیٹا بیس کنکشن ایک آبجیکٹ ہے۔ جب آپ agent.run(task) یا db.save(note) دیکھتے ہیں، تو آپ پڑھ رہے ہیں "اس آبجیکٹ کو اس کے طریقوں میں سے ایک چلانے کے لئے کہیں۔" (مکمل آبجیکٹ ماڈل ہے AI دور میں پروگرامنگ، فیز 5۔)

اسے ٹیسٹ کے ساتھ پن کریں۔

آپ کسی چیز کی بالکل اسی طرح تصدیق کرتے ہیں جس طرح آپ نے تصور 5 میں فنکشن کی تصدیق کی ہے: اس بات پر زور دیں کہ طریقہ کار چلنے سے پہلے اور بعد میں اس کی حالت کیا ہونی چاہیے:

n: Note = Note(title="Groceries", body="milk, eggs")
assert n.done is False # a fresh note starts unfinished
n.mark_done()
assert n.done is True # ...and is finished after mark_done()

ایک ہی اقدام، نیا ہدف: ایک طریقہ صرف ایک فنکشن ہے جو کسی چیز سے منسلک ہوتا ہے، لہذا وہی ایک لائن assert ثابت کرتی ہے کہ یہ برتاؤ کرتا ہے۔ جب ایجنٹ آپ کے لیے کلاس لکھتا ہے، تو آپ اس طرح چیک کرتے ہیں کہ وہ وہی کرتا ہے جو آپ کا مطلب ہے۔

آپ ابھی تک کلاسز نہیں لکھتے، آپ انہیں پڑھتے ہیں۔

جیسا کہ اس کورس میں ہر چیز کی طرح، یہاں کا مقصد پہچان ہے۔ جب ایجنٹ ایک کلاس تیار کرتا ہے، تو آپ اس کی طرف اشارہ کرنے کے قابل ہونا چاہتے ہیں اور یہ کہنا چاہتے ہیں کہ "یہ سیٹ اپ کا طریقہ ہے، یہ اس کی خصوصیات ہیں، یہ ایک ایسا طریقہ ہے جو اس کی حالت کو بدل دیتا ہے۔" یہ تصدیق کرنے کے لیے کافی ہے کہ یہ وہی کرتا ہے جو آپ نے پوچھا ہے۔

9. مزید شکلیں جو آپ کو تیار کردہ کوڈ میں ملیں گی: while، سلائسنگ، try/except، اور input()

آپ ان چاروں کو شاذ و نادر ہی لکھیں گے، لیکن ایجنٹ انہیں مسلسل استعمال کرتا ہے، لہذا جب آپ اس کے آؤٹ پٹ کو پڑھ رہے ہوں اور اس کی تصدیق کر رہے ہوں تو آپ کو انہیں پہچاننے کی ضرورت ہے۔ ایک فوری پیشین گوئی → چلائیں → ہر ایک پر تفتیش کافی ہے۔

while: حالت تبدیل ہونے تک دہرائیں۔ جہاں ایک for لوپ ایک مجموعہ میں فی آئٹم ایک بار چلتا ہے، ایک while لوپ اس وقت تک چلتا رہتا ہے جب تک اس کی حالت درست رہتی ہے:

count: int = 3
while count > 0: # keep looping while this is true
print(count)
count = count - 1
print("done")

پیش گوئی کریں، پھر چلائیں۔ آؤٹ پٹ: 3، 2، 1، done. اسے "count > 0 کے دوران یہ کرتے رہیں۔" تیار کردہ کوڈ میں پہچاننے کے قابل ایک خطرہ: اگر شرط کبھی غلط نہیں ہوتی ہے، تو لوپ ہمیشہ کے لیے چلتا ہے، اس لیے جب آپ while دیکھتے ہیں، تو اس پر ایک نظر ڈالیں کہ آخر اسے کیا روکتا ہے۔

سلائسنگ: فہرست یا تار کا ایک ٹکڑا پکڑیں۔ مربع بریکٹ کے اندر بڑی آنت کا مطلب ہے "پوزیشنز کی ایک حد":

letters: list[str] = ["a", "b", "c", "d", "e"]
print(letters[1:3]) # from position 1 up to (not including) 3
print(letters[:2]) # the first two
print(letters[-1]) # the last one

پیش گوئی کریں، پھر چلائیں۔ آؤٹ پٹ: ['b', 'c']، ['a', 'b']، e۔ گنتی 0 سے شروع ہوتی ہے۔ [1:3] "1 سے لے کر 3 تک نہیں ہے"؛ -1 کا مطلب ہے "آخری والا۔" متن پر ایک ہی نحو کام کرتا ہے: "hello"[:3] "hel" ہے۔

**try / except: کچھ ایسا کرنے کی کوشش کریں جو ناکام ہوسکتی ہے۔ ** کچھ آپریشن اڑا سکتے ہیں: صفر سے تقسیم کرنا، گمشدہ فائل کو پڑھنا، نیٹ ورک کال کا وقت ختم ہونا۔ try/except خطرناک کوڈ چلاتا ہے اور کریش ہونے کی بجائے غلطی کو پکڑتا ہے:

def safe_divide(a: float, b: float) -> float:
try:
return a / b
except ZeroDivisionError: # if dividing by zero is attempted...
return 0.0 # ...do this instead of crashing

پیش گوئی safe_divide(10.0, 2.0) اور safe_divide(10.0, 0.0)، پھر چلائیں۔ آؤٹ پٹس: 5.0 اور 0.0۔ اسے بطور "آزمائیں؛ اگر یہ اس مخصوص طریقے سے ناکام ہوجاتا ہے تو اس کے بجائے ایسا کریں۔" آپ کو try/except کسی بھی چیز کے گرد لپٹا ہوا نظر آئے گا جو ایجنٹ کوڈ میں ناکام ہوسکتا ہے۔

input(): روکیں اور پڑھیں کہ صارف کیا ٹائپ کرتا ہے۔ انٹرایکٹو اسکرپٹس اور کمانڈ لائن ٹولز input() کا استعمال کرتے ہوئے اس شخص سے سوال پوچھتے ہیں اور جواب کا انتظار کرتے ہیں:

name: str = input("What's your name? ")   # waits here until the user types and presses Enter
print(f"Hello, {name}!")

پہچاننے کے لیے ایک چیز، اور ایک جگہ سے تیار کردہ کوڈ اکثر پھسل جاتا ہے، وہ یہ ہے کہ input() ہمیشہ متن واپس کرتا ہے، یہاں تک کہ جب صارف کوئی نمبر ٹائپ کرتا ہے۔ اس کے ساتھ ریاضی کرنے کے لیے، کوڈ کو پہلے اسے تبدیل کرنا چاہیے:

age_text: str = input("Your age? ")   # "30" comes back as text, not a number
age: int = int(age_text) # int(...) converts text to a whole number
print(f"Next year you'll be {age + 1}")

اگر آپ کبھی بھی input() کو int(...) یا float(...) کے بغیر ریاضی میں کھانا کھلاتے ہوئے دیکھتے ہیں، تو یہ جھنڈا لگانے کے لئے ایک مسئلہ ہے: پروگرام یا تو کریش ہو جائے گا یا متن کو شامل کرنے کے بجائے ایک ساتھ چپکائے گا۔

اسے ٹیسٹ کے ساتھ پن کریں۔

غلطی کا معاملہ بالکل اسی قسم کی چیز ہے جس کو پن کرنے کے قابل ہے: اس بات پر زور دیں کہ خطرناک ان پٹ کو سنبھالا گیا ہے، کریش نہیں ہوا:

def test_safe_divide() -> None:
assert safe_divide(10.0, 2.0) == 5.0
assert safe_divide(10.0, 0.0) == 0.0 # handled, not a crash
یہ تصدیق کے لیے کیوں ضروری ہیں۔

ہر شکل generated code کے غلط ہونے کی عام جگہ ہے: ایک while جو کبھی ختم نہیں ہوتا، ایک slice جو ایک نمبر سے ہٹ جاتا ہے ([1:3] آپ کو دو items دیتا ہے، تین نہیں)، ایک except جو وہ error خاموشی سے نگل لیتا ہے جس کے بارے میں آپ کو جاننا چاہیے تھا، یا ایک input() جس کا text math سے پہلے number میں convert ہی نہیں ہوتا۔ شکل کو پہچاننا ہی آپ کو ان جگہوں پر رک کر قریب سے دیکھنے دیتا ہے۔


حصہ 3: AI دور کے پاور تصورات

یہ تصورات وہ ہیں جو "ہیلو ورلڈ" Python کو Python سے الگ کرتے ہیں جو آپ اصل میں ایجنٹ اور ایم ایل کوڈ میں دیکھیں گے۔ ان میں سے زیادہ تر آپ ابھی شروع سے نہیں لکھیں گے۔ ایجنٹ ایسا کرتا ہے، اور آپ کا مقصد خالص تسلیم ہے: جب کوئی ظاہر ہوتا ہے، آپ کو معلوم ہوتا ہے کہ یہ کس کے لیے ہے اور تقریباً یہ کیا کرتا ہے۔ ایک استثناء پہلا ہے، قسم کے اشارے (تصور 10): جنہیں آپ کرتے ہیں لکھنا سیکھتے ہیں، کیونکہ وہ آپ ایجنٹ کو بالکل ٹھیک بتاتے ہیں کہ کیا بنانا ہے۔ (کئی پروڈکشن AI انجینئرز روزانہ استعمال کرنے والے پروڈکشن سے سیدھے کھینچے جاتے ہیں۔)

صرف پڑھنے کے لیے زون، گھبرائیں نہیں۔

رفتار یہاں جان بوجھ کر چھلانگ لگاتی ہے۔ دو صفحات پہلے آپ age = age + 1 پڑھ رہے تھے؛ اب آپ کو جنریٹر، توثیق کرنے والے، اور async نظر آئیں گے۔ یہ ٹھیک ہے۔ آپ سے اس میں سے کچھ لکھنے کی توقع نہیں ہے۔ تصورات 11-15 کے لیے آپ کا واحد کام ہر ایک شکل کو پہچاننا اور سادہ انگریزی میں کہنا ہے کہ یہ کس لیے ہے۔ اگر کوئی بلاک گھنا نظر آتا ہے، تو ایک سطر "اس کو اس طرح پڑھیں…" کا خلاصہ پڑھیں اور آگے بڑھیں۔ کوئی بھی ان کو حفظ نہیں کرتا؛ آپ ان کو تلاش کرنا سیکھیں۔

10. اشارے ٹائپ کریں، وہ لیبل جو ایجنٹ کو چلاتے ہیں۔

آپ تصور 5 میں ایک سے پہلے ہی مل چکے ہیں: price: float۔ ایک قسم کا اشارہ ایک لیبل ہے جو کہتا ہے کہ متغیر یا فنکشن کس قسم کے ڈیٹا کی توقع کرتا ہے۔ Python کو ان کی ضرورت نہیں ہے، لیکن AI دور میں وہ آپ کا سب سے طاقتور ٹول ہیں، ایک وجہ سے:

ٹائپ کے اشارے ایجنٹ کے لیے ہدایات ہیں۔ جب آپ ایجنٹ سے اس کو بھرنے کے لیے کہنے سے پہلے* اس طرح کے دستخط لکھتے ہیں۔

def summarize_notes(notes: list[dict], max_words: int) -> str:
... # the agent writes this part
  • آپ نے واضح طور پر اور غیر مبہم طور پر بتایا ہے کہ ان پٹ ڈکٹ کی ایک فہرست ہے، ایک لفظ کی حد ہے جو مکمل نمبر ہے، اور آؤٹ پٹ ایک تار ہے۔ ایجنٹ اب زیادہ کثرت سے صحیح چیز پیدا کرتا ہے، کیونکہ آپ نے اندازے کو ہٹا دیا ہے۔ اور Pyright ان لیبلز کو پڑھتا ہے اور کوڈ کے چلنے سے پہلے کسی بھی مماثلت کو جھنڈا دیتا ہے۔

یہ TDG کی شرائط میں (AI Era میں پروگرامنگ میں مکمل طور پر احاطہ کرتا ہے)، قسم کو لکھنا تفصیلات لکھنے کا حصہ ہے۔ یہ پہلا 10% ہے جو آپ کا ہے۔

ایک اچھے کی اناٹومی "اس کو پیدا کریں" کی درخواست

چونکہ قسمیں ہدایات ہیں، اس لیے مضبوط ترین کوڈ ایجنٹ کو تین چیزیں دینے کی درخواست کرتا ہے اور چوتھی چیز مانگتا ہے:

  1. دستخط، اقسام کے ساتھ: summarize_notes(notes: list[dict], max_words: int) -> str۔ یہ ان پٹ اور آؤٹ پٹ کو پن کرتا ہے لہذا کوئی اندازہ نہیں ہے۔
  2. ان پٹ → آؤٹ پٹ کی ایک یا دو مثالیں۔ (یہ آپ کے ٹیسٹ کے طور پر دوگنا ہیں۔)
  3. کوئی رکاوٹیں: "خالی فہرست کو ہینڈل کرنا ضروری ہے،" "نیٹ ورک کو کال نہ کریں،" "اسے 20 لائنوں کے نیچے رکھیں۔"
  4. اس سے تصدیق کرنے کے لیے کہیں: "پھر pytest اور pyright چلائیں اور مجھے نتیجہ دکھائیں۔"

ایک مبہم درخواست ("نوٹس کا خلاصہ کرنے کے لیے کچھ لکھیں") کو مبہم کوڈ ملتا ہے۔ ایک ٹائپ شدہ دستخط کے علاوہ ایک مثال کوڈ ملتا ہے جسے آپ حقیقت میں چیک کر سکتے ہیں۔ اور جب نتیجہ غلط ہو تو، صرف دوبارہ کوشش نہ کریں: ناکام آؤٹ پٹ کو چسپاں کریں اور کہیں کہ کیا غلط ہے: "یہ خالی فہرست پر کریش ہو جاتا ہے۔ اسے ہینڈل کریں۔" ایک باخبر تصحیح دس بلائنڈ ری رولز کو شکست دیتی ہے۔

11. ڈیٹا کلاسز اور پیڈانٹک، تشکیل شدہ، تصدیق شدہ ڈیٹا

ایک خام ڈکٹ ({"learning_rate": 0.001}) لچکدار لیکن خطرناک ہے: ٹائپ شدہ کلید یا غلط قسم خاموشی سے گزر جاتی ہے اور نیچے کی طرف ہر چیز کو خراب کر دیتی ہے۔ دو ٹولز اسے ٹھیک کرتے ہیں۔

پہلے ایک انسٹال کریں۔

یہ Pydantic Python میں نہیں بنایا گیا ہے، لہذا ذیل کی مثالوں کے لیے اسے آپ کے Project میں ایک بار شامل کرنے کی ضرورت ہے: اپنے ایجنٹ کو بتائیں "اس Project میں pydantic شامل کریں" (یہ uv add pydantic چلتا ہے)۔ dataclass بلٹ ان ہے اور اسے کسی چیز کی ضرورت نہیں ہے۔

ایک ڈیٹا کلاس آپ کے ڈیٹا کو ایک متعین شکل دیتا ہے۔ یہ تصور 8 کا وہی Note ہے۔ لیکن نوٹس کریں کہ کوئی __init__ نہیں ہے: @dataclass لائن آپ کے لئے* سیٹ اپ کا طریقہ لکھتی ہے، لہذا آپ صرف صفات اور ان کی اقسام کی فہرست بنائیں۔

from dataclasses import dataclass

@dataclass
class Note:
title: str
body: str
done: bool = False # default value

یہ Pydantic مزید آگے بڑھتا ہے: یہ رن ٹائم پر ڈیٹا کو توثیق کرتا ہے اور کسی بھی چیز کو مسترد کرتا ہے جو فٹ نہیں ہوتا ہے:

from pydantic import BaseModel, Field

class ModelConfig(BaseModel):
learning_rate: float = Field(gt=0.0, lt=1.0) # must be between 0 and 1
batch_size: int = Field(gt=0) # must be positive

اگر آپ ModelConfig کو learning_rate=-0.05 کے ساتھ بنانے کی کوشش کرتے ہیں، تو Pydantic ایک ٹوٹی ہوئی قدر کو زہر دینے کی بجائے ایک واضح غلطی فوری طور پر اٹھاتا ہے بجائے اس کے کہ گھنٹوں بعد ٹریننگ چلائی جائے۔ یہی وجہ ہے کہ Pydantic ایجنٹ کوڈ میں ہر جگہ موجود ہے: یہ JSON اسکیموں کو بھی خود بخود تیار کرتا ہے جسے LLMs ٹول کالنگ کے لیے استعمال کرتے ہیں۔ آپ اس سے دوبارہ ملیں گے جب آپ شروع کریں گے عمارت کے ایجنٹوں۔

اسے ٹیسٹ کے ساتھ پن کریں۔

ایک Pydantic ماڈل بنیادی طور پر ایک ٹیسٹ ہے جو ہر بار چلتا ہے جب آپ کا پروگرام ہوتا ہے۔ لیکن آپ کو پھر بھی اس طرز عمل کو پن کرنا چاہیے جس کا آپ خیال رکھتے ہیں، بشمول خرابی کے معاملات۔ اب تک آپ نے دعوی کیا ہے کہ کچھ سچ ہے؛ یہاں آپ زور دیتے ہیں کہ pytest.raises کا استعمال کرتے ہوئے، خراب ان پٹ کو مسترد کیا جانا چاہئے:

import pytest
from pydantic import ValidationError

def test_rejects_negative_learning_rate() -> None:
with pytest.raises(ValidationError): # the block below MUST raise this error
ModelConfig(learning_rate=-0.05, batch_size=32)

یہ ٹیسٹ صرف اس صورت میں پاس ہوتا ہے جب خراب کنفیگریشن کو مسترد کر دیا جائے۔ ناکامیوں کو جانچنا اتنا ہی اہمیت رکھتا ہے جتنا کہ کامیابیوں کی جانچ کرنا: ایجنٹ خوشی سے توثیق پیدا کرے گا جو سخت لگتا ہے لیکن خاموشی سے خراب ڈیٹا کو گزرنے دیتا ہے، اور "مسٹ ریز" ٹیسٹ یہ ہے کہ آپ اسے کیسے پکڑتے ہیں۔

@dataclass لائن ایک ڈیکوریٹر ہے۔

فنکشن یا کلاس کے اوپر والی لائن پر @ علامت ایک ڈیکوریٹر ہے: ایک لیبل جو اس کے بعد آنے والی چیزوں میں رویے کو شامل کرتا ہے، بغیر آپ خود اس رویے کو لکھتے ہیں۔ @dataclass کلاس کو خود بخود ایک کنسٹرکٹر اور پڑھنے کے قابل پرنٹ آؤٹ دیتا ہے۔ آپ کو ابھی تک ڈیکوریٹر لکھنے کی ضرورت نہیں ہے۔ بس تسلیم کریں کہ @something کا مطلب ہے "اگلی چیز کو اضافی اختیارات کے ساتھ لپیٹ دیں۔"

12. جنریٹرز اور yield، میموری ختم ہونے کے بغیر سلسلہ بندی

جب کوڈ کو ایک ملین ریکارڈز پر کارروائی کرنے کی ضرورت ہوتی ہے، تو ان سب کو ایک ساتھ فہرست میں لوڈ کرنے سے آپ کے کمپیوٹر کی میموری ختم ہو سکتی ہے۔ ایک جنریٹر اس کو ایک وقت میں، مانگ کے مطابق اشیاء واپس دے کر حل کرتا ہے۔ جس سگنل کو تلاش کرنا ہے وہ مطلوبہ لفظ ہے yield بجائے return:

from collections.abc import Iterator

def stream_notes(lines: list[str]) -> Iterator[str]:
for line in lines:
yield line.strip().lower() # hand back one item, then pause

واپسی کی قسم Iterator[str] ایک جنریٹر کی کہانی کی علامت ہے: یہ list[str] (ایک تیار شدہ ڈھیر) کا وعدہ نہیں کرتا ہے۔ یہ ایک دوہرانے والے کا وعدہ کرتا ہے، ایک ایسی ندی جسے آپ ایک وقت میں ایک آئٹم سے کھینچتے ہیں۔

return کے ساتھ ایک عام فنکشن پورا نتیجہ بناتا ہے اور اسے ایک گانٹھ میں دے دیتا ہے۔ yield کے ساتھ ایک جنریٹر ہر آئٹم کے بعد رک جاتا ہے اور پوچھے جانے پر صرف اگلا کام کرتا ہے۔ ادائیگی حقیقی ہے: ایک بڑے ڈیٹاسیٹ کو فہرست میں لوڈ کرنے کے بجائے اسے جنریٹر کے ذریعے اسٹریم کرنا ڈرامائی طور پر چوٹی کی میموری کو کم کر سکتا ہے، کیونکہ آپ کبھی بھی پوری چیز کو ایک ساتھ نہیں رکھتے۔ جب آپ yield دیکھتے ہیں تو اسے اس طرح پڑھیں: "یہ ایک ندی پیدا کرتا ہے، ڈھیر نہیں۔"

13. with، چیزوں کو محفوظ طریقے سے کھولیں اور بند کریں۔

فائلیں، ڈیٹا بیس کنکشنز، نیٹ ورک سیشنز - کوئی بھی چیز جسے کھولنا اور پھر قابل اعتماد طور پر بند ہونا چاہیے، یہاں تک کہ اگر کوئی چیز درمیان میں کریش ہو جائے، with بیان کا استعمال کرتا ہے:

with open("notes.txt") as file:
contents: str = file.read()
# the file is automatically closed here, even if an error happened above

جس چیز کا انتظام کیا جا رہا ہے (یہاں، فائل) انڈینٹڈ بلاک کے ختم ہونے پر صاف ہونے کی ضمانت ہے۔ AI کوڈ میں آپ کو with GPU حالت، ماڈل کی تشخیص کے موڈ، اور ٹائمرز کے گرد لپیٹے ہوئے نظر آئیں گے۔ جب آپ with دیکھیں تو اسے اس طرح پڑھیں: "کچھ سیٹ کریں، اسے اس بلاک کے اندر استعمال کریں، اور اسے محفوظ طریقے سے پھاڑ دیں چاہے کچھ بھی ہو۔"

14. async / await، ایک ساتھ بہت سی چیزیں

جب کوئی ایجنٹ 20 API کال کرتا ہے، تو انہیں یکے بعد دیگرے کرنے کا مطلب ہے 20 بار انتظار کرنا۔ غیر مطابقت پذیر کوڈ پروگرام کو تمام درخواستوں کو بند کرنے اور جوابات کے آتے ہی ان کو سنبھالنے دیتا ہے: ایک ایک کرکے 20 قطاروں میں کھڑے ہونے اور ایک ساتھ تمام 20 میں شامل ہونے کے درمیان فرق۔ سگنلز کلیدی الفاظ ہیں async اور await:

async def query_llm(prompt: str) -> str:
response = await call_the_api(prompt) # pause here, let other work proceed
return response

مثال کے طور پر: اگر 20 API کالوں میں سے ہر ایک میں تقریباً 0.1 سیکنڈ لگتے ہیں، تو انہیں یکے بعد دیگرے چلانے میں تقریباً 2 سیکنڈ لگتے ہیں، جب کہ انہیں async کے ساتھ ساتھ چلانے سے سست ترین سنگل کال کے وقت میں ختم ہوسکتا ہے، کیونکہ کل سب سے سست کال کی حد ہوتی ہے، نہ کہ رقم سے۔ آپ کو ابھی تک async کوڈ لکھنے کی ضرورت نہیں ہے۔ بس پہچانیں: async/await کا مطلب ہے *"یہ کوڈ ایک ہی وقت میں بہت سی سست چیزیں کرنے کے لئے بنایا گیا ہے۔

15. ڈنڈر کے طریقے - model(x) کیوں کام کرتا ہے۔

سب سے عجیب نظر آنے والی چیز جو آپ پڑھیں گے وہ ایک طریقہ ہے جس میں ہر طرف ڈبل انڈر سکور ہوتے ہیں، جیسے __init__ یا __call__۔ ان کا عرفی نام "dunders" (ڈبل انڈر سکور) ہے، اور آپ پہلے ہی ایک سے مل چکے ہیں: Concept 8 سے __init__ سیٹ اپ کا طریقہ ایک ڈنڈر ہے۔ وہ خاص طریقے ہیں جو آپ کی اپنی اشیاء کو بلٹ ان کی طرح برتاؤ کرنے دیتے ہیں۔

class Pipeline:
def __init__(self, factor: float) -> None: # runs when you create the object
self.factor = factor

def __call__(self, x: float) -> float: # runs when you "call" the object like a function
return x * self.factor

pipeline = Pipeline(2.5)
print(pipeline(10.0)) # prints 25.0 — the object is called like a function

__init__ ایک نیا آبجیکٹ ترتیب دیتا ہے۔ __call__ وہ ہے جو pipeline(10.0) کو اس طرح کام کرتا ہے جیسے آبجیکٹ ایک فنکشن ہو۔ یہی وجہ ہے کہ، PyTorch اور اسی طرح کی لائبریریوں میں، آپ model(x) لکھتے ہیں نہ کہ model.forward(x): فریم ورک __call__ کو چلانے سے پہلے اہم سیٹ اپ کرنے کی وضاحت کرتا ہے۔ جب آپ ڈنڈر دیکھتے ہیں، تو انہیں اس طرح پڑھیں: "اس چیز کو ایک مقامی Python کی چیز کی طرح کام کرنا سکھایا جا رہا ہے۔"

آپ نے ابھی AI کوڈ پڑھنا سیکھا ہے۔

رکیں اور دیکھیں کہ کیا ہوا ہے۔ آپ ابھی تک خالی صفحہ سے جنریٹر یا async فنکشن لکھ نہیں سکتے۔ اور آپ کو اس کی ضرورت نہیں ہے۔ لیکن اب آپ ایجنٹ کی تخلیق کردہ فائل کو کھول سکتے ہیں اور پہچان سکتے ہیں: "یہ ایک کلاس ہے جس کی خصوصیات اور طریقے ہیں، یہ ایک قسم کا اشارہ ہے، یہ ایک Pydantic ماڈل ہے جو ٹول اسکیما کی وضاحت کرتا ہے، یہ ایک جنریٹر اسٹریمنگ ڈیٹا ہے، کہ with بلاک وسائل کا انتظام کرتا ہے، وہ ڈنڈرسیٹ اپنی مرضی کے مطابق ڈیٹا بناتے ہیں۔" یہ پہچان توثیق کی مہارت ہے جس پر پوری کتاب منحصر ہے۔


حصہ 4: TDG لوپ، آخر سے آخر تک

آپ نے پورے پارٹس 2 اور 3 میں Predict-Run-Investigate کر لیا ہے۔ اب PRIMM-AI+ کے آخری دو حروف، Modify اور Make، جو کہ ایک ساتھ ہیں Test-driven Generation (TDG) سائیکل: وہ طریقہ جو AI دور میں پروگرامنگ کی وضاحت کرتا ہے۔

16. ایک مکمل سائیکل، آپ کے آلے میں

یہ TDG پرانے آرڈر کو الٹ دیتا ہے۔ کوڈ لکھیں → ہوسکتا ہے اس کی جانچ کریں کے بجائے، آپ جائیں: ایک ناکام ٹیسٹ لکھیں جو "درست" کی وضاحت کرتا ہے → ایجنٹ کو کوڈ تیار کرنے دیں → تصدیق کرنے کے لیے ٹیسٹ چلائیں۔ ٹیسٹ کوئی بعد کی سوچ نہیں ہے؛ یہ تفصیلات ہے. اور یہ آپ کی طرف سے آنا چاہیے، کیونکہ اگر آپ ایجنٹ کو کوڈ اور ٹیسٹ دونوں لکھنے دیتے ہیں، تو آپ AI کی اپنی توقعات کے خلاف AI کے کام کی جانچ کر رہے ہیں: کوئی آزاد سگنل بالکل نہیں۔

The Test-Driven Generation loop: you write a failing test, the agent generates the code, you run the tests and verify; if a test is red you refine and repeat, if green you ship. ! اگر کوئی ٹیسٹ سرخ ہے تو آپ اسے بہتر کریں اور دہرائیں، اگر سبز آپ کو بھیجیں](/img/python-crash-course/tdg-loop.png)

تصور 5 سے ٹیکس فنکشن کا سائیکل یہ ہے۔ اپنے سیشن میں ساتھ چلیں۔

مرحلہ 1: آپ ضرورت کو ناکام ٹیسٹ کے طور پر لکھتے ہیں۔ test_tax.py بنائیں:

from tax import total_with_tax

def test_basic() -> None:
assert total_with_tax(100.0, 0.15) == 115.0

def test_zero_price() -> None:
assert total_with_tax(0.0, 0.15) == 0.0

آپ نے پہلے بھی یہ عین مطابق دعوے دیکھے ہوں گے۔ یہ وہ دو سطریں ہیں جو آپ نے تصور 5 میں لکھی ہیں، اب ایک test_*.py فائل میں منتقل ہو گئی ہیں تاکہ pytest انہیں خود بخود چلا سکے۔ assert X == Y کا مطلب ہے "میں اعلان کر رہا ہوں کہ X کو Y کے برابر ہونا چاہیے؛ اگر ایسا نہیں ہوتا ہے تو زور سے ناکام ہو جاتا ہے۔" یہ دو لائنیں کسی بھی کوڈ کے موجود ہونے سے پہلے اس کا صحیح مطلب کی وضاحت کرتی ہیں۔ ابھی pytest چلائیں اور یہ ناکام ہوجاتا ہے: ابھی تک کوئی tax.py نہیں ہے۔ یہ ناکامی نقطہ ہے۔ آپ کے پاس مکمل کی ایک درست، قابل عمل تعریف ہے۔

صرف ایک چیز جو یہاں نئی ​​ہے وہ ہے آرڈر: تصورات 5، 8 اور 11 میں آپ نے پہلے سے موجود کوڈ کے لیے ٹیسٹ لکھا ہے۔ حقیقی TDG میں آپ فیلنگ ٹیسٹ پہلے لکھتے ہیں، پھر اسے پاس کرنے کے لیے ایجنٹ سے کوڈ تیار کرنے کو کہیں۔ ٹیسٹ ایک چیک ہونے سے رک جاتا ہے جسے آپ بعد میں چلاتے ہیں اور ایجنٹ کے خلاف تیار کردہ تفصیل بن جاتا ہے۔

مرحلہ 2: ایجنٹ عمل درآمد تیار کرتا ہے۔ اب اپنے ٹول کو ہدایات دیں:

test_tax.py پڑھیں۔ tax.py ایک total_with_tax(price: float, tax_rate: float) -> float فنکشن کے ساتھ بنائیں جس سے دونوں ٹیسٹ پاس ہوں۔ پھر pytest چلائیں اور مجھے نتیجہ دکھائیں۔

یہ Claude Code آپ کے ٹیسٹ پڑھتا ہے، tax.py لکھتا ہے، اور pytest چلاتا ہے۔ چونکہ آپ نے ٹیسٹ لکھے ہیں، اس لیے آپ کو اس بات کی آزادانہ جانچ پڑتال ہے کہ اس نے کیا پیدا کیا۔

test_tax.py پڑھیں۔ tax.py ایک total_with_tax(price: float, tax_rate: float) -> float فنکشن کے ساتھ بنائیں جس سے دونوں ٹیسٹ پاس ہوں۔ پھر pytest چلائیں اور مجھے نتیجہ دکھائیں۔

یہ OpenCode آپ کے ٹیسٹ پڑھتا ہے، tax.py لکھتا ہے، اور pytest چلاتا ہے۔ چونکہ آپ نے ٹیسٹ لکھے ہیں، اس لیے آپ کو اس بات کی آزادانہ جانچ پڑتال ہے کہ اس نے کیا پیدا کیا۔

مرحلہ 3: آپ تصدیق کرتے ہیں اور اعادہ کرتے ہیں۔ pytest آؤٹ پٹ پڑھیں۔ دو گرین چیکس (2 passed) کا مطلب ہے کہ کوڈ آپ کے بیان کردہ قیاس کو پورا کرتا ہے۔ اگر یہ سرخ ہے، تو آپ ناکامی (اگلا تصور) پڑھیں، پھر بہتر کریں۔ آپ نہیں کرتے ہیں صرف آنکھیں بند کرکے دوبارہ اشارہ کرتے ہیں اور امید کرتے ہیں۔ اور ایک چیز کو قریب سے دیکھیں: اگر ایجنٹ کوڈ کی بجائے ٹیسٹ میں ترمیم کرکے ناکام امتحان پاس کرتا ہے تو اسے روک دیں۔ ٹیسٹ آپ کی قیاس ہے؛ اسے کمزور کر کے اسے سبز کرنے سے صرف کیڑے چھپ جاتے ہیں۔

یہ پورا لوپ ہے، اور یہ PRIMM-AI+ اور 10-80-10 اصول: پر صاف نقشہ بناتا ہے۔

TDG قدمکون قیادت کرتا ہےPRIMM-AI+
لکھنے کی ضرورت + فیل ہونے والے ٹیسٹآپ (پہلا 10%)بنائیں
عمل درآمد پیدا کریںایجنٹ (80%)-
ٹیسٹ چلائیں، تصدیق کریں، اعادہ کریںآپ (آخری 10%)تحقیقات / ترمیم
کنارے کے معاملات شامل کریں جن کے بارے میں آپ سوچ سکتے ہیں۔

ایجنٹ آپ کے کھوئے ہوئے ٹیسٹوں کی تجویز کرنے میں اچھا ہے، اس سے پوچھیں، "ٹیکس کیلکولیشن کے لیے مجھے کن کن کیسز کی جانچ کرنی چاہیے؟"۔ لیکن فیصلہ جس کے بارے میں کیسز "درست" کی وضاحت کرتے ہیں وہ آپ کا ہی رہتا ہے۔ منفی قیمتیں؟ زیرو ٹیکس؟ بہت بڑی تعداد؟ ہر ایک جو آپ شامل کرتے ہیں ایک تیز تصریح ہے۔

اس لوپ کو ہر چیز پر استعمال کریں - یہ ڈیفالٹ ہے، فائنل نہیں۔

یہ TDG بڑی خصوصیات کے لیے مخصوص تقریب نہیں ہے۔ اسے ایجنٹ کی طرف سے تیار کردہ ہر یونٹ پر چلائیں جس میں قابل جانچ معاہدہ ہوتا ہے: ہر فنکشن، ہر طریقہ، ہر توثیق کا اصول۔ تصورات 5، 8، اور 11 سے ایک لائن asserts بیج تھے۔ ان سے بھرا ہوا بڑھتا ہوا tests/ فولڈر ہے جو آپ کو کسی Project پر بھروسہ رکھنے دیتا ہے کیونکہ ایجنٹ اسے تبدیل کرتا ہے۔ ایک عملی اصول: اگر آپ کسی چیز کے لیے ٹیسٹ نہیں لکھ سکتے، تو آپ ابھی تک یہ نہیں سمجھتے کہ اس کے لیے "درست" کا کیا مطلب ہے۔ اور نہ ہی ایجنٹ۔ ٹیسٹ لکھنا یہ ہے کہ آپ کو کیسے پتہ چلتا ہے۔ جیسے جیسے آپ کے Project بڑھتے ہیں، یہی چیز آپ کو رجعت سے بھی بچاتی ہے: ایجنٹ ایک چیز کو ٹھیک کرتا ہے اور خاموشی سے دوسری چیز کو توڑ دیتا ہے۔ آپ کا ٹیسٹ سویٹ الارم ہے جو اسے پکڑتا ہے۔

ٹریس بیک پڑھنا (جب یہ ٹوٹ جاتا ہے)

جب Python ناکام ہوجاتا ہے، تو یہ ایک ٹریس بیک پرنٹ کرتا ہے: سرخ متن کی ایک دیوار جو خوفناک نظر آتی ہے اور حقیقت میں ایک تحفہ ہے۔ اسے نیچے سے اوپر پڑھیں: آخری لائن غلطی کا نام دیتی ہے، اور اس کے اوپر کی سطریں یہ بتاتی ہیں کہ یہ کہاں ہوا ہے۔

Traceback (most recent call last):
File "tax.py", line 2, in total_with_tax
return price + (price * tax_rate)
TypeError: can't multiply sequence by non-int of type 'float'

سب سے نیچے کی سطر پوری کہانی ہے: کچھ ایک تار تھا (str) جب اسے ایک نمبر ہونا چاہئے تھا: price 100.0 کی بجائے "100" (متن) کے طور پر آیا۔ آپ کو اسے خود ٹھیک کرنے کی ضرورت نہیں ہے۔ آپ کو ایجنٹ کو بتانے کے لیے اسے اچھی طرح سے پڑھنا ہوگا*: "قیمت ٹیکسٹ کے طور پر پہنچ رہی ہے، نمبر نہیں۔ اسے سنبھال لیں۔" ایک قطعی وضاحت ایک عین مطابق طے کرتی ہے۔ (ڈیبگنگ کا اپنا مرحلہ ہوتا ہے: [AI دور میں پروگرامنگ، فیز 4](/docs/Programming-in-the-AI-Era/debug-and master))

کبھی بھی آنکھیں بند کرکے دوبارہ اشارہ نہ کریں۔

یہ AI کوڈنگ میں سب سے مہنگی عادت ایسی ناکامی پر "دوبارہ کوشش کریں" کو مارنا ہے جسے آپ نے نہیں پڑھا ہے۔ ایجنٹ خوش دلی سے مختلف غلط جواب دے گا۔ ٹریس بیک پڑھیں، اصل مسئلہ سمجھیں، پھر بیان کریں۔ ایک باخبر فوری دس اندھے کو مارتا ہے۔

مٹھی بھر غلطیاں آپ کو درحقیقت ملیں گی۔

آپ اصلاحات کو یاد نہیں کرتے۔ آپ اس آخری لائن سے زمرہ کو پہچانتے ہیں اور اسے ایجنٹ سے بیان کرتے ہیں۔ یہ چھ تقریباً ہر اس چیز کا احاطہ کرتے ہیں جو ایک ابتدائی کوڈ کو چلاتے وقت دیکھتا ہے:

آخری لائن کہتی ہے…اس کا عام طور پر کیا مطلب ہےایجنٹ کو کیا بتانا ہے
ModuleNotFoundError / ImportErrorایک پیکیج انسٹال نہیں ہے، یا نام کی ہجے غلط ہے۔ "X انسٹال نہیں ہے، اسے uv کے ساتھ شامل کریں"
NameErrorایک ایسا نام استعمال کیا جاتا ہے جس کی کبھی وضاحت نہیں کی گئی تھی (اکثر ٹائپو)"y استعمال کیا جاتا ہے لیکن کبھی وضاحت نہیں کی گئی، ٹائپو؟"
TypeErrorغلط قسم کی قدر، متن جہاں کسی نمبر کی توقع تھی، وغیرہ "ایک نمبر متن کے طور پر آرہا ہے - اسے تبدیل کریں"
AttributeErrorکسی چیز کے بارے میں پوچھنا جس کے پاس نہیں ہے (note.titel)"اس آبجیکٹ میں کوئی وصف نہیں ہے titel، ممکنہ طور پر ایک ٹائپو"
KeyErrorایک کلید کے لیے ڈکٹ پوچھنا جو اس میں نہیں ہے"کلید 'x' ڈکٹ میں نہیں ہے - گمشدہ کیس کو ہینڈل کریں"
IndexErrorاس کے اختتام سے گزرنے والی پوزیشن کے لئے فہرست پوچھنا"فہرست کوڈ کے فرض سے چھوٹا ہے"

میٹا اسکل سیٹ اپ کی طرح ہی ہے (تصور 3): آپ غلطی کو ٹھیک کرنے والے نہیں ہیں، آپ وہ ہیں جو *اسے پڑھتے ہیں اور اسے ٹھیک ٹھیک نام دیتے ہیں۔ "یہ ٹوٹ گیا" ایک اور اندازہ ہو جاتا ہے.

17. ایک مبہم مقصد سے مخصوص ٹکڑوں تک

تصور 16 نے دکھایا کہ ایک یونٹ کی وضاحت اور تصدیق کیسے کی جائے۔ لیکن آپ کے اپنے منصوبے ایک صاف ستھرا فنکشن کے طور پر نہیں پہنچتے ہیں۔ وہ ایک مبہم جملے کے طور پر آتے ہیں: "مجھے ایک ایسا ٹول بنائیں جو میرے نوٹ کا خلاصہ کرے۔" آپ اس کے لیے ایک بھی ٹیسٹ نہیں لکھ سکتے۔ وہ مہارت جو کسی جملے کو تیار کردہ کوڈ میں بدلتی ہے سڑنا: مقصد کو چھوٹے چھوٹے ٹکڑوں میں توڑنا، ہر ایک ٹائپ شدہ دستخط اور ٹیسٹ دینے کے لیے کافی چھوٹا ہے۔ یہ وہ حصہ ہے جو ایجنٹ آپ کے لیے نہیں کر سکتا، کیونکہ یہ وہ جگہ ہے جہاں آپ فیصلہ کرتے ہیں کہ اصل چیز کیا ہے۔

Decomposition: a one-sentence goal breaks into several small units, each given a typed signature and a failing test, which are then generated, verified, and wired together. !(

یہاں حرکت ہے، اور یہ ہر بار ایک جیسی ہے۔

1۔ مقصد کو ایک جملے میں کہیں۔ "میرے نوٹ پڑھیں اور پرنٹ کریں کہ کتنے مکمل ہو چکے ہیں اور کون سے نہیں ہیں۔"

**2۔ ان اقدامات کی فہرست بنائیں جو آپ ہاتھ سے کرنا چاہتے ہیں۔ ** فعل لکھیں: لوڈ نوٹس → گنتی کیے گئے → تلاش کریں زیر التواء عنوانات → خلاصہ ان کو ایک لائن میں → پرنٹ کریں۔ ہر فعل امیدوار یونٹ ہے۔

3۔ ہر یونٹ کو ایک ٹائپ شدہ دستخط دیں: آؤٹ پٹ کے لیے ان پٹ۔ یہ قیاس ہے۔ ابھی تک کوئی لاش نہیں ایجنٹ ان کو لکھتا ہے۔

def load_notes(path: str) -> list[Note]: ...      # text file -> list of notes
def count_done(notes: list[Note]) -> int: ... # notes -> how many are done
def pending_titles(notes: list[Note]) -> list[str]: ... # notes -> titles not done
def summarize(notes: list[Note]) -> str: ... # notes -> one summary line

**4۔ ہر یونٹ کو TDG کریں، ترتیب سے۔ ** اوپر کی ہر سطر اب بالکل ایک تصور 16 سائیکل ہے: فیلنگ ٹیسٹ لکھیں، ایجنٹ سے باڈی تیار کرائیں، تصدیق کریں۔ مثال کے طور پر، summarize چھوٹا اور قابل امتحان ہے:

def test_summarize() -> None:
notes = [Note(title="groceries", done=True), Note(title="call sara", done=False)]
assert summarize(notes) == "1 of 2 done; pending: call sara"

5۔ ان کو ایک ساتھ وائر کریں اور پورے بہاؤ کی جانچ کریں۔ ایجنٹ سے ایک main() لکھنے کو کہیں جو ٹکڑوں کو ترتیب سے کال کرتا ہے، پھر آخر سے آخر تک نتیجہ کے لیے ایک ٹیسٹ لکھیں۔ ہو گیا

غور کریں کہ کیا ہوا: ایک مبہم جملہ چار چھوٹے، آزادانہ طور پر قابل تصدیق معاہدے بن گیا۔ ایجنٹ نے اصل کوڈ کی ہر سطر لکھی۔ لیکن آپ کو ٹکڑے مل گئے اور ہر ایک نے جو وعدہ کیا ہے اس کی وضاحت کی۔ وہ فرنٹ اینڈ سڑن انسانی 10% ہے جو ایجنٹ کے 80% کو قابل اعتماد بناتا ہے۔

ٹکڑوں پر غور کرنے کے لیے ایجنٹ کا استعمال کریں - لیکن معاہدوں کے مالک ہوں۔

آپ ایجنٹ سے یونٹس تلاش کرنے میں آپ کی مدد کے لیے کہہ سکتے ہیں: "میں ایک ایسا ٹول بنانا چاہتا ہوں جو میرے نوٹس کا خلاصہ کرے۔ مجھے کن 3-5 فنکشنز کی ضرورت ہوگی، ان کے ان پٹ اور آؤٹ پٹس کے ساتھ؟" یہ ایک عمدہ ابتدائی فہرست ہے۔ لیکن آپ حتمی دستخطوں کا فیصلہ کرتے ہیں اور آپ ٹیسٹ لکھتے ہیں۔ ایجنٹ کو کبھی بھی مسئلہ کو حل کرنے اور اس کے اپنے جواب کی تصدیق نہ کرنے دیں، یا آپ اپنا آزاد چیک کھو چکے ہیں۔

ایک قابل اعتماد ہوورسٹک: اگر کسی یونٹ کے لیے ٹیسٹ لکھنا مشکل ہے، تو یہ بہت زیادہ کر رہا ہے۔ اسے تقسیم کریں۔ ایک فنکشن جس کی آپ جانچ نہیں کر سکتے وہ فنکشن ہے جس کی آپ تصدیق نہیں کر سکتے، جس کا مطلب ہے کہ نہ ہی آپ اس پر بھروسہ کر سکتے ہیں کہ ایجنٹ نے اس کے لیے کیا بنایا ہے۔ ٹیسٹیبلٹی اور اچھی سڑن ایک ہی مہارت ہے۔

یہ "میں ایک فنکشن کی تصدیق کر سکتا ہوں" سے لے کر "میں AI کے ساتھ پوری چیز بنا سکتا ہوں" تک کا پل ہے۔ یہ بالکل اسی طرح ہے جس طرح کتاب کا SmartNotes Project بڑھتا ہے: ایک وقت میں ایک سڑا ہوا، آزمائشی ٹکڑا۔ آپ اس کی مشق Project 5 منی کیپ اسٹون میں کریں گے، پھر شروع سے ہی Project 6 میں بغیر کسی سہاروں کے۔

ایک پرامپٹ جسے آپ کسی بھی Project کے لیے دوبارہ استعمال کر سکتے ہیں۔

ایک بار جب آپ ایک گول کو گل کر دیتے ہیں، تو یہ ایک ٹیمپلیٹ ہے جسے آپ ہر بار Claude Code یا OpenCode میں چسپاں کر سکتے ہیں۔ یہ اس کورس کے پورے ڈسپلن میں شامل ہے: پہلے ٹیسٹ، کوڈ سے پہلے آپ کی منظوری، آخر میں تصدیق:

I want to build: [your one-sentence goal]

First, break it into 3–5 small functions or classes.
For each unit, propose ONLY:
1. a typed signature (inputs and output)
2. expected behavior in one line
3. edge cases to consider
4. pytest tests

Do NOT write any implementation yet. Wait for me to approve the tests.

After I approve, generate the implementation to pass those tests.
Then run pytest, pyright, and ruff, and show me only the
changed files and the test results.

بوجھ برداشت کرنے والے دو الفاظ صرف اور نہیں ہیں: وہ ایجنٹ کو آگے بڑھنے اور کوڈ (اور اس کے اپنے ٹیسٹ) لکھنے سے روکتے ہیں اس سے پہلے کہ آپ فیصلہ کر لیں کہ "درست" کا کیا مطلب ہے۔ آپ قیاس پر قابو رکھتے ہیں۔ ایجنٹ ٹائپنگ کرتا ہے۔


حصہ 5: فیصلہ

جب AI پر تکیہ نہ کریں، اور اس بات کی تصدیق کیسے کریں کہ آپ پوری طرح سے نہیں پڑھ سکتے

پڑھنے کی روانی کی ایک حد ہوتی ہے، اور اس کے بارے میں ایماندار ہونا بذات خود ایک مہارت ہے۔

  • سیکیورٹی سے متعلق حساس کوڈ غیر گفت و شنید ہے۔ پاس ورڈز، API کیز، ادائیگیوں، یا صارف کے ڈیٹا کو چھونے والی کوئی بھی چیز احتیاط سے پڑھی جاتی ہے اور مثالی طور پر، کسی ایسے شخص کے ذریعہ جائزہ لیا جاتا ہے جو ڈومین کو جانتا ہو۔ AI اعتماد کے ساتھ غیر محفوظ کوڈ لکھتا ہے۔ اگر آپ اس کی تصدیق نہیں کر سکتے ہیں تو اسے نہ بھیجیں۔ (دیکھیں AI دور میں پروگرامنگ، مرحلہ 8 سیکیورٹی کا جائزہ لینے کے لیے۔)
  • جب آپ واقعی اسے نہیں پڑھ سکتے، تو faith پر نہیں بلکہ tests پر زیادہ سختی سے تکیہ کریں۔ اگر کوئی generated function آپ کی موجودہ سطح سے باہر ہے، تو آپ کے pytest checks زیادہ اہم ہو جاتے ہیں، کم نہیں: یہی وہ حصہ ہے جس کی آپ تصدیق کر سکتے ہیں۔ آپ کے منتخب کردہ inputs پر green tests حقیقی ثبوت ہیں۔ “یہ ٹھیک لگتا ہے” ثبوت نہیں۔
  • چھوٹی، واضح تبدیلیاں بعض اوقات ہاتھ سے تیز تر ہوتی ہیں۔ ایک متغیر کا نام تبدیل کرنا یا ایک نمبر کو درست کرنا بیان کرنے کے بجائے خود کرنا تیز تر ہوسکتا ہے۔ ان لمحات کو پہچاننا مشق کے ساتھ آتا ہے۔

ریڈ ٹیم آپ کے اپنے ٹیسٹ

آپ کے ٹیسٹ ہی واحد تصدیق ہیں جو آپ کو مکمل طور پر کنٹرول کرتے ہیں، لہذا ایک کمزور ٹیسٹ بغیر ٹیسٹ سے بدتر ہے، کیونکہ یہ غلط اعتماد دیتا ہے۔ جب ایجنٹ کوڈ تیار کرتا ہے جسے آپ پوری طرح سے نہیں پڑھ سکتے ہیں (ایک مشکل Pydantic validator، ایک async بلاک)، آپ کے ٹیسٹ پورے بوجھ کو اٹھاتے ہیں۔ انہیں مخالف بنائیں:

  • ایجنٹ کو کبھی بھی ٹیسٹ لکھنے نہ دیں کہ اس کا اپنا کوڈ پاس ہونا چاہیے۔ یہی ایک اینٹی پیٹرن ہے جو خاموشی سے اس کورس میں باقی تمام چیزوں کو شکست دیتا ہے: اگر AI کوڈ اور چیک دونوں لکھتا ہے، تو آپ کے پاس کوئی آزاد سگنل نہیں ہے: صرف ایجنٹ خود سے متفق ہے۔ آپ ٹیسٹ لکھتے ہیں، یا کم از کم آپ ہر دعوے کو پڑھتے اور اس کے مالک ہوتے ہیں۔ ہر طرح سے پوچھیں "میں کن کناروں کے کیسز غائب ہوں؟"۔ پھر خود فیصلہ کریں کہ کون سا اہم ہے۔
  • ایجنٹ کو کبھی بھی ٹیسٹ پاس کرنے کے لیے اسے کمزور نہ ہونے دیں۔ جب کوئی ٹیسٹ ناکام ہوجاتا ہے، تو ایجنٹ بعض اوقات کوڈ کی بجائے ٹیسٹ کو تبدیل کرکے اسے "ٹھیک" کر دیتا ہے: کسی دعوے کو ڈھیلا کرنا، کسی کنارے کے کیس کو حذف کرنا، متوقع قدر کو کم کرنا۔ یہ بگ کو جگہ پر چھوڑتے ہوئے سرخ سے سبز ہو جاتا ہے۔ اس پر نگاہ رکھیں، اور اس کی اجازت نہ دیں جب تک کہ آپ یہ فیصلہ نہ کر لیں کہ ٹیسٹ خود ہی غلط تھا۔ ٹیسٹ قیاس ہے؛ ایجنٹ کو اس کے کوڈ کے مطابق قیاس کو دوبارہ لکھنا نہیں آتا ہے۔
  • ناکامیوں کی جانچ کریں، نہ صرف خوش راہ۔ ہر یونٹ سے پوچھیں: کون سا ان پٹ اس کو توڑ دے گا؟ خالی فہرست، صفر، ایک منفی نمبر، ایک غائب کلید، متن جہاں ایک نمبر کی توقع تھی۔ Project 4 میں بگ بالکل اسی صورت میں چھپا تھا جس کا کسی نے تجربہ نہیں کیا تھا۔
  • اگر آپ اس کے لیے ایک ٹیسٹ کے بارے میں نہیں سوچ سکتے، تو آپ اسے ابھی تک نہیں سمجھتے۔ اور آپ یقینی طور پر ایجنٹ کے ورژن کی تصدیق نہیں کر سکتے۔ یہ آپ کا اشارہ ہے کہ مزید گلنا (تصور 17) یا ایجنٹ سے کوڈ لائن کو قبول کرنے سے پہلے اس کی وضاحت کرنے کو کہیں۔

رکھنے کے لیے ایک مبہم ہوورسٹک: گرین ٹیسٹ ثابت کرتے ہیں کہ آپ کا کوڈ وہی کرتا ہے جو آپ کے ٹیسٹ کہتے ہیں۔ مزید نہیں۔ آپ کی تصدیق کا معیار بالکل آپ کے ٹیسٹوں کا معیار ہے۔ (فائلیں، معیاری لائبریری، پیکج ایکو سسٹم، گہری ڈیبگنگ، اور حقیقی سیکیورٹی کا جائزہ جان بوجھ کر AI دور میں پروگرامنگ پر چھوڑ دیا گیا ہے۔ یہ فوری کورس آپ کو فیصلہ دیتا ہے؛ یہ حصہ آپ کو گہرائی فراہم کرتا ہے۔)

اختلاف کو قبول کرنے سے پہلے اس کا جائزہ لیں۔

جب آپ Claude Code یا OpenCode میں کام کرتے ہیں، تو ایجنٹ صرف جواب نہیں دیتا۔ یہ فائلوں کو تبدیل کرتا ہے*۔ کوڈ پڑھنا آدھا کام ہے۔ باقی آدھا پڑھ رہا ہے کیا بدلا۔ اس سے پہلے کہ آپ پیدا کردہ تبدیلیوں کے کسی بیچ کو قبول کریں، اس فہرست کو نیچے چلائیں:

  1. کون سی فائلز تبدیل ہوئیں؟ ایک فنکشن کو ٹھیک کرنے کی درخواست کو خاموشی سے پانچ فائلوں کو نہیں چھونا چاہیے۔
  2. کیا اس سے ٹیسٹوں میں تبدیلی آئی؟ اگر آپ کے ٹیسٹوں میں ترمیم کی گئی تھی، تو کسی اور چیز سے پہلے معلوم کریں کہ کیوں (اوپر اینٹی پیٹرن دیکھیں)۔
  3. کیا اس نے انحصار شامل کیا؟ نئے پیکجوں کا مطلب ہے نیا کوڈ جو آپ نے اپنی مشین پر چلتے ہوئے نہیں لکھا۔ یقینی بنائیں کہ ہر ایک حقیقی اور ضروری ہے۔
  4. کیا اس نے کسی حساس چیز کو چھوا؟ راز، چابیاں، تصدیق، ادائیگیاں، صارف کا ڈیٹا: ان کو غور سے پڑھا جاتا ہے یا کسی ایسے شخص کے ذریعہ جائزہ لیا جاتا ہے جو ڈومین کو جانتا ہو۔
  5. کیا pytest، Pyright، اور Ruff سب گزر گئے؟ تینوں میں سبز رنگ فرش ہے، چھت نہیں۔
  6. کیا آپ مرکزی فنکشن یا کلاس کی سادہ انگریزی میں وضاحت کر سکتے ہیں؟ اگر آپ نہیں کر سکتے ہیں، تو آپ اس کی تصدیق نہیں کر سکتے ہیں: قبول کرنے سے پہلے ایجنٹ سے کہیں کہ وہ آپ کو اس پر لائن سے گزرے۔

یہ ایک جلدی عادت ہے، تقریب نہیں. لیکن فرق کو پڑھے بغیر "سب کو قبول کریں" یہ ہے کہ کس طرح ایک چھوٹی سی غلط تبدیلی کسی کام کرنے والے Project میں کسی کا دھیان نہیں دیتی۔

اس پورے کورس کی تھرو لائن: ایجنٹ کوڈ لاتا ہے۔ آپ اس بارے میں فیصلہ لاتے ہیں کہ آیا یہ درست ہے۔ یہ فیصلہ روانی سے پڑھنے اور آپ کے خود لکھے گئے ٹیسٹوں پر منحصر ہے۔ ایک بار جب آپ لوپ کی مشق کر لیتے ہیں تو نہ تو اختیاری ہے اور نہ ہی مشکل ہے۔


حصہ 6: پریکٹس Projectس

لوپ کے بارے میں پڑھنا اسے چلانے جیسا نہیں ہے۔ یہ چھ Projectس آپ کو PRIMM-AI+ کے ذریعے ترتیب میں لے جاتے ہیں: کوڈ کو پڑھنے سے، اسے ٹیسٹ کرنے، اپنا بنانا، اصل ایجنٹ طرز کے کوڈ کی تصدیق* کرنے کے لیے اس میں چھپے ایک بگ کے ساتھ، ایک چھوٹا اینڈ ٹو اینڈ ٹول بنانا جو ہر تصور کو ایک ساتھ استعمال کرتا ہے، اور آخر کار ایک جملے کے مقصد سے بغیر کسی سہار کے تعمیر کرنا۔ انہیں اپنے Claude Code یا OpenCode سیشن میں ترتیب سے کریں۔ ہر ایک پہلے سے مہارت حاصل کرتا ہے۔

ہر Project آپ کو اپنا مقصد اور اس کی مہارت بتاتا ہے، پھر آپ کو اسٹارٹر دیتا ہے۔ پہلے خود آزمائیں: اپنی پیشین گوئی لکھیں، اپنے ٹیسٹ لکھیں، ایجنٹ کو فوری طور پر بتائیں۔ اور تب ہی حل کھولیں۔ کاپی کرنے کے لیے حل موجود نہیں ہیں: ایجنٹ بہرحال آپ کے لیے کوڈ تیار کر سکتا ہے۔ وہ وہاں موجود ہیں تاکہ آپ چیک کر سکیں کہ آپ کی تفصیلات اور آپ کے ٹیسٹ درست تھے۔ یہ وہ مہارت ہے جس کی درجہ بندی کی جا رہی ہے۔

حل کا استعمال کیسے کریں۔

حوالہ کوڈ ہر حل کا کم سے کم اہم حصہ ہے۔ کیا اہم ہے: کیا آپ کے ٹیسٹوں نے "درست" کا مطلب پکڑا؟ کیا آپ نے آؤٹ پٹ کی صحیح پیش گوئی کی ہے؟ کیا آپ نتیجہ پڑھ سکتے ہیں اور بتا سکتے ہیں کہ یہ صحیح تھا؟ اگر آپ کے ٹیسٹ ریفرنس کوڈ کے خلاف پاس ہوتے ہیں، تو آپ نے مسئلہ کو اچھی طرح بیان کیا ہے۔ یہی جیت ہے۔

یہ Project 1 - پڑھیں اور پیشین گوئی کریں (پیش گوئی · چلائیں · تحقیقات)

مہارتیں: پڑھنے کے افعال، فہم، اور len؛ چلانے سے پہلے پیداوار کی پیشن گوئی

اسٹارٹر۔ اسے ابھی تک نہ چلائیں۔ اسے پڑھیں اور لکھیں کہ تین print لائنوں میں سے ہر ایک کیا پیدا کرے گا:

def shout(text: str) -> str:
return text.upper() + "!"

names: list[str] = ["ada", "alan", "grace"]
greetings: list[str] = [shout(n) for n in names if len(n) > 3]

print(len(names))
print(greetings)
print(shout("hi"))

اب اسے اپنے سیشن میں چلائیں اور موازنہ کریں۔ جہاں آپ کی پیشین گوئی غلط تھی، ایجنٹ سے پوچھیں "لائن X نے ایسا کیوں کیا؟"۔ یہی فرق سبق ہے۔

حل
3
['ALAN!', 'GRACE!']
HI!
  • len(names)3: فہرست میں تین آئٹمز۔
  • greetings → صرف 3 حروف سے زیادہ طویل نام if len(n) > 3 فلٹر کو پاس کرتے ہیں۔ "ada" بالکل 3 (ناکام) ہے، "alan" 4 ہے اور "grace" 5 (پاس) ہے۔ ہر ایک کو ['ALAN!', 'GRACE!'] دیتے ہوئے چلایا جاتا ہے۔
  • shout("hi")"HI!": بڑے حروف میں، ! کے ساتھ شامل کیا گیا ہے۔

اگر آپ فہم کو "ہر نام کے لیے چیخیں، ناموں میں ہر ایک نام کے لیے، اگر یہ 3 حروف سے زیادہ لمبا ہے" پڑھتے ہیں تو آپ اسے صحیح طریقے سے پڑھتے ہیں۔

یہ Project 2 - کسی فنکشن پر آپ کا پہلا TDG سائیکل (میک)

مہارتیں: assert ٹیسٹ کو بطور نمونہ لکھنا، ایجنٹ کو اشارہ کرنا، pytest سے تصدیق کرنا۔

گول۔ ایک فنکشن initials(full_name: str) -> str بنائیں جو نام کے بڑے حروف کو لوٹائے: "ada lovelace""AL"۔

اسٹارٹر۔ ٹیسٹ پہلے، test_initials.py میں، کسی بھی نفاذ کے موجود ہونے سے پہلے لکھیں۔ عام کیس اور کم از کم دو کناروں کے کیسز کا احاطہ کریں (ایک نام؛ اضافی خالی جگہیں)۔ پھر اپنے ایجنٹ سے پوچھیں:

test_initials.py پڑھیں۔ initials.py ایک initials(full_name: str) -> str فنکشن کے ساتھ بنائیں جو ہر امتحان کو پاس کرتا ہے۔ پھر pytest چلائیں اور مجھے نتیجہ دکھائیں۔

گرین چیکس پر بھروسہ کرنے سے پہلے اس کے تیار کردہ کوڈ کو پڑھیں۔

حل

آپ کے ٹیسٹ (اہم حصہ) اس طرح نظر آسکتے ہیں:

from initials import initials

def test_two_names() -> None:
assert initials("ada lovelace") == "AL"

def test_many_names() -> None:
assert initials("grace brewster murray hopper") == "GBMH"

def test_single_name() -> None:
assert initials("alan") == "A"

def test_extra_spaces() -> None:
assert initials(" extra spaces ") == "ES"

ایک حوالہ کا نفاذ جو ان سب کو پاس کرتا ہے:

def initials(full_name: str) -> str:
return "".join(part[0].upper() for part in full_name.split())

full_name.split() متن کو خالی جگہوں پر توڑ دیتا ہے (اور اضافی کو نظر انداز کرتا ہے)، part[0] ہر ٹکڑے کا پہلا حرف لیتا ہے، .upper() اسے بڑا کرتا ہے، اور "".join(...) انہیں ایک ساتھ چپکاتا ہے۔ اگر آپ نے extra_spaces ٹیسٹ لکھا ہے، تو آپ نے خود مشکل کیس کی تصدیق کی ہے: یہ بالکل وہی فیصلہ ہے جو ایجنٹ فراہم نہیں کر سکتا۔

یہ Project 3 - کلاس پر TDG (بنا)

مہارتیں: کلاس کو پڑھنا اور اس کی وضاحت کرنا، ایسے طریقے جو آبجیکٹ کی حالت کو تبدیل کرتے ہیں، آبجیکٹ کے رویے کی جانچ کرنا۔

مقصد۔ ایک چھوٹا سا TaskList بنائیں: کتاب کے اسمارٹ نوٹس جیسی کسی چیز کا بیج۔ یہ کاموں کو شامل کر سکتا ہے، ایک کو مکمل نشان زد کر سکتا ہے، اور رپورٹ کر سکتا ہے کہ کتنے ابھی تک نامکمل ہیں۔

اسٹارٹر۔ پہلے ٹیسٹ لکھیں۔ فیصلہ کریں کہ طریقوں کو کیا کہا جاتا ہے اور وہ کیا واپس کرتے ہیں۔ یہ ڈیزائن ہے۔ نقطہ آغاز:

def test_task_flow() -> None:
tasks = TaskList()
tasks.add("write tests")
tasks.add("call agent")
assert tasks.remaining() == 2
tasks.complete("write tests")
assert tasks.remaining() == 1

پھر ایجنٹ کو ایک TaskList کلاس لاگو کرنے کا اشارہ کریں جو ٹیسٹ پاس کرتا ہے، اور تصدیق کرتا ہے۔

حل

حوالہ کا نفاذ:

class TaskList:
def __init__(self) -> None:
self.tasks: dict[str, bool] = {} # task name -> done?

def add(self, name: str) -> None:
self.tasks[name] = False

def complete(self, name: str) -> None:
if name in self.tasks: # only complete a task that exists
self.tasks[name] = True

def remaining(self) -> int:
return sum(1 for done in self.tasks.values() if not done)

کلاس ہر نام کو ایک done پرچم میں نقشہ سازی میں کاموں کو ذخیرہ کرتی ہے۔ remaining() ان کو شمار کرتا ہے جو ابھی بھی False پر سیٹ ہیں۔ نوٹس کریں کہ ٹیسٹ نے ڈیزائن کو کیسے بنایا: اس نے طریقہ کار کے ناموں اور remaining() کی واپسی کا فیصلہ کیا، اس سے پہلے کہ کوئی کوڈ موجود ہو۔

خاموش بگ کو خود پکڑیں۔ complete("a task I never added") کو کیا کرنا چاہئے؟ ایک ایجنٹ کا پہلا ورژن اکثر self.tasks[name] = True بغیر کسی if name in self.tasks کے گارڈ کے لکھتا ہے، جو خاموشی سے ایک بالکل نیا کام کا اضافہ کرتا ہے، جس میں کسی نے نہیں مانگے گئے ڈیٹا کو ایجاد کیا تھا۔ یہ بالکل قابل فہم لیکن غلط طرز عمل ہے جو ایک ٹیسٹ سے ظاہر ہوتا ہے:

def test_completing_unknown_task_does_nothing() -> None:
tasks = TaskList()
tasks.add("real task")
tasks.complete("typo task") # not a real task
assert tasks.remaining() == 1 # still one; nothing was invented

توسیع: اپنے ایجنٹ سے ہر کام کو created_at ٹائم اسٹیمپ کے ساتھ Pydantic Task ماڈل بنانے کے لئے کہیں، پھر ایک ٹیسٹ شامل کریں جو بالکل نئے TaskList میں remaining() == 0 ہے۔

یہ Project 4 - ایجنٹ کوڈ میں بگ تلاش کریں (تحقیقات · ترمیم کریں)

مہارتیں: طاقت کے تصورات کو پہچاننا (Pydantic، جنریٹر)، تنقیدی طور پر پڑھنا، ایک ایسا ٹیسٹ لکھنا جو ایک حقیقی بگ پکڑتا ہے۔

یہ آپ کے اصل کام کے قریب ترین چیز ہے: ایجنٹ آپ کو قابل فہم نظر آنے والا کوڈ دیتا ہے، اور آپ کو یہ پکڑنا ہوگا کہ کیا غلط ہے۔ نیچے دیے گئے فنکشن کو سمجھا جاتا ہے صرف نوٹوں کے عنوانات واپس کرے گا جو ہوچکے ہیں۔ لیکن اس میں ایک بگ ہے۔

from collections.abc import Iterator
from pydantic import BaseModel

class Note(BaseModel):
title: str
done: bool

def completed_titles(notes: list[Note]) -> Iterator[str]:
for note in notes:
yield note.title

آپ کا کام، ترتیب میں:

  1. تفتیش کریں۔ سادہ انگریزی میں، ہر سطر کا کیا مطلب ہے کہیں۔ (Note ماڈل کیا ہے؟ Iterator[str] آپ کو کیا بتاتا ہے؟ yield کیا کرتا ہے؟)
  2. ٹیسٹ۔ ایک pytest ٹیسٹ لکھیں جو مقصد رویے کو پن کرتا ہے: صرف مکمل شدہ نوٹ واپس آتے ہیں۔ اسے چلائیں۔ اسے ناکام ہونا چاہیے، بگ پکڑنا۔
  3. تبدیل کریں۔ اب جب کہ آپ کا ٹیسٹ درست بیان کرتا ہے، ایجنٹ کو completed_titles کو درست کرنے کا اشارہ کریں، اور جب تک آپ کا ٹیسٹ سبز نہ ہوجائے دوبارہ چلائیں۔
حل

بگ: فنکشن سے done کو مکمل طور پر نظر انداز کرتے ہوئے ہر نوٹ کا عنوان ملتا ہے۔ یہ کبھی جھنڈے کی جانچ نہیں کرتا۔

ایک امتحان جو اسے پکڑتا ہے:

def test_only_completed() -> None:
notes = [Note(title="a", done=True), Note(title="b", done=False)]
assert list(completed_titles(notes)) == ["a"]

بگی کوڈ کے خلاف یہ ناکام ہو جاتا ہے، کیونکہ یہ ["a", "b"] واپس کرتا ہے: اس بات کا ثبوت ہے کہ بگ اصلی ہے، کوئی شکار نہیں۔

فکس ایک لائن ہے: حاصل کرنے سے پہلے ایک done چیک:

def completed_titles(notes: list[Note]) -> Iterator[str]:
for note in notes:
if note.done:
yield note.title

اس Project کا نقطہ: بگ ایک نظر میں پوشیدہ تھا اور ٹیسٹ کے لیے واضح تھا۔ "یہ ٹھیک لگ رہا ہے" اسے بھیج دیا ہوگا۔ آپ کے لکھے ہوئے ٹیسٹ نے اسے پکڑ لیا۔ یہ ایک مشق میں پورا کورس ہے۔

یہ Project 5 - منی کیپ اسٹون: نوٹس ٹول، اینڈ ٹو اینڈ (پورا لوپ)

مہارتیں: ہر چیز، ایک پیڈانٹک ماڈل، ریاست کے ساتھ ایک کلاس، ایک جنریٹر، قسم کے اشارے، ایک f-سٹرنگ کا خلاصہ، اور ایک ٹیسٹ سوٹ، جو ایک TDG سائیکل کے طور پر بنایا گیا ہے۔ یہ کتاب کے SmartNotes کی ایک سکیلڈ ڈاون ریہرسل ہے۔

گول۔ ایک چھوٹا NoteBook بنائیں جس میں نوٹ ہوں (ہر ایک عنوان، باڈی، اور مکمل پرچم کے ساتھ)، آپ کو نوٹس شامل کرنے اور انہیں مکمل نشان زد کرنے دیتا ہے، ابھی تک زیر التواء کو سٹریم کرنے دیتا ہے، اور 2 notes, 1 done, pending: call sara کی طرح ایک لائن کا خلاصہ پرنٹ کرتا ہے۔

اسٹارٹر: اسے ٹیسٹ کے ذریعے ڈیزائن کریں۔ یہ اصل مشق ہے: کسی بھی عمل کو لکھنے یا تخلیق کرنے سے پہلے، ایک test_notebook.py لکھیں جو آپ کے مطلوبہ طرز عمل کو پن کرتا ہے۔ طریقہ کے ناموں کا فیصلہ کریں اور summary() کو کیا کہنا چاہئے۔ اس پر ردعمل ظاہر کرنے کے لیے ایک کنکال:

from notebook import NoteBook

def test_summary_flow() -> None:
nb = NoteBook()
nb.add("groceries", "milk, eggs")
nb.add("call sara", "about the trip")
assert nb.summary() == "2 notes, 0 done, pending: groceries, call sara"
nb.complete("groceries")
assert nb.summary() == "2 notes, 1 done, pending: call sara"

def test_pending_is_a_stream() -> None:
nb = NoteBook()
nb.add("a", "x")
nb.add("b", "y")
nb.complete("a")
assert [n.title for n in nb.pending()] == ["b"] # pending() yields, like a generator

پھر مکمل لوپ چلائیں:

  1. pytest چلائیں۔ یہ ناکام ہوجاتا ہے (ابھی تک کوئی notebook.py نہیں)۔ اچھا: یہ آپ کی قیاس آرائی ہے، مقصد میں ناکام ہونا۔
  2. اپنے agent کو prompt دیں: test_notebook.py پڑھیں۔ notebook.py بنائیں جس میں Note Pydantic model (title, body, done) اور NoteBook class ہو، اور جو ہر test pass کرے: add، complete، ایک pending() generator، اور summary() جو tests کی expected exact string واپس کرے۔ پھر pytest چلائیں اور مجھے result دکھائیں.”
  3. پڑھیں کہ اس نے کیا پیدا کیا۔ کیا آپ Pydantic ماڈل، کلاس اسٹیٹ، yield میں pending()، اور summary() میں f-سٹرنگ کی طرف اشارہ کر سکتے ہیں؟ اگر ہاں، تو آپ نے ایجنٹ کوڈ کا اصلی حصہ پڑھ لیا ہے۔ اس پر بھی pyright اور ruff چلائیں۔
  4. کسی بھی ناکامی پر اسے پڑھ کر دہرائیں، آنکھیں بند کرکے دوبارہ اشارہ نہ کریں۔
حل

ایک حوالہ کا نفاذ جو دونوں ٹیسٹ پاس کرتا ہے:

from collections.abc import Iterator
from pydantic import BaseModel

class Note(BaseModel):
title: str
body: str
done: bool = False

class NoteBook:
def __init__(self) -> None:
self.notes: list[Note] = []

def add(self, title: str, body: str) -> None:
self.notes.append(Note(title=title, body=body))

def complete(self, title: str) -> None:
for note in self.notes:
if note.title == title:
note.done = True

def pending(self) -> Iterator[Note]: # a generator: yields one note at a time
for note in self.notes:
if not note.done:
yield note

def summary(self) -> str:
total = len(self.notes)
done = sum(1 for n in self.notes if n.done)
pending_titles = [n.title for n in self.pending()]
return f"{total} notes, {done} done, pending: {', '.join(pending_titles)}"

کورس کا ہر تصور یہاں نظر آتا ہے: Pydantic model (Note) جس میں type hints اور ایک default ہے، ایک class (NoteBook) جو state رکھتی ہے، ایک method جو object کا attribute بدلتا ہے (complete)، ایک generator (pending) جو yield کرتا ہے، ایک comprehension اور sum(...)، اور ایک f-string جو summary بناتی ہے۔

اسے ایک حقیقی CLI بنائیں (AI Era کورس میں پروگرامنگ کا پل)۔ اوپر ٹیسٹ شدہ کور سخت حصہ ہے۔ اسے کمانڈ لائن ٹول میں تبدیل کرنا سب سے اوپر ایک پتلا شیل ہے۔ اپنے ایجنٹ سے ایک main() شامل کرنے کو کہیں جو ٹرمینل سے add، done، اور list جیسی کمانڈز کو پڑھتا ہے اور ان طریقوں کو کال کرتا ہے۔ پھر کسی بھی نئی منطق کے لیے ایک اور ٹیسٹ لکھنے کو کہیں۔ وہ آخری مرحلہ، ایک ورکنگ CLI جس کے پیچھے ایک پاسنگ ٹیسٹ سوٹ ہے، بالکل سمارٹ نوٹس کی شکل ہے، بالکل چھوٹا۔

کسی ایج کیس کا فیصلہ خود کریں۔ جب کچھ بھی زیر التوا نہ ہو تو summary() کو کیا کہنا چاہئے؟ حوالہ پیچھے چھوڑتا ہے pending: ۔ کیا یہ صحیح ہے؟ ایک ایسا ٹیسٹ لکھیں جو آپ کے فیصلے کو انکوڈ کرتا ہو، پھر ایجنٹ کو مطمئن کریں۔ یہ فیصلہ کرنا کہ یہاں "درست" کا کیا مطلب ہے، اور اسے ٹیسٹ کے ساتھ پن کرنا، پورا کام ہے۔

یہ Project 6 - آپ خود: کوئی اسٹارٹر نہیں، کوئی ٹیسٹ نہیں (اسے خود ہی گلنا)

مہارت: تربیتی پہیے بند ہونے کے ساتھ تصور 17۔ ہر Project نے اب تک آپ کو ایک ٹیسٹ کنکال یا دستخط دیا ہے۔ یہ آپ کو صرف ایک جملہ دیتا ہے۔

مقصد۔ "ایک ایسا ٹول بنائیں جو متن کا ایک پیراگراف لے اور تین سب سے عام الفاظ کو پرنٹ کرے۔"*

آپ کو اتنا ہی ملتا ہے۔ ٹکڑوں کے بارے میں کوئی دستخط، کوئی ٹیسٹ، کوئی اشارے نہیں۔ آپ کا کام پورا 10% ہے:

  1. سڑنا۔ ان اقدامات کو لکھیں جو آپ ہاتھ سے کریں گے، اور ہر ایک کو ٹائپ شدہ دستخط میں تبدیل کریں۔ (آپ متن کو الفاظ میں کیسے تقسیم کرتے ہیں؟ رموز اوقاف کی پٹی؟ انہیں شمار کریں؟ درجہ بندی کریں؟)
  2. یہ Spec. ہر ٹکڑے کے لیے، ایک ناکام pytest ٹیسٹ لکھیں جو "درست" کی وضاحت کرتا ہے: پہلے کچھ بھی پیدا کرنے سے پہلے۔
  3. جنریٹ کریں اور تصدیق کریں۔ ایجنٹ سے ہر یونٹ کو آپ کے ٹیسٹ کے خلاف لاگو کرنے کو کہیں۔ چلائیں pytest, pyright, ruff؛ تکرار کرنا
  4. اسے ایک ساتھ تار ایک report() میں لگائیں اور پورے بہاؤ کی جانچ کریں۔

کوئی واحد صحیح جواب نہیں ہے: صرف سڑن جہاں ہر ٹکڑا چھوٹا اور جانچنے کے قابل ہو۔ یہ مہارت ہے جس کی درجہ بندی کی جارہی ہے۔

حل (ایک درست decomposition، آپ کا مختلف ہو سکتا ہے)

چار چھوٹے، آزادانہ طور پر قابل آزمائش یونٹوں میں ایک معقول خرابی:

def clean(text: str) -> list[str]:
# lowercase, drop punctuation, split into words
cleaned = "".join(c.lower() if c.isalnum() or c.isspace() else " " for c in text)
return cleaned.split()

def tally(words: list[str]) -> dict[str, int]:
counts: dict[str, int] = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
return counts

def top_n(counts: dict[str, int], n: int) -> list[tuple[str, int]]:
return sorted(counts.items(), key=lambda pair: pair[1], reverse=True)[:n]

def report(text: str, n: int) -> str:
pairs = top_n(tally(clean(text)), n)
return ", ".join(f"{word} ({count})" for word, count in pairs)

اور جس قسم کے ٹیسٹ آپ کو لکھنا چاہیے تھے پہلے:

def test_clean_strips_punctuation() -> None:
assert clean("Hi, hi! Bye.") == ["hi", "hi", "bye"]

def test_tally_counts() -> None:
assert tally(["hi", "hi", "bye"]) == {"hi": 2, "bye": 1}

def test_report_picks_top_two() -> None:
assert report("the cat sat on the mat the cat", 2) == "the (3), cat (2)"

ایک فیصلہ جان بوجھ کر کرنے کے قابل ہے: جب دو الفاظ کی گنتی ایک جیسی ہو تو کون سا پہلے آتا ہے؟ Python کا sorted مستحکم ہے، لہذا تعلقات یہاں پہلی ظاہری ترتیب پر آتے ہیں۔ لیکن آپ کو جان بوجھ کر فیصلہ کرنا چاہئے اور اسے ایک ٹیسٹ کے ساتھ پن کرنا چاہئے، اسے حادثاتی طور پر دریافت نہیں کرنا چاہئے۔ (اگر آپ نے تعلقات کے بارے میں بالکل نہیں سوچا تو یہ ایک خلا ہے جو آپ کے ٹیسٹوں کو سامنے آنا چاہیے تھا۔)

اگر آپ کے سڑنے کے مختلف ٹکڑے تھے (کہیں کہ ایک واحد word_frequencies فنکشن) لیکن ہر ٹکڑا آزادانہ طور پر قابل جانچ تھا اور آپ کے ٹیسٹ پاس ہوئے، آپ نے اسے ٹھیک کیا۔ گریڈ اس کوڈ سے مماثل نہیں ہے: یہ ہے کہ آیا آپ نے ایک جملے کے گول کو اپنے طور پر قابل جانچ معاہدوں میں تبدیل کیا ہے۔ یہ بالکل وہی مہارت ہے جس پر آپ اس کے بعد AI کے ساتھ بنائے گئے ہر Project کے لیے انحصار کریں گے۔

جہاں بڑا جانا ہے۔

یہ وارم اپس ہیں۔ اصل پریکٹس Project AI دور میں پروگرامنگ میں SmartNotes ہے۔ آپ اس عین مطابق لوپ کا استعمال کرتے ہوئے نو مراحل میں ایک ایپلیکیشن کو بڑھاتے ہیں، پھر شروع سے ایک دوسرا (QuizForge) بنائیں جس میں یہ ثابت کرنے کے لیے کوئی رہنمائی نہیں کہ مہارت آپ کی ہے۔


آگے کیا ہے

اب آپ بنیادی شکلیں پڑھ سکتے ہیں جو زیادہ تر Python (اقدار، افعال، مجموعہ، کنٹرول فلو، اور کلاسز) بناتے ہیں، پانچ پاور تصورات کو پہچان سکتے ہیں جو ایجنٹ اور ML کوڈ کو بھرتے ہیں، Claude Code یا OpenCode میں ایک مکمل ٹیسٹ پر مبنی جنریشن سائیکل چلاتے ہیں، ایک مبہم مقصد کو قابل ذکر ٹکڑوں میں توڑ سکتے ہیں، اور آپ نے اس پر تمام چھ Projectوں پر عمل کیا ہے۔ یہی خواندگی باقی کتاب مانتی ہے۔

پاس ہو گئے ہو؟ ایک سیلف چیک

اس کورس نے کام کیا ہے اگر آپ اب ان ساتوں کو بغیر نوٹ کے کر سکتے ہیں۔ اگر کوئی متزلزل محسوس کرتا ہے، تو آگے بڑھنے سے پہلے بریکٹ میں تصور کو دوبارہ دیکھیں:

  1. فنکشن کے دستخط کو پڑھیں اور اس کے ان پٹ اور آؤٹ پٹ کی سادہ انگریزی میں وضاحت کریں۔ (تصور 5)
  2. کسی بھی کوڈ کے موجود ہونے سے پہلے یونٹ کے لیے کم از کم تین pytest ٹیسٹ لکھیں۔ (تصورات 5، 16)
  3. ٹائپ شدہ دستخط کا استعمال کرتے ہوئے، AI ایجنٹ سے ان ٹیسٹوں کے خلاف کوڈ کو لاگو کرنے کو کہیں۔ (تصورات 10، 16)
  4. pytest، Pyright، اور Ruff چلائیں، اور پڑھیں کہ ہر ایک آپ کو کیا بتاتا ہے۔ (تصور 3)
  5. ٹریس بیک نیچے سے اوپر پڑھیں اور مسئلہ کو ٹھیک ٹھیک بیان کریں۔ (تصور 16)
  6. یہ AI سے تیار کردہ کوڈ میں ایک قابل فہم لیکن غلط بگ پکڑیں۔ (منصوبہ 4)
  7. ایک مبہم، ایک جملے کے مقصد کو قابل آزمائش یونٹوں میں تحلیل کریں۔ (تصور 17، Project 6)

اگر آپ ساتوں کام کر سکتے ہیں، تو آپ Claude Code یا OpenCode کے ساتھ بیٹھ سکتے ہیں اور ایک چھوٹا، آزمائشی Python پروگرام بھیج سکتے ہیں جسے آپ حقیقت میں سمجھتے ہیں۔ یہی پورا مقصد ہے۔

یہاں سے:

  • AI ایجنٹس بنائیں: جہاں Pydantic ماڈلز، async/await، اور ٹائپ اشارے جنہیں آپ نے پہچاننا سیکھا ہے وہ ایجنٹ کوڈ کا روزمرہ مواد بن جاتا ہے۔
  • **AI کے لیے پوسٹگریس: وہ کوڈ پڑھنا جو آپ کے ایجنٹوں کے ڈیٹا کو اسٹور اور بازیافت کرتا ہے۔
  • ڈیجیٹل ایف ٹی ای کی تعمیر: ہر چیز کو کام کرنے والے AI کارکن میں جمع کرنا۔
  • AI دور میں پروگرامنگ: مکمل گہرا کورس۔ آپ نو مرحلوں میں SmartNotes بناتے ہیں، قاری سے معمار تک جاتے ہوئے، ہر قدم پر TDG سائیکل کا زیادہ حصہ رکھتے ہیں۔

آپ کوڈ ٹائپ کرنا نہیں سیکھ رہے ہیں۔ آپ ان نظاموں کو ہدایت اور تصدیق کرنا سیکھ رہے ہیں جو اسے لکھتے ہیں۔ پڑھنا ہمیشہ مشکل نصف تھا۔ اور آپ نے ابھی شروع کیا۔


60 سیکنڈ کی لغت

مدتسادہ انگریزی
PRIMM-AI+پیشن گوئی کریں · چلائیں · تفتیش کریں · ترمیم کریں · بنائیں - اس کورس کا پہلا طریقہ پڑھیں، ایجنٹ کے ساتھ بطور پارٹنر اور سچائی کے طور پر جانچیں
TDD → ​​TDGٹیسٹ سے چلنے والی ترقی: ناکام ہونے والا ٹیسٹ لکھیں، پھر کوڈ لکھیں۔ اے آئی کے دور میں یہ ٹیسٹ پر مبنی جنریشن بن جاتا ہے، آپ فیلنگ ٹیسٹ لکھتے ہیں، ایجنٹ کوڈ لکھتا ہے، آپ تصدیق کرتے ہیں کہ یہ پاس ہو گیا ہے۔
TDGٹیسٹ پر مبنی جنریشن - پہلے فیلنگ ٹیسٹ لکھیں، ایجنٹ کوڈ تیار کرتا ہے، آپ تصدیق کریں
assertایک لائن کا دعویٰ جیسا کہ assert x == 5، سچ ہونے پر کچھ نہیں کرتا، غلط ہونے پر زور سے کریش ہو جاتا ہے۔ ایٹم ہر ٹیسٹ سے بنایا گیا ہے
ٹائپ / ٹائپ اشارہکسی چیز کا ڈیٹا کس قسم کا ہے اس کے لیے ایک لیبل (str, int, float, bool)، اور ایجنٹ کو ایک درست ہدایت
فنکشن / دستخطایک نامزد، دوبارہ قابل استعمال بلاک؛ اس کی پہلی لائن ان پٹ اور آؤٹ پٹ کا معاہدہ ہے
** فہرست / ڈکٹ / سیٹ / ٹیپل**چار کنٹینرز جو ڈیٹا کو گروپ کرتے ہیں۔ dict (لیبل لگا ہوا جوڑا) وہ ہے جسے آپ سب سے زیادہ پڑھیں گے
کلاس / آبجیکٹکلاس ایک بلیو پرنٹ ہے؛ ایک چیز (مثال) اس سے بنی چیز ہے۔ object.attribute اس کا ڈیٹا پڑھتا ہے۔ object.method() اس سے عمل کرنے کو کہتا ہے
self / وصف / طریقہself کلاس کے اندر "یہ آبجیکٹ" ہے۔ ایک خصوصیت وہ ڈیٹا ہے جو اسے لے جاتا ہے۔ ایک طریقہ ایک فنکشن ہے جو کلاس میں رہتا ہے اور آبجیکٹ پر کام کرتا ہے۔
فہمایک for لوپ کو ایک لائن میں جوڑ کر نئی فہرست بنانے کے لیے
f-stringسامنے f کے ساتھ متن؛ {...} کے اندر کسی بھی چیز کو اس کی قدر (f"{name}") سے بدل دیا جاتا ہے
جنریٹر / yieldیادداشت کو فلیٹ رکھنے کے لیے ایک وقت میں ایک ایک آئٹمز واپس کریں، ایک ندی، ڈھیر نہیں۔
with (سیاق و سباق مینیجر)کسی چیز کو کھولتا ہے، اسے استعمال کرتا ہے، اور غلطی پر بھی اسے محفوظ طریقے سے بند کر دیتا ہے۔
async / awaitایک ہی وقت میں بہت سی سست چیزیں (جیسے API کالز) کرنے کے لیے بنایا گیا کوڈ
ڈنڈر (__call__, __init__)ڈبل انڈر سکور طریقے جو آپ کی اشیاء کو Python کی مقامی چیزوں کی طرح کام کرتے ہیں
ڈیکوریٹر (@name)کسی فنکشن یا کلاس کے اوپر ایک لیبل جو اس میں رویے کا اضافہ کرتا ہے
پیڈینٹکسٹرکچرڈ ڈیٹا کی توثیق کرتا ہے اور JSON اسکیموں کو خود کار طریقے سے تیار کرتا ہے جو LLMs ٹول کالنگ کے لیے استعمال کرتے ہیں
pytest / Pyright / Ruff / uvآپ کے توثیقی ٹولز: ٹیسٹ چلائیں / اقسام کی جانچ کریں / اسٹائل چیک کریں / Python کا نظم کریں
ٹریس بیکPython کی خرابی کی رپورٹ - اسے نیچے سے پڑھیں؛ آخری لائن مسئلے کا نام دیتی ہے

فلیش کارڈز اسٹڈی ایڈ


اپنی سمجھ کی جانچ کریں۔

Checking access...