ফাংশনাল প্রোগ্রামিং
পাইথন ফাংশন্স
একটি সুবিন্যস্ত কোড ব্লক যা একটি নির্দিষ্ট কাজ করার জন্য লিখা হয় তাকে ফাংশন বলে। কোডকে হালকা, রিডেবল এবং একই ধরনের কোড বারবার লিখা পরিহার করার জন্য ফাংশন লিখা হয়৷ কোডের একই ধরনের কাজ এক্সিকিউট করার ক্ষেত্রে সে কাজের জন্য যে ফাংশন লিখা হয়েছে তা কল করে কাঙ্ক্ষিত আউটপুট পাওয়া যায়।
পাইথনে দু ধরনের ফাংশন ব্যবহার করা হয়।
- বিল্ট-ইন (built in)
- ইউজার ডিফাইন্ড (user defined)
পাইথনে যেসব ফাংশন ডিফাইন করা আছে সেগুলো হচ্ছে বিল্ট-ইন ফাংশন্স। যেমনঃ print(), map(),input()
অন্যদিকে যেসব ফাংশন প্রোগ্রামার রা নিজের কোন নির্দিষ্ট কাজ করার জন্য তৈরি করে সেগুলো হচ্ছে ইউজার ডিফাইন্ড ফাংশন্স।
ফাংশন ডিক্লেয়ারেশন
পাইথনে ফাংশন লিখার শুরুতে def কিওয়ার্ড ব্যবহার করা হয় এবং এরপর ফাংশনের নাম ও সাথে প্যারেন্থিসিস "()" ও শেষে কোলন (:) দিতে হয়। প্যারে- ন্থিসিসের ভেতর প্যারামিটারস/আর্গুমেন্টস লিখতে হয়।
ফাংশনের প্রথম লাইন হয় ডক স্ট্রিং যেখানে লিখা থাকে যে এই ফাংশন কি কি কাজ করবে। এটি যদিও অত্যাবশ্যক না তবুও "It is a good practice"
এরপর ফাংশনের প্রধান ব্লক যেখানে কোড লিখা হয়। এবং সবার শেষে return স্টেটমেন্ট তাকে যা ফাংশনের আউটপুট রিটার্ন করে।
ফাংশন এক্সপ্রেশন
def function (parameters):
""" function docstring''""
function body
return (expression)
ফাংশন কলিং
একটি ফাংশন লিখার পর তা থেকে আউটপুট পাওয়ার জন্য ফাংশন কল করতে হয়। এবং ফাংশন এক্সিকিউট করার জন্য নুন্যতম যে আর্গুমেন্টস দরকার তা পাস্ করতে হয়। ফাংশন চাইলে ওই একই প্রোগ্রামের যেকোন যায়গায় বা অন্য ফাংশনে বা অন্য প্রোগ্রামে মেথড হিসেবে কল করা যায়৷ আবার পাইথন প্রম্পট এ রানটাইমেও কল করা যায়। উদাহরণঃ
def addition(a,b):
""" This function will return sum of two digits"""
result =(a+b)
return(result)
addition(5,6)
এত টুকু আমরা যখন রান করাব তখন আমরা কোন আউটপুট স্ক্রিনে দেখতে পাব না। কারণ এখানে কোন print() ফাংশন নেই।
কিন্তু এই ফাংশনকে যদি print() ফাংশনের ভেতর কল করি তাহলে আমরা আউটপুট দেখতে পাব
print (addition (5+6))
call_function = addition (5,6)
print(call_function)
এই দু ক্ষেত্রেই আমরা আউটপুট দেখতে পাব।
আমরা যখন কোন ফাংশন নিজে লিখি তখন সে ফাংশনের সব কিছুই আমরা জানি,কিন্তু যখন কোন লাইব্রেরি কল করি বা অন্য কারো ফাংশন ইম্পোর্ট করি তখন সে ফাংশন সম্পর্কে আমরা সব কিছু জানি না। তবে সেটা জানার ও উপায় আছে। আমরা চাইলে ফাংশন কে প্রশ্ন করতে পারি যে তোমার নাম কি? তোমার আর্গুমেন্টস কয়টা? তোমার ডিটেইলস বল। শুনলে মজার শোনালে ও আসলেই ফাংশন এগুলোর উত্তর দেয়। ইন্টারপ্রটারে আমরা এই addition ফাংশন টা ই ইম্পোর্ট করে দেখাচ্ছি...
>>> from myfunction import addition #myfunction is the filename
>>> addition.__name__
'addition'
>>> addition.__doc__
'docstring of the addition function'
#how many local variables do you have?
>>> addition.__code__.co_nlocals
3
>>> addition.__code__.co_code
b'|\x00|\x01\x17\x00}\x02|\x02S\x00' #byte code of the function
>>> addition.__code__
<code object addition at 0x000002F94C24BD20, file "C:/Users/ASUS-PC/AppData/Local/Programs/Python/Python36\myfunction.py", line 1>
#physical address of the function.
এছাড়াও ভ্যারিয়েবলের নাম, ফাইলনেম সহ আরও অনেক কিছুই জানা যায়।
আর্গুমেন্টস অব ফাংশন্স
আর্গুমেন্ট বা প্যারামিটার, ফাংশন কল করার সময় ফাংশন এক্সিকিউশনের জন্য প্রয়োজনীয় যে ডেটা পাঠাতে তাকে আর্গুমেন্টস বলে। পাইথন ফাংশনে চার ধরনের আর্গুমেন্টস ব্যবহার করা যায়।
- ডিফল্ট আর্গুমেন্টস
- রিকোয়ার্ড বা পজিশনাল আর্গুমেন্টস
- কি-ওয়ার্ড আর্গুমেন্টস
- ভ্যারিয়েবল লেনথ আর্গুমেন্টস
ডিফল্ট আর্গুমেন্টস
পাইথন ফাংশনে যখন একাধিক আর্গুমেন্টস ব্যবহার করা হয় তখন কিছু আর্গুমেন্টসের ডিফল্ট ভ্যালু দেয়া হয়।সে আর্গুমেন্ট পাস না করলে ও ফাংশন সে আর্গুমেন্টের জন্য ডিফল্ট ভ্যালুটি নিয়ে কোড এক্সিকিউট করে। একেই ডিফল্ট আর্গুমেন্টস বলা হয়।>>>def defaultArg( name, msg = "Hello!"):return (name + msg)>>> print(defaultArg('ratul'))ratulHello!আমরা যদি বাই-ডিফল্ট msg প্যারামিটারের একটি ভ্যালু না অ্যাসাইন করে দিতাম তাহলে পাইথন এটিকে “রিকোয়ার্ড আর্গুমেন্ট“ হিসেবে ধরে নিত এবং এরর দেখাত।>>> def defaultArg(name, msg):return (name + msg)>>> print(defaultArg('ratul'))Traceback (most recent call last):File "<pyshell#31>", line 1, in <module>print(defaultArg('ratul'))TypeError: defaultArg() missing 1 required positional argument: 'msg'
রিকোয়ার্ড আর্গুমেন্টস
যে আর্গুমেন্টস ফাংশন কল করার সময় অবশ্যই পাস করতে হয় তাকে রিকোয়ার্ড আর্গুমেন্টস বলে। এবং একটি ফাংশনে একাধিক রিকোয়ার্ড আর্গুমেন্টস থাকলে তা ঠিক একই পজিশনে পাস করতে হয়।
def string (arg1, arg2):
print(str)
string(6)
TypeError: string() missing 1 required positional argument: 'arg2'
[Program finished]
কি-ওয়ার্ড আর্গুমেন্টস
ফাংশন কল করার সময় যে আর্গুমেন্ট গুলোকে তাদের নাম সহ মেনশন করে পাস করা হয় তাদের কি-ওয়ার্ড আর্গুমেন্টস বলে।
>>>def keywordArg( name, role ):
return(name+role)
>>># 2 keyword arguments
>>>keywordArg(name = "Tom", role = "1111")
কি-ওয়ার্ড আর্গুমেন্টের পজিশন চেঞ্জ করে পাঠালে ও পাইথন কোন এরর দেখায় না।তবে কোন পজিশনাল আর্গুমেন্টের আগে কোন কি-ওয়ার্ড আর্গুমেন্ট পাস করলে তখন পাইথন সিন্ট্যাক্স এরর দেখায়।
>>># 2 keyword arguments (out of order)
>>>keywordArg("role = "1111",name = "Tom)
>>># 1 positional, 1 keyword argument
>>>keywordArg("Tom", role = "1111")
>>>keywordArg(role = "1111","Tom")
SyntaxError: non-keyword arg after keyword arg
ভ্যারিবেল লেনথ আর্গুমেন্টস
অনেক প্রোগ্রাম লিখার সময় আমাদের জানা থাকে না যে ঠিক কতটা আর্গুমেন্টস পাঠানো হবে। আমরা যে সাধারন ক্যাল্কুলেটর ব্যবহার করি সেখানেও আমরা আগে থেকে বলে দেই না যে আমরা ঠিক কতটা সংখ্যার ক্যালকুলেশন করব। আমরা একের পর এক ইনপুট দিতে থাকি এবং ক্যাল্কুলেটরের ফাংশন ফলাফল রিটার্ণ করতে থাকে। এরকম অনেক ক্ষেত্রেই অজানা সংখ্যক আর্গুমেন্টসের প্রয়োজন পড়তে পারে। তখনই আমরা পাইথনের ভ্যারিয়েবল-লেন্থ আর্গুমেন্ট ব্যবহার করি।
def greet(*names):
"""This ‘ * ’ converts the argument
into variable length argument """
# names is a tuple with arguments
for name in names:
print("Hello",name)
greet("Ayub","Meraj","Rashed","Tonmoy","Younus","Imran",)
আউটপুট
Hello Ayub
Hello Meraj
Hello Rashed
Hello Tonmoy
Hello Younus
Hello Imran
এবার সেই ছোট্ট প্রোগ্রাম টা লিখি যা অজানা সংখ্যক সংখ্যার যোগফল রিটার্ন করবে।
>>> def add(*nums):
total = 0
for num in nums:
total += num
return total
>>> add(3,4,4)
11
একইভাবে কি-ওয়ার্ড আর্গুমেন্ট ও ভ্যারিয়েবল লেন্থ হিসেবে ডিফাইন করা যায়। তখন একটি স্টারের
*args
জায়গায় দুটি স্টার দিতে হয়
**kwargs
দিতে হয়। এটি একটি ডিকশনারি।
রিকার্শন ইন পাইথন
রিকার্শন বলতে বোঝায় নিজের কাজ নিজে করা। ব্যাপারটা এমন যে তুমি আয়নার সামনে দাঁড়িয়ে নিজেকে প্রশ্ন করছ এবং নিজেই তার উত্তর দিচ্ছ। আমরা একটা নির্দিষ্ট করার জন্য একটি ফাংশন তৈরি করি। যদি এমন হয় যে সে একই কাজটি ওই ফাংশনের ভিতর কোন একটা জায়গায় আবার করা লাগছে তখন আমরা ওই ফাংশনের ভেতরেই আবার তাকে-ই কল করি। একেই বলে রিকার্শন। উদাহরণঃ
def factorial(n):
print("factorial function has been called with n = " + str(n))
if n == 1:
return 1
else:
result = n * factorial(n-1)
return result
print("Final result %s" %(factorial(5)))
আউটপুটঃ
factorial function has been called with n = 5
factorial function has been called with n = 4
factorial function has been called with n = 3
factorial function has been called with n = 2
factorial function has been called with n = 1
final result 120
এ factorial ফাংশন টি প্রথমে 5 এর জন্য এক্সিকিউট হওয়া শুরু হয় এবং যেহেতু n == 1 নয় তাই প্রোগ্রামটি else স্টেট্মেন্টে ঢুকে। তারপরের লাইনে result কাউন্ট করার সময় factorial ফাংশন নিজেকেই আবার কল করে এবং তখন আর্গুমেন্ট n এর মান হল (n-1)=(5-1)=4 এভাবে একই ভাবে 1 পর্যন্ত এক্সিকিউট করে এবং রেজাল্ট রিটার্ন করে। এখানে আমাদের ফাংশনটি n=1 এর জন্য শেষ হয়েছে। এইকন্ডিশন কে বলা হয় বেজ কন্ডিশন। কোন রিকার্সিব ফাংশনে যদি বেজ কন্ডিশন না থাকে তাহলে ফাংশনটি ইনফাইনাইটলি চলতে থাকবে।