سبق Functions

تفاعل وظیفہ یا فنکشن (Functions)
فنکشن کسی بھی پروگرام میں ایسا حصہ ہوتا ہے جسے بار بار استعمال کیا جا سکتا ہے ۔​
فنکشن کا آغاز ایک مختص لفظ def سے ہوتا ہے​
اس کے بعد فنکشن کا نام اور قوسین () ہوتی ہیں جن کا اختتام : (colon) پر ہوتا ہے ۔ اگر کوئی پیرامیٹر (parameter) ہو تو وہ قوسین () کے درمیان آتا ہے​
اگلی لائن میں فنکشن میں جو کام کرنا ہے اس کا آغاز ہوتا ہے اور یہاں سے تمام کوڈ باقاعدہ indented ہوتا ہے۔​

فنکشن کو کال کرنے کے لیے فنکشن کا نام مع قوسین (paranthesis) لکھا جاتا ہے۔ اگر کوئی پیرامیٹر (parameter) ہو تو وہ فنکشن کی قوسین (paranthesis) میں لکھا جائے گا۔​
PHP:
def sqr(a):
    print (a * a)
 
sqr(2)
 
4

ایک اور مفید, مثال Fibonacci series کو فنکشن میں لاگو کرنے سے واضح ہوگی۔ یہ ایسی سیریز ہوتی ہے جس میں ہر نمبر پچھلے دو نمبروں کا جمع ہوتا ہے یعنی​

1 , 1, 2 , 3 , 5 , 8 , 13 , 21 ......​

PHP:
def fib(n):    # write Fibonacci series up to n
    """Print a Fibonacci series up to n."""
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()
 
fib(100)
 
 
1 1 2 3 5 8 13 21 34 55 89
 
ابھی تک ہم نے فنکشن سے کسی بھی ویلیو کی واپسی نہیں کروائی جو کہ عموما فنکشن کا کام ہوتا ہے بہت سی دیگر زبانوں میں۔ پائتھون میں بھی ایسا ہوتا ہے مگر دوسری زبانوں کے برعکس یہاں فنکشن پروسیجر (procedure) کا کام بھی کرتے ہیں یعنی بغیر کوئی ویلیو واپس کیے بھی۔ پائتھون جب کسی فنکشن میں بظاہر کوئی ویلیو واپس نہیں کرتا تب بھی وہ اندرونی طور پر ایک خودکار ویلیو None واپس کر رہا ہوتا ہے مگر انٹرپریٹر (interpreter) اسے دبا دیتا ہے اگر صرف یہی ویلیو واپس ہو رہی ہو۔​

PHP:
>>> fib(0)
 
>>> print (fib(0))
 
None
 
فنکشن سے کسی بھی ویلیو کی واپسی ممکن ہے۔ اوپر Fibonacci series والے فنکشن میں تبدیلی کرکے ہم بجائے نمبر پرنٹ کروانے کے ان کی لسٹ واپس لے سکتے ہیں ۔
PHP:
def fib2(n): # return Fibonacci series up to n
    """Return a list containing the Fibonacci series up to n."""
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)    # see below
        a, b = b, a+b
    return result
 
 
f100 = fib2(120)
print(f100)
 
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

یہاں ہم نے دو تین تبدیلیاں کی ہیں سیریز والے فنکشن میں۔ ایک تو لسٹ result کے نام سے بنائی ہے ۔ اس کے بعد متغیر b کی قیمت ہر while لوپ کے پھیرے میں لسٹ میں اضافہ کرتے رہے ہیں۔
آخر میں پوری لسٹ واپس بھیج دی ہے فنکشن سے

اب فنکشن کال کرتے وقت ایک اور متغیر میں جو کہ ایک لسٹ بن جائے گی اس میں واپس آنے والی لسٹ کو محفوظ کریں گے ۔

اس کے بعد اسے پرنٹ فنکشن میں پاس کرکے پرنٹ کروا لیں یا ویسے ہی۔

PHP:
>>> f100
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
 
