লুপ

লুপ

লুপ মানে ফাঁস। ফাঁস আমরা সবাই চিনি। এটা নিয়ে রাজনীতি করার কিছু নাই। কিন্তু প্রোগ্রামিংয়ের লুপ নিয়ে বলার আছে অনেক কিছুই। এই লুপ মানে হল বারবার। যখন একই কাজ বারবার করার দরকার পড়ে তখন লুপ ব্যবহার করতে হয়। লুপকে কন্ডিশনাল লজিকের ভিতরেই ফালানো যায়। কারণ লুপে কন্ডিশনের উপর ভিত্তি করেই একই কাজ বারবার করা হয়।

আমরা একটা সমস্যার কথা চিন্তা করি। আমরা তো প্রিন্ট করতে সবাই পারি। আমাদের বলা হল, ১ থেকে ১০ পর্যন্ত সংখ্যাগুলো প্রিন্ট করতে হবে। তো, এখন পর্যন্ত আমরা যা যা শিখেছি সে অনুসারে আমাদের প্রোগ্রামটা দেখতে এরকম হবে:

print(1)
print(2)
print(3)
print(4)
print(5)
print(6)
print(7)
print(8)
print(9)
print(10)

আউটপুট

1
2
3
4
5
6
7
8
9
10

চমৎকার জিনিস! আমাদের কাজ কিন্তু হয়ে গেছে। এবার কেউ বললেন, না ১ থেকে ১০ পর্যন্ত করলে হবে না। ১ থেকে ১০০ পর্যন্ত প্রিন্ট করে দেখাতে হবে। তখন কি করব আমরা? আগের মত কোড করতে লেগে যাব। ১০০ পর্যন্ত না হয় পারলাম। যদি ১০০০০ পর্যন্ত প্রিন্ট করতে বলেন কেউ? তখন কি করব? গাধার খাটুনি খাটব আমরা? অবশ্যই না। এজন্য রয়েছে লুপ। উদাহরণ হিসাবে ১ থেকে ১০ পর্যন্ত প্রিন্ট করে দেখব আমরা:

n = 1
while n <= 10:
    print(n)
    n = n+1

আউটপুট

1
2
3
4
5
6
7
8
9
10

মাত্র চার লাইন কোড লিখেই কিস্তিমাত করলাম আমরা। উপরের প্রোগ্রামটা হয়ত আমরা অনেকেই বুঝি নাই। সমস্যা নেই। আমরা এখন লুপের গভীরে প্রবেশ করব।

পাইথনে লুপ আছে দুই ধরনের : (১) হোয়াইল (while) লুপ ও (২) ফর (for) লুপ। আমরা এখন এদের নিয়ে বিস্তারিত কথা বলব।

while লুপ

while লুপে দুইটা পার্ট আছে: লজিকাল এক্সপ্রেশন বা কন্ডিশন আর অ্যাকশন। যখন কন্ডিশনটা সত্য হয় তখনই, কেবল তখনই অ্যাকশন পার্টটা এক্সিকিউট হতে শুরু করে আর যতক্ষণ অবধি কন্ডিশনটা সত্য থাকে ততক্ষণ অবধি অ্যাকশনটা এক্সিকিউট হতে থাকে।

বিষয়টা আমরা বিভিন্ন ফিল্মে দেখা পুলিশি রিমান্ডের সাথে তুলনা করতে পারি। পুলিশ অপরাধীকে সত্য কথা স্বীকার করতে বলে, অপরাধী স্বীকার করে না। তারপর পুলিশ ডলা দেয়া শুরু করে, যতক্ষণ সত্য কথা স্বীকার না করে ততক্ষন ডলা দেয়, মনের ঝাল মিটাইয়া ডলা দেয়। অপরাধী প্রথমে সহ্য করে, তারপর যখন আর পারে না তখন সব কথা বলে দেয়। এখানে কন্ডিশন হচ্ছে অপরাধীর সত্য কথা বলা। আর অ্যাকশন হচ্ছে পুলিশের ডলা।

while লুপের সিনট্যাক্স if এর মতই। কন্ডিশনের পর কোলন : চিহ্ন দিতে হয়। আর অ্যাকশন ব্লকে ইনডেন্টেশন বাধ্যতামূলক। আমরা ইতিমধ্যে while লুপের একটা ব্যবহার দেখেছি। এবার উদাহরণটা আবার পর্যালোচনা করা যাক:

n = 1
while n <= 10:
    print(n)
    n = n+1

