টিডিডি – টেস্ট ড্রিভেন ডেভেলাপমেন্ট

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

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

ধরা যাক, আমাকে কেউ রিকোয়ারমেন্ট দিলো যে, একটি প্রোগ্রাম লিখতে হবে, যেখানে শিক্ষার্থীদের নম্বর ইনপুট দিলে লেটার গ্রেড আউটপুট দেখাবে। তো একটু আলাপ-সালাপ করে আমি রিকোয়ারমেন্ট বুঝে নিলাম এরকম :

  • ৫০ নম্বরের নিচে পেলে ফেইল, অর্থাৎ F গ্রেড।
  • ৫০ থেকে ৫৯ এর মধ্যে নাম্বার পেলে B গ্রেড।
  • ৬০ থেকে ৬৯ এর মধ্যে নাম্বার পেলে B+ গ্রেড।
  • ৭০ থেকে ৭৯ এর মধ্যে নাম্বার পেলে A- গ্রেড।
  • ৮০ থেকে ৮৯ এর মধ্যে নাম্বার পেলে A গ্রেড।
  • ৯০ কিংবা তার বেশি পেলে A+ গ্রেড।

কেউ ল্যাঙ্গুয়েজ ঠিক না করে দিলে আমি পাইথন ব্যবহার করতেই পছন্দ করি, তাই আমার প্রিয় ল্যাঙ্গুয়েজ পাইথনে আমি শুরুতেই একটি ফাংশন লিখে ফেললাম।

def calculate_grade(marks):
    """ Takes marks as input and returns grade as output """
    return "F"

এখন আমি ফাংশনের জন্য টেস্ট কোড লিখে ফেললাম এরকম :

def test_calculate_grade():
    assert calculate_grade(0) == "F"
    assert calculate_grade(30) == "F"
    assert calculate_grade(49) == "F"

তারপরে টেস্ট রান করবো : pytest grade.py। আউটপুট আসবে সব টেস্ট পাশ।

1 passed in 0.01 seconds

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

def calculate_grade(marks):
    """ Takes marks as input and returns grade as output """
    pass

এবারে টেস্ট রান করাবো (সেই আগের কমান্ড pytest grade.py)। আউটপুট আসবে এমন :

>       assert calculate_grade(0) == "F"
E       assert None == 'F'
E        +  where None = calculate_grade(0)
grade.py:9: AssertionError

তাহলে দেখা যাচ্ছে, প্রথমে আমার কোডে কিছু নেই, তাই 0 নম্বর পাওয়ার পরেও F রিটার্ন না করে None রিটার্ন করছে। তাহলে এই কেস পাশ করানোর জন্য এখন আমি ফাংশনটি আপডেট করবো :

def calculate_grade(marks):
    """ Takes marks as input and returns grade as output """
    return "F"

এবারে টেস্ট রান করলে তিনটি টেস্ট কেইসই পাশ করবে। এখন আমি B গ্রেডের জন্য দুইটি টেস্ট কেইস যুক্ত করবো।

def test_calculate_grade():
    assert calculate_grade(0) == "F"
    assert calculate_grade(30) == "F"
    assert calculate_grade(49) == "F"
    assert calculate_grade(50) == "B"
    assert calculate_grade(59) == "B"

এখন টেস্ট রান করলে আউটপুট আসবে এরকম :

>       assert calculate_grade(50) == "B"
E       assert 'F' == 'B'
E         - F
E         + B

grade.py:12: AssertionError

এখন এই টেস্ট কেস পাশ করাতে হবে। এজন্য আমরা এভাবে প্রোগ্রাম লিখবো :

 def calculate_grade(marks):
    """ Takes marks as input and returns grade as output """
    if marks < 50:
        return "F"
    else:
        return "B"

এখন টেস্ট রান করলে সবগুলো কেস পাশ করবে। এখন বাকী সব কেস যোগ করে ফেলবো।

 def test_calculate_grade():
    assert calculate_grade(0) == "F"
    assert calculate_grade(30) == "F"
    assert calculate_grade(49) == "F"
    assert calculate_grade(50) == "B"
    assert calculate_grade(59) == "B"
    assert calculate_grade(60) == "B+"
    assert calculate_grade(69) == "B+"
    assert calculate_grade(70) == "A-"
    assert calculate_grade(79) == "A-"
    assert calculate_grade(80) == "A"
    assert calculate_grade(89) == "A"
    assert calculate_grade(90) == "A+"
    assert calculate_grade(100) == "A+"

এখন একটা একটা করে টেস্টকেস পাশ করানোর জন্য আমি কোড লিখতে থাকবো, এবং প্রতিটি টেস্ট কেস পাশ করে কি না, সেটি দেখার জন্য প্রতিবার টেস্ট রান করাবো। একসময় আমার কোড সব টেস্ট কেস পাশ করবে এবং তখন সেটি দেখতে নিচের মতো হবে :

 def calculate_grade(marks):
    """ Takes marks as input and returns grade as output """
    if marks < 50:
        return "F"
    elif marks < 60:
        return "B"
    elif marks < 70:
        return "B+"
    elif marks < 80:
        return "A-"
    elif marks < 90:
        return "A"
    else:
        return "A+"

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

image_thumb3
Test Driven Development (collected from the Internet)

