Showing posts with label আর্টিকেল. Show all posts
Showing posts with label আর্টিকেল. Show all posts

Friday, March 17, 2017

সফটওয়্যার ডেভেলপার এবং সফটওয়্যার ইঞ্জিনিয়ারের মধ্যে পার্থক্য কী (What is the difference between software developer and software engineer)

ইঞ্জিনিয়ারিংয়ের সঙ্গে অনেকগুলো প্রিন্সিপাল ও ডিসিপ্লিন জড়িত। এটি যেকোনো ইঞ্জিনিয়ারিংয়ের ক্ষেত্রেই প্রযোজ্য। একজন ইঞ্জিনিয়ারের কোনো বিষয়ের উপর তাত্ত্বিক ও ব্যবহারিক জ্ঞান থাকে, যা ব্যবহার করো কেনো বিশেষ জিনিস তৈরি করে থাকে। একজন সিভিল ইঞ্জিনিয়ারিংয়ের ক্ষেত্রে ব্রিজ তৈরি একটি উদাহরণ হতে পারে। ইঞ্জিনিয়ার যখন কোনো একটি প্রোডাক্ট তৈরি করে, সে তার প্রিন্সিপাল ও ডিসিপ্লিনগুলো মেনেই প্রোডাক্টটি তৈরি করে যাতে করে এটি টেস্টেবল হয়(ব্রিজের ক্ষেত্রে এর স্টিল, কনক্রিটকে টেস্ট করা যাবে, টেস্টের ফলাফল সবসময় একই হবে), মেইনটেবেল হয়( ব্রিজটি অবশ্যই একটি নির্দিষ্ট সময় ধরে চলবে, তা ১০০ বছর হতে পারে। হঠাৎ করে ভেঙ্গে পড়ে যাবে না। একে সহজেই পরিচর্চা করা যাবে, এবং ব্রিজের সঙ্গে যাতে করে পরবর্তীতে নতুন কিছু যুক্ত করা যায় সেই সুযোগ রাখতে হবে), ইন্টারনাল ও এক্সটারনাল ইন্টিগ্রিটি রক্ষা হবে (ব্রিজটি হঠাৎ করে মাঝ বরাবর ভেঙ্গে পরবে না, বা এর প্রত্যেকটি আলাদা আলাদা উপাদানগুলো একটার সংঙ্গে অন্যটি সঠিকভাবে লেগে থাকবে ইত্যাদি)। একজন ইঞ্জিনিয়ারের অবশ্যই ইথিকস থাকবে। কেও এসে বললেই একটা ব্রিজ তৈরি করবে না যা কিনা হঠাৎ করে ভেঙ্গে গিয়ে মানুষের মৃত্যুর কারণ হয়ে দাড়াবে। অর্থাৎ একজন ইঞ্জিনিয়ার পুরো পক্রিয়াটিকে তার তাত্ত্বিক ও ব্যবহারিক জ্ঞান ব্যবহার করে সঠিকভাবে কোনো কিছু তৈরি করবে। এই তৈরির প্রক্রিয়ার সঙ্গে অনেক ধরণের মানুষ যুক্ত থাকতে পারে, তাদের সঙ্গে কীভাবে যোগাযোগ করতে হবে এবং পুরো প্রক্রিয়াটি সুন্দরভাবে পরিচালনা করার দক্ষতাও থাকবে একজন ইঞ্জিনিয়ারের যাতে প্রয়োজনের অতিরক্ত রিসোর্স ব্যবহার না হয়, প্রক্রিয়াটি কস্ট ইফেক্টিভ হয় এবং এন্ড প্রডাক্ট ব্যবহারযোগ্য হয়।

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

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

অন্যদিকে সফটওয়্যার ডেভেলপার হলো একজন ব্যক্তি যিনি সফটওয়্যার ইঞ্জিনিয়ারিং ডিসিপ্লিনের কোনো এক বা একাধিক অংশে পারদর্শী। সাধারণ ক্ষেত্রেই তিনি বিশেষ কোনো বা একাধিক প্রোগ্রামিং ল্যাংগুয়েজে পারদর্শী হয়ে থাকেন। সফটওয়্যার ডেভেলপার হওয়ার জন্য অ্যাকাডেমিক সেটিংসে কোনো ডিগ্রী নিতে হবে এমন কোনো বাধ্যবাদকতা বা প্রয়োজনীয়তা নেই। অর্থাৎ সফটওয়্যার ডেভেলপমেন্ট সফটওয়্যার ইঞ্জিনিয়ারিংয়ের একটি অংশ। 

সহজ কথায় বলতে গেলে -

সফটওয়্যার ইঞ্জিনিয়ার = ইঞ্জিনিয়ারিং প্রিন্সিপাল + ডিসিপ্লিন + আরও অনেক কিছু + সফটওয়্যার ডেভেলপার।

সফটওয়্যার ডেভেলপারেরও এই প্রিন্সিপাল ও ডিসিপ্লিন থাকতেও পারে, সেক্ষেত্রে সেগুলো সে নিজে নিজে শিখে নিতে পারে। 

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

তবে টাইটেল নিয়ে খুব বেশি বিচলিত হওয়ার কিছু নেই। বিভিন্ন কোম্পানি বিভিন্নভাবে নামকরণ করে থাকে। 

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

এখানে একটি বিষয় মনে রাখতে হবে যে, সফটওয়্যার ইঞ্জিনিয়ারিং শুধুমাত্র প্রোগ্রামিং নয় ।

পরবর্তী পর্বে সফটওয়্যার ইঞ্জিনিয়ারিং পুরো পক্রিয়া ব্যাখ্যা করার চেষ্টা করবো।

Monday, February 20, 2017

জাভা দিয়ে ওয়েব ক্রলার (Java Web Crawler Implementation)

ওয়েব ক্রলার মূলত একটি প্রোগ্রাম যা বিভিন্ন ওয়েব সাইট ব্রাউজ করে বিভিন্ন তথ্য বের করে। একে অনেক সময় স্পাইডার বা ইন্টারনেট বট ও বলা হয়। একটি ওয়েব ক্রলার তৈরি করা একটি ফান প্রজেক্ট হতে পারে।

জাভা দিয়ে এটি তৈরি করার সময় বেশ কতগুলো বিষয় অর্থাৎ ডিজাইন নিয়ে চিন্তা করা যায়। যেমন -
১. এটি সিঙ্গেল থ্রেডেড (Single threaded,) ও সিনক্রোনাস (synchronous) হতে পারে।
২. মাল্টি থ্রেডেড (multi threaded ) ও কনকারেন্ট (concurrent) হতে পারে।
৩. জাভা ইনপুট/আউটপুটের(I/O) জন্যে স্ট্রিম বেইজড বা নিউআইও(NIO) এর বাফার ও চ্যানেল বেইজড হতে পারে।

শুধুমাত্র ফান প্রজেক্ট হিসেবে করতে চাইলে প্রত্যেকটি কম্বিনেশনের জন্যে আলাদা আলাদা করে তৈরি করা যেতে পারে।

সিঙ্গেল থ্রেডেড ও সিনক্রোনাস ক্রলারের তৈরি করা সহজ। এটি তৈরি করতে হলে নিচের কাজগুলো করতে হবে -
১. প্রথমে একটি ওয়েব অ্যাড্রেস থেকে HTML পেইজ ডাউনলোড করতে হবে।
২. HTML পেইজকে পার্স(parse) করতে হবে।
৩. পার্স করারপর প্রয়োজনীয় তথ্যগুলো আলাদা করতে হবে।
৪. পেইজে আরও কোনো লিংক থাকলে সেগুলো আলাদা করতে হবে।
৫. সেই লিংক থেকে আবার ১ নং এর মতো পুরো প্রক্রিয়াটি শুরু করতে হবে।

এই রকম একটি উদাহরণ পাওয়া যাবে এই লিংকে : https://goo.gl/0EiQnC

তবে এর চেয়ে ভাল উপায় হতে পারে যদি মাল্টি থ্রেডেড ক্রলার তৈরি করতে পারি, যাতে অনেকগুলো থ্রেড একই সাথে পাশাপাশি কাজ করবে।

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

এটি রান করতে হলে আপনার মেশিনে যে যে টুলগুলো থাকবে হবে সেগুলো হলো -
১. গিট (Git)
২. গ্রাডল (Gradle)
৩. জাভা ৮

এটি একটি সংক্ষিপ্ত প্রজেক্ট যাতে ৪ টি ক্লাস রয়েছে এবং দুটি ইন্টারফেস রয়েছে।

মূল অংশ শুরু হবে নিচের ক্লাস থেকে -


এতে প্রথমে একটি বেইজ ইউআরএল দিতে হবে যে ওয়েব সাইট থেকে ক্রল শুরু করবে।

