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

+3


source to share


3 answers


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:....

      

+2


source


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

      

0


source


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

0


source







All Articles