আশা করি টেস্ট ড্রিভেন ডেভেলামপেন্টের ধারণা অনেকেরই কাজে লাগবে চাকরির ইন্টারভিউতে এবং কেউ কেউ হয়ত তার প্রজেক্টে এর প্রয়োগ শুরু করে দিবে। এখন একটি বিষয়। কেউ যদি ৫৯.৫ বা এরকম নাম্বার পায়, তখন তার গ্রেড কী হবে? এটি রিকোয়ারমেন্টে বলা নাই। কিন্তু পরে জানা গেল যে ভগ্নাংশ হলে সেটিকে সিলিং (ceiling) করতে হবে, মানে ৫৯ এর চেয়ে বড় কিন্তু ৬০-এর চেয়ে ছোট সব সংখ্যাকে ৬০ ধরতে হবে। তাহলে এখন আমরা যদি নিচের টেস্টকেস যোগ করি, তাহলে টেস্ট ফেইল করবে:

assert calculate_grade(59.3) == "B"

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

লোড টেস্টিং

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

[এই লেখাটি যারা ওয়েব প্রোগ্রামিংয়ের সঙ্গে পরিচিত, তাদের জন্য। যাদের ওয়েব সম্পর্কে একেবারেই ধারণা নেই, তারা দ্বিমিকের ওয়েব কনসেপ্টস্ নামক ফ্রি অনলাইন কোর্সটি করে ফেলতে পারে।]

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

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

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

এখন আমি আমার কম্পিউটারে কোনো একটা টুলস ব্যবহার করে লোড টেস্টিং করে ফেললাম। কিন্তু এখানে দুটি সমস্যা আছে:

  1. প্রতিটি কম্পিউটারেরই একসাথে ওয়েব রিকোয়েস্ট করার (বা ওয়েব সার্ভিসকে কল করার) একটি সীমাবদ্ধতা থাকে, একটি নির্দিষ্ট সংখ্যার বেশি রিকোয়েস্ট একসাথে পাঠানো যায় না।
  2. দ্বিতীয় সমস্যা হচ্ছে নেটওয়ার্কের গতির সীমাবদ্ধতা। ঢাকায় আমার বাসার কিংবা অফিসের ইন্টারনেট যথেষ্ট গতিসম্পন্ন নয়।

তাই, আমাকে যেটি করতে হবে, একসাথে অনেকগুলো কম্পিউটার যোগাড় করে একসাথে লোড টেস্টিং শুরু করতে হবে। তাহলে আমি যদি ১০টি কম্পিউটার ব্যবহার করি, তাহলে ১০ গুণ লোড তৈরি করতে পারার কথা। কিন্তু সবাই যদি একই নেটওয়ার্কে থাকে, তাহলে এক্ষেত্রেও আমি নেটওয়ার্কের সীমাবদ্ধতার কারণে আটকে যাবো। তাহলে করণীয় কী?

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

ওপরের কাজগুলো বেশ ঝামেলাসাপেক্ষ। তাই আজকাল অনেক সার্ভিস চালু হয়েছে যারা আমার হয়ে লোড টেস্ট করে দিবে। যেমন : loader.io (এরকম আরো আছে, গুগল সার্চ করলেই পাওয়া যাবে)। এসব সার্ভিস তাদের প্রয়োজনমতো কম্পিউটার ব্যবহার করবে, আমার কেবল সার্ভিসটি ব্যবহার করতে জানতে হবে।

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

ইউনিট টেস্টিং

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

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

পাইথনে unittest নামে একটি বিল্ট-ইন মডিউল রয়েছে যেটি ব্যবহার করে ইউনিট টেস্ট করা যায়। কিন্তু আমরা ব্যবহার করবো pytest কারণ এটি ব্যবহার করা অনেক বেশি সহজ। তবে এটি আলাদাভাবে ইনস্টল করতে হয়। কীভাবে ইনস্টল করতে হয়, সেটি ওদের অফিশিয়াল ডকুমেন্টশন থেকে দেখে নিতে হবে, এই লেখা পড়ার জন্য পাইটেস্ট ইনস্টল করার দরকার নেই, পরে করলেও হবে (কারণ এই লেখার উদ্দেশ্য হচ্ছে ইউনিট টেস্টিং সম্পর্কে প্রাথমিক ধারণা দেওয়া)। আরেকটি জিনিস জানতে হবে, সেটি হচ্ছে assert স্টেটম্যান্ট। assert এর পরে কোনো কিছু লিখলে পাইথন সেটা চালিয়ে দেখে এবং ফলাফল হয় True না হয় False হয়। ফলাফল False হলে পাইথন AssertionError এক্সেপশন দেয়।

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

def is_leap_year(year):
        """This functon returns True if year is a leap year, returns False otherwise"""
        if year % 4 == 0:
                return True
        return False

এখন এই ফাংশনের জন্য ইউনিট টেস্ট লিখব :

def test_is_leap_year():
        assert is_leap_year(2016) == True
        assert is_leap_year(2015) == False

আমি আমার প্রোগ্রাম leapyear.py নামে সেভ করলাম। এখন pytest রান করাবো।

 tamimshahriar$ pytest leapyear.py 

======= test session starts========

platform darwin -- Python 3.5.1, pytest-3.0.3, py-1.4.31, pluggy-0.4.0

rootdir: /Users/tamimshahriar/work/practice/pypractice, inifile: 

collected 1 items 

leapyear.py .

======= 1 passed in 0.01 seconds =====

ওপরে দেখতে পাচ্ছি যে আমার টেস্ট ঠিকঠাকভাবে পাশ করেছে, কোনো সমস্যা নেই। এখন আমি খোঁজখবর নিয়ে জানলাম যে 2100 সাল নাকি আসলে লিপইয়ার না, কারণ সালটা যদি 100 দিয়ে বিভাজ্য হয়, সেটা 400 দিয়েও বিভাজ্য হতে হবে। তাহলে আমি এই টেস্ট কেইসটি আমার টেস্টে যোগ করে আবার টেস্ট রান করবো। এখন আমার টেস্ট ফাংশনটি হবে এরকম :

