How to pass an optional namedtuple parameter in a function
__author__ = 'mayukhsarkar'
import collections
def search_student(database=None, ID=None):
flag = False
try:
if ID is None or ID == 0:
raise TypeError
for each in database:
if each.id == ID:
print 'Student Name: ', each.name
flag = True
except TypeError:
print 'Provide the arguments properly'
finally:
return flag
studentDatabase = collections.namedtuple("student", "id name roll_no phone email")
DATABASE = [studentDatabase(1, 'Mayukh Sarkar', 9, '555-2312', 'mayukh2012@hotmail,com'),
studentDatabase(2, 'Alisha Sengupta', 7, '555-1345', 'alisha@gmail.com')]
if not search_student(DATABASE, 1):
print "Data not found"
In this snippet, I want an argument variable parameter in a function search_student
so that if I pass roll_no
, email
then if a student of that ID is found, only the roll and email will be printed along with the name. But if I pass no arguments, only the name is printed
source to share
Use boolean values ββto set a flag for movie and email printing:
def search_student(database=None, ID=None, roll=False, email=False):
if ID is None or ID == 0:
print 'Provide the arguments properly'
return False
for each in database:
if each.id == ID:
print 'Student Name: {}'.format(each.name)
if roll:
print 'Stutent Roll: {}'.format(each.roll_no)
if email:
print("Student email: {}".format(each.email))
break
else:
return "User does not exist in database"
studentDatabase = collections.namedtuple("student", "id name roll_no phone email")
DATABASE = [studentDatabase(1, 'Mayukh Sarkar', 9, '555-2312', 'mayukh2012@hotmail,com'),
studentDatabase(2, 'Alisha Sengupta', 7, '555-1345', 'alisha@gmail.com')]
Output:
In [9]: search_student(DATABASE, 1, email=True,roll=True)
Student Name: Mayukh Sarkar
Stutent Roll: 9
Student email: mayukh2012@hotmail,com
In [10]: search_student(DATABASE, 1,roll=True)
Student Name: Mayukh Sarkar
Stutent Roll: 9
In [11]: search_student(DATABASE, 1, email=True)
Student Name: Mayukh Sarkar
Student email: mayukh2012@hotmail,com
In [12]: search_student(DATABASE, 1)
Student Name: Mayukh Sarkar
In [13]: search_student(DATABASE, 5)
Out[13]: 'User does not exist in database'
I would also store users in a dict using id as key:
def search_student(database=None, ID=None, roll=False, email=False):
if ID is None or ID == 0:
print 'Provide the arguments properly'
return False
get = database.get(ID)
if get is not None:
print 'Student Name: {}'.format(get.name)
if roll:
print 'Student Roll: {}'.format(get.roll_no)
if email:
print("Student email: {}".format(get.email))
else:
return "User does not exist in database"
Then pass the dict as a database:
studentDatabase = collections.namedtuple("student", "id name roll_no phone email")
DATABASE = {1: studentDatabase(1, 'Mayukh Sarkar', 9, '555-2312', 'mayukh2012@hotmail,com'),
2: studentDatabase(2, 'Alisha Sengupta', 7, '555-1345', 'alisha@gmail.com')}
The conclusion is the same:
In [18]: search_student(DATABASE, 1, email=True,roll=True)Student Name: Mayukh Sarkar
Student Roll: 9
Student email: mayukh2012@hotmail,com
In [19]: search_student(DATABASE, 1,roll=True)
Student Name: Mayukh Sarkar
Student Roll: 9
In [20]: search_student(DATABASE, 1, email=True)
Student Name: Mayukh Sarkar
Student email: mayukh2012@hotmail,com
In [21]: search_student(DATABASE, 1)
Student Name: Mayukh Sarkar
In [22]: search_student(DATABASE, 5)
Out[22]: 'User does not exist in database'
You might be better off using a dict for all your logic, but getattr will work with ** kwargs:
import collections
def search_student(database=None, ID=None, **kwargs):
if ID is None or ID == 0:
print 'Provide the arguments properly'
return False
get = database.get(ID)
if get is not None:
print 'Student Name: {}'.format(get.name)
for k in kwargs:
print("Student {}: {}".format(k, getattr(get,k)))
else:
return "User does not exist in database"
studentDatabase = collections.namedtuple("student", "id name roll_no phone email")
DATABASE = {1: studentDatabase(1, 'Mayukh Sarkar', 9, '555-2312', 'mayukh2012@hotmail,com'),
2: studentDatabase(2, 'Alisha Sengupta', 7, '555-1345', 'alisha@gmail.com')}
search_student(DATABASE,1,roll_no=True,email=True)
We need to catch when the user enters an invalid keyword / attribute, there are many ways to handle it, but an easy way is to catch the attribute error:
try:
print("Student {}: {}".format(k, getattr(get, k)))
except AttributeError:
print("Informative message or whatever is suitable")
Or use hasattr and do whatever you want if it returns False:
if get is not None:
print 'Student Name: {}'.format(get.name)
for k in kwargs:
if not hasattr(get,k):
continue
print("Student {}: {}".format(k, getattr(get, k)))
Or pass a default value to getattr:
if get is not None:
print 'Student Name: {}'.format(get.name)
for k in kwargs:
val = getattr(get, k,False)
if val:
print("Student {}: {}".format(k, val))
else:....
source to share
You can use the notation **
to pass a variable number of named arguments to your function.
If an argument **args
then it will be a dictionary of any named arguments that are not yet defined in the function definition, then you can check if roll_no
or is present email
in args
, if so do your logic.
Examples of codes -
>>> def func(**args):
... print(args)
... if 'abc' in args:
... print(args['abc'])
...
>>> func(hello=10)
{'hello': 10}
>>> func(hello=10,abc="Student")
{'hello': 10, 'abc': 'Student'}
Student
>>> def search_student(database=None, ID=None, **args):
... if 'roll_no' in args:
... print(args['roll_no'])
...
>>> search_student(roll_no=10)
10
source to share
so this is not an answer but a post because @Rob asked for more clarification
so if the function exists, say func(database=None, ID=None, [optionals])
so when you call the func(DATABASE, 1, roll_no, email)
name of the person whose id is 1 and his / her email and roll will also be printed
but if I go through func(DATABASE, 1, roll_no, email, phone)
it will print a letter with the roll number and phone number, but if I just give the database and ID and also no options then only the name should be printed. If no entry is found with this id, then it shouldn't print anything
source to share