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

ফাংশনের প্রকারভেদ (Types of function)

আমরা ইতিমধ্যেই কিছু ফাংশন ব্যবহার করে এসেছি, যেমন print() ফাংশন ব্যবহার করে আমরা console এ ফলাফল প্রদর্শন করেছি। ফাংশন হচ্ছে দুই প্রকার –

  • বিল্ট-ইন ফাংশন (Built-in function) এবং
  • ইউজার ডিফাইন্ড ফাংশন (user defined function)

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

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

ফাংশনের বিভিন্ন অংশ (Different parts of a function)

একটা ফাংশনের মূলত চারটি অংশ থাকে-

  • ফাংশনের নাম (function name)
  • ফাংশনের আর্গুমেন্ট (argument) বা প্যারামিটার (parameter)
  • ফাংশনের বডি (function body)
  • রিটার্ণ টাইপ (return type)

একটি উদাহরণের সাহায্যে ফাংশনের বিভিন্ন অংশগুলো চিনে নেই –

# This program is an example of function in python
   
#Function Definition
def multiply_function(x,y):
    z=x*y
    return z
    
print(multiply_function(5,10)) #calling a function

ফলাফল-

50

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

এর পরেই z=x*y স্টেটমেন্ট ব্যবহার করা হয়েচে, এটা ফাংশনের বডি। শেষে একটি রিটার্ণ স্টেটমেন্ট ব্যবহার করা হয়েছে। return কি-ওয়ার্ড দিয়েই বলে দিতে হয় যে ফাংশন টা কি রিটার্ণ করবে। আমরা এই ফাংশনে গুন করে প্রাপ্ত ফলাফল (z) ফেরত পাঠাতে চেয়েছি, তাই এখানে return z ব্যবহার করা হয়েছে।

এখনো এই ফাংশনটিকে কল করা হয়নি, তাই এটা এখনো কোন কাজ করবে না অর্থাৎ প্রোগ্রামটিকে রান করালে কোন ফলাফল প্রদর্শন করবে না। ফলাফলের জন্য ফাংশনকে কল করা প্রয়োজন।

ফাংশনকে কল করতে সেই ফাংশনের নাম এবং আর্গুমেন্ট দিয়ে কল করতে হয়। ৮ম লাইনে আমি দুটি কাজ একসাথে করেছি, ফাংশনকে কল করেছি এবং সেটার ফলাফল print() ফাংশন দিয়ে প্রদর্শন করেছি। মূল ফাংশন কল করার কাজ হচ্ছে এইটুকু –

multiply_function(5,10)

এখানে ফাংশন নামের ভিতর দুইটা আর্গুমেন্ট 5 এবং 10 ব্যবহার করা হয়েছে। এই আর্গুমেন্ট দুটি মূল ফাংশনে pass হবে এবং যথাক্রমে x ও y এর ভ্যালু হিসেবে প্রতিস্থাপিত হবে। অর্থাৎ আমরা এই ফাংশন ব্যবহার করে যেকোন সংখ্যার গুন বের করতে পারব। বার বার নতুন কোড লেখার প্রয়োজন নেই, শুধু আর্গুমেন্ট সহ ফাংশন কল করলেই হবে।

আর্গুমেন্টের ধরণ (Types of arguments)

পাইথনে সাধারণত কোন ফাংশনে যদি প্যারামিটার থাকে তাহলে আর্গুমেন্ট ব্যবহার করা বাধ্যতামূলক। এছাড়াও পাইথনে তিন ধরণের আর্গুমেন্ট আছে –

  • কিওয়ার্ড আর্গুমেন্ট (Keyword argument)
  • ডিফল্ট আর্গুমেন্ট (default argument)
  • ভেরিয়েবল লেন্থ আর্গুমেন্ট (variable length argument)

কিওয়ার্ড আর্গুমেন্ট (Keyword argument)

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

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

# This program is an example of keyword argument in python
   
def multiply_function(x,y):
    z=x/y
    return z
    
print(multiply_function(5,10)) #normal function call

print(multiply_function(y=5,x=10)) #function call using keyword argument

ফলাফল-

0.5                                                                                                                                                                                
2.0

আশাকরি পার্থক্যটা আপনারা সঠিকভাবে বুঝতে পেরেছেন। সাধারণভাবে যদি ফাংশন কল করি তাহলে ক্রমানুসারে ভ্যারিয়েবলের ভ্যালু এসাইন হয়। অর্থাৎ ৭ম লাইনে x এর ভ্যালু 5 এবং y এর ভ্যালু 10 হিসেবে গণনা করেছে; কিন্ত ৯ম লাইনে যেহেতু আমরা ভ্যালুকে কিওয়ার্ড দিয়ে এসাইন করে দিয়েছি তাই ভ্যালুও পরিবর্তন হয়ে গেছে।

ডিফল্ট আর্গুমেন্ট (default argument)

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

ডিফল্ট আর্গুমেন্ট এর জন্য ফাংশনের ডেফিনিশন এই ডিফল্ট একটা ভ্যালু দিয়ে দিতে হয়। বিষয়টিকে আরো ভালভাবে ব্যাখ্যা করার জন্য একটা উদাহরণ দেখে নেই –