এরপরেই রয়েছে Crawler ক্লাস যেখানে থেকে নতুন থ্রেড তৈরি করা হয়। এই থ্রেড HTML পেইজকে ডাওনলোড করে পার্স করতে থাকে। এতে একটি PageProcessor ইন্টারফেইসের ইমপ্লিমেন্টেশন দিতে হয়, যা HTML পেইজটিকে প্রসেস করে। এখানে একাধিক প্রসেসর দেওয়া যেতে পারে। এই প্রজেক্টে HTML পেইজ থেকে লিংকগুলো আলাদা করে পেইজ টি ফাইলে সংরক্ষণ করার জন্যে SaveOnDiskProcessor ক্লাসটি ব্যবহার করা হয়েছে। এতে একটি ফাইলের পাথ দিতে হয়। আপনার প্রয়োজন অনুযায়ী এক বা একাধিক প্রসেসর তৈরি করতে পারেন। এখানে ফাইলে সংরক্ষণ করা হয়েছে, আপনার ডেটাবেইজে সংরক্ষণ করার প্রয়োজন হতে পারে।

সোর্সকোডটি পড়ে বোঝার চেষ্টা করুন। কোনো ফিডব্যাক বা উন্নতি করার উপায় থাকলে ক্লোন করে পুল রিকোয়েস্ট পাঠাতে পারেন। 

Saturday, February 4, 2017

ক্যারেক্টার সেট (Character Set)

ক্যারেক্টার সেট

ক্যারেক্টার সেট নিয়ে কথা বলার আগে একটু এর পেছনের ইতিহাস জেনে নেওয়া উচিৎ। 


টেলিগ্রাফ

একটা সময়ে আমাদের যোগাযোগের একমাত্র মাধ্যম ছিল টেলিগ্রাফ। এতে করে তারের মাধ্যমে বৈদ্যুতিক সিগন্যাল পাঠানো হতো যা প্রায় ১৫০ বছর ধরে ব্যবহার করা হয়। স্যার চার্লস হুইটস্টোন (Sir Charles Wheatstone) এবং স্যার উইলিয়াম ফদারগ্রিল কুক (Sir William Fothergril Cooke) ১৮৩৭ সালে ইংল্যান্ডে সর্ব প্রথম রেলওয়ে টেলিগ্রাফ প্রবর্তন করেন যা কুক ও হুইটস্টোন টেলিগ্রাফ নামে পরিচিত। এতে কতগুলো চুম্বকশলাকা ব্যবহার করা হতো যেগুলোকে তড়িৎচুম্বকীয় আবেশের মাধ্যমে ঘড়ির কাঁটার দিকে (Clockwise) বা ঘড়ির কাঁটার বিপরীত দিকে (Anti-Clockwise) ঘোরানো যেত। চুম্বকশলাকা কোন দিকে ঘুরবে তা নির্ভর করতো টেলিগ্রাফের তারে বিদ্যুত কোন দিকে প্রবাহ হচ্ছে তার উপর। এতে সিগন্যাল ট্রান্সমিশনের যতগুলো চুম্বকশলাকা থাকত ঠিক ততগুলো তারের প্রয়োজন হতো। চুম্বকশলাকাগুলো একটি ডায়মন্ড আকৃতির গ্রিডের ওপরে বসানো থাকতো। এক বা একাধিক চুম্বকশলাকাকে আবিষ্ট করা হতো, তখন চুম্বকশলাকাগুলো গ্রিডের ভেতর একটি বর্ণ নির্দেশ করতো।

ঠিক একই বছর স্যামুয়েল মোর্স (Samuel Morse) আমেরিকান টেলিগ্রাফ প্রবর্তন করেন যা অনেক ক্ষেত্রেই কোক ও হুটিস্টোন টেলিগ্রাফ থেকে সহজ। এতে সিগনাল ট্রান্সমিশনের জন্য একটি তার ব্যবহার করার প্রয়োজন হতো এবং কোনো টেক্সট ইনফরমেশন কতগুলো অন অফ টোন বা লাইট বা ক্লিকের মাধ্যমে পাঠানো হতো যা একজন দক্ষ ব্যক্তি সহজেই বুঝতে পারতো কোনো রকম আদালা যন্ত্র ছাড়াই। একে মোর্সকোড (Morse Code) বলা হয়।

মোর্স কোড মূলত কতগুলো অন (On)/অফ (Off) এর ধারা এবং এগুলো বিভিন্ন দৈর্ঘ্যের হয়। সাধারণত অন সিগন্যালের দৈর্ঘ্য বড় হয় এবং একে ড্যাশ (-) দিয়ে উপাস্থাপন করা হয়। এর উচ্চারণ ডাহ (dah)। অফ সিগন্যালের দৈর্ঘ্য তুলনামূলক ভাবে একটু ছোট হয় একে ডট (.) দিয়ে উপস্থাপন করা হয় এবং এর উচ্চারণ ডিট (dit)। কতগুলো ডট এবং ড্যাশের সিকোয়েন্স দিয়ে একেকটি বর্ণকে উপস্থাপন করা হতো। একটি বর্ণে কতগুলো ড্যাশ এবং ডট থাকবে তার একটি চার্ট তৈরি করা হয়।


চিত্র : মোর্স কোড এর চার্ট

মোর্স কোড একটি বিশেষ আবিস্কার। এই পদ্ধতিতে ভুল হওয়ার সম্ভাবনা কম। এর কারণ খুব সহজে ভোল্টেজ আছে বা নেই, অন কিংবা অফ বলা যায় এবং অন্যান্য টেলিগ্রাফিক পদ্ধতির চেয়ে সহজ। ঠিক এই কারণেই আধুনিক কম্পিউটারগুলোতে বাইনারি সংখ্যা ব্যবহার করা হয়। ১৮৪৪ সালের ২৪ মে মোর্স সর্বপ্রথম একটি ইউ এস টেলিগ্রাফিক লিংকে মোর্স কোড ব্যবহার করে বার্তা পাঠান যা ছিল, What hath God wrought।
সুতরাং দেখা যাচ্ছে একটি টেক্সট তথ্যকে প্রথমে মোর্স কোড অর্থাৎ ডট-ড্যাশ রূপান্তরিত করা হয়, তারপর এটি তারের মাধ্যমে পাঠানো হয়, যেখানে থেকে আবার সেই ডট-ড্যাশ থেকে টেক্সটে রূপান্তরিত করা হয়।
এই তথ্য থেকে দেখা গেল যে, টেলিগ্রাফিক কমিউনিকেশনে মূলত কতগুলো সংকেত (মোর্স কোডের ক্ষেত্রে ডট-ড্যাশ) পাঠানো হয়, সেগুলো পরবর্তীতে অনুবাদ করে মূল তথ্যটি পুনরুদ্ধার করা হয়।


চিত্র : কোক ও হুইটস্টোন টেলিগ্রাফ

এবার আমরা একটু সামনে এগিয়ে করে মূল আলোচনায় চলে আসবো।
মূল ব্যাপার হচ্ছে, ক্যারেক্টার বা বর্ণ হলো যেকোনো লিখন পদ্ধতির মৌলিক একক। এদেরকে একটি বিশেষ আকৃতি বা ছবি দিয়ে প্রকাশ করা হয়। ইংরেজিতে এদের বলে glyph। তবে কম্পিউটার বর্ণ কিংবা ছবি এইরকম কোনো কিছুই মেমোরিতে স্টোর করতে পারে না। কম্পিউটার যা স্টোর করতে পারে তা হলো বিট (bit) যার অর্থ হতে পারে, yes অথবা no; true অথবা false; 1 অথবা 0। কম্পিউটার যেহেতু বিদ্যুতে চলে, সুতরাং আসলে বিট হলো একটি বৈদ্যুতিক পাল্স যা কখনো থাকে, কখনো থাকে না। আমাদের বোঝার সুবিধার্থে এগুলো 0 এবং 1 দিয়ে প্রকাশ করা হয়। তাহলে আমরা সহজ করে বলতে পারি যে, কম্পিউটার যা কিছু স্টোর বা কোনো কমিউনিকেশন লিংক দিয়ে ট্রান্সফার করে তা হলো কতগুলো বিট বা বাইনারি সংখ্যার সিকোয়েন্স বা ধারা।
এখন কতগুলো বাইনারি সিকোয়েন্সকে কোনো ক্যারেক্টার বা বর্ণতে প্রকাশ করতে হলে আমাদের কতগুলো নিয়মকানুনের দরকার হয়। এই নিয়মকানুনগুলোকে এনকোডিং স্কিম (Encoding Scheme) বলা হয়। যেমন,



চিত্র ১.৩৪: ASCII Encoding of 'java'

উপরের ছবিতে, java শব্দটিকে বাইনারি সিকোয়েন্সে রূপান্তরিত করা হয়েছে। এখানে 'a' এর বাইনারি হচ্ছে 01100001, 'b' এর বাইনারি 01100010, এভাবে 'c' এর বাইনারি 01100011। এভাবে ইংরেজি বর্ণমালার ২৬ টি বর্ণকে বাইনারিতে রূপান্তরিত করা হলে,

