> For the complete documentation index, see [llms.txt](https://python.howtocode.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://python.howtocode.dev/control-structure/for-loop.md).

# for লুপ

এর আগে আমরা দেখেছি কোন একটা নির্দিষ্ট কন্ডিশনের সত্যতার উপর ভিত্তি করে একটি কাজ একাধিকবার করার জন্য `while` লুপের ব্যবহার। কিন্তু, পাইথনের যেকোনো সিকোয়েন্স টাইপ অবজেক্ট যেমন, লিস্ট (`list`) এর প্রত্যেকটি এলিমেন্ট নিয়ে কাজ করার জন্য `while` লুপ ব্যবহার করলে একটু বেশি কোড লিখতে হয়। যেমন `while` লুপের কনসেপ্ট ঝালাই করতে এবং ব্যাপারটা বুঝতে নিচের উদাহরণটি দেখি,

```python
fruits = ["Apple", "Orange", "Pineapple", "Grape"]
# Lets make juice with these fruits

start_index = 0
max_index = len(fruits) - 1

while start_index <= max_index: # Work until this condition is True
    fruit = fruits[start_index]
    print(fruit + " Juice!")

    start_index = start_index + 1
```

আউটপুট,

```python
Apple Juice!
Orange Juice!
Pineapple Juice!
Grape Juice!
```

ঠিক একই কাজ `for` লুপ ব্যবহার করে করলে অনেক কম কোড লিখেই করা সম্ভব। `for` লুপ দিয়ে খুব সহজেই যেকোনো সিকোয়েন্স টাইপ অবজেক্ট যেমন `list`, `string` ইত্যাদির মধ্যে iterate করা যায়। তাহলে দেখি উপরের প্রোগ্রামটি কিভাবে ফর লুপ ব্যবহার করে করা সম্ভব,

```python
fruits = ["Apple", "Orange", "Pineapple", "Grape"]
# Lets make juice with these fruits

for fruit in fruits:
    print(fruit + " Juice!")
```

আউটপুট,

```python
Apple Juice!
Orange Juice!
Pineapple Juice!
Grape Juice!
```

আউটপুট কিন্তু একই। তাই, যখনই কোন iterable নিয়ে কাজ করার প্রয়োজন পরবে তখন `for` লুপ ব্যবহার করাই ভালো হয়।

> অন্যান্য ল্যাঙ্গুয়েজ যেমন php তে এরকম কাজের জন্য আছে `foreach` যা দিয়ে কোন অ্যারে তে অপারেশন করা অনেক সহজ হয়ে যায়

এখন ধরুন আপনার কাছে কোন লিস্ট নাই কিন্তু নির্দিষ্ট সংখ্যকবার একটি কাজ পুনরাবৃত্তি করা দরকার। তখন কি করব? এ জন্য একটি সুন্দর ফাংশন হতে পারে `range` যা আমরা আগের চ্যাপ্টারে দেখে এসেছি। মনে আছে, `range` ব্যবহার করে ইচ্ছামত লিস্ট তৈরি করা যায়? এটাকেই কাজে লাগিয়ে নিচের উদাহরণটি দেখি,

```python
for i in range(10):
    print(i)
```

আউটপুট,

```python
0
1
2
3
4
5
6
7
8
9
```

অর্থাৎ, `range` ফাংশন ব্যবহার করে একটি কাল্পনিক লিস্ট তৈরি করা হয়েছে যার এলিমেন্ট গুলো ছিল ০ থেকে ৯ পর্যন্ত `[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]` এরকম। আর সেই লিস্টকেই iterate করা হয়েছে for লুপ দিয়ে অর্থাৎ ১০ বার কাজ করানো হয়েছে এই লুপকে। আর কাজটা ছিল তেমন কিছুই না প্রত্যেকটি এলিমেন্টকে ধরে প্রিন্ট করা।

এখন পর্যন্ত `range` ফাংশন এ প্যারামিটার হিসবে আমরা একটিমাত্র আর্গুমেন্ট দিচ্ছিলাম। আমরা যখন ফর লুপে `range(10)` লিখেছিলাম, এটি মূলত ০ থেকে ৯ পর্যন্ত প্রিন্ট করেছে। আবার একইভাবে যদি `range(20)` বসাই, তাহলেও একইভাবে ০ থেকে ১৯ পর্যন্ত প্রিন্ট করে দেখাতো । কিন্তু আমরা চাইলে আমাদের রেঞ্জ পছন্দমত বলে দিতে পারি, যেমন ধরুন, ৫ থেকে শুরু করে ৯ পর্যন্ত। এজন্য আমাদের যা করতে হবে , রেঞ্জ ফাংশনে দুইটা মান বা প্যারামিটার পাস করতে হবে, প্রথমটা শুরু এবং পরেরটা শেষের মান। নিচের কোডটা খেয়াল করি -

```python
# start with 5 and ends with 10
for i in range(5, 10):
      print(i)
```

আউটপুট

```
5, 6, 7, 8, 9
```

এছাড়াও আমরা স্টেপ সাইজও বলে দিতে পারি এখানে। মানে, কত ঘর পরপর মান বা ভ্যালু প্রিন্ট করবে সেটা। এরজন্য আমাদের উপরের মানদুটির সাথে আরো একটি প্যারামিটার দিতে হবে, যেটা হবে ইন্টারভাল বা স্টেপ সাইজ। যেমন ধরুন, আমরা ৫ থেকে ১৫ পর্যন্ত প্রিন্ট করবো এবং চাই যে তিন ঘর পরপর প্রিন্ট হোক। তাহলে এর জন্য আমাদের রেঞ্জ ফাংশনের ভিতরে যথাক্রামে, 'শুরু, শেষ, স্টেপ\_সাইজ' মানগুলো বসাতে হবে। নিচের কোডটা খেয়াল করি -

```python
# start with 5 and ends with 15 and step size 3
for i in range(5, 15, 3):
      print(i)
```

আউটপুট

```
5 , 8 , 11 , 14
```

আচ্ছা এ পর্যন্ত বুঝা গেলে আমরা একটি কাজ করতে পারি, এ পর্যন্ত তো আমরা সামনের দিকে ভ্যালু প্রিন্ট করা দেখলাম, কেননা আমরা এবার রেঞ্জ ব্যবহার করে এমন একটি কোড লিখি যেটা উল্টো দিকে ভ্যালু প্রিন্ট করবে, মানে ধরুন ১০ থেকে শুরুে হয়ে ০ পর্যন্ত যাবে এবং চলুন এর সাথে স্টেপ সাইজও ব্যবহার করে ফেলি, যেনো দুই ঘর পিছিয়ে পিছিয়ে ভ্যালু প্রিন্ট করে। নিচের কোডটা দেখলে বিষয়টি আরো পরিষ্কার হবে -

```python
# start with 10
# end with 0
# step size -2
for i in range(10, 0, -2):
     print(i)
```

আঊটপুট

```
10
8
6
4
2
```

আচ্ছা একটি মজার বিষয় জেনে রাখি, এই পর্যন্ত রেঞ্জ নিয়ে কাজ করলে আপনি হয়তো খেয়াল করেছেন , রেঞ্জ ফাংশনে আপনি শুধু ইন্টিজার ভ্যালুই দিতে পারেন, ফ্লোট টাইপ ভ্যালু দিতে পারেন না। সত্যি বলতে রেঞ্জ ফাংশন ফ্লোট টাইপ ভ্যালু আর্গুমেন্ট হিসেবে নেয় না।

কিন্তু আমরা চাইলে এর জন্য কাস্টম ফাংশন তৈরি করে নিতে পারি। এখানে আমরা একটি ইউজার ডিফাইন ফাংশন তৈরি করবো, যেটা রেঞ্জ ফাংশনের মতনই কাজ করবে, কিন্তু পার্থক্য হচ্ছে, এটি ফ্লোট টাইপ ডাটা নিয়েও কাজ করতে পারবে। আচ্ছা, ফাংশন সেকশনে ইউজার ডিফাইন ফাংশন নিয়ে বিস্তারিত ব্যাখ্যা আছে। আপনি যদি এর সাথে পরিচিত না হয়ে থাকেন, তাহলে আগে সে বিষয়টি সম্পর্কে জেনে আসুন, তারপর এটি পড়ুন, এতে আপনার বুঝতে সুবিধা হবে। আচ্ছা, নিচের কোডটা খেয়াল করি -

```python
# we need all of those three argumet, such as  start, stop, step
def frange(start, stop, step):
    i = start
    while i < stop:
        yield i
        i += step
for i in frange(0.5, 1.0 ,0.1):
         print(i)
```

আউটপুট

```
0.5
0.6
0.7
0.7999999999999999
0.8999999999999999
0.9999999999999999
```

আচ্ছা, string তো একরকম iterable তাহলে এখানেও একবার `for` লুপ খাটিয়ে দেখি কিছু করা যায় কিনা -

```python
for letter in 'Python': # Here "Python" acts like a list of characters
    print(letter)
```

আউটপুট,

```python
P
y
t
h
o
n
```

`while` লুপের মত ফর লুপেও `break`, `continue` ইত্যাদি কিওয়ার্ড ব্যবহার করে কাজের ধারাকে নিয়ন্ত্রণ করা যায়। যেমন -

```python
for i in range(20):
    if i == 5:
        continue
    if i > 9:
        break
    print(i)

print("Printed first 10 numbers except 5!")
```

```python
0
1
2
3
4
6
7
8
9
Printed first 10 numbers except 5!
```

উপরে `0` থেকে `19` এই ২০টি এলিমেন্ট ওয়ালা একটি লিস্ট/রেঞ্জ এর উপর কাজ করা হয়েছে কিন্তু যখন `5` এলিমেন্টকে পাওয়া গেছে (`i` এর মাধ্যমে) তখন `continue` ব্যবহার করে একে প্রিন্ট না করে এড়িয়ে যাওয়া হয়েছে (লুপের শুরুতে ফিয়ে গিয়ে)। আবার যখন এলিমেন্টটি `9` এর বড়, সেই সময় ফর লুপের কাজ `break` এর মাধ্যমে থামিয়ে দেয়া হয়েছে যে কারনে `9` প্রিন্ট এর পর ফর লুপের কোন কাজ দেখা যাচ্ছে না বরং প্রোগ্রামের শেষ একটি সাধারণ প্রিন্ট স্টেটমেন্ট এর এক্সিকিউশন হয়েছে।

> সংকলন - [নুহিল মেহেদী](https://nuhil.net)