Default Argument Values
دلائل (arguments) ایسا ڈیٹا ہوتا ہے جو ہم کسی بھی فنکشن کو مہیا کرتے ہیں جس کی مدد سے وہ کوئی کام یا فیصلہ لیتا ہے جیسا کہ عام گفتگو میں دلائل کی بنیاد پر فیصلہ سازی یا کسی نتیجہ پر پہنچا جاتا ہے۔ اگر کسی فنکشن میں ہم چاہیں کہ کچھ دلائل اختیاری (optional) ہوں اور اگر صارف وہ دلیل (argument) نہ دینا چاہے یا چھوڑنا چاہے تو ایسی صورت میں ہم ڈیفالٹ ویلیو استعمال کرتے ہیں کسی بھی دلیل (argument) کی جو نہ دی گئی ہو۔

ایک فنکشن لکھتے ہیں جس میں دو دلائل (arguments) ہوں گے اور ایک ان میں سے ڈیفالٹ ویلیو استعمال کرے گا۔

PHP:
cost1 = 15
cost2 = 20
 
def sumCart(item1, item2 = 5):
  totalCost = item1 + item2
  print (totalCost)
 
sumCart(cost1)
20
sumCart(cost1, cost2)
35

اس فنکشن میں دو دلائل (arguments) دیے گئے ہیں جن میں سے دوسرے کی ایک ڈیفالٹ ویلیو بھی مقرر کر دی گئی ہے۔ پھر ان دونوں کو جمع کرکے ان کا جواب پرنٹ کر لیا جاتا ہے۔
جب ہم نے پہلی دفعہ فنکشن کو کال کیا اور صرف ایک دلیل (argument) ہی بھیجی تو فنکشن کے اندر دوسری دلیل (argument) کی ڈیفالٹ استعمال کرتے ہوئے اسے جمع کیا اور جواب پرنٹ کیا۔

کوڈ:
sumCart(cost1)
 
# cost1 = 15 and default value of other argument = 5
# totalCost = 15 + 5
 
20

فنکشن کی دوسری کال میں ہم نے دونوں دلائل دیے اور یوں ڈیفالٹ کی جگہ بھیجے جانے والے دلائل (arguments) استعمال ہوئے اور جواب ہمارے بھیجے گئے دلائل (arguments) پر مشتمل تھا۔

کوڈ:
sumCart(cost1, cost2)
 
# cost1 = 15  , cost2 = 20
#totalCost = cost1 + cost2
#totalCost = 15 +20
 
35

اس فنکشن میں ہم نے یہ بھی دیکھا کہ پیرامیٹر (parameter) کا نام فنکشن کے اندر اور اسے بھیجے جانے کے دوران مختلف ہو سکتا ہے۔
پیرامیٹر (parameter) اور دلیل (argument) کو ایک دوسرے کی جگہ استعمال کیا جا سکتا ہے۔
 
Keyword Arguments
اگر کسی فنکشن میں بہت سارے دلائل (arguments) ہوں اور آپ صرف چند دلائل (arguments) ہی دینا چاہیں تو ایسی صورت میں ان دلائل (arguments) کو نام دے دیا جاتا ہے جو کہ کہلاتا ہے کلیدی لفظ دلائل (keyword arugments) ۔

اس کے فوائد یہ ہوتے ہیں کہ ہمیں دلائل (arguments) کی ترتیب کا خیال رکھنے کی ضرورت نہیں پڑتی اور اگر ڈیفالٹ ویلیو استعمال ہو رہی ہے چند دلائل (arguments) کی تو ہمیں صرف ان دلائل (arguments) دینے کی ضرورت ہوگی جو کہ ڈیفالٹ ویلیو نہیں رکھتے ۔

PHP:
def printinfo( name, age ):
  "This prints a passed info into this function"
  print ("Name: ", name)
  print ("Age ", age)
 
 
# Now you can call printinfo function with keyword arguments in any order
printinfo( age=40, name="Sabir" )
 
Name:  Sabir
Age  40
 
printinfo (name = "Ahmad", age = 25)
 
Name:  Ahmad
Age  25
 
Variable Length Arguments
اگر کسی فنکشن میں دلائل (arguments) کی تعداد متعین نہ ہو یا آپ تعداد کو بدلنا چاہتے ہو تو ایسا فنکشن بھی ممکن ہے اور اسے Variable length argument فنکشن کہتے ہیں۔