def test_is_leap_year():
        assert is_leap_year(2016) == True
        assert is_leap_year(2015) == False
        assert is_leap_year(2100) == False

এখন আবার টেস্ট রান করি : pytest leapyear.py, আউটপুট আসবে এরকম :

========= FAILURES ===========
_______ test_is_leap_year __________

    def test_is_leap_year():
        assert is_leap_year(2016) == True
        assert is_leap_year(2015) == False
>       assert is_leap_year(2100) == False
E     assert True == False
E     +  where True = is_leap_year(2100)

leapyear.py:10: AssertionError

===== 1 failed in 0.03 seconds =====

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

ইউনিট টেস্ট করার সময় বিভিন্ন ধরনের কেস টেস্ট করা উচিত। ইউনিট টেস্টের সুবিধা হচ্ছে :

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

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

ডাটাবেজ নরমালাইজেশন

ডাটাবেজ নরমালাইজেশন (normalization) কী জিনিস? এক কথায় আসলে উত্তর দেওয়া সম্ভব নয়। তাই বরং আসুন, আমরা বিষয়টি নিয়ে একটু বিস্তারিত আলচনা করি। কোনো কিছুকে নরমালাইজ (normalize) করার অর্থ হচ্ছে সেটিকে স্বাভাবিক (normal) অবস্থায় নিয়ে আসা। তো ডাটাবেজের ক্ষেত্রে এই নরমালাইজেশনের অর্থ হচ্ছে ডাটাবেজকে এমন অবস্থায় নিয়ে আসা যেন ডাটা রিডানডেন্সি (data redundancy) না থাকে এবং ডাটা ইন্টিগ্রিটি (data integrity) বজায় থাকে। এই যে এখন আবার নতুন দুটো জিনিস চলে এল, ডাটা রিডানডেন্সি ও ডাটা ইন্টিগ্রিটি। এগুলো আবার কী জিনিস?

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

ডাটা ইনটিগ্রিটি – Integrity শব্দের অর্থ হচ্ছে শুদ্ধতা। অনেক সময় ডাটাবেজে বিভিন্ন কারণে (হার্ডওয়্যারের ত্রুটি কিংবা সফটওয়্যারের সমস্যা বা ডাটাবেজ ডিজাইনের সমস্যা) ডাটায় ভেজাল ঢুকে যায়। এই ভেজাল আবার কী জিনিস? ধরা যাক কোনো একভাবে হিসেব করলে একজন শিক্ষার্থীর মোট নাম্বার হয় ৫৪৬, আবার আরেকভাবে (যেমন অন্য কোনো টেবিল থেকে ডাটা নিয়ে) হিসেব করলে মোট নাম্বার হয় ৫৫৫। তার মানে ডাটাতে ভেজাল ঢুকে গিয়েছে বা ডাটা তার শুদ্ধতা হারিয়ে ফেলেছে। নরমালাইজেশন করলে ডাটার শুদ্ধতা বজায় থাকার সম্ভাবনা বেড়ে যায় অনেক।

এখন, নিচের উদাহরণগুলো দিয়ে নরমালাইজেশন বিষয়টি বোঝার চেষ্টা করি –

fig1

উপরের টেবিলটিতে কোনো নরমালাইজেশন নেই। এই টেবিলে নতুন ডাটা যোগ করতে (data insert), পুরনো ডাটা পরিবর্তন (data update) করতে এবং ডাটা মুছে ফেলতে (data delete) আমাদের কিছু অসুবিধা হবে (সেগুলোকে নরমালাইজেশন দ্বারা দূর করা যায়)। যেমন, আমরা যদি নতুন একজন স্টুডেন্ট এই টেবিলে যোগ করতে চাই যে কোনো সাবজেক্টই নেয় নি, তাহলে subject কলামে NULL ভ্যালু যাবে। আবার আমারা যদি একজন স্টুডেন্ট এর সাবজেক্ট বাড়াতে বা কমাতে চাই তাহলে আমরা খুব সহজে তা করতে পারব না, কারণ subject কলামে ডাটা কমা দিয়ে আলাদা করা আছে।

এখন আমরা Student টেবিলটিকে First normal form (1NF) নিতে চাই। First normal form (1NF) এর শর্ত হচ্ছে টেবিলের সব কলামের ভ্যালু একক (atomic) হতে হবে। আমারা দেখতে পাচ্ছি যে subject কলামের ডাটা একক (atomic) নয়। নিচে দেখানো উপায়ে আমরা Student টেবিলটিকে পরিবর্তন করে First normal form (1NF) এ নিলাম –

fig2

এখন Student টেবিলের সব কলামের ভ্যালু একক (atomic) হয়েছে। এবার আমারা দেখতে পাচ্ছি যে, একই ডাটা বার বার আসছে। শুধুমাত্র subject কলামের ডাটা পরিবর্তন হচ্ছে।

আমারা এবার Second normal form (2NF) এ আমদের Student টেবিলটিকে নিয়ে যাব। এর জন্য নিচের শর্ত দুটি পূরণ করতে হবে –
১) টেবিলটি First normal form (1NF) এ থাকতে হবে
২) কোনও non-prime অথবা non-key attribute, candidate key এর subset এর উপর নির্ভরশীল হতে পারবে না।