a -> 01100001
b -> 01100010
c -> 01100011
d -> 01100100
e -> 01100101
f -> 01100110
g -> 01100111
h -> 01101000
i -> 01101001
j -> 01101010
k -> 01101011
l -> 01101100
m -> 01101101
n -> 01101110
o -> 01101111
p -> 01110000
q -> 01110001
r -> 01110010
s -> 01110011
t -> 01110100
u -> 01110101
v -> 01110110
w -> 01110111
x -> 01111000
y -> 01111001
z -> 01111010

চিত্র: ইংরেজি বর্ণমালার ASCII Encoding


এখন যদি আমরা এই ২৬ টি বর্ণের বাইনারি ভ্যালু মনে রাখতে পারি, তাহলে খুব সহজেই বাইনারিতে যেকোনো লেখা পড়তে পারব, তাই নয় কি?

* এখন একটি প্রোগ্রাম লিখে ফেলুন যা একটি ক্যারেক্টার ইনপুট নেবে এবং সেটি যদি একটি আসকি ক্যারেক্টার হয়, তাহলে তা বাইনারিতে রূপান্তরিত করে কনসোলে প্রিন্ট করবে। 

উপরে যে পদ্ধতিতে ইংরেজি ভাষার বর্ণগুলোকে বাইনারিতে রূপান্তরিত করা হয়েছে, তাকে বলা হয় আসকি (ASCII)। এর পূর্ণরূপ হচ্ছে আমেরিকান স্ট্যান্ডার্ড কোড ফর ইনফরমেশন এক্সচেঞ্জ (American Standard Code for Information Interchange)। এই পদ্ধতিতে 0-0, ছোটো হাতের অক্ষর (a-z), বড় হাতের অক্ষর (A-Z), মুষ্টিমেয় যতিচিহ্ণ যেমন, ডলার চিহ্ন ($), এমপারস্যান্ড চিহ্ন (&) ইত্যাদি এবং এছাড়াও আরও কতগুলো কন্ট্রোল কোড যেমন, ক্যারেজ রিটার্ন (Carriage Return), লাইনফিড (Line Feed) ইত্যাদি নিয়ে মোট 128 টি ক্যারেক্টারের একটি টেবিল তৈরি করা হয়। এটি আসকি টেবিল নামে পরিচিত। গুগলে ASCII Table লিখে সার্চ করলেই টেবিলটি চলে আসবে। এই টেবিলে 128 ক্যারেক্টার থাকার কারণ হচ্ছে, প্রথম যে টেবিলটি তৈরি করা হয়েছিল, সেটি ছিল 7 বিটের। আমরা জানি যে, 7 বিট দিয়ে সর্বোচ্চ 128 () টি কম্বিনেশন তৈরী করা যায়, সুতরাং এতে সর্বোচ্চ 128 টি ক্যারেক্টার থাকতে পারে। পরবর্তীতে এই টেবিলকে সম্প্রসারিত করে 8 বিটে উন্নীত করা হয় এবং এতে 256 () টি ক্যারেক্টার রয়েছে।

http://www.ascii-code.com/ এই লিংকটিতে গেলে 256 টি ক্যারেক্টারের তালিকা দেখা যাবে।
এখন প্রশ্ন হতে পারে তাহলে আমরা কম্পিউটার স্ক্রিনে যে লেখা দেখছি তা কীভাবে দেখছি। এর উত্তর জানতে হলে আমাদের জানতে হবে ফন্ট কী।

ফন্ট (Font)
ফন্ট হলো এক ধরনের কম্পিউটার কোড যার মাধ্যমে কোনো একটি বর্ণকে কম্পিউটার স্ক্রিনে Glyph বা pictograph এর মাধ্যমে প্রদর্শন বা উপস্থান করা হয়। অর্থাৎ, ফন্ট হচ্ছে কোনো ক্যারেক্টার বা বর্ণের ছবি। এর মধ্যে ক্যারেক্টারের ও Glyph এর ম্যাপিং থাকে। যখন একটি ক্যারেক্টার ডিসপ্লে করার দরকার হয়, আমরা জানি যে, প্রত্যেকটি ক্যারেক্টারের একটি স্বতন্ত্র সংখ্যা থাকে, সেই সংখ্যা দিয়ে ফন্ট থেকে একটি Glyph বা ছবি বের করে আনা হয়। সহজ কথায় বলতে গেলে, ফন্ট মূলত কতগুলো Glyph এর অ্যারে যার ইনডেক্স হলো ক্যারেক্টারের সংখ্যা। একটি ফন্টের ভেতর আরও একাধিক ডেটা থাকতে পারে, যেমন, কীভাবে একটি ফন্টকে regular, italic, bold, uppercase, lowercase রূপান্তরিত করা যায় ইত্যাদি। এছাড়াও kerning (দুটি ক্যারেক্টারের মধ্যের দূরত্ব), hinting (কীভাবে বিভিন্ন সাইজের ফন্ট ডিসপ্লে বা আঁকা যায়), ligatures (অনেক সময় একাধিক glyph দিয়ে একটি ক্যারেক্টার তৈরি করতে হয়, যেমন, যুক্তবর্ণ) ইত্যাদি তথ্যও থাকে।
এবার আরও ভেতরে প্রবেশ করার আগে কতগুলো টার্ম জেনে নেওয়া যাক,

এনকোড (Encode)/ এনকোডিং (Encoding), ক্যারেক্টার সেট (Character Set) / কারসেট (charset), কোড পয়েন্ট (Code Point)

কম্পিউটার শুধুমাত্র বাইনারি সংখ্যা নিয়ে কাজ করে। কম্পিউটারে আমরা যে বর্ণমালা ব্যবহার করি, সেগুলোর প্রত্যেকটিকে একটি ইন্টিজার সংখ্যা (অঋণাত্বক বা নন-নেগেটিভ) দিয়ে ম্যাপিং করা হয়। ম্যাপিংয়ের অর্থ হচ্ছে, কোনো একটি ক্যারেক্টার বা বর্ণ একটি নির্দিষ্ট সংখ্যাকে নির্দেশ করে। যে নির্দিষ্ট ক্যারেক্টার বা বর্ণগুলোর এই ম্যাপিং করা হয়, তাদেরকে ক্যারেক্টার সেট (Character Set) / কারসেট (charset) বলা হয়। প্রত্যেকটি ক্যারেক্টারের যে ইন্টিজার ভ্যালু বা মান দেওয়া হয়, তাকে কোড পয়েন্ট (Code Point) বলা হয়। এই পুরো প্রক্রিয়াকে এনকোডিং (Encoding) বলা হয়। উদাহরণ, Latin capital letter A ('A') এর ASCII টেবিলে ইন্টিজারের ভ্যালু 65। বাইনারিতে এটি হয়ে যায়, 01000001। এখানে Latin capital letter A হচ্ছে আসকি ক্যারেক্টার সেটের একটি এনকোডেড ক্যারেক্টার এবং এর কোড পয়েন্ট হচ্ছে 01000001।
এখানে মনে রাখতে হবে যে, একই ক্যারেক্টারের কোড পয়েন্ট বিভিন্ন এনকোডিং স্কিমে বিভিন্ন হতে পারে এবং একই কোড পয়েন্ট বিভিন্ন এনকোডিং স্কিমে বিভিন্ন হতে পারে।

স্ট্রিং (String)
একাধিক ক্যারেক্টার এক সঙ্গে থাকলে তাদেরকে স্ট্রিং বলা হয়।

বাইনারি (Binary), অকটাল (Octal), ডেসিমাল (Decimal), হেক্সাডেসিামাল (Hexadecimal) / হেক্স (Hex)
আমরা জানি যে, যেকোনো সংখ্যাকে অনেকগুলো উপায়ে লেখা যায়। যেমন, 125 একটি ডেসিমাল সংখ্যা। এর বাইনারি হচ্ছে, 01111101। একইভাবে এর অকটাল, 175 এবং হেক্স বা হেক্সাডেসিমাল হচ্ছে 7D। সবগুলোর ভ্যালু যদিও এক কিন্তু হেক্স দৈর্ঘ্যে একটু ছোট এবং বাইনারি থেকে বেশি সহজে পড়া যায়। তাই অনেক সময় দেখা যাবে একই মানের সংখ্যা কোথাও হেক্স, আবার কোথাও ডেসিমাল দিয়ে প্রকাশ করা হচ্ছে।