PHP:
def printinfo( arg1, *vartuple ):
  "This prints a variable passed arguments"
  numOfArgs = len(vartuple)
  print ("Output is: ",arg1)
 
  if numOfArgs == 0:
      pass
  else:
      print ("Variable Output as follows: ")
 
  for var in vartuple:
      print(var)
  return
 
# Now you can call printinfo function
printinfo( 10 )
Output is: 10
 
printinfo( 70, 60, 50 )
Output is:  70
Variable Output as follows: 
60
50
 
 
printinfo(1, 120, 300,40, 60, 66)
Output is:  1
Variable Output as follows: 
120
300
40
60
66
 
اگر ہم متعدد پیرامیٹر (parameter)مکانی دلائل ( position arguments) اور کلیدی لفظ دلائل ( keyword arguments) کے استعمال کرنا چاہ رہے ہیں اور ان کی تعداد کا ہمیں پہلے سے علم نہیں ہے یا وہ تبدیل ہو سکتی ہے تو ایک ہی فنکشن میں دونوں کام ہو سکتے ہیں۔

PHP:
def total(initial=5, *numbers, **keywords):
    count = initial
    for number in numbers:
        count += number
    for key in keywords:
        count += keywords[key]
        print(key,":" ,keywords[key])
    return count
 
print(total(10, 1, 2, 3, vegetables=50, fruits=100, seafood=30))
 
vegetables : 50
seafood : 30
fruits : 100
196
 
اس فنکشن میں پہلی پوزیشن پر لازمی دلیل (required argument) ہے جس کی ڈیفالٹ قیمت دی گئی ہے۔
initial = 5

اس کے بعد غیر متعین مکانی دلائل (variable positional arguments) دیے گئے ہیں جو کہ کسی بھی لازمی دلیل (required argument) کے بعد ہی شروع ہو سکتے ہیں ایک فنکشن کی تعریف میں۔ انہیں ظاہر کرنے کے لیے * کا استعمال کیا جاتا ہے۔
PHP:
def total(, *numbers, ):

اس کے بعد غیرمتعین کلیدی لفظ دلائل (variable keyword arguments) دیے گئے ہیں جو کہ غیر متعین مکانی دلائل (variable positional arguments) کے بعد آتے ہیں اور انہیں ظاہر کرنے کے لیے ** کا استعمال کیا جاتا ہے
PHP:
def total(, , **keywords):

تمام غیر متعین مکانی دلائل (variable positional arguments) ایک Tuple کی شکل میں بھیجے جاتے ہیں۔
غیرمتعین کلیدی لفظ دلائل (variable keyword arguments) ایک dictionary کی شکل میں بھیجے جاتے ہیں جس میں الفاظ اور ان کے معنی ہوتے ہیں یعنی ایک پیرامیٹر (parameter) نام اور قیمت کے ساتھ۔

Tuple اور dictionary پر ہم آگے چل کر تفصیل سے پڑھیں گے ۔
 
Doc String
اگر کسی فنکشن کی پہلی لائن ٹرپل کوٹس (triple quotes) میں ہو تو وہ لائن فنکشن کے کام کے بارے میں بتانے کے لیے ایک تبصرے کے طور پر شامل کی ہوتی ہے اور اسے کسی بھی فنکشن کے دستاویز بنانے کے لیے استعمال کیا جاتا ہے۔


PHP:
def total(var1, var2):
    '''This functions sums up two values and prints them'''
    print("Total is ",var1+var2)
 
print(total.__doc__)
This functions sums up two values and prints them

فنکشن کی پہلی لائن ٹرپل کوٹس (triple quotes) میں فنکشن کے بارے تبصرہ ہے اور اسے حاصل کرنے کے لیے ہم نے فنکشن کے نام کے فوری بعد __doc__ استعمال کیا ہے۔

کوڈ:
total.__doc__

docstring یا Documentation String ایک لائن پر بھی مشتمل ہو سکتی ہے اور متعدد لائنوں پر بھی محیط ہو سکتی ہے۔
 