# This program is an example of default argument in python
   
def multiply_function(x=10,y=5):
    z=x/y
    return z
    
print(multiply_function()) # function call using default argument

print(multiply_function(100,5)) #normal function call

ফলাফল-

2.0                                                                                                                                                                                
20.0 

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

৮ম লাইনে আমরা সাধারণ একটা ফাংশন কল করেছি, আর্গুমেন্ট হিসেবে ১০০ এবং ৫ পাঠিয়েছি, এক্ষেত্রে ফলাফল দেখিয়েছে ২০

অর্থাৎ ডিফল্ট আর্গুমেন্ট এর ক্ষেত্রে কোন ভ্যালু না দিয়ে ডিফল্ট ভ্যালুটাকেই আর্গুমেন্ট হিসেবে ধরবে আর আর্গুমেন্টে কিছু ভ্যাল্য দিলে সেটার প্রাধান্য পাবে।

ভেরিয়েবল লেন্থ আর্গুমেন্ট (variable length argument)

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

# This program is an example of variable length argument in python
    
def multiply_function(*values):
    z=values[0]/values[1]
    return z
 
print(multiply_function(100,5)) # function call

ফলাফল-

20.0

ফাংশন ডেফিনিশন এ একটা প্যারামিটার আছে কিন্তু আর্গুমেন্ট এ দুইটা ভ্যালু পাঠাচ্ছি। ভ্যালুটা যখন যাচ্ছে তখন সেটা লিস্ট হিসেবে যাচ্ছে।

এখানে উল্লেখ্য ফাংশন ডেফিনিশন এর প্যারামিটার এর আগে একতা * চিহ্ন দিয়ে দিতে হয়।

এই পদ্ধতি ব্যবহার করে একটি key এর মাধ্যমেও ভ্যালু পাঠানো যায়। সেক্ষেত্রে পূর্বের ন্যায় key এবং তার ভ্যালু দিয়ে দিতে হয়। এখানে একটা উদাহরন দেখে নেই –

# This program is an example of variable length argument in python
    
def multiply_function(**values):
    z=values['x']/values['y']
    return z
 
print(multiply_function(x=100,y=5)) # function call

ফলাফল

20.0

এখানে x এবং y একটা key এর মত কাজ করছে।

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

ভেরিয়েবল স্কোপ (Variable Scope)

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

  • লোকাল ভেরিয়েবল (Local Variable)
  • গ্লোবাল ভেরিয়েবল (global variable)

লোকাল ভেরিয়েবল (Local Variable)

কোন একটা ভেরিয়েবলের স্কোপ যখন একটা নির্দিষ্ট কোড ব্লক বা ফাংশনের মধ্যে সীমাবদ্ধ থাকে তখন তাকে লোকাল ভেরিয়েবল বলা হয়।

গ্লোবাল ভেরিয়েবল (global variable)

যখন কোন ভেরিয়েবলে স্কোপ সমস্ত প্রোগ্রাম জুড়ে থাকে তখন তাকে গ্লোবাল ভেরিয়েবল বলা হয়।

এখন আমরা এ সম্পর্কিত একটি উদাহরণ দেখে নেই –

# This program is an example of local and global variable in python
    
x=100

def division_globalvar_function(value):
    z=x/value # Division using global variable x
    return z
    
def division_localvar_function(value):
    x=20
    z=x/value # Division using local variable x
    return z
 
print(division_globalvar_function(5)) # function call

print(division_localvar_function(5)) # function call

ফলাফল –

20.0                                                                                                
4.0

উপরের প্রোগ্রামটির ৩য় লাইনে x একটি গ্লোবাল ভেরিয়েবল হিসেবে কাজ করছে। ৬ষ্ট লাইনে x ব্যবহার করা হয়েছে অর্থাৎ ঐ x এর ভ্যালু সমস্ত প্রোগ্রাম জুড়েই বিদ্যমান তথা এটি একটি গ্লোবাল ভেরিয়েবল। ১৪ শ লাইনে যখন এই ফাংশনকে কল করা হয়েছে তখন এর ফলাফল ২০ এসেছে।

কিন্তু পরবর্তীতে ১০ম লাইনে x এর ভ্যালু ২০ এসাইন করা হয়েছে। এই ফাংশনের ভিতরে যখন x কাজ করছে তখন সেটা প্রথমেই লোকাল ভেরিয়েবল হিসেবে ব্যবহৃত হবে। এখানে দুইটি ভেরিয়েবলের নামই এক x, তবুও এখানে যেহেতু একটা দ্বন্দের সৃষ্টি হয়েছে সেহেতু লোকাল ভেরিয়েবলটি প্রাধান্য পাবে। এক্ষেত্রে যখন ১৬শ লাইনে এটিকে কল করা হয়েছে তখন এর ফলাফল এসেছ 4.0

উল্লেখ্য, গ্লোবাল ভেরিয়েবলের পরিধি বেশি, কিন্তু ক্ষমতার দিক দিয়ে লোকাল ভেরিয়েবলের ক্ষমতা বেশি।

আশাকরি আপনারা সবাই লোকাল এবং গ্লোবাল ভেরিয়েবল সম্পর্কে ভালভাবে জানতে পেরেছেন।