আসকি টেবিল থেকে 128টি ক্যারেক্টার পাওয়া যায়। বর্ধিত আসকি (Extended ASCII) টেবিল থেকে যদিও 256 টি ক্যারেক্টার পাওয়া যায়, কিন্তু তা শুধুমাত্র ইংরেজি বর্ণমালার জন্য সীমাবদ্ধ। পৃথিবীতে নানা রকম ভাষা আছে, বাংলা (Bangla), ফরাসী (French), সুইডিস (Swidish), জার্মান (German) ইত্যাদি। এগুলোর বর্ণ আলাদা। সুতরাং দেখা যাচ্ছে আসকি এনকোডিং স্কিম দিয়ে এই ভাষার লেখাগুলোর বর্ণ ব্যবহার করা যাচ্ছে না। এই সমস্যা সমাধান করার জন্য অনেকেই নানা রকম এনকোডিং স্কিম তৈরি করেছে, যেমন- ISO-646, ISO-8859, UCS-2, UCS-4 CP47, Windows-1250, MIK, ISCII, TSCII ইত্যাদি।

এছাড়াও পৃথিবীতে আরও অনেক ভাষা রয়েছে- যেমন হিন্দি, আরবি, কোরিয়ান, রাশিয়ান ইত্যাদি। চাইনিজ এবং জাপানিজ ভাষায় হাজার হাজার বর্ণ রয়েছে যা কিনা 8 বিট দিয়ে প্রকাশ করা সম্ভব নয়। এই সমস্যা সমাধান করার জণ্যে পরবর্তীতে মাল্টি-বাইট এনকোডিং স্কিম (Multi-Byte Encoding Scheme) প্রবর্তন করা হয়। 8 বিটের পরিবর্তে যদি 16 বিট ব্যবহার করা হয়, তাহলে বা 65536 টি কম্বিনেশন পাওয়া যায়। এরকম একটি এনকোডিং স্কিম হলো, BIG-5। এ পদ্ধতিতে একটি বাইনারি সিকোয়েন্সের ধারাকে 8 বিট অন্তর অন্তর না ভেঙে 16 বিট পর পর ভেঙে সেই ব্লকের ভ্যালু নিয়ে কোড পেজ (Code Page) বা ক্যারেক্টার সেট থেকে বের করা হয়। এটি মূলত বেসিক চাইনিজ বর্ণগুলোর জন্য ব্যবহার করা হয়। এছাড়াও আরেকটি এনকোডিং সিস্টেম হলো, GB18030 যাতে বেসিক এবং সিম্প্লিফায়ড দুটো বর্ণমালায় রয়েছে।


ইউনিকোড (Unicode)
সুতরাং দেখা যাচ্ছে যে, বিভিন্ন ভাষার বর্ণ কম্পিউটার সিস্টেমে ব্যবহার করার জন্য বিভিন্ন রকম এনকোডিং সিস্টেম তৈরি করা হয়ছে। এগুলো অনেক সময় একটি আরেকটির সঙ্গে কাজ করে না। একই সঙ্গে একাধিক ভাষার বর্ণ এক সঙ্গে ব্যবহার করা কঠিন হয়ে পরে। এইসব সমস্যা সমাধান করার জন্য অবশেষে একটি এনকোডিং স্ট্যান্ডার্ড প্রবর্তন করা হয়, যার মাধ্যমে সবগুলো ভাষার বর্ণগুলো ব্যবহার যায়। এই এনকোডিং স্ট্যান্ডার্ডকে ইউনিকোড (Unicode) বলা হয়। তবে এখানে একটি বিষয় মনে রাখতে হবে যে, ইউনিকোড কোনো এনকোডিং স্কিম নয়। ইউনিকোড মূলত একটি টেবিল যা কিনা ক্যারেক্টারগুলো কোড পয়েন্ট নির্দেশ করে। এগুলোকে এনকোডিং করার জন্য একাধিক এনকোডিং স্কিম রয়েছে। ইউনিকোড কোড পয়েন্ট হেক্সাডেসিম্যালে লেখা হয়। এর কারণ হেক্সাডেসিম্যাল সংখ্যাগুলো ছোট। প্রত্যেকটি কোড পয়েন্টের আগে "U+" থাকে। যেমন, বাংলা ‘ক’ এর কোড পয়েন্ট হচ্ছে, U+0995। ‘খ’ এর কোড পয়েন্ট হচ্ছে, U+0996

ইউনিকোড টেবিলে মোট 1,114,112 কোড পয়েন্ট রয়েছে যেখানে সব ধরনের চিহ্ন, ইউরোপিয় (European), মধ্যপ্রাচ্যীয় (Middle Eastern), দক্ষিনীয় (Southern), প্রাচ্যীয় (Eastern), উত্তরীয় (Northern), পশ্চিমা (Western), প্রাগৈতিহাসিক (Pre-Historian) সব ধরনের ক্যারেক্টার রয়েছে। এর ফলে একটি ডকুমেন্টে যেকোনো ধরনের ক্যারেক্টার ব্যবহার করা যায়।
1,114,112 টি সংখ্যা রাখার জন্য ইউটনিকোডে 4 বাইট বা 32 বিট ব্যবহার করা হয়। তবে এখানে সমস্যা হচ্ছে যে, চাইনিজ বা জাপানিজ ক্যারেক্টারগুলো এনকোড করা জন্য বড় সংখ্যা দরকার হলেও সবগুলো বর্ণের জন্য 32 বিট দরকার পড়ে না। যেমন, 

'A' বর্ণটি এনকোড করা হলে তা হবে 00000000 00000000 00000000 01000001
'B' বর্ণটি এনকোড করা হলে তা হবে - 00000000 00000000 00000000 01000010 

যা কিনা যা দরকার তার দেখে অনেক বেশি। তাই ইউনিকোড কোড পয়েন্ট এনকোডিং অপটিমাইজ করার জন্য কতগুলো বিশেষ এনকোডিং স্কিম তৈরি করা হয়েছে। যেমন, UTF-32, UTF-16, UTF-8। UTF-32 এনকোডিং স্কিমে সবগুলো কোড পয়েন্ট 32 বিটে এনকোড করা হয়। UTF-16, UTF-8 এর এনকোডিং স্কিম একটু ভিন্ন। যদি কোনো বর্ণ বা ক্যারেক্টার এক বাইট বা 8 বিটে প্রকাশ করা যায়, তাহলে সেটি এক বাইট বা 8 বিটে এনকোড করবে এবং এর স্কিম হবে UTF-8। যদি 2 বাইট দরকার হয় তাহলে এটি 2 বাইট ব্যবহার করবে এবং স্কিম হবে UTF-16। এভাবে 4 বাইট পর্যন্ত ব্যবহার করবে। এতে করে অনেক কম জায়গায় ব্যবহার করা যায়। অন্যদিকে UTF-16 মাঝামাঝি, যা কিনা 2 বাইট থেকে শুরু করে 4 বাইট পর্যন্ত ব্যবহার করতে পারে।

character
Encoding
Bits
A
UTF-8
01000001
A
UTF-16
00000000 01000001
A
UTF-32
00000000 00000000 00000000 01000001

টেবিল: ইউনিকোড কোড পয়েন্ট এনকোডিং স্কিম

তাহলে ইতিমধ্যে আমরা জেনে গেছি, ক্যারেক্টার সেট এবং এনকোডিং কী। ক্যারেক্টারকে কম্পিউটারে স্টোর করতে হয় কতগুলো সংখ্যার মাধ্যমে। এনকোডিং স্কিমের উপর ভিত্তি করে একটি ক্যারেক্টার বা বর্ণকে বিভিন্ন রকম সংখ্যা বা বিট সিকোয়েন্স দিয়ে এনকোড করা যায়। একটি সংখ্যা বা বিট সিকোয়েন্স বিভিন্ন বর্ণ বা ক্যারেক্টার প্রকাশ করতে পারে। আমরা এও বুঝতে পারলাম যে মোর্স কোড মূলত একটি এনকোডিং সিস্টেম যাতে বর্ণ বা ক্যারেক্টারগুলো বিট সিকোয়েন্স না হয়ে কতগুলো ডট-ড্যাশের সিকোয়েন্স।
এখন যদি কোনো বিট সিকোয়েন্স যদি আমরা স্টোর করি বা কোনো কমিউনিকেশন লিংকের মাধ্যমে ট্রান্সফার করি, তাহলে এনকোডিং স্কিম জানা থাকলে তা সহজে পাঠোদ্ধার করা সম্ভব।

Friday, January 13, 2017

প্রোগ্রামিং প্যারাডাইম

সফটওয়্যার মূলত প্রোগ্রাম। একটি প্রোগ্রামে কতগুলো ইনস্ট্রাকশন লেখা থাকে। কম্পিউটার প্রোগ্রামের ইনস্ট্রাকশন অনুযায়ী কাজ করে। এই ইনস্ট্রাকশনগুলো ইচ্ছে মতো দেওয়া যায় না। এগুলো দেওয়ার কতগুলো পদ্ধতি ও স্টাইল রয়েছে। 

এই আলোচনার বিষয়বস্তু হচ্ছে প্রোগ্রামিং স্টাইল। 