[candidate key মানে এমন কলাম বা কলামের সমষ্টি যা একটি টেবিলের প্রতিটি রেকর্ড কে আলাদা ভাবে চিহ্নিত করতে পারে। একটি টেবিলের এক বা একাধিক candidate key থাকতে পারে। এর মধ্যে একটি বিশেষ candidate key কে আমরা primary key বলি। যে attribute/column কোনও candidate key এর অংশ নয় তাকে non-prime attribute অথবা non-key attribute বলে।]।

আমদের Student টেবিলটি First normal form (1NF) এ আছে। আমাদের দ্বিতীয় শর্তটি পূরণ করতে হবে। Student টেবিল থেকে আমরা লক্ষ করি যে, {studentId, subject} কলাম দুটি মিলে হচ্ছে একটা candidate key এবং name, age, postCode, city কলামগুলো হচ্ছে non-prime attribute।

এখন name, age, postCode, city কলামগুলি শুধুমাত্র studentId কলামের উপর নির্ভরশীল এবং studentId হল candidate key: {studentId, subject} এর একটি subset।

আমরা Student টেবিলটিকে নিচের মত করে Second normal form (2NF) এ নিতে পারি। আমারা একটি নতুন টেবিল Student_Subject তৈরি করলাম স্টুডেন্ট এবং সাবজেক্ট এর মধ্যে সম্পর্ক ঠিক রাখার জন্য।

fig3

তাহলে আমাদের ডাটাবেজ এখন Second normal form (2NF)-এ চলে আসল। এবারে আমরা শেষ ধাপে যাব এবং একে Third normal form (3NF)-এ নেব। যার মাধ্যমে আমাদের নরমালাইজেশন করার প্রক্রিয়াটি সম্পন্ন হবে।

Third normal form (3NF) এ নেওয়ার জন্য আমদের নিচের দুটি শর্ত পূরণ করতে হবে –
১) টেবিল Second normal form (2NF) এ থাকতে হবে
২) কোনো Transitive functional dependency থাকতে পারবে না

[Transitive functional dependency – মনে করি একটি টেবিলের প্রাইমার‍ি কি (primary key) হচ্ছে A এবং এই টেবিলের দুটি নন-প্রাইম (non-prime) কলাম হচ্ছে B এবং C, যেখানে C কলামের ভ্যালু যতটা A কলামের ভ্যালুর উপরে নির্ভরশীল তার চাইতে B কলামের ভ্যালুর উপর বেশি নির্ভরশীল, আবার B কলামের ভ্যালু A কলামের ভ্যালুর উপরে সরাসরি নির্ভরশীল, তাহলে আমরা বলতে পারি যে C কলাম transitively কলাম A এর উপর নির্ভরশীল। ওই যে, ছাগল ঘাস খায়, মানুষ ছাগল খায়, তার মানে মানুষ ঘাস খায় – এরকম লজিক আর কী।]

আমাদের Student টেবিলটিতে studentId হচ্ছে প্রাইমার‍ি কি (primary key) এবং postCode আর city হচ্ছে দুটি নন-প্রাইম (non-prime) কলাম। আমরা লক্ষ করি যে, city কলামটি যতটা studentId কলামের উপরে নির্ভরশীল তার চাইতে বেশি নির্ভরশীল postCode কলামটির উপরে এবং postCode কলামটি আবার studentId কলামের উপরে সরাসরি নির্ভরশীল। সুতরাং আমরা বলতে পারি যে city কলামটি transitively কলাম studentId এর উপর নির্ভরশীল।

তাই Student টেবিলটিকে Third normal form (3NF)-এ নিতে নিচের মতো পরিবর্তন করতে পারি এবং PostCode_City নামে একটি নতুন টেবিল তৈরি করতে পারি –

fig4

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

লেখক – মোঃ শফিউজ্জামান রাজিব, বিগডাটা প্রফেশনাল।

প্রোগ্রামিং ইন্টারভিউঃ কোডিং

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

x = input()
y = input()
print x / y

তখন ইন্টারভিউয়ার তোমাকে বলল, “আপনি একটা ফাংশন লিখে কাজটা করেন”। “আচ্ছা, ঠিকাছে” বলে তুমি নিচের মতো কোড লিখে ফেললে –

def division(x, y):
    return x / y

x = input()
y = input()
print division(x, y)

এবার তুমি পরিতৃপ্ত, তোমার কোড দেখতে বেশ সুন্দর হয়েছে। কিন্তু ইন্টারভিউয়ারের চেহারা দেখে বোঝা যাচ্ছে, তিনি এখনো তেমন খুশি নন। তখন তিনি জিজ্ঞাসা করলেন, আচ্ছা, y-এর মান যদি 0 হয়?

একথা বলতে না বলতেই তুমি ঝট করে নিচের কোড টাইপ করে মুচকি হাসি দিলে:

def division(x, y):
    try:
        return x / y
    except ZeroDivisionError:
        return "Can not divide by zero"

x = input()
y = input()
print division(x, y)

তুমি মনে মনে ভাবছ, “যাক, এবারের কোড বুলেট প্রুফ”। ইন্টারভিউয়ার এবারে বললেন, আচ্ছা, x-এ 5 আর y-তে 2 ইনপুট দিলে কী হবে? পাইথন (2 সিরিজে)-এ সেটার উত্তর হবে 2। কিছুক্ষণ চিন্তাভাবনা করে তুমি তোমার কোড একটু পরিবর্তন করে নিচের মতো করে লিখলে –

def division(x, y):
    try:
        return x * 1.0 / y
    except ZeroDivisionError:
        return "Can not divide by zero"

x = input()
y = input()
print division(x, y)

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

def division(numerator, denominator):
    """ Divides numerator by denominator. In case the denominator is    zero, it returns None 
    """
    try:
        return numerator * 1.0 / denominator
    except ZeroDivisionError:
        print "Can not divide by zero"
        return None