Local Variable
جب ہم کسی فنکشن میں کوئی متغیر (variable) بناتے ہیں تو وہ اسی فنکشن میں ہی کارآمد ہوتے ہیں اور کسی طور پر بھی فنکشن سے باہر کسی اور متغیر سے ان کا کوئی تعلق یا حوالہ نہیں ہوتا۔ ایسے متغیر (variable) اس فنکشن کے لیے مقامی (local) ہوتے ہیں نیز کسی بھی فنکشن کے اندر بنائے گئے متغیر کو ہم مقامی (local) کہیں گے۔

Global Variable
جب ہم کسی فنکشن سے باہر کوئی متغیر (variable) بناتے ہیں تو وہ آفاقی (global) ہوتا ہے۔

ایسے متغیر (variable) عموما پروگرام کے شروع میں بنائے جاتے ہیں یا کسی فنکشن سے پہلے بنا کر پھر بعد والے فنکشن میں انہیں استعمال کیا جا سکتا ہے۔ اگر ایک فنکشن میں ہم کوئی آفاقی متغیر (global variable) استعمال کرنا چاہیں تو اس کے لیے ہمیں پہلے فنکشن کے اندر بتانا پڑے گا کہ یہ متغیر آفاقی ہے اور پھر اگر ہم اسے استعمال کرنا چاہیں تو کر سکتے ہیں۔

PHP:
x = 50
 
def func(x):
    print('x is', x)
    x = 2
    print('Changed local x to', x)
 
func(x)
print('x is still', x)
 
 
x is 50
Changed local x to 2
x is still 50

اس مثال میں ہم نے فنکشن سے پہلے x نامی ایک متغیر بیان کیا جس کی قیمت 50 رکھی اور اسے پرنٹ کروایا۔ اس کے بعد ہم نے func کے اندر x کے نام سے ہی ایک اور متغیر بیان کیا جس کی قیمت 2 رکھا اور اسے پرنٹ کروایا۔

فنکشن کی کال پر پہلے آفاقی متغیر x کی قیمت 50 پرنٹ ہوئی۔
پھر مقامی متغیر x کی قیمت 2 پرنٹ ہوئی۔

اس کے بعد ہم نے func کی کال کے بعد دوبارہ ایک دفعہ پرنٹ فنکشن میں x کی قیمت پرنٹ کروائی تو وہ آفاقی متغیر کی قیمت پرنٹ ہوئی جو کہ 50 ہے۔

Scope
متغیر کی وسعت یا حد کو Scope کہتے ہیں۔ اس کا خیال رکھنا پڑتا ہے کیونکہ کوئی متغیر اپنی حد سے باہر کارآمد نہیں ہوگا اور ہم اسے استعمال نہیں کر سکیں گے بلکہ ایرر میسج آئے گا کہ متغیر اپنی حدود سے تجاوز کر چکا ہے یا متغیر کی تعریف نہیں کی گئی ہے۔
 

محمدصابر

محفلین
گلوبل کی مثال نہیں دی۔
PHP:
x = 50
 
def func():
 
    global x
 
    print('x is', x)
 
    x = 2
 
    print('Changed global x to', x)
 
func()
 
print('Value of x is', x)
 
x is 50
 
Changed global x to 2
 
Value of x is 2
 

دوست

محفلین
جب ایکس کی قدر 50 ہے تو گلوبل ہے۔ func() کے ساتھ کوئی بھی اور فنکشن لکھ لیں، ایکس وہاں بغیر ڈیفائن کیے استعمال ہو سکے گا۔ اس کی طےشدہ قدر 50 رہے گی، لیکن اسے تبدیل بھی کیا جا سکے گا۔ یہاں اصل میں لوکل اور گلوبل ہر دو قسم کے متغیر کی مثال دی گئی ہے۔ (جہاں تک میں سمجھ سکا ہوں، سی شارپ میں گلوبل متغیر سیٹ کرنے کا طریقہ بھی کم و بیش یہی ہے۔ کلاس کے آغاز میں متغیر ڈیفائن کرنے سے وہ ہر فنکشن میں قابل رسائی رہتا ہے۔ البتہ ساتھ public static کے الفاظ لگانے پڑتے ہیں)
 

محمدصابر

