Sunday, November 5, 2017

BUBT Intra University Programming Contest Summer 2017 [Junior] Editorial

যতদিন কম্পিটিটিভ প্রোগ্রামিং করেছি (কেউ পজিশন জিজ্ঞেস না করলে ভালো হয় :( ), দেখেছি কনটেস্ট শেষে তার এডিটরিয়াল পাওয়া যাচ্ছে। এডিটরিয়াল হলো কনটেস্ট এর প্রবলেমের বিষয়ে শর্টকাট আলোচনা, যেখানে সরাসরি কোন সলুশন/কোড থাকেনা থাকে সলভিংএর কিছু টেকনিকস। তো আমারও স্বপ্ন ছিল একদিন টিউটোরিয়াল লিখব। যদিও নিম্মোক্ত লেখাকে কোনভাবে টিউটোরিয়াল বলা যায় কি না আমার জানা নেই। সেটা বিজ্ঞজনেরা বিবেচনা করবেন। আমি আমার স্বপ্ন পূরণ করি। হা হা।

  1. Easy Problem 4
Problem Setter: Md. Saifur Rahman, Assistant Professor, Dept. of CSE
এখানে মুলত প্রদত্ত যে কোন দুটি সংখ্যার পার্থক্য জানতে চাওয়া হয়েছে। যেটা একটি সংখ্যা থেকে আরেকটি সংখ্যা বিয়োগ করলেই পাওয়া যায়। কিন্তু একটা সমস্যা হলো পার্থক্য সবসময় ধণাত্মক, কিন্তু বিয়োগফল ঋণাত্মকও হতে পারে। তো সহজ হিসাব হলো পার্থক্য জানতে হলে সবসময় বড় সংখ্যা থেকে ছোট সংখ্যা বিয়োগ দিতে হবে, তাহলেই আর ঋণাত্মক মান আসবে না। জগতে সবই if/else  এর খেলা। গোপন খবর:  math.h এর একটা ফাংশন আছে abs(x,y)।

  1. The Unsolvable Math
Problem Setter: Md. Joshim Uddin, Dept. of CSE
যারা পিলো পাস বা বালিশ খেলা খেলেছে এটা তাদের পারার কথা। পিলো পাসের সাথে এখানের পার্থক্য হলো পিলো পাসে পিলো ছুটে যাওয়া পর্যন্ত খেলা হয়, এখানে কয়বার খেলা হবে সেটা বলে দেয়া হয়েছে এবং জানতে চাওয়া হয়েছে খেলা শেষে কার কাছে থাকবে বল। ধরা যাক দুজন প্লেয়ার পিলো পাস খেলবে। ইনিশিয়ালি পিলো কার কাছে আছে এবং কয় রাউন্ড খেলা হবে বলে দেয়া হয়েছে। ইনপুট সেট দেখে বোঝা যাচ্ছে যে লিনিয়ারলি একটা করে চেক করেও সলুশন করা যায় কারন ইনপুট সেট ছোট। এই জগতে সবই ভাগশেষ অর্থাৎ রিমাইন্ডারের খেলা।

  1. Solve the Equation 1
Problem setter: Tushar Roy , Department of CSE, 23rd intake

সহজ বিষয়, একটা ইকুয়েশনের রেজাল্ট জানতে চাওয়া হয়েছে। সমস্যা হলো ডাটা লিমিট।
x = n^2 - (n-1)^2.  এখানে n হতে পারে 10^12 পর্যন্ত। তাহলে n^2 হতে পারে 10^12 * 10^12 অর্থাৎ 10^24 পর্যন্ত যেটার ভ্যালু 25 ডিজিট। দুর্ভাগ্যক্রমে long long এর ভ্যালুও সর্বোচ্ছ 19 ডিজিট। সুতরাং ইকুয়েশনকে সলভ করে অপটিমাল রেজাল্ট হিসেবে যে ইকুয়েশন পাওয়া যায় সেটা ব্যবহার করতে হবে।

  1. Solve the Equation 1
Problem setter: Tushar Roy , Department of CSE, 23rd intake

হাইস্কুলে করা ঐকিক নিয়ম। সবই যোগ বিয়োগ গুণ ভাগের খেলা। 4 স্কেলে SGPA বের করে ঐকিক নিয়মে 5 স্কেলে নিতে হবে। আর কিছু না।

  1. Digits 2
Problem setter: Md. Ashraful Islam, Lecturer, Dept. of CSE
অনেক ছোটবেলার একক দশক শতক বের করার পদ্ধতি। একটি সংখ্যার সর্বশেষ ডিজিট নিতে হবে। পিছন থেকে প্রথম ডিজিট একক (unit digit), তারপর দশক (tens digit) তারপর শতক (hundreds digit)। যেকোন সংখ্যাকে 10 দিয়ে ভাগ করলে সেটার ভাগশেষ বিভাজ্য সংখ্যার শেষ ডিজিট যেমন 123%10=3(শেষ ডিজিট)। এই পদ্ধতিতেও সলুশন করা যায়। আবার প্রদত্ত সংখ্যাকে স্ট্রিং হিসেবে নিয়েও করা যায়।

  1. Bubble Sort!!!
Problem setter: Abu Obaida Opu, Department of CSE

এই প্রবলেমের স্টেটমেন্ট আমি বুঝিনাই। এটা আমার ইংরেজির সুদক্ষতার (!) কারনেই হোক আর অ্যানালিটিকাল অ্যাবিলিটির অদক্ষতার কারনেই হোক। আমি দু:খিত। :(

  1. Finding the radius of circle
Problem setter: Md. Mukib Hossen, Department of CSE

এটা প্লেইন জিওমেট্রির প্রবলেম। এই এক্সটারনালি টাচড সার্কেলের প্রবলেমকে Tangent Circles অথবা Apollonius' problem বলে। আমি জিওমেট্রি পারিনা, সুতরাং এটা থেকে দেখা যেতে পারে।

  1. Leap Year 8
Problem setter: Rayhan Ahmed , Department of CSE

এটা ইম্পলিমেন্টেশন প্রবলেম। লজিকও স্টেটমেন্টে দেওয়া আছে। শুধু সমস্যা ডাটা ক্যাপাসিটি। 100 ডিজিট এমনকি long long এ ও আসবে না। স্ট্রিং এ ইনপুট নিতে হবে। তাহলে ভাগ যায় কি না দেখবো কেমনে? প্রত্যেক সংখ্যার ই নি:শেষে বিভাজ্য সংখ্যার একটা প্যটার্ণ থাকে। যেমন 5 দিয়ে বিভাজ্য সংখ্যার শেষে 5 অথবা 0 থাকবে। প্যাটার্ণ খুজে বের করলেই কেল্লা ফতে।

  1. Modified 3n+1
Problem setter: Murad Al Wajed, Department of CSE
ইম্পলিমেন্টেশন প্রবলেম। রিকার্সিভ ওয়ে বা ফর লুপ দিয়ে স্টিং ম্যানিপুলেট করে করা যায়। এখানে  ‍3a হলে ‍aaa যোগ হবে স্ট্রিং এ,  +b হলে স্ট্রিং এ b যোগ হবে। স্ট্রিং ম্যানিপুলেটের জন্য C++ STL এর string লাইব্রেরির কাজগুলা দেখা যেতে পারে।


আমাকে কোনভাবেই ভালো প্রোগ্রামার বলা যায়না। সুতরাং আমার ভুল থাকতে পারে। নোটিফাই করলে ভুল ঠিক করে নেয়া হবে। ধন্যবাদ। :)

Md. Rasedur Rahman Roxy
BSc in CSE
Bangladesh University of Business & Technology

Friday, December 23, 2016

আনইনফর্মড সার্চ এবং আর্টিফিসিয়াল ইন্টেলিজেন্স বাকিটা ইতিহাস

আর্টিফিসিয়াল ইন্টেলিজেন্স বা এআই এর একটি গুরুত্বপূর্ন বিষয় আনইনফর্মড সার্চ। তো প্রথমে শুরু করি এই জিনিষটা কি তা দিয়ে। গুগল মামাকে জিজ্ঞেস করে জানা গেল-

An uninformed (a.k.a. blindbrute-force) search algorithm generates the search tree without using any domain specific knowledge.

কিছু বুঝা গেলনা? আমিও বুঝিনি। তাই সহজ বাংলা ভাষায় বলা যায়-
যেসব সার্চ স্ট্রাটেজি তাদের গোল/ডেস্টিনেশন কোথায় আছে তা নিয়ে মাথা ঘামায় না এবং তারা কোথায় যাচ্ছে তা নিয়েও মাথা ঘামায় না যতক্ষন না তারা তাদের গোল/ডেস্টিনেশনে না পৌছায়।
অর্থাৎ তাদের পথ নিয়ে কোন মাথাব্যাথা নেই। পৌছুতে পারলেই হল।

যেহেতু এই টাইপের সার্চিং স্ট্রাটেজিগুলো তাদের পথ নিয়ে মাথা ঘামায় না, সেহেতু আমরা আশা করতে পারিনা এগুলো সবসময় আমাদের সহজ অথবা ছোট পথে ডেস্টিনেশনে নিয়ে যাবে। এটা এই সার্চের একটা লিমিটেশন।
এরকম কিছু অন্ধ্য খোঁজ অথবা আনইনফর্মড সার্চ অ্যালগরিদম হলো-
·        Breadth First Search
·        Depth First Search
·        Depth Limited Search
·        Iterative Deepening Search

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

না পড়লেও সমস্যা নেই। পড়াশোনা করে কেউ কখনো বড়লোক হয়না।

তো প্রথমে আমরা Breadth First Search নিয়ে আলোচনা করি।
Breadth  অর্থ প্রসার/প্রস্থ। অ্যালগরিদম তোমার কাম কি? নামেই পরিচয়। এই অ্যালগরিদম সবসময় প্রস্থ বরাবর সার্চ করে যায়। যেটাকে আমরা লেভেল বলি। একটি গ্রাফের লেভেল বুঝতে শুধুমাত্র এক ছবিই যথেষ্ট।





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

q.push(strt);

তারপর যেহেতু আমরা সোর্সনোড ভিজিট করবো সেহেতু সোর্সনোড যে ভিজিট করছি তার ট্রেস রাখবো।

vis[node]=1;

যেহেতু আমরা এই নোড ভিজিট করছি সেহেতু এটাকে আমরা path নামক ভেক্টর এ পুশ করবো।

path.push_back(node);

যদি কিউ খালি হয় তাহলে আমরা রিটার্ন করবো কারন তখন কোথাও কেউ নাই।

if(q.empty()) return;

তারপর আমরা কিউতে প্রথমে যে এলিমেন্ট আছে তাকে নিব

int x=q.front();

এবং সেটাকে কিউ থেকে বাদ দিব।

q.pop();

এবার কারেন্ট নোড থেকে যেসব নোডে যাওয়া যায় এবং তার মধ্যে যেসব নোড এখনো ভিজিটেড না সেগুলোকে কিউতে রাখবো।

for(int i=1;i<=n;i++)
    {
        if(graph[x][i] && !vis[i])
        {
            q.push(i);
        }
    }


এবং কিউ থেকে পরবর্তী নোডকে আবার ফাংশনে পাঠাবো (রিকার্সিভ ওয়ে)।
কিন্তু এভাবে তো আমাদের গোল নোডে পৌছানোর পরও ফাংশন স্টপ হবেনা। কারন এরপরও অনেক নোড কিউতে থাকতে পারে। তাহলে?
সিম্পল, আমরা একটা ভেরিয়েবল রাখবো যেটা আইডেন্টিফাই করবে গোল পাওয়া গেছে কি না। পাওয়া গেলে রিটার্ন, না পাওয়া গেলে কন্টিনিউ, কারেন্ট নোড গোল নোড হলে ভেরিয়েবলের ভ্যেলু চেঞ্জ।

if(get_goal) return;
    if(node==goal)
    {
        path.push_back(node);
        get_goal=true;
        return;
    }

এই কাজগুলোকেই গুছিয়ে করা হয়েছে এখানে।
  

এবার আমরা Depth First Search নিয়ে আলোচনা করি।
শ্রদ্ধেয় শাফায়েত ভাইয়ের আর্টিকেল থেকে আমরা জানতে পেরেছি এই অ্যালগরিদম লেভেল বাই লেভেল সার্চ না করে একটা নোড থেকে তার নিচের নোড, তার থেকে তার নিচের নোড এভাবে চলে যায়। অনেক নিচু মনের অ্যালগরিদম। তো এখানে আমরা আগের মতই ভিজিট করবো, path এ পুশ করবো, গোল চেক করবো। যেটা করবো না সেটা হলে কিউ ব্যাবহার করবো না। কোন নোডের চাইল্ড নোড আনভিজিটেড পেলেই সেটাকে আমরা ফাংশনে পাঠাবো।

for(int i=1;i<=n;i++)
    {
        if(graph[node][i] && !vis[i])
        {
            dfs(i);
        }
    }

কাজগুলো গুছিয়ে করা হয়েছে এখানে-



এখন এখানে একটা বিশাল সমস্যা হতে পারে। কত বিশাল? একেবারে ডোনাল্ড ট্রাম্পের আমেরিকার মত বিশাল। যদি কখনো একটি নোডের চাইল্ড সংখ্যা অসীম হয়, তাহলে ফাংশন শুধু সেদিকে যেতেই থাকবে। অন্যদিকে যে কেউ তার জন্য অপেক্ষা করছে সেটা সে ভুলে যাবে। খারাপ কথা। তো এই সমস্যা সমাধানের জন্য ডিএফএস কে মডিফাই করে ডেভেলপ করা হলো ডিএলএস। এখানে অ্যালগরিদমের পায়ে আমরা বেড়ী দিয়ে দিব কয়েদিদের মত। তাকে বলে দেয়া হবে কত লেভেল ডেপথ পর্যন্ত সে যেতে পারে। তো সেজন্য আমরা একটা ভেরিয়েবল ইউজ করবো যেটাকে নাম দিলাম- dls_level.
প্রত্যেক নোডের চাইল্ড নোডে এন্টার করার আগে দেখবে লেভেল কি বেশী হবে কি না। যদি হয় তাহলে যাবেনা।

for(int i=1;i<=n;i++)
{
   if(graph[node][i] && !vis[i])
   {
     if(dls_level < lim)
        dls(i,lim);
   }
}

আর বাকি সব কাজ আগের মতই।



এখানেও একটা সমস্যা আছে। আমরা তাকে বললাম 2 লেভেল পর্যন্ত সার্চ করতে। কিন্তু আমাদের গোল আছে 5 লেভেলে। তখন? তখন সে গোল না পেয়েই রিটার্ন করবে। এ সমস্যা সমাধান করা হয়েছে Iterative Deepening Search এ। সহজভাবে বললে এটা ডিএলএস এর লিমিট আমরা একটা লুপের মাধ্যমে বাড়িয়ে বার বার চেক করবো গোল পাওয়া যায় কি না।



ইনপুট আউটপুট সহ পুরো প্রোগ্রাম:


যেকোন ধরনের অনিচ্ছকৃত ভূল মার্জনিয়। শুদ্ধ করে নেব।
অনেক ধন্যবাদ অমিত কুমার নাথ স্যারকে এরকম বোরিং সাবজেক্ট উৎসাহ দিয়ে পড়ানোর জন্য।


Resources:
Artificial Inteligence A Modern Approach by Stuart Russel & Peter Norvig


Md. Rasedur Rahman Roxy
BSc in CSE
Bangldesh University of Business & Technology

Monday, August 8, 2016

লিনাক্সে টার্মিনাল ব্যবহার পর্ব-২

লিনাক্সে টার্মিনাল ব্যাবহারপর্ব -১  এ আমরা দেখেছিলাম কিভাবে কমান্ড লাইন অর্থ্যাৎ ব্যাশ এর কাজ শুরু করবো। আজ আমরা তার কিছু অ্যাডভান্স কাজ এবং কমান্ডস দেখবো। প্রথমেই দেখা যাক আমরা লিনাক্সের টার্মিনালে কিভাবে কিছু ‍প্রিন্ট করবো। ব্যাপারটা খুবই সহজ। জাষ্ট লিখব
echo “Text here.”

এখানে আমরা একটা ষ্ট্রিং নিয়ে কাজ করেছি। চাইলে আমরা ষ্ট্রিংটাকে আগে রিড করেও তারপর প্রিন্ট করতে পারি। তাহলে রিড করার জন্য আমাদের লিখতে হবে-
read x

তাহলেই টার্মিনালে ইনপুট চাইবে। সেখানে আমরা ইনপুট দিলে সেটা x ভেরিয়েবলে স্টোর হবে। এই ভেরিয়েবল যেকোন টাইপ হতে পারে। এবার আমরা x কে প্রিন্ট করবো। লিখব-
echo $x

এখানে ডলার সাইন নির্দেশ করছে এটা একটা ভেরিয়েবল। ডলার যেমন দামি, এটাও তেমন দামি জিনিস। হা হা…
আচ্ছা এবার আমরা একটা নিউমেরিকাল ইনপুট দিয়ে দেখি প্রিন্ট হয় কি না।

ওয়াও। দ্যাটস ওসাম।
ব্যাপারটা ওনেকটা সি প্রোগ্রামিং এর মত তাইনা? অবশ্য একটা সমস্য আছে। সেখানে আমরা একবারে একটা ফাইলে প্রোগ্রাম লিখি এবং সেটাকে একবারে রান করে ইনপুট দিয়ে আউটপুট পাই। কিন্তু এখানে এক লাইন এক লাইন করে লিখতে হয়।
আচ্ছা যদি এখানেও যদি পুরো প্রোগ্রাম একসাথে লিখে রান করা যেত তবে কেমন হতো তুমি বলতো? এই পথ যদি না শেষ হয় তবেকেমন হত তুমি বলতো? অনেক ভালো।
ওয়েল লিনাক্স আমাদের সে সুযোগও দিচ্ছে। এটাকে স্ক্রিপ্টিং বলে। আমরা আমাদের প্রয়োজনীয় কমান্ডগুলি একটা ফাইলে লিখবো, যেটাকে বলা হয় শেল। সি প্রোগ্রাম যেমন .c এক্সটেনশন দিয়ে শেষ হয়, শেল ফাইল তেমনি .sh এক্সটেনশন দিয়ে শেষ হয়।

ওকে তাহলে আমরা একটা ফাইল ক্রিয়েট করে সেটাতে কিছু কমান্ড লিখি। ফাইল ক্রিয়েটের জন্য আমরা যে কোন একটা টেক্সট এডিটর ব্যবহার করবো। আমি এখানে nano ব্যাবহার করছি। nano ওপেন করার জন্য আমরা টর্মিনালে শুধু লিখবো- nano
টেক্সট এডিটরে আমরা আমাদের কমান্ডগুলো লিখবো। লেখা শেষ হলে ctrl+x চাপবো। তখন এডিটর আমাদের কাছে জানতে চাইবে আমরা কি ফাইলটি সেভ করবো কি না। সেভ করলে y না করলে n। আমরা সেভ করবো। y লিখে এন্টার চাপবো।


তারপর আমাদের কাছে ফাইলের নাম চাইবে। আমরা ফাইলের নাম লিখে এন্টার করবো। এবং অবশ্যই নামের শেষ .sh দিতে ভুলবো না।

ফাইল সেভ করলে আমরা আবার টার্মিনালে ফেরত আসবো।

এবার আমরা ফাইলটা ওপেন করবো, অর্থাৎ রান করবো। সেজন্য আমরা লিখবো-
./filename.sh


ও ও…. এটা কি হলো? আমাদের বলছে পারমিশন নেই। কেমনে কি? ওকে তাহলে আমরা একটু পারমিশন নিয়ে আলোচনা করি।
লিনাক্সের পারমিশনকে আমরা দুই ক্যাটাগরিতে নিতে পারি। এক. এক্সেসিবিলিটি এবং দুই. ইউজার.
এক্সেসিবিলিটি পারমিশন তি ধরনের। রিড পারমিশন যেটার পয়েন্ট হলো 4, রাইট পারমিশন যেটার পয়েন্ট 2 এবং এক্সিকিউশন পারমিশন যেটার পয়েন্ট 1. এখন কোন ফাইলের পারমিশন যদি থাকে 3 তাহলে আমরা বুঝবো সেটার শুধুমাত্র এক্সিকিউশন এবং রাইট পারমিশন আছে (1+2=3)। একইভাবে যদি কোন ফাইলের যদি পারমিশন পয়েন্ট থাকে 7 তাহলে আমরা বুঝবো সেটার সব পারমিশন আছে (1+2+4=7)।
আবার তিন ধরনের ইউজার হলো ওনার, গ্রুপ(নেটওয়ার্ক গ্রুপ) এবং আদার্স/পাবলিক। তিন ধরনের ইউজারের জন্য তিনটি পারমিশন পয়েন্ট।
তো কোন ফাইলের পারমিশন সেট করার কমান্ড হলো-
chmod *** filename.sh

এখানে তিনটি স্টার যথাক্রমে ওনার, গ্রুপ এবং আদার্স/পাবলিক ইউজারের জন্য। সুতরাং আমরা চাইলে এক ইউজারের জন্য এক ধরনের পারমিশন দিতে পারবো।

আচ্ছা এবার তাহলে আমরা আমাদের ফাইলটিতে পারমিশন দি। যেহেতু আমরা কোন নেটওয়ার্কের সাথে কানেক্টেড না। তাহলে আমরাই ওনার আমরাই গ্রুপ আমরাই আদার্স/পাবলিক এবং আমরা সবাই রাজা আমাদের এই রাজার রাজত্বে। সুতরাং আমরা ফুল পারমিশন দিব।
chmod 777 filename.sh

এবার আমরা আমাদের ফাইল আবার রান করি।

ওয়াও। এটা কাজ করছে।
আচ্ছা তাহলে আমরা এবার একটা ছোটখাট প্রোগ্রাম করি যেটাতে দুটি সংখ্যা ইনপুট নিয়ে তাদের যোগফল দেখাবে।
তো আমরা nano ওপেন করে লিখবো এবং add.sh নাম দিয়ে সেভ করবো-

পারমিশন দিব-
chmod 777 add.sh
এবং রান করে ইনপুট দিব।

এখানে কিছু বিষয় খেয়াল রাখতে হবে। যেমন অপ্রয়জনীয় স্পেস দেয়া যাবেনা। সেমিকমা দেয়া যাবেনা ইত্যাদি।
আচ্ছা এবার আমরা একটু কন্ডিশনাল প্রোগ্রামিং শিখবো। অর্থাৎ IF ELSE এর কাজ। তো দেখা যাক-
আমরা একটা প্রোগ্রাম লিখবো যেটা একটি সংখা ইনপুট নিয়ে সেটা কি পজিটিভ, নেগেটিভ নাকি জিরো সেটা দেখাবে। যার নাম দিলাম cond.sh-

পারমিশন সেট করে রান করবো এবং আউটপুট দিব।

এখানে -gt মানে হলো grater then, -lt মানে হলো less then, আর fi নির্দেশ করছে আমাদের পূর্বক্ত if স্টেটমেন্ট শেষ হবে এখানে।
আচ্ছা এই পর্বের বিদায়বেলায় আমরা লুপিং শুরু করে যাব। আপাতত আমরা শুধু ফর লুপ নিয়ে মাথা ঘামাবো। (কারন এর বেশী আমি কিছু পারিনা।)
তাহলে আমরা একটা প্রোগ্রাম লিখি যেটা একটি সংখ্যা ইনপুট নিবে এবং ১ থেকে ওই সংখ্যা পর্যন্ত প্রিন্ট করবে এবং শেষে সবগুলো সংখ্যার যোগফল প্রিন্ট করবে। যেটার নাম দিলাম loop.sh

ব্যাস এ যেহেতু সেকেন্ড ব্রেস ব্যাবহার হয়না। সেহেতু আমরা আমাদের লুপ এর ভিতরের ষ্টেটমেন্টগুলো এবং এই দুটি সিনট্যাক্সের ভিতরে লিখবো।
রান করার পর আমরা আউটপুট দেখলাম-

এই পর্ব এই পর্যন্তই। আবারও বলছি যেহেতু আমি লিনাক্সে পুরোপুরি নবিশ। সুতরাং ভুল হতে পারে। ক্ষমাসুন্দর দৃষ্টিতে দেখে জানানোর অনুরোধ করছি। শুদ্ধ করে নেব। ধন্যবাদ।

Md. Rasedur Rahman Roxy
Dept. of CSE
Bangladesh University of Business & Technology

Tuesday, June 28, 2016

লিনাক্সে টার্মিনাল ব্যবহার পর্ব-১

লিনাক্স অপারেটিং সিষ্টেম সম্পর্কে আমরা সবাই কমবেশি জানি। তারপরেও একটু বলি। লিনাক্স একটি ওপেন সোর্স কার্নেল যেটা একজন ফিনিশ ছাত্র লিনাস টরভাডস এর মাধ্যমে 1991 সালে সর্বপ্রথম ছোট পরিসরে ডেভেলপড হয়। এটি একটি ওপেন সোর্স প্রজেক্ট অর্থাৎ এর সোর্সকোড আল্লাহর ওয়াস্তে পাওয়া যায় এবং যে কেউ সেটাকে নিজের মত আপডেট করে নতুন ভাবে বানাতে পারে। যাই হোক আমরা লিনাক্সের কমান্ড লাইনে ফিরে যাই। যদিও লিনাক্সের সব ডিস্ট্রিবিউশনেরই খুব সুন্দর সুন্দর ইউজার ইন্টারফেস আছে তারপরও কেন যেন কমান্ডলাইনে কাজ করেই বেশী মজা পাওয়া যায়। আমার এই লেখাতে আমি আমার অপারেটিং সিস্টেম কোর্সে যেসব কমান্ড শিখেছি সেগুলো গুছিয়ে লেখার চেষ্টা করব।
প্রথমেই আসি কিভাবে কমান্ড লাইন উইন্ডো অর্থাৎ টার্মিনাল ওপেন করবো।
উবুন্টু লিনাক্সে Ctrl+T চেপে টার্মিনাল উইন্ডো ওপেন করা হয়। আর প্রায় সব ডিস্ট্রোতেই (উবুন্টু, রেড হ্যাট, কালি আমি ব্যবহার করেছি) ডেক্সটপে রাইট বাটনে ক্লিক করে একদম নিচ থেকে Open Terminal সিলেক্ট করে ওপেন করা যায়।



আমি কালি লিনাক্স ব্যাবহার করি। সেখানে সাইডবারে এরকম টার্মিনাল আইকন এ ক্লিক করেও টার্মিনাল ওপেন করা যায়।


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

আমরা যদি জানতে চাই আমরা বর্তমানে কোন অবস্থানে আছি ডিস্কের, অর্থাৎ কোন লোকেশনে তাহলে
pwd

কমান্ডটি এক্সিকিউট (এন্টার কি প্রেস) করবো।
এই pwd এর মানে হচ্ছে print working directory. অর্থাৎ বর্তমানে কর্মরত ডিরেক্টরি। ও হ্যাঁ ফোল্ডারকে ডিরেক্টরিও বলা হয়।
দেখা যাচ্ছে আমরা বর্তমানে অপারেটিং সিস্টেমের রুট নামক ফোল্ডারে অবস্থান করছি। বাই ডিফল্ট আমাদের টার্মিনাল রুটেই অবস্থান করবে। শিকড়ের টান বলে কথা।

আচ্ছা এবার আমরা যদি চাই এই ফোল্ডারে আমরা আরেকটা ফোল্ডার ক্রিয়েট করবো, তাহলে নিচের কমান্ডটি এক্সিকিউট করবো।
mkdir Folder_Name

এখানে mkdir  মানে Make Directory. এক্ষেত্রে একটা বিষয় খেয়াল রাখতে হবে ফোল্ডারের নামের মাঝে স্পেস দিলে শুধুমাত্র প্রথম অংশটুকু নাম হিসেবে নেবে। কেন সেটা আমি জানিনা। এই কমান্ড এক্সিকিউট করার পর টার্মিনালে কোন আউটপুট আসবে না।
কিন্তু আমরা কমান্ড দিয়েই দেখতে পারি ফোল্ডার তৈরি হয়েছে কি না। তার জন্য নিচের কমান্ডটি এক্সিকিউট করবো।
ls

(এলএস) এই কমান্ডের মাধ্যমে আমরা কারেন্ট ডিরেকটরির সব ফাইল এবং ফোল্ডার লিস্ট আকারে পাবো। এখানে আমরা দেখতে পাচ্ছি একটা লিস্ট। এখানে নীল রঙের নামগুলো ইন্ডিকেট করছে এগুলো ননএক্সিকিউটেবল ফোল্ডার, এবং সবুজ রঙ বলছে এগুলো এক্সিকিউটেবল ফাইল। ডট(.) কিছু একটা থাকা মানে সেটা ফাইল। আর বিভিন্ন ডিস্ট্রোতে রঙ্গের বিভিন্নতা থাকতে পারে।

ওকে, এবার আমরা যদি চাই যে আমরা আমাদের নতুন তৈরি করা ফোল্ডারটিকে এন্ট্রি মারবো, তাহলে ঝটপট নিচের কমান্ডটি এক্সিকিউট করে ফেলি।
cd Folder_name


এখানে cd মানে হলো change directoryআমরা দেখতে পাচ্ছি আমাদের কমান্ড স্ট্রিং পরিবর্তিত হয়েছে। এখন আমরা যদি পূব ব্যাবহৃত pwd কমান্ডটি আবার এক্সিকিউট করি তাহলে আমরা দেখব যে আমার কারেন্ট ওয়ার্কিং ডিরেক্টরি পরিবর্তিত হয়েছে।

এবার আমরা দেখি আমাদের এই নতুন তৈরি ফোল্ডারে কি কি আছে।

যেহেতু এটা একদম ব্রান্ড নিউ ডিরেক্টরি সুতরাং এটাতে কিছু থাকবেনা এটাই স্বাভাবিক।

এবার আমাদের যদি মনে হয় আমরা আবার শিকড়ের টানে রুট এ ফিরে যাবো তাহলে নিচের কমান্ডটি এক্সিকিউট করে ফেলি।
cd ..

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

আচ্ছা এখন আমাদের যদি ফোল্ডারের নামটা পছন্দ না হয় তাহলে আমরা সেটাকে রিনেমও করতে পারি কমান্ড দিয়ে।
mv Folder_name New_folder

দেখা যাচ্ছে আমরা আমাদের ফোল্ডারের নাম পরিবর্তন করে Folder_name থেকে New_folder এ রিনেম করে ফেলেছি। দ্যাটস ওসাম।

এখন যদি আমরা চাই আমরা আমাদের এই New_folder  টাকে রুট থেকে Documents ফোল্ডারে মুভ করবো তাহলে
mv New_folder Documents


প্রশ্ন আসতে পারে রিনেম এবং মুভ এর কমান্ড সেম কেন। উত্তর আমি জানিনা অন্তত এখন পর্যন্ত।

সমস্যা হলো এখন ডকুমেন্টস ফোল্ডারে আমাদের New_folder ফরএভার এলোন থাকতে চাচ্ছেনা। সে দু:খে মরে যেতে চায়। সো আমরা তাকে ডিলেট করে দিতে পারি। আফটার অল যে চলে যেতে চায় তাকে যেতে দিতে হয়।
rmdir New_folder


এখানে rmdir মানে হলো রিমোভ ডিরেক্টরি। দেখা যাচ্ছে আমাদের ফরএভার এলোন New_folder  সাহেবের অকাল প্রয়ান ঘটেছে। তাইতো Documents ফোল্ডারটি শুন্যতায় হাহাকার করে।

এখন একটা মজার কমান্ড। আমরা চাইলে টার্মিনালে আমাদের কারেন্ট ডেইট, টাইম দেখতে পারি। শুধুমাত্র টার্মিনালকে বলতে হবে
date


একি ভাবে কারেন্ট মাসের ক্যালেন্ডারও দেখতে পারি।
cal

দেখা যাচ্ছে আমাদের টার্মিনালে অনেক হিজিবিজি হয়ে গেছে। সুতরাং আমরা টার্মিনালকে বলবো সব আবর্জনা clear করতে।

বাহ্ আমাদের টার্মিনাল পরিষ্কার হয়ে গেছে। কি সুন্দর কথা শুনে। বাসার বুয়ারাও যদি এরকম শুনতো।
ওয়েল অনেক কমান্ডিং হয়েছে। এবার আমরা একটা নির্দিষ্ট টাইমে কম্পিউটারকে শাটডাউন হওয়া অর্ডার দিয়ে ঘুমিয়ে পড়তে পারি।
shutdown 01:00


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

Md. Rasedur Rahman Roxy
Dept. of CSE
Bangladesh University of Business & Technology