উদাহরণসরূপ বলা যেতে পারে যে, আমরা সাবাই পোশাক পড়ি। কিন্তু প্রত্যেকে আলাদা আলাদা পোশাক পড়ে থাকে, বাঙালীদের পোশাকের নিজস্ব স্টাইল রয়েছে। তবে কেউ কেউ ওয়েস্ট্রার্ন ড্রেস পড়তে স্বাচ্ছন্দবোধ করে। আবার কোনো কোনো বিশেষ অনুষ্ঠানে ড্রেস কোড থাকে। তবে আপনি সে রকম পোশাকই পরিধান করুন না কেনো, পোশাক পড়ার মূল কারণ একই।

একইভাবে প্রোগ্রামিং করার ক্ষেত্রেও এরকম অনেকগুলো স্টাইল রয়েছে। তবে যে স্টাইলেই প্রোগ্রাম লিখুন না কেনো, মূল উদ্দ্যেশ্য কম্পিউটারকে ইনস্ট্রাকশন দেওয়া, তাকে দিয়ে কাজ করিয়ে নেওয়া। 

প্রোগ্রামিংয়ের স্টাইলগুলোকে প্রোগ্রামিং প্যারাডাইমও বলা হয়। প্রোগ্রামিংয়ের বেশ কতগুলো প্যারাডাইম রয়েছে -

১. ইম্পারেটিভ (imperative) 
২. ডিক্লেয়ারেটিভ (declarative) 
৩. স্ট্রাকচারড (structured) 
৪. প্রসিডিউরাল (procedural) 
৫. ফাংশনাল (functional) 
৬. অবজেক্ট ওরিয়েন্টেড (object oriented) 
ইত্যাদি। 

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

একটি প্রোগ্রামে দুটি জিনিস থাকে- ডেটা ও ফাংশন। একটি প্রোগ্রামে কতগুলো ভ্যারিয়েবল ডিক্লেয়ার করা হয়, যেখানে নানা রকম ডেটা রাখা হয়। ফাংশনগুলো সেই ডেটার উপর কাজ করে। ফাংশন যখন কাজ করে সেই ভ্যারিয়েবলগুলো মানের পরিবর্তন হয় বা ফাংশন সেগুলো পরিবর্তন করে। কোন বিশেষ মুহূর্তে ভ্যারিয়েবলগুলোতে যে মান থাকে সেগুলোকে প্রোগ্রামের অবস্থা বা স্টেট (state) বলা যায়। অন্য অর্থে ভ্যারিয়েবলগুলোই প্রোগ্রামের স্টেট বা অবস্থা। প্রোগ্রামের স্ট্যাটের অবস্থান অনুযায়ী নাম ও স্কোপ আলাদা হয়। প্রোগ্রাম সাধারণত একটা ফাইলে লেখা হয়। এই ফাইলের একদম উপরে যদি কোন ভ্যারিয়েবল ডিক্লেয়ার করা হয় এবং সেগুলোকে প্রোগ্রামের যে কোনো জায়গা থেকে অ্যাকসেস করা যায়, তাহলে সেগুলোকে গ্লোবাল (global) ভ্যারিয়েবল বা স্টেট বলা হয়। আবার যদি কোনো ফাংশনের মধ্যে ডিক্লেয়ার করা হয়, তার স্কোপ হয় লোকাল(local) এবং একে লোকাল ভ্যারিয়েবল বলা হয়। এদেরকে যে ফাংশনে ডিক্লেয়ার করা হয়েছে তার বাইরে অন্য কোথাও থেকে অ্যাকসেস করা যায় না। 

একটি প্রোগ্রামে নানা রকম এক্সপ্রেশন ও স্টেটমেন্ট থাকে। এক্সপ্রেশন হলো যেখান থেকে কোনো একটি ভ্যালু বা মান বের করা যায়। যেমন- 



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



উপরের লাইনটি একটি এক্সপ্রেশন যা প্রোগ্রামকে ১০০ নম্বর লাইনে যেতে বলছে। এটি একটি স্টেটমেন্ট। পাইথনের ক্ষেত্রে নিচের উদাহরণটি দেওয়া যায়




এবার প্রোগ্রামিংয়ের বিভিন্ন প্যারডাইমগুলো নিয়ে হালকা আলোচনা করা যাক -


ইম্পারেটিভ - 
এই স্টাইলের প্রোগ্রামগুলো স্টেপ বাই স্টেপ লেখা হয়। প্রোগ্রামে কতগুলো গ্লোবাল স্টেট থাকে। ফাংশনগুলো এই গ্লোবাল স্টেটকে পরিবর্তন করে। প্রোগ্রামে কোথায় কী করতে হবে তা লিখে দিতে হয়। অনেকটা কতগুলো কমান্ড একের পর এক সাজিয়ে প্রোগ্রাম লেখার মতো। তবে কীভাবে প্রোগ্রামটি এক্সিকিউট হবে, প্রােগ্রাম এক্সিকিউট হলে কী আউটপুট হবে, ভ্যারিয়েবলগুলোর পরিবর্তনগুলো কীভাবে করতে হবে ইত্যাদি প্রোগ্রামারকে বিস্তারিত পুঙ্খানুপুঙ্খভাবে (in detail) বলে দিতে হয়। পুনরাবৃত্তিমূলক কাজগুলো করার জন্যে GoTo ব্যবহার করা হয়। এর এক্সিকিউশন হয় স্টেটমেন্ট বেইজড। কোন একটা ফাইলে উপর থেকে প্রোগ্রাম প্রত্যেকটি স্টেটমেন্ট এক্সিকিউট করে করে কোনো কাজ সম্পাদন করে। 



ডিক্লেয়ারেটিভ -
এই স্টাইলের প্রোগ্রামে প্রোগ্রামার কী চায় তা বলে, কিন্তু কীভাবে তা আসবে বা কিভাবে আউটপুটটি তৈরি হবে তা বলা থাকে না। অর্থাৎ প্রোগ্রামার প্রোগ্রামে কী করতে হবে তা লিখে, কীভাবে করতে হবে তা লিখে না। এটি ইম্পারেটিভ প্রোগ্রামের অনেকটা উল্টো। এতো কোনো অ্যাসাইনমেন্ট থাকে না, লুপ থাকে না। এটি শুধুমাত্র এক্সপ্রেশন বেইজড। এতে শুধু এক্সপ্রেশন লেখা যায় যা থেকে কোনো ভ্যালু deduce বা বের করা আনা যায়। ডাটাবেজের সিকুয়েল প্রোগ্রাম ডিক্লেয়ারেটিভ প্রোগ্রামিংয়ের উদাহরণ বলা যায়। 



স্ট্রাকচারড প্রোগ্রামিং -
এটিও ইম্পারেটিভ প্রোগ্রামিংয়ের একটা আলাদারূপ এবং এতে বাড়তি কিছু বিষয় থাকে। এতে লুপিং, ব্রাঞ্চি করা যায়। প্রোগ্রামের ফ্লো উপর থেকে নিচে না এসে বিভিন্ন দিকে চলে যেতে পারে- এগুলোর জন্য if, switch ইত্যাদি ব্যবহার করা হয়। পুনরাবৃত্তিমূলক কাজ করার জন্য এতে GoTo এর বদলে লুপ ব্যবহার করা হয়। এই প্রোগ্রামিংয়ে কোডগুলো বিভিন্ন স্ট্রাকচারে গুছিয়ে সুন্দর করে উপস্থাপন করা হয়। এতে নানা রকম সাব-রুটিন বা ফাংশন থাকে। কোডগুলোকে বিভিন্ন ব্লকে সাজানো যায়। এতে করে পরিস্কারভাবে কোড লেখা যায় যাতে করে পরবর্তীতে প্রোগ্রামারদের পড়রে সুবিধা হয়।



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



ফাংশনাল -
ফাংশনাল প্রোগ্রামিংকে প্রোগাম লেখা হয় কতগুলো ফাংশন সুবিন্যস্ত (compose) করে। তবে ফাংশনাল প্রোগ্রামের বড় বৈশিষ্ট হলো এটি কোনো গ্লোবাল স্টেটকে পরিবর্তন করে না। মনে করুন, একটি ফাংশনের কাজ হলো ১ ইনক্রিমেন্ট করা। এটি যদি ফাংশনাল প্রোগ্রামিংয়ে লেখা হয় তাহলে এই ফাংশন কোনো গ্লোবাল ভ্যারিয়েবলকে পরিবর্তন করবে না। বরং এটি একটি সংখ্যা আর্গুমেন্ট হিসেবে নিয়ে এক ইনক্রিমেন্ট করে রিটার্ন করবে। আরেকটি উদাহরণ দেওয়া যাক -

ধরুন, একটি ক্লাসের সবগুলো ছাত্রছাত্রীর বয়সের গড় নির্ণয় করতে হবে। এর জন্য প্রথমে এদের বয়স যোগ করতে হবে। 

বয়স নির্ণয় করার প্রক্রিয়াটি নিচের মতো হতে পারে- 

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

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