محفلین
جب ایکس کی قدر 50 ہے تو گلوبل ہے۔ func() کے ساتھ کوئی بھی اور فنکشن لکھ لیں، ایکس وہاں بغیر ڈیفائن کیے استعمال ہو سکے گا۔ اس کی طےشدہ قدر 50 رہے گی، لیکن اسے تبدیل بھی کیا جا سکے گا۔ یہاں اصل میں لوکل اور گلوبل ہر دو قسم کے متغیر کی مثال دی گئی ہے۔ (جہاں تک میں سمجھ سکا ہوں، سی شارپ میں گلوبل متغیر سیٹ کرنے کا طریقہ بھی کم و بیش یہی ہے۔ کلاس کے آغاز میں متغیر ڈیفائن کرنے سے وہ ہر فنکشن میں قابل رسائی رہتا ہے۔ البتہ ساتھ public static کے الفاظ لگانے پڑتے ہیں)
نہیں شاکر بھائی پائیتھون میں اگر آپ گلوبل کی ورڈ استعمال نہیں کرتے تو وہ اس فنکشن میں لوکل ویری ابیل بنا کر اس کو علیحدہ سے استعمال کرنا شروع کر دیتا ہے۔جیسا اُوپر محب کی مثال میں دیکھا جا سکتا ہے۔
دراصل میں جو سمجھا ہوں وہ یہ ہے کہ گلوبل لکھنے سے پائیتھون اسی نام کے ساتھ اس باہر والے ویری ایبل تک ایک پوائنٹر بطور لوکل بنا دیتا ہے۔ یہ طریقہ سی شارپ سے فرق ہے۔
ابھی تو نان لوکل کا کی ورڈ بھی آ رہا ہے۔ :)
 
نہیں شاکر بھائی پائیتھون میں اگر آپ گلوبل کی ورڈ استعمال نہیں کرتے تو وہ اس فنکشن میں لوکل ویری ابیل بنا کر اس کو علیحدہ سے استعمال کرنا شروع کر دیتا ہے۔جیسا اُوپر محب کی مثال میں دیکھا جا سکتا ہے۔
دراصل میں جو سمجھا ہوں وہ یہ ہے کہ گلوبل لکھنے سے پائیتھون اسی نام کے ساتھ اس باہر والے ویری ایبل تک ایک پوائنٹر بطور لوکل بنا دیتا ہے۔ یہ طریقہ سی شارپ سے فرق ہے۔
ابھی تو نان لوکل کا کی ورڈ بھی آ رہا ہے۔ :)

گلوبل متغیر اگر فنکشن سے پہلے بنایا گیا ہے تو وہ فنکشن کے اندر استعمال نہیں ہوگا تاوقتیکہ گلوبل کا مختص لفظ لکھ کر دوبارہ سے اسے فنکشن میں قابل استعمال نہ بنا لیا جائے۔ جیسا کہ اوپر والی مثال میں متغیر x پہلے آفاقی (globally) طور پر بیان کیا گیا ہے اور میں گلوبل کا لفظ شامل نہیں کیا گیا۔ اس کے بعد اسی متغیر کو فنکشن میں قابل استعمال بنانے کے لیے گلوبل کا لفظ لگایا گیا ہے۔

یہ باقی زبانوں سے مختلف ہے۔
وضاحت کے لیے شکریہ محمدصابر
 
Non Local Variable
آفاقی(global) اور مقامی (local) متغیر(variable) کے درمیان ایک اور متغیر بھی ہوتا ہے جو نہ تو آفاقی ہوتا ہے اور نہ مقامی بلکہ بین بین حد(scope) ہوتی ہے ایسے متغیر(variable) کی ۔

غیر مقامی (non local) متغیر (variable) تب استعمال ہوتے ہیں جب ایک فنکشن کے اندر ایک اور فنکشن کی تعریف کی جائے ۔ ایسے میں بیرونی فنکشن میں بیان کردہ متغیر کو اگر اندرونی فنکشن میں استعمال کرنا ہو تو اسے non local کے کلیدی لفظ (keyword) کے ساتھ لکھتے ہیں اور پھر استعمال کیا جا سکتا ہے۔