আশা করি তোমরা ইন্টারভিউতে প্রশ্ন শুনেই কোডিংয়ে ঝাঁপিয়ে পড়বে না। তাই তোমার জন্য টিপস্ হচ্ছে –

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

 

সফটওয়্যার ইঞ্জিনিয়ারিং ইন্টারভিউ

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

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

১) প্রবলেম সলভিং স্কিলঃ যখন ইন্টারভিউতে তোমাকে একটি প্রবলেম সলভ করতে দেওয়া হয়, তখন দেখা হয় যে তুমি প্রবলেমটি ঠিকভাবে বুঝলে কী না। না বুঝলে প্রয়োজনীয় প্রশ্ন করে সবকিছু পরিষ্কার করে নিলে কী না। সমস্যাটি তুমি কিভাবে বিশ্লেষণ করলে? এটি করতে তোমার কী পরিমাণ সময় লাগল? তোমাকে কতটুকু হিন্টস্ দিতে হয়েছে। এসব বিষয় গুরুত্বপূর্ণ।

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

৩) কম্পিউটার সায়েন্সের মৌলিক জ্ঞানঃ কম্পিউটার সায়েন্সের বেসিক বলতে আমরা বুঝি ডাটা স্ট্রাকচার ও অ্যালগরিদম, ডিজিটাল লজিক, অপারেটিং সিস্টেম, ডাটাবেজ, নেটওয়ার্কিং – এসব মৌলিক বিষয়ের ওপর নূন্যতম ধারণা। তোমাকে বিটওয়াইজ অপারেশন জানতে হবে, থ্রেড ও প্রসেসের পার্থক্য জানতে হবে, রেস কন্ডিশন বুঝতে হবে, রিলেশনাল ডাটাবেজ কী, কেন, নোএসকিউএল কেন প্রয়োজন, এগুলো জানা থাকতে হবে।

৪) অভিজ্ঞতাঃ অভিজ্ঞ প্রার্থীদের ক্ষেত্রে পূর্বে যেসব কোম্পানীতে কাজ করেছ, সেগুলো কেমন, তুমি কোন অংশে কাজ করেছ, সেখানে তোমার অবদান কী – এসব বিষয় বেশ খুঁটিয়ে দেখা হয়। আর ফ্রেশ গ্র্যাজুয়েটদের ক্ষেত্রে প্রোগ্রামিং কনটেস্ট, প্রজেক্ট এসবের অভিজ্ঞতা দেখা হয়। ভার্সিটিতে হয়ত তুমি প্রজেক্ট অন্য কাউকে দিয়ে করিয়ে পার হয়ে যেতে পারবে কিন্তু ইন্টারভিউতে এসে ঠিকই ধরা খাবে। এর জন্য প্রস্তুত থেকো।

৫) সফট স্কিলঃ তোমার টেকনিক্যাল স্কিলের বাইরে তুমি এমনিতে মানুষ কেমন, আচার-ব্যবহার, যোগাযোগের দক্ষতা (কমিউনিকেশন স্কিল) এসবও যাচাই করা হয় (কিন্তু কখন এটা করা হচ্ছে, সেটি তুমি টের পাবে না)। অভিজ্ঞ ইন্টারভিউয়ার কিন্তু ইন্টারভিউ শেষে প্রার্থী সম্পর্কে বেশ কিছু প্রশ্নের উত্তর নিজের মনেই দেয়, সবচেয়ে দরকারি প্রশ্ন হচ্ছে, “আমি কি আমার টিমে এই ব্যক্তির সাথে কাজ করতে খুব খুশি হব?” – উত্তর যদি “না” হয়, তবে চাকরি পাওয়ার কোনো সম্ভাবনা নেই।

সবশেষে বলি, গ্র্যাব (grab.com)-এ আমার বস অরুল (তিনি আগে ১৬ বছর মাইক্রোসফটে ও ৩ বছর অ্যামাজনে কাজ করেছেন) আমাকে ইন্টারভিউ নেওয়ার ক্ষেত্রে একটি সহজ টিপস্ দিয়েছেন। ইন্টারভিউ শেষে নিজেকে প্রশ্ন করতে হবে, “আমার বর্তমান টিমের বেস্ট প্রোগ্রামারকে অন্য টিমের জন্য ছেড়ে দিয়ে এই ছেলেকে (বা মেয়েকে) আমার টিমে নিতে কি আমি রাজি?”

বই রিভিউঃ গ্রাফ অ্যালগরিদম

ডক্টর তানভীরুল ইসলাম
ডক্টর তানভীরুল ইসলাম

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

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

14567368_1807469962854152_6542489571723649238_o

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

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

ডঃ তানভীরুল ইসলাম, ন্যাশনাল ইউনিভার্সিটি অব সিঙ্গাপুর।

বইটি সম্পর্কে আরো তথ্য জানা যাবে এই লিঙ্কে ঃ http://dimik.pub/book/104

অ্যারোস্পেসে ক্যারিয়ার গড়তে হলে

বিশ্ব মহাকাশ সপ্তাহ (World Space Week) উপলক্ষে ন্যাশনাল ইউনিভার্সিটি অব সিঙ্গাপুরে চলছে বিভিন্ন অনুষ্ঠান। গতকাল (শুক্রবার) সেখানে যাই তানভীরুল ইসলামের একটা বক্তৃতা শোনার জন্য।

এমা লেম্যান
এমা লেম্যান