ফাংশনাল প্রোগ্রামিং মূলত এভাবেই চিন্তা করা হয়। এর আরও অনেকগুলো বৈশিষ্ট্য রয়েছে। সেগুলো হলো - 

১. একটি ফাংশন আরেকটি ফাংশনে আর্গুমেন্ট হিসেবে পাস করা যায়।
২. একটি ফাংশন অন্য একটি ফাংশন রিটার্ন করতে পারে। 
৩. ফাংশন পিউর (pure) হয়- অর্থাৎ একই ইনপুটের জন্যে সবসময় ফাংশন একই রেজাল্ট রিটার্ন করবে এবং এটি কখনোই গ্লোবাল স্টেটকে পরিবর্তন করবে না। 
৪. সব ফাংশন কল করার সঙ্গে সঙ্গেই এক্সিকিউট হয়ে যায় না। যখন প্রয়োজন পরে শুধুমাত্র তখনই এক্সিকিউট হয়। একে লেজি ইভ্যালিউশন (lazy evaluation) বলে। 
৫. এতে ডিক্লেয়ারেটিভভাবে কোড লেখা যায়। 

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



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

কোড রিইউজ করার জন্য এতে ইনহেরিট্যান্সের সুবিধা সহ, পলিফরফিজম ও এনক্যাপসুলেশন ইত্যাদি বৈশিষ্ট্য থাকে। 

উপরে উল্লেখিত এই কয়েকটি ছাড়াও আরও অনেক রকম প্রোগ্রামিং প্যারাডাইম রয়েছে যেগুলো নিয়ে এখানে আলোচনা করা হলো না।

এখানে মূলত প্রোগ্রামিংয়ের স্টাইল বা প্যারাডাইম নিয়ে আলোচনা করা হলো, প্রোগ্রামিং ল্যাংগুয়েজ নিয়ে নয়। একটি প্রোগ্রামিং ল্যাংগুয়েজ অনেকগুলো প্যারডাইম ইমপ্লিমেন্ট করতে পারে। একজন প্রোগ্রামার তার নিজের পছ্ন্দ ও প্রয়োজন অনুযায়ী স্টাইল বা প্যারাডাইম ঠিক করে নেয় কোনটা সে ব্যবহার করবে।

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

Monday, January 9, 2017

Agile and Scrum

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

Agile এর বাংলা অর্থ হতে পারে কর্মদক্ষ কিংবা চটপটে। অর্থাৎ যা খুব সহজে নিজেকে পরিবর্তন করতে পারে প্রয়োজন অনুসারে। 

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

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

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

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

অ্যাজাইলের ১২ টি ম্যানিফেস্টো রয়েছে। 

http://agilemanifesto.org/principles.html
উপরের সাইটিতে গেলে সেগুলো দেখা যাবে।

মূল কথা হচ্ছে, অ্যাজাইলে অনেকগুলো আইটারেশন থাকে। একবারে সবগুলো না করে ছোট ছোট অংশে ভেঙ্গে কাজ করা এবং খুব সহজে পরিবর্তনকে বরণ করা।
হেরাক্লিটাস নামে এক গ্রিক দার্শনিক বলে গেছেন- 

The Only Thing That Is Constant Is Change
সুতরাং পরিবর্তন তো থাকবেই। 

এছাড়াও এটি একটি মানসিকতাও। এতে করে সঠিক কাজটি করা যায়। আপনি একটি ভুল করলে, বুঝতে পারার সঙ্গে সঙ্গে তা শুধরে নেওয়ার মানসিকতা থেকে সঠিকটাকে গ্রহণ করা। 

মানুষ হিসেবেও অ্যাজাইল হওয়া জরুরী।


এই আইডিয়া বেশ কয়েকভাবে ইমপ্লিমেন্ট করা হয়েছে। এগুলো হলো - স্ক্রাম (Scrum), এক্সট্রিম প্রোগ্রামিং (extreme programming), কানবান(Kanban) ইত্যাদি। 

এগুলোর মধ্যে স্ক্রাম অনেক বেশি ব্যবহার হয়। বলা যেতে পারে যেসব ইন্ড্রাস্ট্রি অ্যাজাইল ব্যবহার করে তাদের ৮০-৮৫% শতাংশ স্ক্রাম ব্যবহার করে। 




স্ক্রাম মূলত একটি ফ্রেমওয়ার্ক যা কতগুলো ভ্যালুজ, প্রিন্সিপালস, এন্ড প্র্যাকটিসেস দিয়ে থাকে যা দিয়ে কোনো অর্গানাইজেশনে ইঞ্জিনিয়ারিং প্রজেক্ট বা সমস্যা সমাধানের মৌলিক ভিত্তি তৈরি করে দেয়। 

উপরে বলেছি যে, অ্যাজাইলে একটি প্রজেক্টকে কতগুলো ছোট ছোট অংশে ভাগ করা হয়। এই ছোট অংশগুলোকে আইটারেশন (iteration) বলা হয়। স্ক্রামে এই প্রত্যেকটি আইটারেশনকে স্প্রিন্ট (sprint) বলা হয়।

প্রত্যেকটি স্প্রিন্টের শেষে মূল প্রজেক্টের একটা নিদির্ষ্ট অংশ(end product) তৈরি হয় যা ক্লায়েন্টকে ডেলিভার করা যায়। এটি ক্লায়েন্ট ব্যবহার করে সাথে সাথে ফিডব্যাক দিতে পারে। এতে করে ক্লায়েন্ট-ডেভেলপার সবসময় একটি কনস্ট্যান্ট ফিডব্যক লুপের মধ্যে থাকে এবং এতে ভুল হওয়ার সম্ভবনা কমে যায়। এতে করে ক্লায়েন্টের সম্পূর্ণ ভিজিবিলিটি থাকে। অন্যদিকে ওয়াটারফলে এই ভিজিবিলিটি থাকেই না। 

তাহলে প্রশ্ন হতে পারে একটি প্রজেক্টকে কীভাবে ছোট ছোট অংশে ভাগ করা যায়। স্ক্রামে রিকোয়ারমেন্টগুলোকে ইউজার স্টোরি (user story) আকারে লেখা হয়। 

ইউজার স্টোরি একটি সংক্ষিপ্ত বর্ণনা যেখানে সফটওয়্যারের একটি ফিচার একজন ইউজারের পার্সপেক্টিভ থেকে লেখা হয়। অনেকটা এমন- একজন ব্যবহারকারী (user) যখন কোনো নির্দিষ্ট ফিচার ব্যবহার করবে সে কী প্রত্যাশা করে। উদাহরণ- 


As an I want to do < certain things in the site> so that I can do < this things> 
An a website user, I need a home button, so that I can return back to the homepage with a single click. 

প্রত্যেকটি ইউজার স্টোরিতে তিনটি বিষয় থাকে। 

১. Role বা ক্যারেক্টার অর্থাৎ যে ইউজার স্টোরির নির্দিষ্ট কাজটি করতে যাচ্ছে
২. feature - অর্থাৎ ক্যারেক্টারটি আসলে যে কাজটি করতে যাচ্ছে
৩. benefit - এই কাজটি করে কী লাভ হবে? 

কোনো একটি ইউজার স্টোরিতে যদি এই তিনটি অংশ থাকে, তাহলে এই প্রত্যেকটি স্টোরি হবে একটি অখণ্ড, একটি নির্দিষ্ট ফিচার যা তৈরি করার (কোড লেখার) পর একটি এক্সিকিউটেবলে পরিণত হবে এবং তা ইউজার ব্যবহার করতে পারবে। 

এই ইউজার স্টোরিগুলোকে একটি কালেকশনে রাখা হয় যার নাম ব্যাকলগ (backlog)। এই ব্যাকলগ তিন রকম হতে পারে -
১. প্রোডাক্ট ব্যাকলগ – এখানে একটি প্রজেক্ট বা প্রোডাক্টের (যে সফটওয়্যারটি তৈরি করা হচ্ছে) সবগুলো ব্যাকলগ থাকে।

২. স্প্রিন্ট ব্যাকলগ – একটি নির্দিষ্ট স্প্রিন্টের ব্যাকলগ যা কোন নিদির্ষ্ট স্প্রিন্টে যে ইউজার স্টোরিগুলো নিয়ে কাজ করা হচ্ছে সেগুলো।

৩. রিলিজ ব্যাকলগ – এটি কয়েকটি স্প্রিন্ট মিলে হতে পারে। অনেক সময় স্প্রিন্ট ছোট সময়ে হয়(১ সপ্তাহ বা ২ সপ্তাহ) 

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

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