আমাদের দরকার ছিল ১ থেকে ১০ পর্যন্ত প্রিন্ট করা। প্রথমে আমরা n ভ্যারিয়েবলের মান 1 অ্যাসাইন করেছি। তারপর while লুপ লেখা শুরু করলাম। যতক্ষণ কন্ডিশন সত্য, মানে n এর মান 10 এর সমান বা ছোট, ততক্ষণ অ্যাকশন এক্সিকিউট হবে, মানে n এর ভ্যালু প্রিন্ট হবে। আর প্রতিবার প্রিন্ট করার পর n এর মান 1 করে বাড়বে। লুপ যখন প্রথমবার ঘুরবে তখন n এর মান 1 থাকবে, তাই 1 ই প্রিন্ট হবে। এরপর n এর মান 1 বেড়ে গিয়ে 2 হবে। 2, 10 এর চেয়ে ছোট, তাই লুপটা আবার ঘুরবে, n এর মান 2 প্রিন্ট করবে, n এর মান 1 বেড়ে গিয়ে 3 হবে … এভাবে চলতে চলতে একসময় n এর মান বেড়ে 10 হবে। 10 যেহেতু 10 এর সমান তাই আবার লুপের অ্যাকশন এক্সিকিউট হওয়া শুরু করবে। এবার প্রিন্ট হবে 10, তারপর n এর মান 1 বেড়ে গিয়ে 11 হবে। 11, 10 এর সমানও নয় আবার ছোটও নয়। তখন কন্ডিশন মিথ্যা হয়ে যাবে ফলে লুপ আর ঘুরবে না মানে অ্যাকশন আর এক্সিকিউট হবে না।

এবার নতুন একটা সমস্যার কথা চিন্তা করা যাক। শিশুকালে আমরা শতকিয়া যোগ করতাম। শতকিয়া যোগ হল ১ থেকে ১০০ পর্যন্ত সংখ্যাগুলোকে যোগ করা। মানে 1+2+3+4+…+100 = ? বের করা। while লুপ ব্যবহার করে আমরা এখন এটার সলিউশন করব।

n = 1
temp = 0
while n <= 100:
    temp = temp + n
    n = n + 1
print(temp)

আউটপুট

5050

তো কি করলাম এখানে? আমরা প্রথমে n এর মান 1 আর temp এর মান 0 অ্যাসাইন করে দিলাম। তারপর while লুপ ঘুরানো শুরু করলাম। while লুপের কন্ডিশন হল n এর মান 100 এর সমান বা ছোট। সেক্ষেত্রে অ্যাকশন হল n এর মান temp এর সাথে যোগ করে যোগফল temp এ অ্যাসাইন করব। তারপর n এর মান 1 বাড়িয়ে দেব। এভাবে 100 বার লুপ ঘুরে temp এর ভিতর 1+2+3+4+…+100 এর মান অ্যাসাইন হবে। তারপর আমরা temp এর মান প্রিন্ট করে দেখাব।

আমরা যারা গণিতে সমান্তর ধারার প্রব্লেমগুলো সলভ করেছি তারা কিন্তু চাইলে এটাকে অন্যভাবে সলভ করতে পারি। এর জন্য একটা সূত্র অ্যাপ্লাই করতে হবে আমাদের।

1+2+3+4+ ... +n = n(n+1)/2

এখানে n হল 1 থেকে শুরু করে যে সংখ্যাটা পর্যন্ত হিসাব করতে হবে আমাদের সেটা। আমাদের উপরের সমস্যাটার ক্ষেত্রে n এর মান হল 100। চলুন সবাই মিলে সূত্রটা অ্যাপ্লাই করি:

n = 100
temp = n*(n+1)
temp = temp/2
print(temp)

আউটপুট

5050.0

একই আউটপুট আসল, তাই না? এরমানে আমাদের সলিউশনটা ঠিকই আছে। সূত্র ব্যবহার করার কারণে আমাদের সলিউশনটা কিন্তু অনেক বেশি ইফিশিয়েন্ট হল। আসলে বড় বড় প্রোগ্রামের ক্ষেত্রে লুপ একটা ঝামেলা স্বরূপ। অহেতুক সিপিইউ খায়, মেমরি খায়। অবশ্য এখনই এসব বিষয় নিয়ে মাথা ঘামানোর কোন দরকার নাই।

নিচের সমস্যাটা কিভাবে সলভ করা যায়? এটা প্রাকটিস প্রব্লেম। কথায় আছে না, Practice makes a man perfect.

