সরাসরি পর্বে যান
পর্ব ০৪ · ৫৫-এর মধ্যে · মডিউল ১

প্রথম প্রোগ্রাম — print, comment আর ভুল পড়া

Your First Python Program — print(), Comments & Reading Error Messages

Taught in Bangla, this lesson writes a first Python program: how statements run top to bottom, print() with sep and end, a small receipt program, comments and docstrings, Python's rules for lines, whitespace and case, and how to read error messages and tracebacks.

এই পর্বে যা শিখবেন

  • Python একটি ফাইল কোন ক্রমে পড়ে ও চালায় — আর কেন একটি ভুলে কখনো কিছুই চলে না, কখনো অর্ধেক চলে
  • print() দিয়ে লেখা, সংখ্যা, হিসাব আর বাংলা ছাপা; sep ও end দিয়ে আউটপুটের চেহারা ঠিক করা
  • কখন comment লিখবেন, কী লিখবেন — আর docstring জিনিসটা কী
  • SyntaxError, NameError, IndentationError চেনা এবং একটি traceback অংশে অংশে পড়া
  • AI-কে error নিয়ে প্রশ্ন করার সঠিক কাঠামো, আর AI-এর “সমাধান” যাচাইয়ের চেকলিস্ট

১ · প্রোগ্রাম মানে নির্দেশের তালিকা — ওপর থেকে নিচে

পাড়ার চায়ের দোকানে সকালবেলা ভিড়। মামা একটি ছোট কাগজে অর্ডার লিখে ছেলেটির হাতে দিলেন: “এক — দুধ চা বানাও। দুই — দুটো সিঙ্গারা প্লেটে দাও। তিন — টেবিল নম্বর চারে দিয়ে আসো।” ছেলেটি কাগজের ওপর থেকে পড়া শুরু করবে, একটি কাজ শেষ করে পরেরটিতে যাবে। সে তিন নম্বর আগে করবে না, আর কাগজে যা লেখা নেই তা নিজে থেকে বানিয়েও নেবে না।

একটি program ঠিক এই অর্ডার স্লিপের মতো — কম্পিউটারের জন্য লেখা নির্দেশের একটি তালিকা। Python-এ প্রতিটি নির্দেশকে বলে statement, আর সাধারণত প্রতিটি statement থাকে আলাদা লাইনে। আপনি যে .py ফাইলটি লেখেন (একে script-ও বলে), Python সেটি ওপর থেকে নিচে চালায়।

তবে একটি সূক্ষ্ম কথা আছে, যা এই পর্বের অর্ধেক রহস্য খুলে দেবে। Python ফাইলটি চালানোর আগে একবার পুরোটা পড়ে নেয় এবং দেখে নেয় ব্যাকরণ (syntax) ঠিক আছে কি না। ব্যাকরণ ঠিক থাকলে তবেই প্রথম লাইন থেকে চালানো শুরু হয়। কাজটি করে Python-এর interpreter — ভেতরে ঠিক কী হয়, সেটি পর্ব ০৫-এ বিস্তারিত দেখবেন। নিচের ডায়াগ্রামে “পরে” চাপুন:

1# সকালের প্রথম অর্ডার2print("অর্ডার: দুধ চা")3print("দাম:", 15, "টাকা")4print("ধন্যবাদ!")
Python এখন কী করছে
কাজ
ছাপা হয়েছে
  1. আগে পুরো ফাইলে একবার চোখ বোলানো। সব লাইন একসাথে সবুজ — Python এখনো কিছু চালায়নি, শুধু দেখছে কোথাও বন্ধনী খোলা রয়ে গেছে কি না, কোট বন্ধ হয়েছে কি না। এখানে কোনো ভুল নেই, তাই চালানো শুরু হবে। ভুল থাকলে এই ধাপেই থেমে যেত, একটি লাইনও ছাপা হতো না।
  2. লাইন ১ — comment. # দিয়ে শুরু লাইনটি মানুষের জন্য নোট। Python এটি পুরোপুরি বাদ দিয়ে যায়, তাই আউটপুটে কিছুই আসেনি।
  3. লাইন ২ — প্রথম print. উদ্ধৃতিচিহ্নের ভেতরের লেখাটি হুবহু পর্দায় গেল, আর শেষে নিজে থেকেই নতুন লাইন শুরু হলো।
  4. লাইন ৩ — তিনটি জিনিস একসাথে। একটি লেখা, একটি সংখ্যা, আরেকটি লেখা — কমা দিয়ে আলাদা করা। print এদের মাঝে একটি করে space বসিয়ে এক লাইনে ছেপেছে: দাম: 15 টাকা.
  5. লাইন ৪ — শেষ নির্দেশ। আরেকটি লাইন ছাপা হলো। খেয়াল করুন, আউটপুটের ক্রম আর কোডের ক্রম হুবহু এক।
  6. ফাইল শেষ, প্রোগ্রামও শেষ। আর কোনো লাইন নেই, তাই Python থেমে গেল। আলাদা করে “শেষ” বলার দরকার হয়নি — C-র মতো main() বা return 0 এখানে লাগে না।
মূল ধারণা

Python-এর কাজ দুই ধাপে: (১) পুরো ফাইলের ব্যাকরণ যাচাই, তারপর (২) ওপর থেকে নিচে একটি একটি করে statement চালানো। ব্যাকরণে ভুল থাকলে কিছুই চলে না। আর চালানোর মাঝপথে কোনো লাইনে সমস্যা হলে আগের লাইনগুলোর কাজ হয়ে যায়, বাকিগুলো আর চলে না। অংশ ৭-এ এই পার্থক্যটি হাতেনাতে দেখবেন।

প্রায় প্রতিটি প্রোগ্রামিং বইয়ের প্রথম প্রোগ্রাম পর্দায় “hello, world” লেখে। এই রীতির শুরু Bell Labs-এ, Brian Kernighan-এর হাতে — প্রথমে B ভাষার একটি টিউটোরিয়ালে, পরে C-র টিউটোরিয়ালে। ১৯৭৮ সালে Kernighan ও Dennis Ritchie-র বই The C Programming Language প্রকাশিত হলে উদাহরণটি সারা বিশ্বে ছড়িয়ে পড়ে। Python-এ সেই প্রোগ্রামটি মাত্র এক লাইন: print("Hello, World!")

২ · print() — পর্দায় লেখা পাঠানো

print হলো Python-এর সঙ্গে আসা একটি function — একটি তৈরি করা যন্ত্র, যাকে নাম ধরে ডাকলে একটি নির্দিষ্ট কাজ করে দেয়। ডাকার নিয়ম: নামের পরে গোল বন্ধনী, আর বন্ধনীর ভেতরে যা ছাপাতে চান। বন্ধনীর ভেতরের এই জিনিসগুলোকে বলে argument. বন্ধনী ছাড়া শুধু print লিখলে ফাংশনটি ডাকা হয় না — অনেকটা মামাকে নাম ধরে ডেকে কিছু না বলার মতো।

লেখা ছাপাতে উদ্ধৃতিচিহ্ন লাগে

কোনো লেখা ছাপাতে চাইলে সেটি উদ্ধৃতিচিহ্নের (কোট) ভেতরে রাখতে হয়। কোটের ভেতরের লেখাকে বলে string. কোট দেখেই Python বোঝে, “এটা হুবহু লেখা — এর ভেতরে কোনো নির্দেশ খুঁজব না।” কোট না দিলে Python শব্দটিকে কোনো জিনিসের নাম ভেবে খুঁজতে যাবে, আর না পেলে error দেবে।

Python-এ একক কোট ('...') আর জোড়া কোট ("...") — দুটোই চলে, অর্থও এক। দুটো রাখার কারণ খুব ব্যবহারিক: লেখার ভেতরেই একটি কোট দরকার হলে অন্যটি দিয়ে চারপাশ ঘিরে দেওয়া যায়।

কোডপর্দায় যা আসেকী শিখলাম
print("চা হবে?")চা হবে?কোট পর্দায় আসে না, শুধু ভেতরের লেখা
print('চা হবে?')চা হবে?একক কোটেও একই ফল
print("Mama's tong")Mama's tongলেখার ভেতরে ' থাকলে বাইরে "
print('সে বলল "আসছি"')সে বলল "আসছি"লেখার ভেতরে " থাকলে বাইরে '
print("ক\nখ")ক
খ
\n মানে “এখানে নতুন লাইন”
print()(একটি ফাঁকা লাইন)কিছু না দিলে শুধু নতুন লাইন

টেবিলের \n একটি escape sequence — backslash (\) দিয়ে শুরু দুই অক্ষরের সংকেত, যা একটি বিশেষ অক্ষর বোঝায়। \n হলো newline, অর্থাৎ নতুন লাইন। একই কোট ভেতরেও লাগলে \" লেখা যায়, যেমন "সে বলল \"আসছি\"". String নিয়ে পুরো আলোচনা পর্ব ০৯-এ; আপাতত এটুকুই যথেষ্ট।