ধরা যাক, একটি টিমে দুইজন ডেভেলপার আছে, তারা দুই সপ্তাহে ১৫ পয়েন্ট স্টোরি নিয়ে কাজ করে, তাহলে সেই টিমের ক্যাপাসিটি হচ্ছে ১৫। স্প্রিন্টটি যদি দুই সপ্তাহের হয়, সেক্ষেত্রে একটি স্প্রিন্টে ব্যাকলগ থেকে প্রায়োরিটি অনুযায়ী ১৫ পয়েন্টের স্টোরি বেছে নিয়ে স্প্রিন্ট শুরু করা হয়। এর জন্যে একটি সংক্ষিপ্ত স্প্রিন্ট প্ল্যানিং মিটিং হয়ে থাকে। যেখানে ডেভেলপমেন্ট টিম মেম্বার, প্রোডাক্ট ওনার (product owner) মিলে সিন্ধান্ত নেয়। এই মিটিংয়ের পর ডেভেলপাররা স্টোরিগুলোকে আরও ছোট ছোট টাস্কে বিভক্ত করে এবং এতে টাইম এস্টিমেশন দেয়- একটি ছোট টাস্ক করতে কতক্ষণ লাগতে পারে ইত্যাদি। 

এখন স্প্রিন্ট শুরু হয়ে গেল। কিন্তু এখন প্রশ্ন হচ্ছে, কীভাবে কাজের ট্র্যাক রাখা যায়। খুব সংক্ষিপ্ত সময়ের টাইট টামইলাইনে নানাভাবে deviate হওয়ার সম্ভবনা থাকে। এরজন্য স্ক্রামে প্রতিদিন একটা নির্দিষ্ট সময়ে ১৫ মিনিটের একটি সংক্ষিপ্ত মিটিং হয়। একে daily scrum meeting বা daily scrum বলা হয়। এই মিটিং প্রত্যেকটি টিম মেম্বার উপস্থিত থাকে এবং প্রত্যেকেই তিনটি প্রশ্নের উত্তর দিয়ে থাকে -
১. আপনি গতকাল কী কাজ করেছেন? (status update)
২. আপনি আজ কী করতে যাচ্ছেন ? (planning update)
৩. আপনার কাজে কোনো ব্লকার বা কোনো কিছুতে আটকে আছেন কিনা? (obstacle update) 

এছাড়াও প্রত্যেকটি টিম মেম্বার যে নিদির্ষ্ট স্টোরিতে কাজ করছে, সেগুলোতে কে কতক্ষণ কাজ করেছে তা লগ করে থাকে। এতে করে কোন স্টোরিতে কতক্ষণ কাজ করা হয়েছে বা কতক্ষণ বাকি তা রেকর্ড করা থাকে। এর জন্য একটি স্ক্রাম বোর্ড ব্যবহার করা হয়। 


এতে করে যেকোনো মুহূর্তে টিমের একটি কমপ্লিট পিকচার পাওয়া যায়। এই বোর্ডের অনলাইন সফটওয়্যার রয়েছে। এগুলোর মধ্যে TrelloJIRA জনপ্রিয়।  

একটি স্ক্রাম টিমে তিনটি ক্যারেক্টার বা এনটিটি থাকে - স্ক্রাম মাস্টার (Scrum Master) , প্রোডাক্ট ওনার (product owner) এবং ডেভেলপমেন্ট টিম (development team)। স্ক্রাম মাস্টারের কাজ হলো সবকিছু ঠিকঠাক মতো চলছে কিনা তা খেয়াল রাখা। সে অনেকটা কোচ (coach) হিসেবে কাজ করে। তার মূল উদ্দেশ্য থাকে কীভাবে একটি হাই পার্মমেন্স টিম তৈরি করা যায়। টিমে কোনো রকম bottleneck বা সমস্যা থাকলে তা স্ক্রাম মাস্টার সমাধান করার চেষ্টা করে।

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

ডেভেলপমেন্ট টিম হলো যারা মূলত সফটওয়্যারটি তৈরি করে- এক্ষেত্রে সফ্টওয়্যার ডেভেলপার, টেস্টার ইত্যাদি।
স্প্রিন্ট শেষে একটি স্প্রিন্ট রিভিও মিটিং হয়। এই মিটিংয়ে মূলত ডেভেলপমেন্ট টিম নির্দিষ্ট স্প্রিন্টে কী কী কাজ হয়েছে তা ডেমোনস্ট্র্যাট করে।

স্প্রিন্ট শেষ হয় আরেকটি মিটিং দিয়ে যার নাম sprint retrospective. 

এই মিটিং স্ক্রাম টিমের প্রসেসগুলো নিয়ে আলোচনা করা হয়। এতে কোথাও কোন সমস্যা থাকলে সেগুলো নিয়ে আলেচনা করা হয় এবং কিভাবে সেগুলো থেকে বের হওয়া যায়। 

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

Friday, January 6, 2017

Act with Prudence


Whatever you undertake, act with prudence and consider the consequences

Kevlin Henney এর একট বই আছে, নাম 97 Things Every Programmer Should Know

এই বইয়ের প্রথম চ্যাপ্টারের নাম - Act with prudence.  তারপরেই উপরের লাইনটা আছে। 

Prudence শব্দের অর্থ দূরদর্শিতা বা বিচক্ষণতা। 
লাইনটার মানে দাড়ায় - বিচক্ষণতা সহিত কাজ কর। 

এবার মূল আলোচনায় চলে আসি। আলোচনার বিষয়বস্তু টেকনিক্যাল ডেব্ট(technical debt)

এই জিনিস খায় না মাথায় দেয় তাই বলছি- 
লোন নেওয়ার স্বল্পকালিন কিছু সুবিধা আছে। আমার হয়তো কিছু টাকার দরকার পড়েছে, আমি ব্যাংক থেকে লোন নিয়ে সাময়িক প্রয়োজনটা মেটাতে পারি। যেকোনো লোনের দীর্ঘ মেয়াদী ফলাফল মোটেও ভালো নয় এই জিনিস সবাই জানে। যতই দিন যাবে চক্রবৃদ্ধি হারে সুদ বাড়তে থাকবে এবং কোনো একসময় আমি যে পরিমান লোন নিয়েছিলাম তার থেকে কয়েকগুণ (ক্ষেত্রবিশেষে ৪/৫ গুণ) বেশি টাকা পরিশোধ করতে হয়। 

তবে এই লোন যত তাড়াতাড়ি শোধ করা যায় ততই মঙ্গলজনক (এতে সুদের পরিমান কম থাকে)। মূল বিষয়টা হচ্ছে লোন নেওয়া সাময়িক সুবিধার মনে হলেও এটি মোটেও ভালো কোনো বিষয় নয়। 

টেকনিক্যাল ডেব্‌ট মূলত রুপক অর্থে ব্যবহৃত(metaphorical term) শব্দ। যেকোনো কাজের কিছু নিয়ম কানুন(discipline) থাকে। ধরুণ আপনি একটি ব্রিজ তৈরি করতে চান। কোনোরকম শৃঙ্খলা ছাড়া একটি ব্রিজ ইচ্ছমতো বানানো সম্ভব নয়। সিভিল ইঞ্জিনিয়াররা পুরো প্রক্রিয়ার পরিকল্পনা তৈরি করে, এই পরিকল্পনাতে প্রচুর হিসেব নিকেশ থাকে, কীভাবে কোন রিসোর্স কোথায় ব্যবহার করা হবে তা নির্দিষ্ট করা হয়। 

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

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

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

অনেকসময় একজন ডেভেলপার/প্রোগ্রামারকে এমন সিন্ধান্তের মুখোমুখি হতে হয় - 
  1. doing it right. 
  2. doing it quick 
কখনো কখনো আপানকে দ্বিতীয় সিন্ধান্তটি নিতে হয়। আপনি ধরে রাখেন যে, পরবর্তীতে এসে এটিকে আপনি ঠিক করবেন। কিন্তু বাস্তবতা আসলে এমনটা কখনো হয় না। আপনার কাছে প্রতিনিয়ত নতুন নতুন সমস্যা আসতেই থাকবে। আপনি পরে করবেন বলে যে কাজটি রেখে চলে গেলেন তা হয়তো কখনোই করা হয়ে উঠবে না। আর এদিকে আপনার ঋণ বেড়েই চলবে। এভাবে ঋণ বাড়তে বাড়ে কোনো সময় আপনরা পুরো প্রজেক্ট মুখ থুবড়ে পরতেই পার। এটি খুবই স্বাভাবিক। 

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

কিন্তু আমরা জানি যে, বাস্তবে এমনটা সবসময় সম্ভব নয়। তাই সিন্ধান্ত নেওয়ার সময় চিন্তাভাবনা করে বিচক্ষণতার সাথে নেওয়া উচিৎ এবং এর পরিণতি (consequences) সম্পর্কে অবগত থাকা উচিৎ। 


কাজী নজরুল ইসলামের একটা কবিতার লাইন - 

“দিনে দিনে বহু বাড়িয়াছে দেনা শুধিতে হইবে ঋণ”

দেনা না বাড়ানোই উত্তম।