তানভীরের বক্তৃতার পরই “Building a Career in Aerospace” শিরোনামে আরেকটি বক্তৃতা শুনি। বক্তৃতা করেন এমা লেম্যান (Ms. Emma Lehman), যিনি বর্তমানে গুগলের একটি প্রতিষ্ঠান টেরাবেলা-তে ফ্লাইট অপারেশনস টিমের নেতৃত্ব দিচ্ছেন।

 

সেখানে কী কাজ হয়, জানা যাবে নিচের ভিডিও থেকে:

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

Jpeg
building a career in aerospace

১) লিখতে জানতে হবে: বিজ্ঞানীদের বিভিন্ন রিসার্স পেপার, গ্র্যান্ট প্রপোজাল ইত্যাদি খুব ভালোভাবে লিখতে হয়। তাই লেখালেখি-তে দক্ষতা অর্জন করতে হবে।

২) লেগে থাকতে হবে: কোনো কিছুই সহজ নয়, লেগে থাকা চাই। শুরুতে কোনো কাজ ভালো নাও লাগতে পারে। কিন্তু পরিশ্রম করে যেতে হবে। তাতে একসময় কাজটা সহজ হয়ে যাবে।

৩) নিজের নেটওয়ার্ক ব্যবহার করতে হবে: কেউ যখন লেখাপড়া শেষ চাকরির জন্য তৈরি, তখন নিজের কানেকশন মানে পরিচিত মানুষদের কাজে লাগাতে হবে। চাকরির জন্য কারো কাছে সিভি পাঠানোতে লজ্জ্বার কিছু নেই।

৪) ঝুঁকি নিতে হবে: সবসময় নিরাপদ চাকরি বেছে নিলে সেটা ক্যারিয়ারের জন্য ভালো নাও হতে পারে।

৫) এমন একটি কাজ বা চাকরি খুঁজে নিতে হবে, যেটি তুমি উপভোগ করবে আর কাজ থেকে তুমি অনুপ্রেরণাও পাবে।

৬) সবসময় আরামের কাজ খুুঁজবে না। যেসব জিনিস তুমি জানো, সহজেই করতে পারো, এরকম কাজ বারবার করে কোনো লাভ নেই।

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

৭) অ্যারোস্পেস স্টার্টআপে কাজ নিলে কাজ করার সুযোগ অনেক বেশি পাওয়া যায়। তাই স্টার্টআপেই কাজ খুঁজে নেওয়া উচিত।

৮) অ্যারোস্পেসের জগতেই অনেক ধরণের কাজ আছে। আমি কেবল এরকম কাজ করবো, বা এরকম কোম্পানীতে কাজ করব, এরকম মানসিকতা না রেখে নতুন চ্যালেঞ্জ নেওয়ার ব্যাপারে ফ্লেক্সিবল থাকতে হবে।

৯) পাইথন প্রোগ্রামিং শিখতে হবে।

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

শেখার জন্য পড়া

“সুশিক্ষিত লোক মাত্রই স্বশিক্ষিত” – অনেক বছর আগে কথাটি বলেছিলেন প্রমথ চৌধুরী। সাম্প্রতিক এক বক্তব্যে শিক্ষাব্যবস্থা নিয়ে বেশ চমৎকার কিছু কথা বলেছেন খান একাডেমির প্রতিষ্ঠাতা সালমান খান। সেখানেও তিনি এই কথাটিই বোঝাতে চেয়েছেন। সুবিন ডট কম-এর পাঠকদের জন্য বক্তব্যটির লিখিত রূপ দিয়েছেন তামান্না নিশাত রিনি।

খান একাডেমির প্রতিষ্ঠাতা- সালমান খান
খান একাডেমির প্রতিষ্ঠাতা- সালমান খান

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

  • দক্ষতা অর্জনের চিন্তা এবং
  • শেখার জন্য নিজের ইচ্ছা।

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

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

জীবনে বিভিন্নভাবে অনেক অনেক বিষয়ে এভাবে ধীরে ধীরেই মানুষ দক্ষ হয়ে উঠে। যেমনঃ মার্শাল আর্ট। মার্শাল আর্ট শেখার সময় প্রথমে হোয়াইট বেল্টের জন্য চর্চা চালিয়ে যেতে হয় যতদিন প্রয়োজন ততদিন। হোয়াইট বেল্ট পাওয়ার জন্য যেসব বিষয়ের চর্চা করতে হয়, যখন সেসব বিষয়ে একজন পরিপূর্ণ দক্ষতা অর্জন করে, তখন তাকে “ইয়েলো বেল্টের” জন্য দক্ষতা অর্জনের যোগ্য মনে করা হয় এবং হোয়াইট বেল্ট থেকে ইয়েলো বেল্টে উত্তীর্ণ করা হয়। একই ঘটনা ঘটে যেকোনো বাদ্যযন্ত্র বা সঙ্গীত শেখার ক্ষেত্রেও। প্রাথমিক বা বেসিক জিনিসগুলো বার বার চর্চা করে আয়ত্বে এনে পরবর্তীতে উচ্চতর ধাপে অগ্রসর হতে হয়।