সংখ্যা আর হিসাব ছাপানো

সংখ্যার জন্য কোট লাগে না। শুধু তা-ই নয়, বন্ধনীর ভেতরে হিসাব লিখলে Python আগে হিসাবটি করে, তারপর ফলটি ছাপায়। এখানেই কোট থাকা আর না-থাকার আসল পার্থক্য:

কোডফলব্যাখ্যা
print(15 + 10)25আগে যোগ, তারপর ছাপা
print("15 + 10")15 + 10কোটের ভেতরে — তাই হুবহু লেখা, কোনো হিসাব নয়
print(3 * 10)30* মানে গুণ
print(10 / 4)2.5/ ভাগে সবসময় দশমিক সংখ্যা আসে
print(2 ** 10)1024** মানে ঘাত (2-এর 10 ঘাত)
print("দাম:", 2 * 15)দাম: 30লেখা আর হিসাব একসাথে, কমা দিয়ে আলাদা

শেষ সারিটি খেয়াল করুন। print-কে কমা দিয়ে যত খুশি argument দেওয়া যায় — লেখা, সংখ্যা, হিসাব, মিলিয়ে-মিশিয়ে। সে প্রতিটির মাঝে একটি space বসিয়ে এক লাইনে ছাপে। অনেকে শুরুতে "দাম: " + 30 লেখার চেষ্টা করেন; সেটি error দেয়, কারণ লেখা আর সংখ্যা সরাসরি + দিয়ে জোড়া যায় না। কেন যায় না, তা টাইপের আলোচনায় পর্ব ০৬-এ পরিষ্কার হবে। আপাতত নিরাপদ পথ হলো কমা। আর ভাগ ও দশমিকের কিছু মজার ফাঁদ (যেমন 0.1 + 0.2) পর্ব ০৭-এর জন্য তোলা রইল।

বাংলা ছাপানো

Python 3-এ প্রতিটি string আসলে Unicode লেখা, তাই print("আমার সোনার বাংলা") কোনো বাড়তি ঝামেলা ছাড়াই কাজ করে। ফাইলটি UTF-8-এ সেভ হলেই হলো, আর VS Code নিজে থেকেই তাই করে। কখনো Windows-এ আউটপুট অন্য ফাইলে বা অন্য প্রোগ্রামে পাঠাতে গিয়ে বাংলা অক্ষর নিয়ে error এলে python -X utf8 file.py দিয়ে চালিয়ে দেখুন — এটি Python-কে পুরোপুরি UTF-8 ব্যবহার করতে বলে।

C/C++ জানলে

C-তে একটি লাইন ছাপাতেও #include <stdio.h>, main(), printf, ; আর আলাদা compile ধাপ লাগে; Python-এ শুধু print(...). printf-এর মতো %d ফরম্যাট লাগে না — print নিজেই বোঝে কোনটা সংখ্যা, আর নতুন লাইনও নিজে দেয়। Block বোঝাতে Python কোঁকড়া বন্ধনীর বদলে indentation ব্যবহার করে, আর comment শুরু হয় // নয়, # দিয়ে। C-র দিকটি দেখতে চাইলে পড়ুন C কোর্সের প্রথম প্রোগ্রাম।

৩ · sep আর end — আউটপুটের চেহারা আপনার হাতে

আগের অংশে দেখলেন, print দুটি জিনিস নিজে থেকে করে: argument-গুলোর মাঝে একটি space বসায়, আর শেষে নতুন লাইন দেয়। এই দুটি অভ্যাস বদলানো যায় দুটি বিশেষ argument দিয়ে — sep (separator, অর্থাৎ মাঝের জিনিস) আর end (শেষের জিনিস)। এগুলো লিখতে হয় নাম ধরে, যেমন sep="-"; এ ধরনের argument-কে বলে keyword argument.

ধরুন আপনি বন্ধুর জন্মদিনে একটি ছোট শুভেচ্ছা-কার্ড পর্দায় বানাবেন। নিচের ডায়াগ্রামে দেখুন প্রতিটি পরিবর্তনে আউটপুট কীভাবে বদলায়:

card.pyকিছু না বদলালে
print("শুভ", "জন্মদিন", "রাফি")

আউটপুট:
শুভ জন্মদিন রাফি
(মাঝে space, শেষে নতুন লাইন)
card.pysep বদলানো
print("শুভ", "জন্মদিন", "রাফি", sep=" ~ ")
print("১২", "০৩", "২০২৬", sep="/")

আউটপুট:
শুভ ~ জন্মদিন ~ রাফি
১২/০৩/২০২৬
card.pyend বদলানো
print("শুভ জন্মদিন", end=", ")
print("রাফি!")

আউটপুট:
শুভ জন্মদিন, রাফি!
(দুটি print, কিন্তু একটি লাইন)
card.pyপুরো কার্ড
print("*" * 22)
print("শুভ", "জন্মদিন", sep=" ✿ ")
print("প্রিয় রাফি", end=" — ")
print("অনেক শুভকামনা")
print("*" * 22)

আউটপুট:
**********************
শুভ ✿ জন্মদিন
প্রিয় রাফি — অনেক শুভকামনা
**********************
  1. স্বাভাবিক অবস্থা। তিনটি argument, মাঝে নিজে থেকেই একটি করে space. আসলে print-এর ভেতরে আগে থেকেই ধরা আছে sep=" " আর end="\n" — এগুলোকে বলে default মান।
  2. sep বদলালে মাঝের জিনিস বদলায়। sep=" ~ " দিলে শব্দগুলোর মাঝে বসে ~ . তারিখ লেখার সময় sep="/" খুব কাজের। আর sep="" দিলে মাঝে কিছুই বসে না — শব্দগুলো গায়ে গায়ে লেগে যায়।
  3. end বদলালে শেষের জিনিস বদলায়। প্রথম print শেষে নতুন লাইনের বদলে , দিয়েছে, তাই পরের print একই লাইনে লেখা চালিয়ে গেছে। end-এ \n না থাকলে নতুন লাইন হবে না — এটা মনে রাখার মতো।
  4. সব মিলিয়ে একটি কার্ড। "*" * 22 মানে * চিহ্নটি ২২ বার — string-কে সংখ্যা দিয়ে গুণ করলে লেখাটি ততবার পুনরাবৃত্তি হয়। মাঝের লাইনে sep, তার পরের দুই print-এ end. মাত্র পাঁচ লাইনে সাজানো একটি কার্ড।

বাস্তবে লেখা আর হিসাব মেশানো আউটপুটের জন্য পেশাদাররা বেশি ব্যবহার করেন f-string — string-এর আগে একটি f বসিয়ে ভেতরে { } দিয়ে মান বসানো, যেমন print(f"মোট: {2 * 15 + 30} টাকা"). এটি ছাপে মোট: 60 টাকা. f-string-এর পুরো ক্ষমতা — দশমিকের ঘর ঠিক করা, কলাম সোজা রাখা — দেখবেন পর্ব ১০-এ। এই পর্বে আমরা কমা, sep আর end দিয়েই কাজ চালাব, যাতে ভিত্তিটা পোক্ত হয়।

৪ · একটি আসল প্রোগ্রাম — চায়ের দোকানের রসিদ

এবার শেখা জিনিসগুলো জুড়ে একটি কাজের প্রোগ্রাম লিখি। “মামার টং”-এ একজন খদ্দের দুটি দুধ চা (১৫ টাকা করে), তিনটি সিঙ্গারা (১০ টাকা করে) আর একটি বিস্কুট (৫ টাকা) নিলেন। মামা চান হাতে যোগ না করে Python-কে দিয়ে রসিদ ছাপাতে, যাতে হিসাবে ভুল না হয়। নিচের কোডটি চালিয়ে দেখুন:

# রসিদ: মামার টং (চায়ের দোকান), দাম টাকায়
# যোগফল হাতে না লিখে Python-কে দিয়ে হিসাব করাচ্ছি, যাতে ভুল না হয়
print("=" * 26)
print("   MAMAR TONG - Receipt")
print("=" * 26)
print("Milk tea  x2 @15 =", 2 * 15)
print("Singara   x3 @10 =", 3 * 10)
print("Biscuit   x1  @5 =", 1 * 5)
print("-" * 26)
print("Total            =", 2 * 15 + 3 * 10 + 1 * 5, "Tk")
print("ধন্যবাদ", "আবার আসবেন", sep=", ", end="!\n")

