for লুপ আর range — নির্দিষ্ট সংখ্যক বার চলা
কতবার চলবে জানা থাকলে for লুপই সঠিক পছন্দ। range-এর তিনটি রূপ, শেষ সীমা কেন বাদ যায়, আর for না while — কোনটা কখন।
- 1সমস্যা
- 2বোঝা
- 3উদাহরণ
- 4অনুমান
- 5নিজে করা
- 6কঠিন করা
যে সমস্যাটা আমরা সমাধান করছি
আগের মিশনে ১ থেকে ৫-এর যোগফল বের করতে আমাদের চারটে লাইন লাগল, আর তার মধ্যে দুটো ছিল শুধু হিসাব রাখার জন্য — শুরুর মান আর এক করে বাড়ানো। ওই বাড়ানোর লাইনটা ভুলে গেলেই অসীম লুপ।
কিন্তু খেয়াল করুন, এই ধরনের কাজে কতবার চলবে তা আমরা আগেই জানি। পাঁচবার। এমন ক্ষেত্রে হিসাব রাখার দায়িত্ব নিজের কাঁধে নেওয়ার কোনো দরকার নেই — পাইথনকে দিয়ে দিলেই হয়।
for লুপ ঠিক সেটাই করে। আর যেহেতু গোনার কাজটা আপনার হাতে থাকে না, for লুপ কখনো অসীম হয় না — এটাই এর সবচেয়ে বড় সুবিধা।
এই মিশন শেষে আপনি পারবেন
forলুপ দিয়ে নির্দিষ্ট সংখ্যক বার কোড চালাতেrange()-এর তিনটি রূপ ব্যবহার করতে- বলতে কেন
range(1, 5)চারটি সংখ্যা দেয়, পাঁচটি নয় - লেখার প্রতিটি অক্ষরের উপর লুপ চালাতে
forনাwhile— কোন কাজে কোনটা, সেই সিদ্ধান্ত নিতে
আগে যা জানা লাগবে: while লুপ — শর্ত সত্য থাকা পর্যন্ত চলা।
সবচেয়ে সহজ রূপ
for number in range(5):
print(number)0
1
2
3
4তিন লাইনের কাজ এক লাইনে, আর কোনো কাউন্টার নিজে সামলাতে হয়নি। পড়তে হয় এভাবে: "`range(5)` যে সংখ্যাগুলো দেয়, তাদের প্রতিটির জন্য একবার করে ব্লকটা চালাও — আর প্রতিবার সেই সংখ্যাটা `number`-এ রাখো।"
দুটো জিনিস প্রথমেই চোখে পড়ে:
শুরু হয় শূন্য থেকে, আর 5 আসে না — মোট পাঁচটি সংখ্যা, কিন্তু 0 থেকে 4। এটাই পাইথনের সর্বত্র একই নিয়ম: স্লাইসে যেমন শেষ সীমা বাদ যায়, range-এও তাই।
number নামটা আপনার পছন্দ। for i in range(5) লেখাও চলে, আর গণনার জন্য i লেখা প্রচলিত রীতি। কিন্তু সংখ্যাটার যদি একটা অর্থ থাকে, নাম দিন সেই অর্থে — for student_number in range(30) পড়েই বোঝা যায়।
range()-এর তিনটি রূপ
print("--- range(5) ---")
for i in range(5):
print(i, end=" ")
print()
print("--- range(2, 6) ---")
for i in range(2, 6):
print(i, end=" ")
print()
print("--- range(0, 10, 3) ---")
for i in range(0, 10, 3):
print(i, end=" ")
print()
print("--- range(5, 0, -1) ---")
for i in range(5, 0, -1):
print(i, end=" ")
print()--- range(5) ---
0 1 2 3 4
--- range(2, 6) ---
2 3 4 5
--- range(0, 10, 3) ---
0 3 6 9
--- range(5, 0, -1) ---
5 4 3 2 1নিয়মগুলো:
range(stop)—0থেকে শুরু,stop-এর আগে শেষrange(start, stop)—startথেকে শুরু,stop-এর আগে শেষrange(start, stop, step)— প্রতিবারstepকরে এগোয়;stepঋণাত্মক হলে পিছনের দিকে
শেষ দুটো একবার মিলিয়ে দেখুন। range(0, 10, 3) দেয় 0 3 6 9 — পরের হত 12, কিন্তু সেটা 10 ছাড়িয়ে যায়, তাই থামে। আর range(5, 0, -1) দেয় 5 4 3 2 1 — 0 আসে না, কারণ শেষ সীমা এখানেও বাদ।
কেন শেষ সীমা বাদ যায়? কারণ এতে হিসাব সহজ হয়।range(0, 5)-এ সংখ্যা কতটা?5 - 0, অর্থাৎ পাঁচটা।range(3, 8)-এ?8 - 3, পাঁচটা। বিয়োগ করলেই সংখ্যাটা পাওয়া যায়, কোনো "এক যোগ করতে হবে কি" নিয়ে ভাবতে হয় না। আর দুটোrangeপাশাপাশি বসালে —range(0, 5)আরrange(5, 10)— কিছুই বাদ পড়ে না, কিছুই দুবার আসে না।
এক থেকে দশ পর্যন্ত চাইলে
এই ভুলটা এতবার হয় যে আলাদা করে বলা দরকার:
print("Wrong — stops at 9:")
for i in range(1, 10):
print(i, end=" ")
print()
print("Right — includes 10:")
for i in range(1, 11):
print(i, end=" ")
print()Wrong — stops at 9:
1 2 3 4 5 6 7 8 9
Right — includes 10:
1 2 3 4 5 6 7 8 9 10নিয়মটা এক লাইনে: শেষ যে সংখ্যাটা চান, stop-এ তার এক বেশি লিখুন।
যোগফল জমানো — এবার সহজে
total = 0
for number in range(1, 6):
total = total + number
print("Sum of 1 to 5:", total)Sum of 1 to 5: 15while দিয়ে লেখা একই কাজের সাথে মিলিয়ে দেখুন: কাউন্টার তৈরি করা নেই, বাড়ানো নেই, অসীম লুপের ভয় নেই। শুধু অ্যাকিউমুলেটরটা আগের মতোই লুপের বাইরে শুরু করতে হয়।
লেখার উপর লুপ
for শুধু সংখ্যার উপর চলে না — লেখার উপরেও চলে, অক্ষর ধরে ধরে:
word = "Python"
for letter in word:
print(letter, end="-")
print()
vowel_count = 0
for letter in "programming":
if letter in "aeiou":
vowel_count = vowel_count + 1
print("Vowels:", vowel_count)P-y-t-h-o-n-
Vowels: 3এখানে range নেই, কারণ দরকারই নেই — for letter in word সোজা অক্ষরগুলোর উপর ঘোরে। ইনডেক্স নিয়ে হিসাব করার চেয়ে এটা সহজ, আর IndexError-এর সম্ভাবনাও থাকে না।
সংখ্যা আর অক্ষর — দুটোই একসাথে দরকার হলে enumerate() আছে, কিন্তু সেটা লিস্টের মিশনের বিষয়।
break আর continue এখানেও চলে
while-এ যেভাবে কাজ করত, ঠিক সেভাবেই:
for number in range(1, 20):
if number % 7 == 0:
print("First multiple of 7:", number)
breakFirst multiple of 7: 7for না while — সিদ্ধান্তটা কীভাবে নেবেন
একটাই প্রশ্ন করুন: কতবার চলবে, সেটা লুপ শুরুর আগেই জানা আছে?
জানা থাকলে for:
- ৫ বার চালাতে হবে
- ১ থেকে ১০০ পর্যন্ত যেতে হবে
- একটা শব্দের প্রতিটি অক্ষর দেখতে হবে
- একটা তালিকার প্রতিটি জিনিস নিয়ে কাজ করতে হবে
জানা না থাকলে while:
- সঠিক ইনপুট না পাওয়া পর্যন্ত জিজ্ঞেস করতে হবে
- ব্যবহারকারী
quitনা লেখা পর্যন্ত চলতে হবে - ফাইলে লাইন থাকা পর্যন্ত পড়তে হবে
সন্দেহ হলে for বেছে নিন। কারণ সোজা: for লুপ থেমে যাওয়ার নিশ্চয়তা দেয়, while দেয় না। যেখানে দুটোই খাটে, সেখানে যেটা কম ভুল হতে দেয় সেটাই ভালো পছন্দ।
একটা সম্পূর্ণ উদাহরণ
multiplication.py:
# Print a multiplication table, then a small summary
number = int(input("Which table? "))
upto = int(input("Up to? "))
print()
print(f"--- Table of {number} ---")
total = 0
for i in range(1, upto + 1):
result = number * i
total = total + result
print(f"{number} x {i:2} = {result:4}")
print()
print(f"Rows : {upto}")
print(f"Sum : {total}")
print(f"Average : {total / upto:.2f}")Which table? 7
Up to? 5
--- Table of 7 ---
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
Rows : 5
Sum : 105
Average : 21.00তিনটি জিনিস লক্ষ্য করুন। এক, range(1, upto + 1) — upto পর্যন্ত পেতে এক বেশি লিখতে হয়েছে। দুই, {i:2} আর {result:4} — f-string-এর ভেতরে সংখ্যাটা কত ঘর জায়গা নেবে তা বলে দেওয়া যায়, যাতে কলামগুলো সোজা থাকে। তিন, total লুপের বাইরে শুরু, ভেতরে জমছে — সেই একই অ্যাকিউমুলেটর।
আর একটা প্রশ্ন নিজেকে করুন: ব্যবহারকারী Up to?-এর জায়গায় 0 লিখলে কী হবে? range(1, 1) কোনো সংখ্যাই দেয় না, তাই লুপ একবারও চলে না — আর তারপর total / upto মানে শূন্য দিয়ে ভাগ। আগের মিশনের সেই শিক্ষাটাই আবার: লুপের পরে জমা মান ব্যবহার করার আগে যাচাই করে নিতে হয়।
কিছু ভাঙা অবস্থা ও তার সমাধান
শেষ সংখ্যাটা বাদ পড়ে যাচ্ছে range(1, 10) শেষ করে 9-এ। stop-এ এক বেশি দিন: range(1, 11)।
`TypeError: 'float' object cannot be interpreted as an integer range() শুধু পূর্ণসংখ্যা নেয়। range(2.5) বা range(1, n / 2) চলবে না — int() দিয়ে নিন, বা // দিয়ে ভাগ করুন।
`SyntaxError: expected ':' for লাইনের শেষে কোলন দেওয়া হয়নি।
`IndentationError: expected an indented block after 'for' statement লুপের ভেতরের লাইনটা ভেতরে ঠেলা হয়নি।
লুপ একবারও চলল না range ফাঁকা। range(5, 0) কিছুই দেয় না — বড় থেকে ছোটতে নামতে হলে তৃতীয় আর্গুমেন্টে -1 দিতে হয়: range(5, 0, -1)।
লুপের পরে যোগফল 0 আসছে total = 0 লাইনটা লুপের ভেতরে ঢুকে গেছে, তাই প্রতিবার শূন্য হয়ে যাচ্ছে। ওটা বাইরে থাকতে হবে।
লুপের ভেতরের ভেরিয়েবলটা বাইরে দরকার, কিন্তু NameError আসছে range ফাঁকা হওয়ায় লুপ একবারও চলেনি, তাই ভেরিয়েবলটা তৈরিই হয়নি। লুপের আগে একটা শুরুর মান দিয়ে রাখুন।
ধাপ ৪ / ৬ — অনুমান
যাচাই করুন
এই লুপটি কী ছাপবে?
for i in range(1, 5):
print(i, end=" ")- A1 2 3 4
- B1 2 3 4 5
- C0 1 2 3 4
- D1 2 3
তিন নম্বর আর্গুমেন্টটি ধাপ ঠিক করে দেয়। আউটপুট কী?
for i in range(0, 10, 3):
print(i, end=" ")- A0 3 6 9
- B0 3 6 9 12
- C3 6 9
- D0 1 2 3 4 5 6 7 8 9
প্রোগ্রামারের ইচ্ছা ছিল ১ থেকে ১০-এর যোগফল, অর্থাৎ ৫৫। কিন্তু ছাপা হচ্ছে ৪৫। কেন?
total = 0
for number in range(1, 10):
total = total + number
print("Sum of 1 to 10:", total)- A`range(1, 10)` শেষ করে `9`-এ, `10` বাদ পড়ে — `range(1, 11)` লিখতে হবে
- B`total` লুপের বাইরে শুরু করা হয়েছে, ভেতরে করা উচিত ছিল
- C`for`-এর বদলে `while` লুপ ব্যবহার করলে ঠিক আসবে
- D`total + number`-এর বদলে `total + i` লিখতে হবে
উত্তর দিতে অ্যাকাউন্ট লাগবে
উত্তর মিলিয়ে দেখতে সাইন ইন করুন
প্রশ্নগুলো উপরে আছে, আর মাথায় মাথায় উত্তর ভেবে নেওয়াই আসল কাজ। সঠিক উত্তর, ব্যাখ্যা আর তিন ধাপের ইঙ্গিত দেখতে সাইন ইন করুন।
নিজে করুন
stars.py নামে একটা ফাইল লিখুন, যেটি একটা সংখ্যা নিয়ে এরকম একটা ত্রিভুজ ছাপে। 5 দিলে:
*
**
***
****
*****তারপর এই তিনটি কাজ যোগ করুন:
- মোট কতটা তারা ছাপা হলো, সেটা নিচে লিখুন (৫-এর জন্য ১৫)
- ত্রিভুজটা উল্টো করে ছাপান — উপরে পাঁচটা, নিচে একটা
- জোড় নম্বরের সারিগুলো বাদ দিয়ে ছাপান (
continueদিয়ে)
প্রথম কাজটা মিলিয়ে দেখার একটা সহজ উপায় আছে — ১ থেকে ৫-এর যোগফল হাতে বের করে দেখুন আপনার প্রোগ্রামের সংখ্যাটার সাথে মেলে কি না। আর "*" * i মনে আছে তো? তারার সারি বানাতে লুপের ভেতরে আরেকটা লুপের দরকার নেই।
ধাপ ৬ / ৬
কঠিন করা — অধ্যায়ের কুইজ
সহজ থেকে কঠিন — দশটি প্রশ্ন, শেষেরগুলো ইচ্ছে করেই কঠিন।
সাইন ইন করে কুইজ দিন