$$1+3+5+7+ … +97 = ?$$

for লুপ

‘উন্নয়নের অঙ্গীকার, ধারাবাহিকতা দরকার’ এই কথাটা তো আমরা কমবেশি সবাই জানি। বর্তমান সরকারের নির্বাচনী ডায়লগ ছিল এটা। এটা দিয়ে সরকারি দল বুঝাতে চেয়েছে, গত মেয়াদে তারা উন্নয়নের যে ধারা তৈরি করেছে তা বজায় রাখার জন্য এই মেয়াদেও তাদের ক্ষমতায় আসা দরকার। রাজনীতি নিয়ে আমাদের চিন্তা-ভাবনা আপাতত করার দরকার নেই। আপাতত চিন্তা করার দরকার ‘ধারাবাহিক’ কথাটা নিয়ে। ইংরেজিতে এটাকে আমরা সিকুয়েন্স বলি। যখন পাঁচটা মানুষ একজন আরেকজনের থেকে ১ ফুট দূরত্ব নিয়ে দাঁড়িয়ে আছে তখন আমরা বলতে পারি তারা একটা সিকুয়েন্স মেইনটেইন করে দাঁড়িয়ে আছে।

একটা জিনিস কি আমরা খেয়াল করেছি যে লিস্ট, টাপলেও সিকুয়েন্স থাকে। সিকুয়েন্সটা হল এদের ইনডেক্স নম্বরে। ইনডেক্স নম্বর 0, 1, 2, 3 … এরকম করে থাকে। সিকুয়েন্স তো অবশ্যই।

for লুপ দিয়ে আমরা এসব সিকুয়েন্সিয়াল আইটেমকে ইটারেট করতে পারি। ইটারেট করা মানে হল আইটেম বাই আইটেম রিড করতে পারা। যাকে ইটারেট করা যায় তাকে ইটারেটর (Iterator) অবজেক্ট বলে। লিস্ট, টাপল, সেট, ডিকশনারি সবাইকেই ইটারেট করা যায়। ইটারেটর সম্পর্কে একটা চ্যাপ্টারে আমরা বিস্তারিত জানব। আপাতত এই ক্ষুদ্র জ্ঞানই আমাদের সম্বল।

a = ['onion', 'potato', 'ginger', 'cucumber']
print(type(a))
for item in a:
    print(item)

আউটপুট

<class 'list'>
onion
potato
ginger
cucumber

এখানে আমরা একটা লিস্টকে ইটারেট করে এর সব আইটেমগুলো রিড করলাম। for item in a এই স্টেটমেন্টে এক একবার লুপ ঘুরনে a এর ভ্যালুগুলো একটা একটা করে item ভ্যারিয়েবলে অ্যাসাইন হয়েছে। তারপর item কে আমরা প্রিন্ট করেছি।

টাপল, সেট আর ডিকশনারিকে ইটারেট করার পদ্ধতি লিস্টের মতই।

a = {'name' : 'MD. Maksudur Rahman Khan', 'nickname' : 'Maateen', 'email' : 'maateen@outlook.com', 'phone' : '01711223344'}
print(a)
print(type(a))
for item in a:
    print(item)

আউটপুট

{'phone': '01711223344', 'email': 'maateen@outlook.com', 'nickname': 'Maateen', 'name': 'MD. Maksudur Rahman Khan'}
<class 'dict'>
phone
email
nickname
name

শুধু লিস্ট, টাপল, সেট আর ডিকশনারিই নয়, স্ট্রিংকেও এইভাবে ইটারেট করতে পারি আমরা।

a = 'Python'
for letter in a:
    print(letter)

আউটপুট

P
y
t
h
o
n

কি সুন্দরভাবে ইটারেট করে ফেললাম! আচ্ছা, ১ থেকে ১০ পর্যন্ত প্রিন্ট করার সমস্যাটার কথা মনে আছে? for লুপ দিয়েও আমরা এই কাজটা করতে পারি। তবে এজন্য আমাদেরকে range() ফাংশনটা ব্যবহার করতে হবে। এই ফাংশনটার ভিতরে একটা ইন্টিজার দেয়ার মানে হল 0 থেকে শুরু ঐ ইন্টিজারের আগ পর্যন্ত সিকুয়েন্স তৈরি করা। যেমন:

>>> range(5)
range(0, 5)
>>> list(range(5))
[0, 1, 2, 3, 4]

আচ্ছা, যদি 5 থেকে 19 পর্যন্ত সিকুয়েন্স তৈরির প্রয়োজন হয়? তখন range(5, 20) এভাবে লিখতে হবে। এর মানে হল 5 থেকে শুরু করে 21 এর আগ পর্যন্ত মানে 20 পর্যন্ত।

>>> range(5, 21)
range(5, 21)
>>> list(range(5, 21))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

আচ্ছা, যদি 5 থেকে 20 পর্যন্ত সিকুয়েন্স তৈরির প্রয়োজন হয় যেখানে 5 এর পর 7 আসবে, তারপর 9 আসবে মানে 2 করে বাড়বে? তখন range(5, 21, 2) এভাবে লিখতে হবে। এর মানে হল 5 থেকে শুরু করে 21 এর আগ পর্যন্ত মানে 20 পর্যন্ত আর 5 এর পর থেকে 2 করে বাড়বে।

>>> range(5, 20, 2)
range(5, 20, 2)
>>> list(range(5, 20, 2))
[5, 7, 9, 11, 13, 15, 17, 19]

যাহোক, range() ফাংশনের প্রয়োগ আমরা সবাই বুঝেছি। এবার আমরা এটাকে ব্যবহার করে ১ থেকে ১০ পর্যন্ত প্রিন্ট করব।

for number in range(1, 11):
    print(number)

আউটপুট

1
2
3
4
5
6
7
8
9
10

চমৎকার! তাই না?

লুপ কন্ট্রোল স্টেটমেন্ট

লুপ তো ঘোরে। লুপের এই ঘোরাঘুরি কন্ট্রোল করার জন্য লুপ কন্ট্রোল স্টেটমেন্ট ব্যবহার করা হয়। পাইথনে তিনটা লুপ কন্ট্রোল স্টেটমেন্ট আছে: break, continue, pass

break

লুপের ভিতর অ্যাকশন ব্লকে break স্টেটমেন্ট আসলে লুপের ঘোরাঘুরি সেখানেই থেমে যায়। লুপের পরবর্তী স্টেটমেন্টগুলো এক্সিকিউট হওয়া শুরু করে। যেমন:

for number in range(1, 11):
    if number == 5:
        break
    print(number)

আউটপুট

1
2
3
4

আগেরটার সাথে এটার পার্থক্য হল: নতুন একটা কন্ডিশন বসিয়েছি আমরা। যখন number এর মান 5 হয়েছে তখন লুপটা ব্রেক হয়েছে। তাই শুধু 1 থেকে 4 পর্যন্তই প্রিন্ট হয়েছে এখানে।

continue

লুপের ভিতর অ্যাকশন ব্লকে continue থাকলে, এর পরের সব অ্যাকশন স্টেটমেন্ট স্কিপ করবে এবং রি-ইটারেশনের জন্য লুপের এক্সপ্রেশন রি-টেস্ট হবে। যেমন:

for number in range(1, 11):
    if number == 5:
        continue
    print(number)

আউটপুট

1
2
3
4
6
7
8
9
10

যখন number এর মান 5 হবে তখন continue স্টেটমেন্টটা কাজ করছে। ফলে এইবার number এর ভ্যালুটা প্রিন্ট হয়নি আর।

pass

pass স্টেটমেন্ট হল একটা নাল (null) অপারেশন। এটা যখন এক্সিকিউট হয় তখন আসলে কিছুই ঘটে না। প্রশ্ন হতে পারে তাহলে এটা কোন কাজে লাগে। লাগে, লাগে! লাগালেই লাগে।

for number in range(1, 11):
    if number == 5:
        pass
    print(number)

আউটপুট

1
2
3
4
5
6
7
8
9
10

কিছুই ঘটল না। কিছু ঘটার কথাও না। pass এর ফজিলত আমরা পরে বিভিন্ন ক্ষত্রে দেখতে পারব।

লুপের সাথে else

পাইথনে লুপের সাথে আমরা চাইলে else ব্যবহার করতে পারি। while লুপে else স্টেটমেন্ট ইউজ করলে, যখন while লুপের এক্সপ্রেশনটা মিথ্যা হবে তখনই else ব্লক এক্সিকিউট হওয়া শুরু হবে।

n = 1
while n <= 10:
    print(n)
    n = n + 1
else:
    print('The loop is over.')

আউটপুট

1
2
3
4
5
6
7
8
9
10
The loop is over.

আর for লুপে else স্টেটমেন্ট ইউজ করলে, যখন for লুপের ইটারেশন শেষ হয়ে যাবে তখনই else ব্লক এক্সিকিউট হওয়া শুরু হবে।

for n in range(0, 11):
    print(n)
    n = n + 1
else:
    print('The loop is over.')

আউটপুট

0
1
2
3
4
5
6
7
8
9
10
The loop is over.

ইনফিনিট (Infinite) লুপ

উপরে এতক্ষন অবধি আমরা যত লুপ পড়লাম সব ছিল সেন্টিনেল (Sentinel) লুপ। এই ধরনের লুপের ঘোরাঘুরি নির্দিষ্ট কোন বুলিয়ান এক্সপ্রেশনের উপর ভিত্তি করে আজ হোক বা কাল এক সময় বন্ধ হবেই। কিন্তু এর বাইরেও এক প্রকার লুপ আছে যা একবার চাব্বি মাইরা দিলে ছাইড়া জনম ভইরা চলতে থাকবে। এই ধরনের লুপকে বলা হয় ইনফিনিট লুপ। নিচের উদাহরণটা দেখি। এর আউটপুট জীবনেও শেষ হবে না।

i = 1
while i > 0:
    i += 1
    print(i)

সবাই বুঝলাম, তাই না? লুপ কিন্তু অনেক গুরুত্বপূর্ণ একটা টপিক। বারবার পড়ে ও প্রাকটিস করে হৃদয়ে গেঁথে নেব সবাই।

প্রবলেম সলভিং

লুপ সম্পর্কে আমরা এখন অনেকটাই জানি। এই অর্জিত জ্ঞান প্রয়োগ করে তাহলে কয়েকটা প্রবলেম সলভ করার চেষ্টা করা যাক। একটা প্রবলেম কয়েকভাবে সলভ করা যেতে পারে। এ নিয়ে রাজনীতি করার কিছু নেই।

প্রবলেম-১

ইউজার যেকোনো একটা পূর্ণসংখ্যা ইনপুট দেবে। আর ওই পূর্ণসংখ্যার নামতা আউটপুট হিসেবে দেখাতে হবে।

print('Please, input the number:')
number = int(input())
count = 1
while count <= 10:
    print(number, 'x', count, '=', number*count)
    count += 1

আউটপুট

Please, input the number:
9
9 x 1 = 9
9 x 2 = 18
9 x 3 = 27
9 x 4 = 36
9 x 5 = 45
9 x 6 = 54
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81
9 x 10 = 90
Please, input the number:
27
27 x 1 = 27
27 x 2 = 54
27 x 3 = 81
27 x 4 = 108
27 x 5 = 135
27 x 6 = 162
27 x 7 = 189
27 x 8 = 216
27 x 9 = 243
27 x 10 = 270

ইউজার যে ইন্টিজার ইনপুট দেবে আমরা তার নামতা আউটপুট দেব। বেশ ভালো কথা। নামতা হলো একটা সংখ্যাকে 1 থেকে 10 দিয়ে গুণ করে গুণফল দেখানো। কাজটা আমরা লুপের সাথে করতে পারি। count-এর মান 10 বা এর ছোট হলে লুপ ঘুরবে। ইনিশিয়ালি count-এর মান 1 দিয়েছি। তাই লুপ ঘোরা শুরু করবে। লুপের ভেতর প্রথমে count আর ইউজারর ইনপুট দেওয়া ইন্টিজারের গুণফল প্রিন্ট করব। তারপর count-এর মান 1 বাড়িয়ে দেব। তারপর count-এর মান হবে 2, আবার লুপ ঘোরা শুরু হবে। এভাবে count-এর মান 10 অবধি লুপ ঘুরবে আর গুণফল প্রিন্ট করবে। count-এর মান বেড়ে যখন 11 হবে তখন আর লুপটি ঘুরবে না, বন্ধ হয়ে যাবে ঘোরাঘুরি।

প্রবলেম-২

১ থেকে ১০০ পর্যন্ত যেসব সংখ্যা ৩ দ্বারা নিঃশেষে বিভাজ্য কিন্তু ৫ দ্বারা নয়, তাদের লিস্ট আউটপুট হিসেবে দেখাতে হবে।

my_list = []

for i in range(1, 101):
    if i%3 == 0 and i%5 != 0:
        my_list.append(i)

print(my_list)

আউটপুট

[3, 6, 9, 12, 18, 21, 24, 27, 33, 36, 39, 42, 48, 51, 54, 57, 63, 66, 69, 72, 78, 81, 84, 87, 93, 96, 99]

সবার প্রথমে আমরা একটা ফাঁকা লিস্ট (my_list) তৈরি করে নিয়েছি। এরপর আমরা ফর লুপ ব্লক শুরু করেছি। এই লুপে 1 থেকে 101 এর আগ পর্যন্ত প্রতিটি পূর্ণসংখ্যা নিয়ে কাজ করেছি আমরা। প্রতিটি পূর্ণসংখ্যার ক্ষেত্রে আমরা চেক করে দেখেছি তা 3 দ্বারা নিঃশেষে বিভাজ্য কিনা এবং 5 দ্বারা নিঃশেষে বিভাজ্য নয় কিনা। এই শর্ত সত্য হলে পূর্ণসংখ্যাটিকে my_list-এ অ্যাপেন্ড করেছি। লুপের ঘোরাঘুরি শেষ হয়ে গেলে my_list কে প্রিন্ট করে দেখিয়েছি।

প্রবলেম-৩

ধরা যাক, বিভিন্ন সংখ্যার একটি তালিকা রয়েছে। তালিকাটা নিচের মত -

13, 34, 19, 28, 46, 61, 73, 49, 1, 31, 4, 7, 91, 58, 52, 82, 70, 43, 88, 55, 97, 16, 22, 25, 79, 85, 40, 64, 94, 67, 37

এই তালিকা থেকে ৫০-এর চেয়ে ছোট সংখ্যাগুলোকে নিয়ে একটি লিস্ট বানিয়ে আউটপুট হিসেবে দেখাতে হবে।

a = [13, 34, 19, 28, 46, 61, 73, 49, 1, 31, 4, 7, 91, 58, 52, 82, 70, 43, 88, 55, 97, 16, 22, 25, 79, 85, 40, 64, 94, 67, 37]
my_list = []

for i in a:
    if i < 50:
        my_list.append(i)

print(my_list)

আউটপুট

[13, 34, 19, 28, 46, 49, 1, 31, 4, 7, 43, 16, 22, 25, 40, 37]

প্রথমে প্রদত্ত তালিকাটিকে লিস্ট হিসেবে a ভ্যারিয়েবলে অ্যাসাইন করেছি। পাশাপাশি একটা ফাঁকা লিস্ট (my_list)-ও তৈরি করেছি আমরা। এরপর আমরা ফর লুপ ব্লক শুরু করেছি। এই লুপে a লিস্টের প্রতিটি আইটেম নিয়ে কাজ করেছি আমরা। প্রতিটি আইটেমের ক্ষেত্রে আমরা চেক করে দেখেছি তা 50 এর চেয়ে ছোট কিনা। ছোট হলে আইটেমটিকে my_list-এ অ্যাপেন্ড করেছি। লুপের ঘোরাঘুরি শেষ হয়ে গেলে my_list কে প্রিন্ট করে দেখিয়েছি।

প্রবলেম-৪

নিচের তালিকাটি লক্ষ্য করা যাক -

40, 45, 33, 34, 8, 38, 28, 22, 1, 7, 49, 41, 14, 5, 22, 39, 15, 19, 36, 37, 43, 2, 5, 42, 46, 48, 49, 12, 48, 37, 8, 20, 30, 20, 4, 37, 27, 29, 7, 44, 15, 32, 35, 10, 28, 18, 2, 15, 36, 38

এই তালিকা থেকে সকল ডুপ্লিকেট (duplicate) ভ্যালু রিমুভ করতে হবে।

a = [40, 45, 33, 34, 8, 38, 28, 22, 1, 7, 49, 41, 14, 5, 22, 39, 15, 19, 36, 37, 43, 2, 5, 42, 46, 48, 49, 12, 48, 37, 8, 20, 30, 20, 4, 37, 27, 29, 7, 44, 15, 32, 35, 10, 28, 18, 2, 15, 36, 38]
my_list = []

for i in a:
    if i not in my_list:
        my_list.append(i)

print(my_list)

আউটপুট

[40, 45, 33, 34, 8, 38, 28, 22, 1, 7, 49, 41, 14, 5, 39, 15, 19, 36, 37, 43, 2, 42, 46, 48, 12, 20, 30, 4, 27, 29, 44, 32, 35, 10, 18]

প্রথমে প্রদত্ত তালিকাটিকে লিস্ট হিসেবে a ভ্যারিয়েবলে অ্যাসাইন করেছি। পাশাপাশি একটা ফাঁকা লিস্ট (my_list)-ও তৈরি করেছি আমরা। my_list ভ্যারিয়েবলে আমরা a লিস্টের আইটেমগুলোকে অ্যাপেন্ড করব, তবে কোন আইটেমেট ডুপ্লিকেট রাখব না। এজন্য আমরা ফর লুপ ব্লক শুরু করেছি। এই লুপে a লিস্টের প্রতিটি আইটেম নিয়ে কাজ করেছি আমরা। প্রতিটি আইটেমের ক্ষেত্রে আমরা চেক করে দেখেছি তা ইতিমধ্যে my_list-এ আছে কিনা। না থাকলে সেটিকে my_list-এ অ্যাপেন্ড করেছি। লুপের ঘোরাঘুরি শেষ হয়ে গেলে my_list কে প্রিন্ট করে দেখিয়েছি।

প্রবলেম-৫

ইউজার একটা পূর্ণসংখ্যা ইনপুট দেবে। সেটির ওপর ভিত্তি করে আমরা *এর স্কয়ার ডিজাইন করব। অর্থাৎ ইউজার যদি 5 ইনপুট দেয় তাহলে নিচের মতো একটা স্কয়ার ডিজাইন করব।

*****
*****
*****
*****
*****
print('Please, input the number:')
number = int(input())
temp = number

while number > 0:
    count = temp
    while count > 0:
        print('*', end='')
        count -= 1
    print()
    number -= 1

আউটপুট

Please, input the number:
4
****
****
****
****
Please, input the number:
7
*******
*******
*******
*******
*******
*******
*******

এখানে আমরা দুটি while লুপ (নেস্টেড লুপ) নিয়ে কাজ করেছি। বিষয়টা এ রকম যে একটা while লুপ দিয়ে আমরা *এর লাইন প্রিন্ট করব আর আরেকটা while দিয়ে আমরা লাইন ব্রেক নেব। ভেতরের লুপটাতে আমরা print(’*’, end=“) ব্যবহার করেছি। print() ফাংশনটা যখন কাজ করে তখন সেটা স্ট্রিংয়ের শেষে নিজ থেকেই একটা \n যোগ করে নিউ লাইন প্রিন্ট করে দেয়। কিন্তু আমরা তো পাশাপাশি প্রিন্ট করব। সে ক্ষেত্রে নতুন একটা লাইন প্রিন্ট হলে ঝামেলা আমাদের জন্য। তাই আমরা প্রিন্ট ফাংশনকে বলে দিয়েছি যে বাপু, তোমার শেষে গিয়ে নতুন কিছু যোগ করার দরকার নেই। এবং বাইরের লুপের ভেতর আমরা print() ফাংশন ব্যবহার করেছি কিন্তু ভেতরে কোনো কিছু পাস করিনি। কিছু পাস করি আর না করি, সে কিন্তু নিজ উদ্যোগে একটা নিউ লাইন প্রিন্ট করতে ভুল করেনি।

প্রবলেম-৬

ইউজার একটি শব্দ ইনপুট দেবে। আমাদের প্রোগ্রাম দেখবে সেটি একটি প্যালিনড্রোম (Palindrome) কি না! প্যালিনড্রোম হলো কোনো শব্দ, সংখ্যা বা সিক্যুয়েন্স যাদের ওলটালেও ওই এক জিনিসই থাকে। যেমন : 707 কে ওলটালেও 707 ই থাকে। আবার Madam-কে ওলটালে Madam ই থাকে।

print('Please input your word:')
word = input()
word = word.casefold()
reversed_word = word[::-1]

if word == reversed_word:
    print('Great! It is a pallindrome.')
else:
    print('LOL! It is not a pallindrome.')

আউটপুট

Please input your word:
madam
Great! It is a pallindrome.
Please input your word:
number
LOL! It is not a pallindrome.

আমরা ইউজারের কাছে থেকে একটা ওয়ার্ড (স্ট্রিং) ইনপুট নিয়েছি। word[::-1] দিয়ে আমরা ওয়ার্ডটাকে রিভার্স করেছি মানে উল্টে দিয়েছি। তারপর নরমাল ওয়ার্ড আর রিভার্সড ওয়ার্ডের মধ্যে তুলনা করে সিদ্ধান্ত নিয়েছি। আরেকটা ব্যাপার, এই প্রবলেমটা কন্ডিশনাল লজিক চ্যাপ্টারে দেখানো উচিত ছিল। ওখানে ভুলে স্কিপ করে গিয়েছিলাম, তাই সুযোগ পেয়ে এখানেই দেখিয়ে দিলাম।

প্রবলেম-৭

এখন আমরা অনন্ত জলিলের খোঁজ দ্য সার্চ-এর প্রবলেম সলভ করব। ধরা যাক, ছোট থেকে বড় সাজানো বিভিন্ন সংখ্যার একটা তালিকা আছে। তালিকাটা নিচের মতো—

1, 3, 5, 7, 11, 13, 15, 17, 20, 26, 31, 44, 54, 56, 65, 77, 94, 100

এই তালিকা থেকে ইউজারের ইনপুট দেওয়া নির্দিষ্ট একটি সংখ্যা খোঁজ দ্য সার্চ করে বের করতে হবে। এ আর কঠিন কী!

my_list = [1, 3, 5, 7, 11, 13, 15, 17, 20, 26, 31, 44, 54, 56, 65, 77, 94, 100]

print('Input the number:')
number = int(input())

first = 0
last = len(my_list)-1
found = False
cycle = 0

while first <= last and not found:
    midpoint = (first + last)//2
    if my_list[midpoint] == number:
        found =True
    else:
        if number < my_list[midpoint]:
            last = midpoint-1
        else:
            first = midpoint+1
    cycle +=1

print('Found after', cycle, 'cycle.')

আউটপুট

Input the number:
44
Found after 4 cycle.
Input the number:
20
Found after 1 cycle.

এখানে আমরা চমৎকার একটা অ্যালগরিদম ইমপ্লিমেন্ট করেছি। অ্যালগরিদম হলো কোনো সমস্যা সমাধান করার রাস্তা, কাজকে সহজ করার উপায়। যাহোক, আমরা যে সংখ্যাটা খুঁজছি সেটাকে বের করার জন্য আমরা একটা ট্যাকটিস ফলো করেছি। আমরা প্রথমে লিস্টের ঠিক মধ্যখানের সংখ্যাটা বের করেছি। তারপর দেখেছি এটাই আমাদের সংখ্যা কি না। যদি না হয় তখন দেখেছি আমাদের সংখ্যাটা এটার তুলনায় ছোট নাকি বড়। ছোট হলে, মধ্যখানের সংখ্যাটার বামের সব সংখ্যা লিস্ট হিসেবে বিবেচনায় নিয়েছি। আর বড় হলে মধ্যখানের সংখ্যাটার ডানের সব সংখ্যা লিস্ট হিসেবে বিবেচনায় নিয়েছি। তারপর লিস্ট হিসেবে বিবেচনায় নেওয়া সংখ্যাগুলোর ভেতর আগের সিস্টেম চালিয়েছি যতক্ষণ না নির্দিষ্ট সংখ্যাটা খুঁজে পাওয়া যায়। এভাবে দুভাগ করে করে খোঁজ দ্য সার্চ করার এই পদ্ধতিকে বলে বাইনারি সার্চ মেথড।

অনুশীলনী

(১) লুপ ব্যবহার করে ১ থেকে ১০০ পর্যন্ত পূর্ণসংখ্যাগুলোর সমষ্টি বের করতে হবে।

(২) ইউজার একটা পূর্ণসংখ্যা ইনপুট দেবে। সেটির ওপর ভিত্তি করে আমরা *এর ত্রিভুজ ডিজাইন করব। অর্থাৎ ইউজার যদি 5 ইনপুট দেয় তাহলে নিচের মত একটা ত্রিভুজ ডিজাইন করব।

*
**
***
****
*****

(৩) ১ থেকে ১০০-এর ভিতর যেসকল সংখ্যা রয়েছে, সেখান থেকে দৈবচয়নের মাধ্যমে বাছাই করে ন্যূনতম ত্রিশ সংখ্যার একটা লিস্ট তৈরি করতে হবে। এই লিস্টে একই সংখ্যা একাধিকবার থাকতে পারবে না। (এখন পর্যন্ত অর্জিত জ্ঞান দিয়ে সলভ করতে না পারলে, পুরো বই শেষ করে আবার চেষ্টা করতে হবে।)

(৪) A = {1, 2, 3, 4, 5} ও B = {5, 6, 7, 8} দুটি সেট। union() ও intersection() ফাংশন (আসলে মেথড) ব্যবহার না করে তাদের ইউনিয়ন ও ইন্টারসেকশন সেট C বের করতে হবে।

comments powered by Disqus