কিন্তু, যেটা দেখা যায় আমাদের একাডেমিক শিক্ষাব্যবস্থা কিন্তু এমন নয়। আমরা সবাই যে গতানুগতিক শিক্ষাব্যবস্থায় শিক্ষাগ্রহণ করি, সেখানে এই ধাপে ধাপে কোন কিছু শিখে সে বিষয়ে সর্বোচ্চ দক্ষতা অর্জন করে উচ্চতর ধাপে যাওয়ার সুযোগ নেই। গতানুগতিক শিক্ষাব্যবস্থায় কী হয়? সেখানে বয়স এবং মুখস্থ করার ক্ষমতার উপর ভিত্তি করে শিক্ষার্থীদের একটা গ্রুপ করা হয়। একজন শিক্ষক তাদের সবাইকে একইদিকে একইভাবে পরিচালনা করেন। ধরা যাক আমরা প্রাথমিক- অ্যালজেব্রা ক্লাসের কথা চিন্তা করি, যেখানে পড়ানো হচ্ছে exponents। শিক্ষক প্রথমদিন exponents সম্পর্কে লেকচার দিলেন, কিছু বাড়ির কাজ দিলেন, আমরা বাসায় গেলাম, বাড়ির কাজ করলাম। পরের দিন সকালে সেই বাড়ির কাজ শিক্ষক রিভিউ করলেন, আবার exponents এর কিছু লেকচার দিলেন আবার বাড়ির কাজ দিলেন পরের দিনের জন্য, লেকচার-বাড়ির কাজ, লেকচার-বাড়ির কাজ এভাবে চলতে থাকলো। দুই-তিন সপ্তাহ এভাবে চলার পর একটা পরীক্ষা নেয়া হলো। সেখানে আমি হয়ত ৭৫ পেলাম, তুমি ৯৫ পেলে, আবার কেউ ৯০ শতাংশ নম্বর পেলো। যদিও এই পরীক্ষার মাধ্যমে আমরা আমাদের জ্ঞানের অপ্রতুলতা শনাক্ত করতে পারি, তারপরেও সংশ্লিষ্ট বিষয়ের ২৫ ভাগ বিষয়ই অজানা থেকে যায়।

যদিও শেখার সময় আমাদের কিছু ঘাটতি থেকে যায়, তা সত্ত্বেও, পুরো ক্লাস পরের টপিকে চলে যায় যেখানে আরো Advanced বিষয় অপেক্ষা করছে। সে বিষয়টি আবার আগে আমরা যা বেসিক কোর্সে শিখে আসি নি, সেগুলোর উপর ভিত্তি করেই তৈরি। যেমনঃ লগারিদম বা নেগেটিভ Exponents। ঐ একই বাড়ির কাজ-লেকচার প্রক্রিয়ায় এই কোর্সও অগ্রসর হতে থাকে। একটা সময় আমরা বিস্ময়ের সাথে লক্ষ্য করি বিষয়গুলো বেশ অদ্ভুত। যেখানে আমি এই বিষয়ের ২৫ শতাংশ মূল বিষয়ই জানি না, সেখানে আমাকে অনেক জটিল জিনিস দেখানো হচ্ছে। অ্যালজেব্রার মূল বিষয় যে কঠিন তা কিন্তু নয়, বা শিক্ষার্থীদের যথেষ্ট মেধা নেই তাও সত্যি নয়। একমাত্র কারণ, বেসিক জ্ঞানের ঘাটতি, যেখানে একটা ইক্সপোনেন্টের ইকুয়েশন লেখা হচ্ছে যার ৩০ শতাংশ বিষয়-ই আমি জানি না। এবং সেখান থেকেই গণিতের সাথে আমার বিচ্ছিন্নতার সূচনা হয়।

যদি আমরা এই জিনিসের সাথে আমাদের দৈনন্দিন কাজের তুলনা করি, তাহলে বুঝা যায় ব্যাপারটা কতটা অদ্ভুত। যেমনঃ বাড়ি তৈরি করা। আমরা একজন কনট্রাকটারকে ডেকে এনে বললাম, “দুই সপ্তাহের মধ্যে আমাদের বাড়ির ফাউন্ডেশন তৈরি হতে হবে। তুমি যা পারো কর।” সুতরাং, তাদের যা করার তারা করলো। হয়ত এই দুই সপ্তাহের মধ্যে বৃষ্টি হলো, বাড়ি তৈরির উপকরণগুলো ঠিকঠাকমত সাইটে পৌঁছালো না। দুই সপ্তাহ পর পর্যবেক্ষক এলেন এবং এসে বললেন, “এখানে কংক্রিট ঠিকমত জমেনি, একটু ভিজে আছে, এখানে ইট ঠিকমত বসেনি। ঠিক আছে আমি এটাকে ৮০% ঠিকঠাক সার্টিফিকেট দিলাম।” তুমি বললে, “WOW, চলো দোতলা বানানো শুরু করি।” একই জিনিসের পুনরাবৃত্তি হয় দোতলা বানানোর ক্ষেত্রেও। আমরা যা করার করি , পর্যবেক্ষককে দেখাই তিনি এবার হয়ত ৭৫% ঠিকঠাক বললেন। এভাবে দুইতলা, তিনতলা করে বানানো চলতে লাগলো। হঠাৎ, তিনতলা বানানোর সময় পুরো বিল্ডিংটা ধপাস করে পরে গেল। তখন যদি আমাদের প্রতিক্রিয়া হয় এমন, যেমনটি আমরা শিক্ষাব্যবস্থায় দেখাই, যেমন আমরা বলতে পারি, আমাদের কন্ট্রাকটার ভালো ছিলো না, পর্যবেক্ষক ঠিকমত কাজ করেনি। আরো ভালভাবে পর্যবেক্ষণ করার দরকার ছিলো। কিন্তু ততক্ষণে পুরো প্রসেসটাই ভেঙ্গে পরেছে। কারণ আমরা জানতাম যে সেখানে ঘাটতি আছে তারপরেও আমরা এই ঘাটতির উপর ভিত্তি করেই নির্মানকাজ চালিয়ে গিয়েছিলাম।

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