আউটপুটে প্রথমে = চিহ্নের একটি দাগ, দোকানের নাম, আবার দাগ; তারপর তিনটি জিনিসের লাইন — 30, 30, 5; একটি - দাগ; তারপর Total = 65 Tk; আর একদম শেষে ধন্যবাদ, আবার আসবেন!. লক্ষ করুন: (১) প্রতিটি দাম Python নিজে হিসাব করেছে, কোডে কোথাও 65 লেখা নেই। (২) বাঁ পাশের লেখাগুলো সমান দৈর্ঘ্যের (১৮ অক্ষর) রাখা হয়েছে, তাই = চিহ্ন আর সংখ্যাগুলো একই কলামে এসেছে। (৩) শেষ লাইনে sep=", " দুই অংশের মাঝে কমা বসিয়েছে, আর end="!\n" শেষে বিস্ময়চিহ্ন দিয়ে তারপর নতুন লাইন দিয়েছে।

রসিদের জিনিসের নাম ইংরেজিতে কেন? কারণটি কৌশলগত। Monospace ফন্টে প্রতিটি ইংরেজি অক্ষর সমান চওড়া, তাই space গুনে কলাম সোজা রাখা যায়। বাংলায় যুক্তাক্ষর, কার আর ফলা মিলে একটি দৃশ্যমান অক্ষর তৈরি হয় কয়েকটি Unicode চিহ্ন দিয়ে (যেমন “ন্য” তিনটি চিহ্ন), ফলে গুনে গুনে space দিলেও কলাম বাঁকা হয়ে যায়। বাংলা ছাপানোয় কোনো সমস্যা নেই — সমস্যা শুধু সারি মেলানোয়। পর্ব ০৯-এ বাংলা Unicode-এর এই ভেতরের গল্পটা দেখবেন।

এই রসিদে একটি দুর্বলতা আছে, যা আপনি হয়তো খেয়াল করেছেন: দাম 15 লেখা হয়েছে দুই জায়গায় — জিনিসের লাইনে আর মোটের হিসাবে। কাল চায়ের দাম ২০ টাকা হলে দুই জায়গাতেই বদলাতে হবে; একটি ভুলে গেলে রসিদ ভুল যোগফল দেখাবে, অথচ কোনো error আসবে না। এই সমস্যার সমাধান হলো মানটিকে একটি নাম দিয়ে একবার রাখা — অর্থাৎ ভ্যারিয়েবল, পর্ব ০৬-এর বিষয়।

REPL-এ চালালে কী হয়, ফাইলে চালালে কী হয়

পর্ব ০৩-এ আপনি REPL দেখেছেন — >>> চিহ্নের পাশে একটি করে লাইন লিখে সঙ্গে সঙ্গে ফল দেখার জায়গা। REPL একটি বাড়তি সুবিধা দেয়: আপনি কোনো হিসাব বা মান লিখলে সে নিজে থেকেই ফলটি দেখায়। কিন্তু ফাইলে এই সুবিধা নেই। পার্থক্যটা দেখুন:

>>> 2 * 15 + 3 * 10
60
>>> "মামার টং"
'মামার টং'
>>> print("মামার টং")
মামার টং

REPL প্রতিটি হিসাবের ফল নিজে থেকে দেখায় (echo). খেয়াল করুন, শুধু string লিখলে ফল আসে কোটসহ ('মামার টং') — এটি Python-এর নিজের চোখে মানটির রূপ। print দিলে আসে মানুষের পড়ার রূপ, কোট ছাড়া।

# calc.py
2 * 15 + 3 * 10
"মামার টং"
print("মামার টং")

$ python calc.py
মামার টং

প্রথম দুই লাইনের হিসাব Python ঠিকই করেছে, কিন্তু ফল কাউকে দেখায়নি — ফেলে দিয়েছে। ফাইলে কিছু দেখতে চাইলে print লাগবেই। নতুনরা প্রায়ই REPL-এ পরীক্ষা করে ফাইলে কপি করেন, তারপর অবাক হন “আউটপুট কোথায় গেল?”

৫ · Comment আর docstring — কোডের পাশে মানুষের জন্য নোট

রসিদের কোডের প্রথম দুই লাইন # দিয়ে শুরু। এগুলো comment — # থেকে লাইনের শেষ পর্যন্ত যা লেখা, Python তা পুরোপুরি উপেক্ষা করে। Comment লেখা হয় মানুষের জন্য: ছয় মাস পরের আপনার জন্য, আপনার সহকর্মীর জন্য, কিংবা যে কোডটি রিভিউ করবে তার জন্য। কোনো লাইনের শেষেও comment দেওয়া যায়, যেমন print(2 * 15) # দুই কাপ চা. PEP 8 (Python-এর স্টাইল নির্দেশিকা) বলে এমন comment-এর আগে অন্তত দুটি space আর #-এর পরে একটি space রাখতে।

“কী” নয়, “কেন” লিখুন

নতুনরা সাধারণত এমন comment লেখেন যা কোডটিই আরেকবার বাংলায় বলে দেয়। এতে কোনো তথ্য যোগ হয় না, উল্টো কোড বদলালে comment পুরোনো হয়ে মিথ্যা বলতে থাকে। ভালো comment সেই কথা বলে যা কোড দেখে বোঝা যায় না — কারণ, সিদ্ধান্ত, সতর্কতা।

✗ দুর্বল comment (কী করছে)

# 15 কে 2 দিয়ে গুণ করো
print(2 * 15)

কোড দেখেই তো বোঝা যাচ্ছে গুণ হচ্ছে! comment-টি কিছুই যোগ করেনি।

✓ কাজের comment (কেন করছে)

# শুক্রবারের অফার: দুই কাপ নিলে কাপপ্রতি ১৫, এমনিতে ২০
print(2 * 15)

এখন পাঠক জানেন 15 কোথা থেকে এলো, আর অফার শেষ হলে কী বদলাতে হবে।

Comment-এর আরেকটি বহুল ব্যবহার হলো সাময়িকভাবে কোনো লাইন বন্ধ রাখা — লাইনের শুরুতে # দিলে সেটি আর চলে না। VS Code-এ Ctrl + / চাপলে বাছাই করা লাইনগুলো একসাথে comment হয়ে যায়। Debug করার সময় কাজের কৌশল, কিন্তু কাজ শেষে এমন মৃত কোড মুছে ফেলাই ভালো অভ্যাস।

মূল ধারণা

PEP 8-এর একটি বাক্য মনে গেঁথে রাখার মতো: “Comments that contradict the code are worse than no comments.” — কোডের সাথে না মেলা comment, কোনো comment না থাকার চেয়েও খারাপ। কোড বদলালে comment-ও বদলান। আর কোড এত জটিল হলে যে লম্বা ব্যাখ্যা লাগে, তখন আগে ভাবুন কোডটিকেই সহজ করা যায় কি না।

Docstring — এক ঝলক

ফাইলের একদম শুরুতে তিনটি করে কোট ("""...""") দিয়ে লেখা একটি string রাখলে সেটি হয় docstring — পুরো ফাইলটি কী কাজের, তার পরিচয়পত্র। এটি comment-এর মতো দেখালেও আসলে comment নয়: Python এটিকে মনে রাখে, আর help() ফাংশন বা VS Code-এর মতো টুল এটি পড়ে দেখাতে পারে। তিন কোটের string কয়েক লাইন জুড়ে লেখা যায়:

"""মামার টং-এর রসিদ ছাপানোর ছোট প্রোগ্রাম।

দাম টাকায়। চালান: python receipt.py
"""
print("=" * 26)

ফাংশনের ভেতরে docstring লেখার নিয়ম আর রীতি (PEP 257) দেখবেন পর্ব ১৩-এ। এখনকার জন্য মনে রাখুন: # দেয় লাইনের পাশে নোট, docstring দেয় পুরো ফাইল বা ফাংশনের পরিচয়।

৬ · Python-এর ব্যাকরণ — লাইন, ফাঁকা জায়গা আর বড়-ছোট হাতের অক্ষর

মানুষ অনেক ভুল বানান পড়েও অর্থ বুঝে নেয়; কম্পিউটার নেয় না। Python-এর কয়েকটি ব্যাকরণ-নিয়ম প্রথম দিন থেকেই জানা দরকার, কারণ নতুনদের বেশিরভাগ error এগুলো থেকেই আসে।

এক লাইনে একটি statement

Python-এ সাধারণত লাইনের শেষই statement-এর শেষ — C-র মতো ; লাগে না। চাইলে print("ক"); print("খ") লিখে এক লাইনে দুটি statement রাখা যায়, কিন্তু PEP 8 এটিকে নিরুৎসাহিত করে। ব্যতিক্রম একটাই জানা দরকার: কোনো বন্ধনী — গোল, বর্গ বা কোঁকড়া — খোলা থাকলে Python পরের লাইনেও statement চলছে বলে ধরে নেয়। এই কারণেই একটি বন্ধনী বন্ধ করতে ভুলে গেলে Python পরের লাইনগুলো পর্যন্ত খুঁজতে থাকে।