PHP:
def func_outer():
    x = 2
    print('x is', x)
 
    def func_inner():
        nonlocal x
        x = 5
 
    func_inner()
    print('Changed local x to', x)
 
func_outer()
 
x is 2
Changed local x to 5
 

محمداحمد

لائبریرین
Recursive Functions
تکراری یا دہرائے جانے والے فنکشن

پائتھون کے کسی بھی فنکشن میں ہم دوسرے فنکشن کو کال کر سکتے ہیں، اسی طرح ایک فنکشن خود اپنے آپ کو (یعنی اسی فنکشن کو) بھی کال کر سکتا ہے۔ ایسے فنکشن اپنی ہی تکرار کرتے ہیں اور اس طرح آرگیومینٹس (Arguments) کی معمولی تبدیلی سے کوڈ کو آسان اور موثر بنایا جا سکتا ہے۔ بظاہر recursive functions کی افادیت کا اندازہ نہیں ہوتا لیکن پروگرامنگ میں کہیں کہیں یہ آپ کے کام کو بہت آسان کر دیتے ہیں۔

PHP:
def countdown(n):
    if n <= 0:
        print ('Blastoff!')
        return
    else:
        print (n)
    countdown(n-1)
 
countdown(3)

اس مثال میں count down چلانے کے لئے فنکشن کے پیرامیٹر میں کاؤنٹ ڈاؤن شروع کرنے والا عدد بطور آرگیومینٹ Argument لیا گیا ہے اور فنکشن باڈی میں if function استعمال کیا گیا ہے جو دی گئی شرط کی تصدیق اور نتائج کی بنیاد پر عمل کرتا ہے۔ فنکشن کے آخر میں پھر اسی فنکشن کو کال کرلیا گیا ہے اور اب کی دفعہ پیرامیٹر میں n کے بجائے n - 1 دیا گیا ہے۔ ہر بار فنکشن کال ہونے پر n کی قدر کو پرنٹ کروایا گیا ہے اور ہر بار دئیے گئے عدد سے 1 کو منہا کرکے اسے 0 تک لایا گیا ہے ۔ جیسے ہی شرط پوری ہوتی ہے یعنی n کی قدر 0 ہو جاتی ہے تو Blast Off کے الفاظ پرنٹ کروائے گئے ہیں۔

اس فنکشن کا نتیجہ کچھ یوں ہوگا:

3
2
1
Blastoff!

Recursive Functions کہیں کہیں بہت کارامد ثابت ہوتے ہیں۔
 

محمداحمد

لائبریرین
بہت عمدہ طریقے سے سمجھایا ہے محمد احمد

بہت شکریہ بھیا۔۔۔! میں تو ڈر رہا تھا کہ کہیں کچھ اُلٹا سیدھا نہ لکھ دوں کیونکہ اردو میں اس طرح کی تکنیکی تحریر / وضاحت لکھنے کا کبھی اتفاق نہیں ہوا۔ پھر آپ اردو کی اتنی کامل اصطلاحات استعمال کرتے ہیں کہ آپ پر 'اردو وکی' کا گمان ہوتا ہے۔ :) تاہم میں نے سلسلے کو آگے بڑھانے کی خاطر جو سمجھ آیا لکھ دیا۔
 
بہت شکریہ بھیا۔۔۔ ! میں تو ڈر رہا تھا کہ کہیں کچھ اُلٹا سیدھا نہ لکھ دوں کیونکہ اردو میں اس طرح کی تکنیکی تحریر / وضاحت لکھنے کا کبھی اتفاق نہیں ہوا۔ پھر آپ اردو کی اتنی کامل اصطلاحات استعمال کرتے ہیں کہ آپ پر 'اردو وکی' کا گمان ہوتا ہے۔ :) تاہم میں نے سلسلے کو آگے بڑھانے کی خاطر جو سمجھ آیا لکھ دیا۔

ہاہاہاہا ۔ کیسی باتیں کرتے ہیں آپ نے بھی بالکل ویسے ہی لکھا ہے اور اب تو ڈر نکل گیا نہ :)

بہت اچھا اور صحیح کیا اور آئندہ بھی ایسے ہی کرنا ہے۔
 
Top