এটা বুঝা গুরুত্বপূর্ণ যে, এভাবে শিখলে একজন শিক্ষার্থী শুধুমাত্র একটি বিষয়ে পারর্দশী হবে না, সেই সাথে তার মানসিকতা দৃঢ় হবে। এটি তাকে বুঝতে সাহায্য করবে যে, যদি কোন বিষয়ে তুমি ২০ নম্বর কম পাও, তার মানে এই নয় যে তুমি সি গ্রেড ছাত্রের ডিএনএ নিয়ে জন্ম নিয়েছো । এর অর্থ হচ্ছে, এই বিষয়ের উপর তোমার আরো অনেক বেশি সময় দিতে হবে। তোমার মনের জোর দৃঢ় করতে হবে; তোমার অধ্যবসায় থাকতে হবে; তোমার শেখার উপর তোমাকে কর্তৃত্ব করতে হবে।

এখন অনেক সংশয়বাদী বলবে, এই ব্যবস্থা অবশ্যই সুন্দর। যেখানে সংশ্লিষ্ট বিষয়ে কর্তৃত্ব অর্জনের ব্যাপার আছে, মানসিক দৃঢ়তার সম্পর্ক আছে । ব্যাপারটা যথেষ্ট অর্থপূর্ণ হলেও, অবাস্তব। এভাবে করলে প্রতিটা শিক্ষার্থী তাদের নিজস্ব পথে থাকবে। ফলে শিক্ষাব্যবস্থাকে ব্যক্তিগত করতে হবে, প্রতিটি ছাত্রের জন্য আলাদা আলাদা প্রাইভেট টিউটর এবং ওয়ার্কশীটের ব্যবস্থা রাখতে হবে। কর্তৃত্ব-ভিত্তিক এই ধরণের শিক্ষার ধারণা কিন্তু নতুন না। ১০০ বছর আগে Winnetka, Illinois-এ পরীক্ষামূলকভাবে এই শিক্ষানীতি চালানো হয়েছিল। পরে সেখান থেকে বলা হয়, কারিগরিভাবে এটা আসলেই সম্ভবপর না। সেই প্রজেক্টে প্রত্যেকটি ছাত্রকে আলাদা আলাদা ওয়ার্কশীট দিতে হতো এবং চাহিদা মোতাবেক তাদের মূল্যায়ন করতে হতো।

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

আমাদের এই চিন্তাকে উৎসাহ দেয়ার জন্য, এখন আমি একটা চিন্তা পরীক্ষার কথা বলবো। চিন্তা করা যাক, ৪০০ বছর আগের শিক্ষা সংস্কৃতিতে সমৃদ্ধ পশ্চিম ইউরোপের কথা। তখন তাদের জনসংখ্যার ১৫ শতাংশ পড়তে পারতো। সে সময়ের কাউকে যদি প্রশ্ন করা হতো, “তোমাদের জনসংখ্যার কত শতাংশ মানুষ পড়তে পারে?” উত্তর পাওয়া যেতঃ “হয়ত ১৫-২০ শতাংশ।” বর্তমানে এই জরিপ চালালে তোমারাই জানো ফলাফল আসবে যথেষ্ট ইতিবাচক, সম্ভাবনা এতই ভাল যে বলা যায় ১০০ শতাংশ লোকই পড়তে পারবে। কিন্তু যদি এই প্রশ্নটা একটু ঘুরিয়ে করা হয় যে, “জনসংখ্যার কত শতাংশ ক্যালকুলাস বা জৈব রসায়ন বুঝে? কত শতাংশ ক্যান্সারের গবেষণায় অবদান রাখতে পারবে? ” অধিকাংশই উত্তর দিবে, “অত্যাধুনিক শিক্ষাব্যবস্থায় শিক্ষিত জনগণের হয়ত ২০-৩০ শতাংশ”।

কেমন হবে যদি এই পরীক্ষার হিসাব গতানুগতিক শিক্ষা কাঠামোয় নিজের অভিজ্ঞতার উপর হিসাব করে করা হয় অথবা নিজের বন্ধুদের নিয়ে করা হয়ঃ যেখানে সবাইকে ক্লাসের সাথে একই গতিতে নিয়ে যাওয়া হয়, শেখার ঘাটতিকে সাথে নিয়ে। এক্ষেত্রে যখন তুমি ৯৫ শতাংশ নম্বর পাচ্ছো, তখনো তুমি কিন্তু জানো না কোন ৫% তুমি জানো না।এভাবে ধীরে ধীরে জ্ঞানের ঘাটতি বাড়তে থাকে- তুমি উপরের আরেকটি ক্লাসে চলে যাও। একসময় তোমার পিঠ দেয়ালে ঠেকে যায়, তুমি বল, “আমি ক্যান্সার গবেষক হতে পারবো না; আমি পদার্থবিদ হতে পারবো না; আমি গণিতজ্ঞ হতে পারবো না।” কর্তৃত্ব-ভিত্তিক শিক্ষাব্যবস্থায় যদি তোমাকে চালানোর সুযোগ দেয়া হয়, যদি তোমাকে তোমার শেখার সঠিক মাধ্যমটি দেয়া হয়, তখন যদি শেখার সময় তুমি কোনো ভুল কর – ভুলের এই মুহূর্তটিকে শেখার মুহূর্ত হিসেবে বিবেচনা কর। তারপর তখন যে নম্বর, যে শতকরা নম্বরটি জৈব রসায়ন বা ক্যালকুলাসে তুমি পাবে সেটিতে তোমার দক্ষতার হার অবশ্যই হবে ১০০ এর অনেক কাছাকাছি।

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

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