লাইনের শুরুর ফাঁকা জায়গা — এটিও ব্যাকরণ

বেশিরভাগ ভাষায় লাইনের শুরুতে কতটা ফাঁকা রাখলেন তাতে কিছু যায় আসে না; সেটা শুধু দেখতে সুন্দর করার জন্য। Python-এ তা নয়। লাইনের শুরুর ফাঁকা জায়গাকে বলে indentation, আর Python একে ব্যাকরণের অংশ হিসেবে পড়ে: কোন লাইনগুলো একসাথে একটি দল (block), তা বোঝানো হয় indentation দিয়ে। পর্ব ১১-এ if শেখার সময় block-এর আসল ব্যবহার দেখবেন। এখনকার নিয়ম সহজ — কোনো block না থাকলে প্রতিটি লাইন একদম বাঁ দিক থেকে শুরু হবে। অকারণে একটি space-ও দিলে Python আপত্তি করবে। আর block-এর ভেতরে প্রতিটি স্তরে ৪টি space — এটাই সর্বজনীন রীতি; VS Code-এ Tab চাপলে নিজে থেকেই ৪টি space বসে।

বড় হাতের আর ছোট হাতের অক্ষর আলাদা

Python case-sensitive: print, Print আর PRINT তিনটি সম্পূর্ণ আলাদা নাম। Python চেনে শুধু ছোট হাতের print. ফোনে টাইপ করলে বা Word থেকে কপি করলে প্রথম অক্ষর প্রায়ই নিজে থেকে বড় হাতের হয়ে যায় — নতুনদের একটি খুব সাধারণ error এভাবেই আসে। আরেকটি ফাঁদ: WhatsApp বা Word থেকে কপি করা কোডে সোজা কোট (") বদলে বাঁকা কোট (“ ”) হয়ে যেতে পারে, যা Python চেনে না।

পরীক্ষার হলে রোল কল হচ্ছে: “রোল ২১৪৫!” যিনি সাড়া দেবেন, তাঁর রোল হুবহু ২১৪৫ হতে হবে — ২১৪৬ হলে চলবে না, “কাছাকাছি” হলেও না। Python-ও নাম ধরে ডাকার সময় একই রকম কড়া: pritn বা Print নামে কেউ নেই, তাই কেউ সাড়া দেয় না। পার্থক্য একটাই — আধুনিক Python অন্তত বলে দেয়, “আপনি কি print বোঝাতে চেয়েছিলেন?”

৭ · Error মেসেজ পড়া — Python আসলে সাহায্য করতে চাইছে

প্রথম দিনে লাল লেখার একটি দেয়াল দেখে অনেকেই ভাবেন, “আমি পারব না।” কথাটা উল্টো করে ভাবুন: Python আপনার ভুল খুঁজে পেয়েছে, এবং সেটি কোথায়, কী ধরনের — তা লিখে জানাচ্ছে। পেশাদার প্রোগ্রামাররাও প্রতিদিন error দেখেন; তাঁদের সাথে নতুনদের পার্থক্য হলো, তাঁরা মেসেজটি পড়েন। Python এই মেসেজগুলোকে বলে exception, আর মেসেজের পুরো বিবরণটিকে বলে traceback.

নিচের প্রোগ্রামে ইচ্ছা করে একটি বানান ভুল রাখা হয়েছে। চালিয়ে দেখুন — শুধু error নয়, error-এর আগে কী ছাপা হলো সেটাও খেয়াল করুন:

print("অর্ডার: দুধ চা")
print("দাম:", 15, "টাকা")
pritn("ধন্যবাদ!")
print("এই লাইন পর্যন্ত Python পৌঁছাবে না")

প্রথম দুই লাইন ঠিকঠাক ছাপা হয়েছে: অর্ডার: দুধ চা আর দাম: 15 টাকা. তারপর লাইন ৩-এ এসে Python pritn নামে কিছু খুঁজে পায়নি, তাই থেমে গিয়ে traceback দিয়েছে, যার শেষ লাইন: NameError: name 'pritn' is not defined. Did you mean: 'print'?. চতুর্থ লাইনটি আর চলেনি। কেন প্রথম দুই লাইন চলল? কারণ এটি ব্যাকরণের ভুল নয় — pritn("...") লেখাটা ব্যাকরণে ঠিকই আছে, শুধু নামটি অচেনা। নামটি আছে কি না, তা জানা যায় কেবল লাইনটি চালাতে গিয়ে।

একটি traceback অংশে অংশে

উপরের traceback-টি পাঁচ লাইনের। এটিকে ওপর থেকে না পড়ে, অভিজ্ঞরা যে ক্রমে পড়েন সেই ক্রমে পড়ি — শেষ লাইন আগে:

1Traceback (most recent call last):2  File "order.py", line 3, in <module>3    pritn("ধন্যবাদ!")4    ^^^^^5NameError: name 'pritn' is not defined. Did you mean: 'print'?
পড়ার খাতা
অংশ
যা জানলাম
  1. শেষ লাইনের প্রথম শব্দ — error-এর ধরন। NameError মানে “এমন একটি নাম ব্যবহার হয়েছে যা Python চেনে না।” ধরনটি জানলেই অর্ধেক খোঁজা শেষ: NameError হলে বানান দেখুন, SyntaxError হলে বন্ধনী-কোট দেখুন।
  2. কোলনের পরে — মেসেজ আর পরামর্শ। name 'pritn' is not defined — ঠিক কোন নামটি অচেনা, তা-ও বলে দিয়েছে। সাথে Did you mean: 'print'? — Python 3.10 থেকে এমন পরামর্শ দেয়, কাছাকাছি বানানের চেনা নাম খুঁজে।
  3. File লাইন — ঠিকানা। কোন ফাইল (order.py), কোন লাইন (line 3). in <module> মানে ভুলটি কোনো ফাংশনের ভেতরে নয়, ফাইলের মূল অংশে। VS Code-এ এই লাইনে Ctrl চেপে ক্লিক করলে সরাসরি সেই জায়গায় চলে যাওয়া যায়।
  4. কোডের লাইন আর ^ চিহ্ন। Python দোষী লাইনটি দেখিয়ে তার নিচে ^^^^^ দিয়ে ঠিক কোন অংশে সমস্যা, তা দাগিয়ে দেয়। এখানে দাগ পড়েছে pritn-এর নিচে। লাইনের ভেতরের এই সূক্ষ্ম অবস্থান দেখানো শুরু হয় Python 3.11 থেকে।
  5. শিরোনাম — সবশেষে। most recent call last মানে “সবচেয়ে সাম্প্রতিক ঘটনা সবার নিচে।” পরে যখন ফাংশন অন্য ফাংশনকে ডাকবে, traceback-এ অনেকগুলো File লাইন জমবে; তখনো আসল ভুলের সবচেয়ে কাছের তথ্য থাকবে নিচে। এজন্যই নিয়ম: traceback নিচ থেকে ওপরে পড়ুন।

ব্যাকরণের ভুল — যখন একটি লাইনও চলে না

NameError ধরা পড়ে চালানোর সময়। কিন্তু অংশ ১-এ দেখেছেন, Python চালানোর আগে পুরো ফাইলের ব্যাকরণ যাচাই করে। সেখানে ভুল পেলে আসে SyntaxError, আর তখন ফাইলের একটি লাইনও চলে না — ভুলটি দশম লাইনে হলেও প্রথম লাইন ছাপা হবে না। এই মেসেজে “Traceback” শিরোনাম থাকে না, সরাসরি ফাইল আর লাইন দিয়ে শুরু হয়। Python 3.14-এ নতুনদের সবচেয়ে সাধারণ চারটি ব্যাকরণ-ভুলের আসল মেসেজ:

# ১. বন্ধনী বন্ধ করা হয়নি
  File "shop.py", line 1
    print("মামার টং"
         ^
SyntaxError: '(' was never closed

# ২. কোট বন্ধ করা হয়নি
  File "shop.py", line 1
    print("Hello)
          ^
SyntaxError: unterminated string literal (detected at line 1)

# ৩. দুই argument-এর মাঝে কমা নেই
  File "shop.py", line 1
    print("Tea" 20)
          ^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?

# ৪. অকারণে লাইনের শুরুতে space
  File "shop.py", line 2
    print("b")
IndentationError: unexpected indent

প্রতিটি মেসেজ নিজেই সমাধানের দিকে ইশারা করছে: “বন্ধনী কখনো বন্ধ হয়নি”, “string শেষ হয়নি”, “কমা ভুলে গেছেন?”, “অপ্রত্যাশিত indent”. শেষেরটি IndentationError, যা আসলে SyntaxError-এরই একটি বিশেষ রূপ। তুলনার জন্য, NameError-এর মতো চালানোর সময়ের ভুলগুলোকে (NameError, পরে দেখবেন TypeError, ZeroDivisionError) একসাথে বলে runtime error.

Errorকখন ধরা পড়েআগের লাইন চলে?প্রথমে কী দেখবেন
SyntaxErrorচালানোর আগে, ব্যাকরণ যাচাইয়েনা, কিছুই চলে নাবন্ধনী, কোট, কমা, কোলন
IndentationErrorচালানোর আগেনালাইনের শুরুর space
NameErrorলাইনটি চালানোর মুহূর্তেহ্যাঁনামের বানান, বড়-ছোট হাত, কোট বাদ পড়েছে কি না

SyntaxError-এ দেখানো লাইন নম্বর সবসময় ভুলের আসল জায়গা নয়। বন্ধনী খোলা রেখে দিলে Python পরের লাইনগুলো পর্যন্ত খুঁজতে থাকে, তাই কখনো কখনো ভুল থাকে দেখানো লাইনের আগের লাইনে। দেখানো লাইনে কিছু না পেলে এক লাইন ওপরে তাকান।

একটি প্রোগ্রামে তিনটি ভুল — একটা একটা করে

বাস্তবে ভুল প্রায়ই একসাথে কয়েকটি থাকে। কিন্তু Python প্রথমটি পেলেই থেমে যায়। নিচের ডায়াগ্রামে দেখুন, একটি ঠিক করলে কীভাবে পরেরটি সামনে আসে — আর কোন ধাপে কতটুকু আউটপুট আসে:

shop.py → pythonপ্রথম চেষ্টা
print("মামার টং"_
print("চা:", 15)
····print("মোট:", 15 + 10)
pritn("আবার আসবেন")

আউটপুট: (কিছুই না)
  File "shop.py", line 1
SyntaxError: '(' was never closed
shop.py → pythonদ্বিতীয় চেষ্টা
print("মামার টং")
print("চা:", 15)
····print("মোট:", 15 + 10)
pritn("আবার আসবেন")

আউটপুট: (এখনো কিছুই না)
  File "shop.py", line 3
IndentationError: unexpected indent
shop.py → pythonতৃতীয় চেষ্টা
print("মামার টং")
print("চা:", 15)
print("মোট:", 15 + 10)
pritn("আবার আসবেন")

আউটপুট:
মামার টং
চা: 15
মোট: 25
Traceback (most recent call last):
  File "shop.py", line 4, in <module>
NameError: name 'pritn' is not defined. Did you mean: 'print'?
shop.py → pythonসব ঠিক
print("মামার টং")
print("চা:", 15)
print("মোট:", 15 + 10)
print("আবার আসবেন")

আউটপুট:
মামার টং
চা: 15
মোট: 25
আবার আসবেন
  1. প্রথম চেষ্টা — SyntaxError, শূন্য আউটপুট। ফাইলে তিনটি ভুল (লাল দাগ), কিন্তু Python দেখাল শুধু প্রথমটি: লাইন ১-এর বন্ধনী বন্ধ হয়নি। একটি লাইনও ছাপা হয়নি, কারণ ব্যাকরণ যাচাই পার হয়নি। সমাধান: শেষে ) দেওয়া।
  2. দ্বিতীয় চেষ্টা — IndentationError, এখনো শূন্য আউটপুট। বন্ধনী ঠিক হতেই পরের ব্যাকরণ-ভুলটি দেখা দিল: লাইন ৩-এর শুরুতে চারটি অকারণ space (····). এটিও চালানোর আগের ভুল, তাই এবারও কিছু ছাপা হয়নি। সমাধান: space মুছে লাইনটি বাঁ দিক থেকে শুরু করা।
  3. তৃতীয় চেষ্টা — NameError, তিন লাইন আউটপুট। এবার ব্যাকরণ পুরো ঠিক, তাই চালানো শুরু হলো। প্রথম তিন লাইন ছাপা হলো, তারপর লাইন ৪-এ pritn পেয়ে থামল। আউটপুটের পরিমাণ দেখেই বোঝা যায় এটি ভিন্ন জাতের ভুল। সমাধান: বানান ঠিক করা, Python-এর পরামর্শ মেনেই।
  4. চতুর্থ চেষ্টা — সব চলল। চার লাইনই ছাপা হলো। শিক্ষা: একবারে সব ভুল খুঁজতে যাবেন না। প্রথম মেসেজটি পড়ুন, একটি জিনিস ঠিক করুন, আবার চালান। এই ছন্দই debugging-এর ভিত্তি — পর্ব ৪০-এ এটিকে পেশাদার স্তরে নিয়ে যাব।
পরীক্ষা ও ইন্টারভিউতে
  • print-এর default sep আর end কী? — sep একটি space (" "), end একটি newline ("\n").
  • print(1, 2, 3, sep="")-এর আউটপুট? — 123; মাঝে কিছুই বসে না।
  • Comment আর docstring-এর পার্থক্য? — Comment (#) Python পুরোপুরি উপেক্ষা করে; docstring একটি string, যা Python রেখে দেয় এবং help() দিয়ে পড়া যায়।
  • SyntaxError আর NameError-এর মূল পার্থক্য? — SyntaxError চালানোর আগেই ধরা পড়ে, তাই কিছুই চলে না; NameError ধরা পড়ে সেই লাইন চালানোর সময়, আগের লাইনগুলো চলে যায়।
  • Python কি case-sensitive? — হ্যাঁ; print আর Print আলাদা নাম, দ্বিতীয়টি NameError দেয়।

৮ · AI-এর যুগে — “চলছে না” নয়, পুরো traceback দিন

Error পেলে আজকাল অনেকেই সরাসরি AI-কে জিজ্ঞেস করেন। খুব ভালো অভ্যাস — যদি প্রশ্নটি ঠিকভাবে করা হয়। “আমার কোড চলছে না, ঠিক করে দাও” লিখলে AI-কে অনুমান করতে হয়: কোন ভুল, কোন লাইন, কোন Python version? অনুমান ভুল হলে সে আত্মবিশ্বাসের সাথে ভুল সমাধান দেবে। অথচ traceback-এ এই সব তথ্য আগে থেকেই লেখা আছে। ডাক্তারকে “শরীর খারাপ” না বলে রিপোর্টটা দেখানোর মতো ব্যাপার।

ভুল প্রশ্ন: “কোড চলছে না।”
ঠিক প্রশ্ন: কোড + পুরো traceback + কী আশা করেছিলেন।

AI-এর সাধারণ “সমাধান”-ফাঁদ

AI যা করতে পারেকেন সমস্যাআপনি কী করবেন
Python 2-এর ধাঁচে print "Hello" লিখে দেয় (পুরোনো উদাহরণ থেকে শেখা)Python 3-এ SyntaxError: Missing parentheses in call to 'print'বলে দিন “Python 3.12 বা নতুন”
NameError সারাতে বানান ঠিক না করে নতুন একটি নাম তৈরি করে দেয়Error চলে যায়, কিন্তু কোড আরও জটিল আর ভুল জায়গায় ঠিক হয়আগে নিজে দেখুন — বানান ভুল কি না
Error সারাতে গিয়ে হিসাবই বদলে দেয় (যেমন দাম বা সূত্র)প্রোগ্রাম চলে, কিন্তু ভুল উত্তর দেয় — সবচেয়ে বিপজ্জনকআগের ও পরের কোড পাশাপাশি মিলিয়ে দেখুন
পুরো প্রোগ্রাম নতুন করে লিখে দেয়কী বদলাল বোঝা যায় না, নতুন ভুল ঢুকতে পারেশুধু বদলানো লাইনটি চান
Error-টাকে চাপা দেওয়ার কোড যোগ করে (try/except, পর্ব ২৪)মেসেজ আর আসে না, কিন্তু ভুলটা থেকেই যায়“error লুকাবে না, কারণ সারাবে” — স্পষ্ট বলুন

নিচের কাঠামোটি কপি করে রাখুন। শেষ দুটি নির্দেশ খেয়াল করুন — এগুলোই AI-কে আপনার যুক্তি বদলে ফেলা থেকে আটকায়, আর আপনাকে শেখার সুযোগ দেয়।

আমি Python 3.14 দিয়ে নিচের প্রোগ্রামটি চালাচ্ছি (কমান্ড: python shop.py). [এখানে পুরো কোড পেস্ট করুন] এই traceback আসছে: [এখানে পুরো traceback পেস্ট করুন — প্রথম লাইন থেকে শেষ লাইন পর্যন্ত] আমি আশা করেছিলাম আউটপুট হবে: [যা আশা করেছিলে] ১. error-এর ধরন আর কারণ সহজ বাংলায় বোঝাও। ২. শুধু যে লাইন বদলাতে হবে সেটি দেখাও, পুরো কোড আবার লিখো না। ৩. প্রোগ্রামের হিসাব বা যুক্তি বদলাবে না — শুধু ভুলটা সারাও। যুক্তিতেও সমস্যা মনে হলে আলাদা করে বলো।

AI-এর দেওয়া সমাধান হাতে পেলে — যাচাইয়ের চেকলিস্ট

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এগুলো আপনাকে কোড-লেখক থেকে চিন্তাশীল প্রোগ্রামার বানাবে।

প্র ০১প্রায় সব ভাষার প্রথম প্রোগ্রাম কেন “Hello, World” — এই রীতি কোথা থেকে এলো, আর এর আসল কাজ কী?

রীতিটির জন্ম Bell Labs-এ, ১৯৭০-এর দশকের শুরুতে। Brian Kernighan B ভাষার একটি টিউটোরিয়াল লিখেছিলেন (সাধারণত ১৯৭২-৭৩ সালের বলে উল্লেখ করা হয়), যেখানে বাইরের ভ্যারিয়েবল বোঝাতে “hello, world” ছাপানোর উদাহরণ ছিল। B-তে একটি character constant-এ মাত্র কয়েকটি অক্ষর রাখা যেত, তাই লেখাটি টুকরো করে কয়েকটি ভ্যারিয়েবলে রাখতে হয়েছিল। পরে ১৯৭৪ সালের দিকে Kernighan-এর C টিউটোরিয়ালেও এটি আসে। আর ১৯৭৮ সালে Kernighan ও Dennis Ritchie-র বই The C Programming Language (যাকে সবাই “K&R” বলে) প্রথম প্রোগ্রাম হিসেবে hello, world ছাপানো দেখালে রীতিটি সারা বিশ্বে স্থায়ী হয়ে যায়। মূল লেখায় ছোট হাতের অক্ষর ছিল, বিস্ময়চিহ্নও ছিল না — “Hello, World!” রূপটি পরে জনপ্রিয় হয়েছে।

কিন্তু এর আসল কাজ মজা নয়, পুরো পথটা পরীক্ষা করা। একটি লাইন ছাপাতে পারার মানে: ভাষাটি ইনস্টল হয়েছে, editor ঠিকমতো ফাইল সেভ করছে, ফাইলটি ঠিক জায়গায় আছে, interpreter বা compiler চলছে, আর আউটপুট পর্দায় পৌঁছাচ্ছে। প্রোগ্রামটি এত ছোট যে ভুল হলে দোষ কোডের নয় — পরিবেশের। পেশাদাররা নতুন সার্ভার, নতুন টুল বা নতুন লাইব্রেরি পেলেও প্রথমে এমন একটি “ধোঁয়া-পরীক্ষা” (smoke test) চালান।

Hello World ভাষাগুলোর তুলনাও করে দেয়। C-তে লাগে header, main, printf, return আর compile; Java-তে class আর public static void main; Python-এ এক লাইন। এই পার্থক্য Python-এর নকশার একটি দর্শন দেখায় — শুরু করা সহজ হোক, আনুষ্ঠানিকতা যেন শেখার পথে বাধা না হয়। আবার উল্টো দিকও আছে: C-র আনুষ্ঠানিকতা আপনাকে প্রথম দিনেই দেখায় প্রোগ্রাম কোথা থেকে শুরু হয়, কী ফেরত দেয়; Python সেগুলো লুকিয়ে রাখে।

মূল উপলব্ধি: নতুন যেকোনো পরিবেশে আগে সবচেয়ে ছোট কাজটি চালিয়ে দেখুন। আসল কাজের মাঝখানে নয়, শুরুতেই নিশ্চিত হোন যে পথটি খোলা — তাহলে পরের ভুলগুলো কোথা থেকে আসছে তা আলাদা করা সহজ হবে।

প্র ০২Python 2-তে print "Hello" চলত, Python 3-এ কেন বন্ধনী লাগে? একটি ছোট শব্দ বদলাতে এত ঝামেলা কেন করা হলো?

Python 2-তে print ছিল একটি statement — ভাষার একটি বিশেষ শব্দ, if বা for-এর মতো, যার নিজস্ব অদ্ভুত নিয়ম ছিল। লাইনের শেষে কমা দিলে নতুন লাইন বন্ধ হতো (print "a",); অন্য জায়গায় লিখতে হলে বিশেষ চিহ্ন লাগত (print >>sys.stderr, "error"); মাঝের space বদলানোর কোনো সহজ উপায় ছিল না। আর যেহেতু এটি ফাংশন ছিল না, তাই একে অন্য ফাংশনে পাঠানো যেত না, নিজের মতো আরেকটি print দিয়ে বদলানোও যেত না।

২০০৬ সালে Georg Brandl PEP 3105 — “Make print a function” প্রস্তাব করেন। Python-এর স্রষ্টা Guido van Rossum নিজেও আগে থেকেই print statement-কে নকশার একটি ভুল মনে করতেন। প্রস্তাব অনুযায়ী print হলো একটি সাধারণ ফাংশন, আর সেই বিশেষ নিয়মগুলোর জায়গা নিল পরিষ্কার keyword argument: sep, end, file (পরে Python 3.3-এ flush). এখন print("error", file=sys.stderr) সবার কাছে পড়তে সহজ, আর এই পর্বে যে sep/end শিখলেন, তা এই পরিবর্তনেরই ফল।

দাম কিন্তু কম ছিল না। ২০০৮ সালের ডিসেম্বরে Python 3.0 এলো ইচ্ছা করে পুরোনো কোডের সাথে অসামঞ্জস্যপূর্ণ হয়ে — শুধু print নয়, string-এর Unicode আচরণ, ভাগের নিয়মসহ অনেক কিছু বদলেছিল। লক্ষ লক্ষ লাইন পুরোনো কোড এক রাতে Python 3-এ চলত না। উত্তরণে প্রায় এক যুগ লেগেছে; Python 2-র আনুষ্ঠানিক সমাপ্তি হয় ২০২০ সালের ১ জানুয়ারি। মাঝের সময়টায় Python 2.6 থেকে from __future__ import print_function লিখে পুরোনো কোডেও নতুন print ব্যবহার করা যেত, যাতে মানুষ ধীরে ধীরে সরে আসতে পারে।

আজও ইন্টারনেটের অনেক পুরোনো উদাহরণ, আর সেগুলো থেকে শেখা AI, মাঝে মাঝে বন্ধনী ছাড়া print লিখে ফেলে। Python 3 তখন নিজেই বলে দেয়: Missing parentheses in call to 'print'. Did you mean print(...)?

মূল উপলব্ধি: ভাষার নকশায় “বিশেষ ব্যতিক্রম” প্রথমে সুবিধাজনক মনে হয়, কিন্তু সময়ের সাথে বোঝা হয়ে দাঁড়ায়। সাধারণ, একই নিয়মে চলা জিনিস (এখানে: সব কিছুই ফাংশন) দীর্ঘমেয়াদে বেশি নমনীয় — যদিও বদলানোর খরচ অনেক বড় হতে পারে।

প্র ০৩C, Java, JavaScript block বোঝায় { } দিয়ে; Python কেন indentation দিয়ে? এটা কি শুধু রুচির ব্যাপার?

Python-এর এই সিদ্ধান্তের শিকড় ABC নামের একটি ভাষায়। ১৯৮০-এর দশকে নেদারল্যান্ডসের CWI গবেষণা প্রতিষ্ঠানে Guido van Rossum ABC ভাষার বাস্তবায়নে কাজ করতেন। ABC বানানো হয়েছিল নতুনদের জন্য সহজ ভাষা হিসেবে, আর সেখানে block বোঝানো হতো indentation দিয়ে। ১৯৮৯ সালের শেষে Guido যখন Python লেখা শুরু করেন, তখন ABC-র এই ধারণাটি তিনি নিয়ে আসেন। ধারণাটি আরও পুরোনো: ১৯৬৬ সালে Peter Landin তাঁর বিখ্যাত প্রবন্ধে এমন নিয়মকে “off-side rule” নাম দেন, আর পরে Haskell, F# ও YAML-এর মতো ভাষাও এটি ব্যবহার করে।

যুক্তিটা রুচির চেয়ে গভীর। Brace-ওয়ালা ভাষায় দুটি জিনিস আলাদা: compiler দেখে বন্ধনী, মানুষ দেখে indentation. দুটো না মিললে মানুষ যা পড়ছে আর মেশিন যা চালাচ্ছে তা ভিন্ন হয়ে যায়। এর সবচেয়ে বিখ্যাত উদাহরণ ২০১৪ সালে Apple-এর SSL কোডের “goto fail” বাগ: C কোডে একটি goto fail; লাইন ভুল করে দুবার লেখা হয়েছিল। Indentation দেখে মনে হচ্ছিল দ্বিতীয়টিও শর্তের ভেতরে, কিন্তু বন্ধনী না থাকায় সেটি সবসময় চলত — ফলে একটি গুরুত্বপূর্ণ নিরাপত্তা-যাচাই বাদ পড়ে যেত। Python-এ এমন অমিল সম্ভবই নয়, কারণ যা দেখছেন, সেটাই ব্যাকরণ।

Python-এর আরেকটি পরিচিত দর্শন হলো, কোড যতবার লেখা হয় তার চেয়ে অনেক বেশিবার পড়া হয় — PEP 8 এই কথাটি Guido-র উক্তি হিসেবে উল্লেখ করে। Indentation বাধ্যতামূলক হওয়ায় সব Python কোড মোটামুটি একই রকম দেখায়; অন্যের কোড পড়া সহজ হয়।

অসুবিধাও আছে। ওয়েবসাইট বা চ্যাট থেকে কপি করলে indentation নষ্ট হয়ে কোড ভেঙে যেতে পারে; Tab আর space মেশালে Python 3 TabError দেয়; খুব গভীর nesting-এ লাইন ডানে সরে যায়। মজার ব্যাপার, Python-এ from __future__ import braces লিখে দেখুন — উত্তর আসে SyntaxError: not a chance. এটি ভাষার নির্মাতাদের রসিকতা, আর একটি স্পষ্ট ঘোষণাও।

মূল উপলব্ধি: ভালো নকশা প্রায়ই “দুটি সত্যের উৎস”-কে একটিতে নামিয়ে আনে। মানুষের চোখ আর মেশিনের নিয়ম যখন একই জিনিস দেখে, তখন একটি পুরো শ্রেণির ভুল নিজে থেকেই অসম্ভব হয়ে যায়।

প্র ০৪পুরোনো Python-এর error মেসেজ ছিল শুধু “invalid syntax”; এখন কেন সে “'(' was never closed” বা “Did you mean” বলে? কী বদলেছে?

অনেক বছর ধরে Python-এর ব্যাকরণ-ভুলের মেসেজ ছিল প্রায় সবসময় একই: SyntaxError: invalid syntax, আর একটি ^ চিহ্ন, যা প্রায়ই ভুলের আসল জায়গা থেকে দূরে থাকত। বন্ধনী খোলা রাখলে error দেখাত পরের লাইনে, আর নতুনরা সেই নির্দোষ লাইনটির দিকে তাকিয়ে বসে থাকতেন। বদলটা এসেছে ধাপে ধাপে, কয়েকটি version জুড়ে।

  • ভিত্তি — নতুন parser (Python 3.9): PEP 617-এর মাধ্যমে Python-এর ব্যাকরণ পড়ার অংশটি (parser) নতুন করে লেখা হয়। নতুন parser অনেক বেশি তথ্য ধরে রাখতে পারে, তাই ভুলের ধরন চেনা সহজ হয়।
  • Python 3.10: নির্দিষ্ট মেসেজ আসে — '(' was never closed, Perhaps you forgot a comma?, আর NameError ও AttributeError-এ কাছাকাছি নামের পরামর্শ: Did you mean: 'print'?
  • Python 3.11 — PEP 657: traceback-এ লাইনের ভেতরে ঠিক কোন অংশে ভুল, তা ^^^^ ও ~~~~ চিহ্ন দিয়ে দেখানো শুরু হয়। এক লাইনে কয়েকটি হিসাব থাকলেও বোঝা যায় কোনটি দোষী।
  • Python 3.12 ও 3.13: আরও পরামর্শ যোগ হয় — যেমন স্ট্যান্ডার্ড লাইব্রেরির module import করতে ভুলে গেলে মনে করিয়ে দেওয়া; 3.13-এ টার্মিনালে রঙিন traceback আর ভুল keyword argument-এর নামে পরামর্শ।
  • Python 3.14: keyword-এর বানান ভুলেও পরামর্শ — whille লিখলে Did you mean 'while'?

এই কাজের সামনের সারিতে ছিলেন Python core developer Pablo Galindo Salgado সহ কয়েকজন; নতুন parser আর PEP 657 — দুটোরই লেখকদের মধ্যে তিনি আছেন। অন্য ভাষার জগতেও একই হাওয়া বইছিল — Clang, Rust বা Elm-এর মতো টুলের বন্ধুসুলভ মেসেজ দেখিয়েছিল যে error মেসেজও ব্যবহারকারীর অভিজ্ঞতার অংশ।

একটি সতর্কতা: “Did you mean” একটি অনুমান, নির্দেশ নয়। আপনি হয়তো নতুন একটি নাম বানাতে চেয়েছিলেন, তৈরি করতে ভুলে গেছেন; তখন print-এর পরামর্শ মানলে ভুল আরও বাড়বে। আর পুরোনো Python (যেমন 3.8) ব্যবহার করলে এসব সাহায্যের অনেকটাই পাবেন না — নতুন version ব্যবহারের এটিও একটি বাস্তব কারণ।

মূল উপলব্ধি: Error মেসেজ হলো একটি টুলের ব্যবহারকারী-ইন্টারফেস। ভালো মেসেজ বলে কী হয়েছে, কোথায় হয়েছে, আর সম্ভবত কী করতে হবে — আপনি নিজে কোনো প্রোগ্রাম বানালে তার error মেসেজও এভাবে লিখুন।

প্র ০৫অভিজ্ঞরা কেন বলেন comment-এ “কী” নয়, “কেন” লিখুন? বেশি comment লেখা কি খারাপ?

Brian Kernighan ও Rob Pike ১৯৯৯ সালে The Practice of Programming বইয়ে comment নিয়ে কয়েকটি সোজাসাপ্টা পরামর্শ দেন, যা আজও উদ্ধৃত হয়: স্পষ্ট জিনিস নিয়ে কথা বাড়াবেন না (“Don't belabor the obvious”); কোডের সাথে বিরোধিতা করবেন না (“Don't contradict the code”); আর খারাপ কোডকে comment দিয়ে ব্যাখ্যা না করে নতুন করে লিখুন (“Don't comment bad code, rewrite it”). শেষ কথাটির শিকড় আরও পুরোনো — Kernighan ও P. J. Plauger-এর ১৯৭৪ সালের বই The Elements of Programming Style.

যুক্তিটা এরকম। কোড নিজেই বলে দেয় কী হচ্ছে — 2 * 15 দেখলেই বোঝা যায় গুণ হচ্ছে। এটা আবার comment-এ লিখলে দুটি সমস্যা: পাঠকের সময় নষ্ট, আর রক্ষণাবেক্ষণের বোঝা। কাল কেউ কোডে 2 * 20 করল কিন্তু comment-এ “15 দিয়ে গুণ” রয়ে গেল — এখন comment মিথ্যা বলছে, আর পাঠক বুঝতে পারছেন না কোনটা বিশ্বাস করবেন। PEP 8 ঠিক এই কারণেই বলে, কোডের সাথে না মেলা comment, কোনো comment না থাকার চেয়েও খারাপ।

অন্যদিকে, যা কোড কখনো বলতে পারে না তা হলো কারণ: এই সংখ্যাটা কেন ১৫ (শুক্রবারের অফার); এই সহজ পথটা কেন নেওয়া হয়নি (বড় ইনপুটে ধীর); এই অদ্ভুত লাইনটা কেন আছে (অমুক ব্যাংকের API এভাবেই চায়)। এই তথ্য হারিয়ে গেলে পরের কেউ “অপ্রয়োজনীয়” ভেবে লাইনটা মুছে ফেলবে, আর পুরোনো বাগ ফিরে আসবে।

তাহলে বেশি comment কি খারাপ? সংখ্যা নয়, মান গুরুত্বপূর্ণ। শেখার সময় নিজের জন্য বিস্তারিত নোট রাখা খারাপ নয় — এই কোর্সের উদাহরণেও মাঝে মাঝে ব্যাখ্যামূলক comment পাবেন। কিন্তু পেশাদার কোডে লক্ষ্য হলো: ভালো নাম আর সহজ গঠন দিয়ে কোডকে নিজের কথা নিজে বলতে দেওয়া, আর comment রাখা কারণ, সতর্কতা ও সিদ্ধান্তের জন্য। AI-এর লেখা কোডে প্রায়ই প্রতিটি লাইনের ওপর “কী”-জাতীয় comment থাকে — সেগুলো ছেঁটে “কেন”-জাতীয় comment রাখা একটি ভালো অনুশীলন।

মূল উপলব্ধি: Comment হলো ভবিষ্যতের পাঠকের কাছে লেখা চিঠি। যে কথা কোড দেখে বোঝা যায় না, শুধু সেটুকুই লিখুন — আর কোড বদলালে চিঠিটাও হালনাগাদ করুন।

অনুশীলন

প্রথম তিনটিতে কোড লিখতে হবে না — আগে মাথায় উত্তর ঠিক করুন, তারপর চালিয়ে মিলিয়ে দেখুন।

  1. আউটপুট অনুমান করুন: নিচের তিন লাইনের আউটপুট কাগজে লিখুন, তারপর চালিয়ে মেলান — print("ঢাকা", "চট্টগ্রাম", sep=" → ", end=" | "), print("সময়:", 5, "ঘণ্টা"), print(3 * 20, "টাকা", sep="")

    প্রথম লাইনের শেষে নতুন লাইন নেই, তাই দ্বিতীয়টি একই লাইনে বসে: ঢাকা → চট্টগ্রাম | সময়: 5 ঘণ্টা. তৃতীয় লাইনে আগে হিসাব (60), তারপর sep="" থাকায় কোনো ফাঁকা নেই: 60টাকা. অর্থাৎ মোট দুই লাইন আউটপুট। যদি তিন লাইন ভেবে থাকেন, end-এর কাজটি আরেকবার দেখে নিন।

  2. Error শিকারি: প্রতিটির জন্য বলুন কোন error আসবে, আর error-এর আগে কিছু ছাপা হবে কি না — (ক) প্রথম লাইন print("শুরু"), দ্বিতীয় লাইন Print("শেষ") (খ) প্রথম লাইন print("শুরু"), দ্বিতীয় লাইন print("শেষ) (গ) একটি লাইন print(মামা)

    (ক) NameError — Print নামে কিছু নেই; ব্যাকরণ ঠিক, তাই আগে শুরু ছাপা হবে, তারপর error (সাথে Did you mean: 'print'?)।

    (খ) SyntaxError: unterminated string literal — কোট বন্ধ হয়নি। ব্যাকরণের ভুল, তাই প্রথম লাইনটিও ছাপা হবে না।

    (গ) NameError: name 'মামা' is not defined — কোট ছাড়া লেখায় Python “মামা” নামের কোনো জিনিস খুঁজছে। Python বাংলা অক্ষরেও নাম রাখতে দেয়, তাই এটি ব্যাকরণের ভুল নয়, অচেনা নামের ভুল। সমাধান: print("মামা").

  3. REPL বনাম print: পর্ব ০৩-এর মতো টার্মিনালে python লিখে REPL খুলুন। একবার শুধু "আজ বৃষ্টি" লিখে Enter, আরেকবার print("আজ বৃষ্টি"). দুই আউটপুটে পার্থক্য কী? এবার শুধু print (বন্ধনী ছাড়া) লিখে দেখুন কী আসে।

    প্রথমটিতে REPL মানটি নিজে দেখায় কোটসহ — 'আজ বৃষ্টি', যাতে বোঝা যায় এটি একটি string. দ্বিতীয়টিতে print মানুষের পড়ার জন্য কোট ছাড়া ছাপে। বন্ধনী ছাড়া print লিখলে কিছু ছাপা হয় না; REPL শুধু জানায় এটি একটি built-in function — <built-in function print>. অর্থাৎ নাম লিখলে ফাংশনটিকে দেখা যায়, বন্ধনী দিলে তবেই সেটি চলে। এই পার্থক্যটা পর্ব ১৩-এ ফাংশন শেখার সময় খুব কাজে লাগবে।

  4. নিজের রসিদ: আপনার এলাকার একটি দোকানের (ফুচকা, ফটোকপি, মুদি — যেকোনো) জন্য একটি রসিদ-প্রোগ্রাম লিখুন: অন্তত তিনটি জিনিস, প্রতিটির পরিমাণ × দাম Python দিয়ে হিসাব, মোট টাকা, শুরুতে একটি “কেন”-জাতীয় comment, আর শেষ লাইনে sep বা end ব্যবহার করে একটি শুভেচ্ছা।

    একটি নমুনা (একমাত্র সঠিক উত্তর নয়):

    # ফটোকপির দোকান; রঙিন পাতার দাম বেশি, তাই আলাদা লাইনে রাখা
    print("-" * 24)
    print("B/W copy   x40  @2 =", 40 * 2)
    print("Color copy  x5 @10 =", 5 * 10)
    print("Binding     x1 @30 =", 1 * 30)
    print("-" * 24)
    print("Total              =", 40 * 2 + 5 * 10 + 1 * 30, "Tk")
    print("ধন্যবাদ", "আবার আসবেন", sep=" — ", end="!\n")

    যাচাই করুন: মোট হাতে হিসাব করলে ৮০ + ৫০ + ৩০ = ১৬০ — আউটপুটের সাথে মেলে? বাঁ পাশের লেখাগুলো সমান দৈর্ঘ্যের না হলে = চিহ্নগুলো এক কলামে আসবে না; space গুনে ঠিক করুন। আর comment-টি কি “কী” বলছে, না “কেন”?

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমএকটি traceback পেলে কাজের সঠিক ক্রম সাজান (▲▼ চেপে সরান)

  1. শেষ লাইন পড়ে error-এর ধরন ও মেসেজ জানা
  2. File লাইন থেকে ফাইলের নাম ও লাইন নম্বর বের করা
  3. কোডের সেই লাইনে গিয়ে ^ চিহ্নের জায়গাটি দেখা
  4. একটিমাত্র জিনিস ঠিক করা
  5. প্রোগ্রাম আবার চালিয়ে পরের মেসেজ দেখা

Python-এ print("A", "B", "C", sep="") চালালে আউটপুট কী হবে?

  • A B C
  • ABC
  • A,B,C
  • SyntaxError

Python 3.10 বা নতুন version-এ print("Hello" (শেষের বন্ধনী নেই) চালালে কোন মেসেজ আসে?

  • NameError: name 'Hello' is not defined
  • IndentationError: unexpected indent
  • SyntaxError: '(' was never closed
  • SyntaxError: unterminated string literal

একটি লম্বা Python traceback পেলে প্রথমে কোন অংশটি পড়া সবচেয়ে কাজের?

  • প্রথম লাইন — Traceback (most recent call last)
  • সবচেয়ে ওপরের File লাইন
  • শুধু ^ চিহ্ন
  • শেষ লাইন — error-এর ধরন ও মেসেজ

একটি Python ফাইলের প্রথম লাইন print("শুরু"), দ্বিতীয় লাইন Print("শেষ"). চালালে কী ঘটবে?

  • “শুরু” ছাপা হবে, তারপর NameError
  • দুটি লাইনই ছাপা হবে
  • কিছুই ছাপা হবে না, শুরুতেই SyntaxError
  • IndentationError আসবে

নিচের কোন comment-টি সবচেয়ে কাজের?

  • # 2 কে 15 দিয়ে গুণ করো
  • # শুক্রবারের অফার: দুই কাপে কাপপ্রতি ১৫ টাকা
  • # পর্দায় লেখা ছাপাও
  • # এখানে কিছু একটা হচ্ছে

REPL-এ 2 + 3 লিখলে 5 দেখায়। একই লাইনটি একা একটি .py ফাইলে রেখে চালালে কী হবে?

  • পর্দায় 5 দেখাবে
  • SyntaxError আসবে
  • হিসাব হবে, কিন্তু পর্দায় কিছুই দেখাবে না
  • NameError আসবে

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. Python আগে পুরো ফাইলের ব্যাকরণ যাচাই করে, তারপর ওপর থেকে নিচে একটি একটি statement চালায়।
  2. print কমা দিয়ে দেওয়া জিনিসগুলোর মাঝে space আর শেষে newline দেয়; বদলাতে sep ও end. লেখা কোটের ভেতরে, হিসাব কোটের বাইরে।
  3. Comment (#) মানুষের জন্য — লিখুন কেন, কী নয়। Docstring (""") ফাইল বা ফাংশনের পরিচয়পত্র।
  4. বানান, বড়-ছোট হাতের অক্ষর আর লাইনের শুরুর indentation — Python-এ সবই ব্যাকরণ।
  5. SyntaxError হলে কিছুই চলে না, NameError হলে আগের লাইনগুলো চলে। Traceback নিচ থেকে ওপরে পড়ুন; AI-কে দিন পুরো traceback, আর তার সমাধান মিলিয়ে দেখুন।

পরের পর্বে: আজ বারবার বলেছি “Python আগে ব্যাকরণ যাচাই করে, তারপর চালায়।” পরের পর্বে সেই পর্দাটা সরাব — interpreter আসলে কী, bytecode কী, আর কেন বলা হয় Python-এ সবকিছুই object.

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান