১০) লুপ

list8 = { 27, 72, 7, 2, 736, 288, 5, 42, 73, 6 }

আমাদেরকে যদি বলা হয় এই লিস্টের প্রতিটা সংখ্যাকে আলাদা আলাদা করে আউটপুট এ দেখাতে হবে প্রিন্ট ফাংশন দিয়ে, তাহলে আমরা সেটা কিভাবে করবো? আমরা হয়তো ১০ টা Print[ list8[[1]] ] Print[ list8[[2]] ] ... Print[ list8[[10]] ] লিখে লিস্টটার প্রতিটা এলিমেন্ট আলাদা আলাদা করে দেখাতে পারি। কিন্তু সমস্যা টা হচ্ছে, লিস্টে ১০টা এলিমেন্ট না থেকে যদি ১০০ টা বা ১০০০ টা উপাদান থাকতো? তাহলেও কি আমরা এরকম ১০০ বা ১০০০ টা প্রিন্ট লিখতাম ? কী বিশ্রী হতো ব্যাপারটা যদি এরকম লেখতাম। আর এতো বার প্রিন্ট লেখাটাও কষ্টসাধ্য। মানুষের যদি এতো কষ্টই করতে হতো তাহলে কম্পিউটার প্রোগ্রামিং ব্যাপারটা আসলোই বা কেন? 🤷‍♂️

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

তাহলে আমরা list8 এর সব গুলা উপাদান দেখানোর জন্য আলাদা আলাদা প্রিন্ট ফাংশন ইউজ না করে একটা প্রিন্ট লিখে সেটাকে লুপে ফেলতে পারি। তখন লুপ ঐ একটা প্রিন্টকে ইউজ করে লিস্টের সব গুলা উপাদান দেখায়ে দিবে। ম্যাথম্যাটিকা তে ৩ ধরনের লুপ আছে

Do Loop

আমরা প্রথমে যে লুপ দিয়ে শুরু করবো, সেটা হচ্ছে Do[] লুপ। Do লুপের স্ট্রাকচার টা এর নামের মতোই, অর্থাৎ লুপটাকে কি কাজ করতে হবে সেটা ডু নামের পরপরই লিখতে হয়। এরপর কোন রেঞ্জের মধ্যে কাজ টা করতে হয় সেটা বলে দিতে হয়। Do লুপ দিয়ে লিস্টের সব উপদান প্রিন্ট করে দেখানোর জন্য আমরা প্রথমে Do[] লিখবো এরপর কী কাজ করতে হবে সেটা লিখবো। অর্থাৎ, এক্ষেত্রে Print[] । এখানে আমরা কী প্রিন্ট করতে চাচ্ছি? - লিস্টের প্রতিটা উপাদান। লিস্টের প্রথম উপাদান দেখার জন্য আমরা list8[[1]] , ২য় উপাদান দেখার জন্য আমরা list8[[2]] ,৩য় উপাদান দেখার জন্য list8[[3]] এভাবে লিখতাম। তাহলে লিস্টের যেকোনো উপাদান এক্সেস করার সাধারণ একটা ফর্ম কী হবে? যেহেতু list8[[]] এতোটুক প্রতিবারই ইউজ হচ্ছে, তাহলে এই জিনিসটা কমন। তাহলে প্রতিবার কী চেঞ্জ হচ্ছে? ব্রাকেট এর ভেতরের নাম্বার টা। তো এই নাম্বারের বদলে আমরা যদি একটা ভ্যারিয়েবল দিই তাহলে একটা জেনারেল ফর্ম পেয়ে যাচ্ছি: list8[[i]]

এখন এই i এর মান কোন রেঞ্জের মধ্যে হবে? যেহেতু লিস্ট এর প্রথম উপাদানের ইন্ডেক্স ১ তাই আই এর মান শুরু হবে ১ থেকে। এবং i এর শেষ মান হবে লিস্টের শেষ উপাদানের ইনডেক্স এর মানের সমান, অর্থাৎ, লিস্টে কতগুলা উপাদান আছে তার সমান। এই রেঞ্জের মধ্যের প্রতিটা পূর্ণসংখ্যাই i গ্রহণ করবে। i এর রেঞ্জ ১ থেকে ১০ এটা লেখে {i, 1, 10} এভাবে। এখন এটা Do[] এর মধ্যে দিলেই আমাদের কাজ শেষ।

এখানে একটা বিষয় হচ্ছে: আমরা লিস্টের মোট উপাদান গুণে গুণে রেঞ্জে বসাইছি। কিন্তু অনেকসময় লিস্ট অনেক বড় হতে পারে, আবার লিস্ট টা ইনপুট হিসেবে নিতে পারি; তখন আমাদের পক্ষে লিস্টে মোট কতগুলা উপাদান আছে সেটা জানা মুশকিল হয়ে পরবে। তাই এসব গণনার ঝামেলায় না গিয়ে আমরা কিন্তু Length[] টা কমান্ড ইউজ করতে পারি। তাহলে আমরা সরাসরি জানতে পারবো লিস্টে কতগুলা উপাদান আছে। তখন রেঞ্জ হয়ে যাবে: {i, 1, Length[list8]}

এখানে প্রথমে i এর মানে 1 দিয়ে শুরু হইছে, তাই Print[ list8[[i]] ] এর i এর মান 1 হয়েছে। Print করার পর আর কোনো কাজ ছিল না, তাই i এর মান এক বেড়ে 2 হয়েছে। এরপর এই 2 Print[ list8[[i]] ] এর মধ্যে বসেছে। এরপর আবার i এর মান এক বেড়ে 3 হয়েছে তারপর সেই 3 Print[] এর মধ্যে বসেছে। এভাবে i এর মান 10 পর্যন্ত হয়েছে। তারপর i এর মান এক বেড়ে 11 হয়েছে, কিন্তু 11 তো রেঞ্জের মধ্যে নাই, তাই লুপটা ওখানেই থেমে যাবে। এরপর লুপের বাইরে যদি কোনো কাজ থাকে সেগুলো করবে।

একটি রেঞ্জের মধ্যকার সকল Prime নাম্বার Print করা

একটা সংখ্যা প্রাইম কিনা, সেটা দেখার একটা ফাংশন আছে, নাম হচ্ছে PrimeQ[]। এর মধ্যে একটা সংখ্যা দিলে সেই সংখ্যা যদি প্রাইম হয় তাহলে PrimeQ[] Trueদেখাবে। আর প্রাইম না হলে False দেখাবে।

আমরা যদি ১ থেকে ৫০ এর মধ্যে প্রাইম নাম্বার গুলো প্রিন্ট করতে চাই তাহলে কিন্তু সেই কাজ টা লুপ দিয়ে করতে পারি। আমরা লুপ চালায়ে ১ ২ ৩ এভাবে ৫০ পর্যন্ত সংখ্যা এক এক করে নিব, তারপর PrimeQ[] দিয়ে চেক করবো সংখ্যাটা প্রাইম কিনা, যদি প্রাইম হয় তাহলে সেই সংখ্যাটা (যা কিনা i ) প্রিন্ট করবো, না হলে কিছু করবো না। অর্থাৎ, এখানে আমাদের লুপের মধ্যে If-ও ব্যবহার করতে হবে।

While Loop

আমাদের আলোচনার ২য় লুপ হচ্ছে While[] , এটার স্ট্রাকচার এরকম While[condition, tasks...] যা পড়লে অনেকটা এরকম শোনায়: while the condition is true, execute given tasks । অর্থাৎ, While এর মধ্যে একটা শর্ত দেওয়া থাকবে, সেই শর্ত টা যতক্ষণ পর্যন্ত সত্যি থাকবে, ততক্ষণ পর্যন্ত লুপ টা নির্দিষ্ট কাজ করতে থাকবে। যেই মাত্র শর্ত টা মিথ্যা হয়ে যাবে, ম্যাথমেটিকা লুপ থেকে বের হয়ে যাবে।

While লুপে, Do লুপের মতো রেঞ্জ দেওয়ার সুযোগ নেই। Do লুপে আমরা একটা ভ্যারিয়েবল ঠিক করে ছিলাম, যার কাজ ছিল একটা রেঞ্জের সব ইন্টিজার মান গ্রহণ করা এবং প্রতিবার কাজ শেষে নিজের মান এক করে বাড়ানো। এই কাজ গুলা আমাদের আলাদা করে বলে দিতে হয়নি, আমরা শুধু রেঞ্জ ঠিক করে দিয়েছিলাম, বাকি কাজ সে নিজেই করেছে। এটাই ছিল Do লুপের বিশেষত্ব । কিন্তু while লুপের বিশেষত্ব হচ্ছে, একে একটা কন্ডিশন দিতে হবে, হোয়াইল তার ভেতরের কাজ গুলো রিপিট করতে থাকবে যতক্ষণ পর্যন্ত তাকে দেওয়া কন্ডিশন টা সত্য থাকবে।

একটু চিন্তা করলেই আমরা বুঝতে পারবো যে, While এর কন্ডিশনটা তৈরী করতে হবে একটি ভ্যারিয়েবল ও একটি মানের তুলনা দিয়ে। সেই ভ্যারিয়েবলকে আবার লুপের মধ্যে নিজের মান চেঞ্জ করাতে হবে, তাহলে মান চেঞ্জ হতে হতে একটা সময় পর সে আর given condition টা মানবে না, তখন লুপ টা থেমে যাবে। উদাহরণ দিলে আশা করি ক্লিয়ার হবে।

একটি লুপকে যে ভ্যারিয়েল টা কন্ট্রোল করে তাকে বলে লুপ কন্ট্রোল ভ্যারিয়েবল, অর্থাৎ, যার উপর মূলত শর্ত আরোপ করা হয়। এক্ষেত্রে আমাদের লুপ কন্ট্রোল ভ্যারিয়েবল টা হচ্ছে iWhile লুপের শুরু তেই যেহেতু কন্ডিশন টা থাকে, তাই আমাদের লুপ কন্ট্রোল ভ্যারিয়েবলকে আগেই ডিক্লেয়ার করে নিতে হয়, এবং ম্যানুয়ালি তার মধ্যে প্রাথমিক বা initial value টা এ্যাসাইন করে দিতে হয় (এখানে যেহেতু আমরা একটি লিস্টের শুরু থেকে সব গুলো এলিমেন্ট দেখবো, তাই i এর initial value হিসেবে দিয়েছি 1 )। এরপর, লুপের মধ্যে সেই লুপ কন্ট্রোল ভ্যারিয়েল এর সাহায্যে একটা কন্ডিশন সেটাপ করতে হয়, এখানে যেহেতু i কে লিস্টের ইনডেক্স হিসেবে ইউজ করবো, এবং লিস্টে মোট ১০টা এলিমেন্ট আছে, তাই কন্ডিশন টা হবে i <= 10 । কন্ডিশন দেওয়া হয়ে গেলে আমরা যে কাজ গুলো লুপের মধ্যে repeatedly করতে চাচ্ছি সেগুলা সেমিকোলন দিয়ে পর পর লিখতে হবে।

এখানে যে জায়গাটায় একটু বিশেষ নজর দিতে হবে সেটা হলো increment এর পার্ট-টুকু। আমরা Do লুপে শুধু রেঞ্জ দিয়েছিলাম, লুপ নিজের থেকেই i এর মান প্রতিবার এক করে বাড়িয়েছে। কিন্তু While লুপে আমাদের কে সেটা ম্যানুয়ালি করতে হবে। i = i + 1 দিয়ে আমরা মূলত সেই কাজটাই করেছি। লুপের ভেতর সব কাজ হয়ে যাওয়ার পর আমরা এই increment অংশ টুকু দিচ্ছি এবং এখানে বলতেছি যে i এর বর্তমান যে মান, তার সাথে 1 যোগ করে যা পাওয়া যায়, তা আবার i এর মধ্যেই এ্যাসাইন করেে দাও। অর্থাৎ, এটি i এর মান প্রতিবার এক করে বাড়িয়ে দিচ্ছে।

এখানে লক্ষণীয় বিষয় হচ্ছে, while এর মধ্যে দুইটা অংশ, প্রথমটা কন্ডিশন, ২য় টা কি কাজ করতে হবে সেটা। এই দুইটা অংশ কমা দিয়ে আলাদা করে দেওয়া হয়। এই কোডটাতে আমাদের একটা কাজ এর বদলে দুইটা কাজ করতে হয়েছে, প্রিন্ট করা এবং মান বাড়ানো। তাই আমরা সেগুলা কমা দিয়ে আলাদা না করে সেমিকোলন দিয়ে আলাদা করেছি। কমা দিয়ে আলাদা করলে i এর মান বাড়ানোকে ম্যাথম্যাটিকা While এর ৩য় অংশ মনে করতো এবং error দেখাতো, কারণ একটু আগেই বললাম while এর ২টা অংশ, ৩টা নয়।

আমরা এখন প্রাইম নাম্বারের ব্যাপারটা দেখবো হোয়াইল লুপ দিয়ে। আমরা ১ থেকে ৫০ পর্যন্ত সংখ্যা গুলো চেক করবো তাই i এর মান ১ থেকে শুরু হবে, এবং ৫০ কে অতিক্রম করবে না এটা হবে আমাদের কন্ডিশন। আর আমাদের লুপের ভেতর কাজ হবে i প্রাইম হলে সেটা দেখানো, আর সব শেষে i এর মান করে বাড়ানো।

While লুপে কিছু ঝামেলা রয়েছে। যেমন: যে ভ্যারিয়েবল দিয়ে আমরা লুপটা চালাবো এবং লুপের ভেতরের কাজগুলো করবো সেই ভ্যারিয়েবলকে আমাদের লুপ শুরু হওয়ার আগেই আলাদা করে ডিক্লেয়ার করতে হয় এবং ইনিশিয়াল মান দিতে হয়। আবার লুপের ভেতর যে কাজের অংশ টা আছে সেখানে ভ্যারিয়েবলটার মান increse করে দিতে হয় প্রতিবার। যদি আমরা increment করতে ভুলে যাই তাহলে i এর ভ্যালু চেঞ্জ হবে না, ফলে কন্ডিশনটা কখনো মিথ্যাও হবে না, এবং লুপ টা আজীবন চলতে থাকবে। তাই এই ব্যাপারে সাবধানতা অবলম্বন করতে হবে।

For Loop

আমাদের আলোচনার সর্বশেষ লুপটা হচ্ছে For লুপ। For লুপ সবচেয়ে ফ্লেক্সিবল লুপ। আগের আলোচ্য লুপ দুইটাতে দুইটা করে অংশ ছিল। কিন্তু ফর লুপ এ চারটা অংশ। প্রথম অংশে ভ্যারিয়েবল ডিক্লেয়ার করে ইনিশিয়াল মান দেওয়া হয়। ২য় অংশে থাকে কন্ডিশন। ৩য় অংশে থাকে ইনক্রিমেন্ট। আর, যে কাজগুলো আমরা লুপের মধ্যে ফেলে বার বার করতে চাচ্ছি সেটা থাকে চতুর্থ অংশে।

তারমানে লুপটা While লুপের মতোই অনেকটা, পার্থক্য হলো, While লুপে আমরা ভ্যারিয়েবল ডিক্লেয়ার করেছি লুপের আগেই, আর এখানে আমরা ডিক্লেয়ার করবো লুপের ভেতরে একদম শুরুতে। আবার While লুপে ভ্যারিয়েবলটার মান আমরা চেঞ্জ/increment করেছিলাম কাজের যে অংশটুকু ওটার একদম শেষে। কিন্তু For লুপে এই মান চেঞ্জ করার ব্যাপারটার জন্য আলাদা একটা অংশই আছে।

তো লিস্টের প্রতিটা এলিমেন্ট প্রিন্ট করা এবং প্রাইম নাম্বার বের করার কোড গুলো For লুপ দিয়ে অনেকটা এরকম হবে:

এই ছিলো আমাদের ৩টা লুপের স্ট্রাকচার। অর্থাৎ এভাবে আমরা লুপ গুলো লিখবো। কিন্তু লুপ গুলা কাজ করে কীভাবে? While প্রথমে চেক করে: কন্ডিশন এ যে ভ্যারিয়েবল টা ইউজ হয়েছে সেই ভ্যারিয়েবলটার মানের জন্য কন্ডিশন টা সত্য কিনা। যদি সত্য হয় তাহলে লুপের ভেতরের কাজ করবে। এরপর লুপ কন্ট্রোল ভ্যারিয়েবল অর্থাৎ কন্ডিশন এ যে ভ্যারিয়েবল ইউজ হয়েছে সেটার মান চেঞ্জ হবে increment সেকশনে। এরপর আবার কন্ডিশন এর কাছে আসবে এবং নতুন মান দিয়ে আবার কন্ডিশন চেক করবে। সত্য হলে লুপের ভেতর ঢুকবে তারপর কাজ গুলো করে লুপ কন্ট্রোল ভ্যারিয়েবল এর মান চেঞ্জ করবে। আর মিথ্যা হলে লুপ থেকে বের হয়ে আসবে।

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

Last updated