Monday, November 21, 2016

হ্যাশ ফাংশন -২

আগের পোস্টের সমস্যাটি হলো- দুটি ভিন্ন ভিন্ন স্ট্রিং হ্যাশ ফাংশনে দিলে যদি একই ভ্যালু পাওয়া যায় তাহলে কী হবে? উত্তরটির জন্য পুরো আর্টিক্যাল পড়তে হবে।

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

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





উপরের ছবি দুটি থেকে দেখতে পাচ্ছো, আদা, কলা, পেঁপে, রসুন এবং মরিচ এগুলোর হ্যাশ ভ্যালু যথাক্রমে ১,২,৩ ও ৭, ৮। সুতরাং এগুলো অ্যারের ০,১,২ ও ৬,৭ নম্বর ইন্ডেক্সে বসনো হয়েছে। কিন্তু জীবন তো আর পুষ্পশয্যা নয়। একটু পরেই এসেছে আম। আর তোমার হ্যাশ ফাংশন এর জন্যে ভ্যালু রিটার্ন করেছে ১।

সমস্যাটি নিশ্চয় বুঝতে পারছো। এই সমস্যাকে বলা হয় কলিশন (collision)। এখন তুমি যদি অ্যারের ১ নম্বর ইনডেক্সে আমের দাম রাখো, তাহলে আগের আদার দামের সাথে এটি রিপ্লেস হয়ে যাবে। এতে করে তুমি যদি পরবর্তীতে আদার দাম দাও, তোমার হ্যাশটেবিল আমের দাম দিয়ে দিবে যা হওয়া উচিৎ নয়।

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

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

তবে এতেও একটি সমস্যা আছে। তোমার মুদির দোকানের সবগুলো পণ্য যদি একটি নির্দিষ্ট বর্ণ দিয়ে শুরু হয় তাহলে প্রথম স্লটে একটি বিশাল চেইন হবে। এক্ষেত্রে হ্যাশ টেবিল থেকে কোন পণ্যের দাম খুঁজে আনার সময় আর O(1) থাকবে না বরং সেটি হয়ে যাবে O(n)। কারণ তখন তোমাকে লিংকডলিস্ট থেকে উপাদানটি খুঁজতে হবে। লিংকডলিস্ট থেকে কোন উপাদান খুঁজে বের করতে সময় লাগে O(n)।



উপরের ছবি থেকে নিশ্চয় দেখতে পাচ্ছো সমস্যাটি কোথায়? তোমার অ্যারের বাকি স্লটগুলো প্রায় খালি রয়ে গেছে।
তাহলে এখান থেকে দুটি বিষয় জানা গেলো –
১. হ্যাশ ফাংশন অনেক গুরুত্বপুর্ণ। এটি খুব সিম্পল হলে সমস্যা।
২. প্রত্যেকটি স্লটেই যদি অনেক বড় লিংকলিস্ট থাকে, তাহলে কনস্ট্যান্ট টাইম অর্থাৎ O(‌1) সময়ে তুমি উপাদান খুঁজে বের করতে পারছো না।
এখন যদি তুমি একটি ভালো হ্যাশ ফাংশন লিখতে পারো, এবং প্রত্যেক স্লটেই যাতে বিশাল লিংকডলিস্টের চেইন না হয় তা নিশ্চিত করতে পারো তাহলেই O(‌1) সময়ে হ্যাশ টেবিল থেকে ভ্যালু পড়তে পারবে।

এবার Load Factor বলে একটা টার্ম আছে, এটি নিয়ে একটু বলি তোমাদের। একটি হ্যাশটেবিলের লোড ফ্যাক্টর খুব সহজেই বের করা যায়।

Load Factor = Number of items in the hash table / Total slot in the array


তাহলে তোমার অ্যারেতে যদি স্লট হয় 10 এবং উপাদানের সংখ্যা যদি হয় ৭ তাহলে লোড ফ্যাক্টর হবে- 0.7। এটি দিয়ে একটি হ্যাশটেবলি কতগুলো স্লট ফাকা আছে তা বের করা যায়। একটি হ্যাশটেবিলের লোড ফ্যাক্টর যদি 1 হয় তাহলে এর বোঝায়, এর প্রত্যেকটি স্লটে একটি করে উপাদান রয়েছে। লোড ফ্যাক্টর একের অধিক থাকার অর্থ হলো, টেবিলের কোন স্লটে একাধিক উপাদান রয়েছে।

কনস্ট্যান্ট টাইম অর্থাৎ O(1) সময়ে কোন উপাদান খুঁজে পাওয়া নিশ্চিত করতে চাইলে লোড ফ্যাক্টর সবসময় একের নিচে রাখতে হবে। এটি করার জন্যে যখনই লোড ফ্যাক্টর ১ এর বেশি হবে তখনই টেবিলকে রিসাইজ করে আবার প্রত্যেকটি উপাদানের হ্যাশ ক্যালকুলেট করে বিভিন্ন স্লটে বসাতে হবে। এই অপারেশনটি মোটামুটি এক্সপেনসিভ। তবে তুমি কনস্ট্যান্ট টাইম উপাদানগুলো খুঁজে পাচ্ছো টেবিলের সাইজ যতোই হোক না কেনো।

তাহলে উপরের আলোচনা থেকে নিশ্চয় বুঝতে পারছো যে, যদিও কনস্ট্যান্ট টাইমে আমরা উপাদান খুঁজে বের করতে চাচ্ছি, কিন্তু সবসময় তা সম্ভব নয়। তবে best case এটি অবশ্যই O(1) হবে এবং worst case-এ এটি O(n) হতে পারে।

Sunday, November 20, 2016

হ্যাশ ফাংশন

মনে করো, তুমি একটি মুদি দোকান দিয়েছো। তোমার দোকানে হরেকরকম পণ্যদ্রব্য রয়েছে। এই পণ্যগুলোর নাম ও দাম আলাদা আলাদা। এগুলো মনে রাখতে গিয়ে তুমি হিমশিম খাচ্ছো। তুমি সবগুলো খাতায় লিখে রেখেছো। যখনই তুমি একটি পণ্য বিক্রি করো, তোমাকে সেই খাতা দেখতে হয়। খাতা থেকে খুঁজে বের করতে হয়।

খাতাতে যদি নামগুলো বর্ণানুক্রমে রাখা না থাকে, তাহলে তোমার প্রতিবার খুঁজে বের করতে অনেক সময় লাগে। অ্যালগরিমদ ক্লাসে নিশ্চয় শিখেছো যে এক্ষেত্রে খুঁজে বের করার সময় O(n) । তবে নামগুলো যদি বর্ণানুক্রমে রাখা থাকে তাহলে বাইনারি সার্চ ব্যবহার করা যায় আর তখন সময় লাগবে O(log n)। তুমি নিশ্চয় জানো যে O(n) চেয়ে O(log n) কম সময় লাগে।

চিত্র: O(n) vs O(log n) 

যদিও O(log n) কম সময় লাগছে, তবুও কিছুটা সময় লাগছে। সবচেয়ে ভাল হতো যদি কোন সময়ই না লাগতো। তুমি সবগুলো পণ্যের নাম এবং দাম মুখস্থ করে ফেলতে পারতে এবং ক্রেতা কোন পণ্যের নাম বলার সঙ্গে সঙ্গেই তুমি দাম বলে দিতে পারতে।

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

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

মনে করো, তোমার ১০ সাইজের একটি অ্যারে রয়েছে। এখন, ধরো, পেঁপের দাম ২০ টাকা। পেঁপে নামটি যদি হ্যাশ ফাংশনে দাও, তাহলে এটি যদি ৪ রিটার্ন করে, তাহলে অ্যারের চতুর্থ নম্বর ইনডেক্সে পেঁপের দামর রেখে দেবে। এভাবে আদার নাম হ্যাশ ফাংশনে দিলে যদি ৩ রিটার্ন করে, তাহলে তাকে তিন নম্বর ইনডেক্সে রেখে দিলে। এভাবে কলা, মরিচ ইত্যাদি রেখে দিলে। এখন যখন তোমার এগুলো দাম জানার দরকার হয়, তাহলে চট করে হ্যাশ ফাংশনে নামটি দিয়ে তার ইনডেক্সটি বের করে নিলে। অ্যারতে ইনডেক্স জানলে ভ্যালু পড়ে আনা খুব সহজ। অ্যারে থেকে ভ্যালু পরে আনার সময় আসলে O(1) ।

চিত্র: হ্যাশ ফাংশন


চিত্র: হ্যাশ টেবিল


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

উপরের যে উদাহরণটি দিয়েছি তাতে একটি সমস্যা রয়েছে। সেটি নিয়ে পরবর্তীতে আলোচনা করবো। তবে সমস্যাটি তুমি চিন্তা করে যদি খুঁজে বের করতে পারো তাহলে নিচে কমেন্ট করে জানাও।

পরের অংশ:  লিংক