1 of 38

Lecture 15

�Advanced Argument Passing

2 of 38

Advanced Argument passing

3 of 38

Argument passing. Keyworded Arguments

When defining a function, you can specify only what you need

4 of 38

Argument passing. Keyworded Arguments

When defining a function, you can specify only what you need

You want to write a function that reports news about DSC20 class for each lecture. The report should include:

  1. Name of the lecturer
  2. Date
  3. Day of the week
  4. Topic

5 of 38

Argument passing. Keyworded Arguments

You want to write a function that reports news about DSC20 class for each lecture. The report should include:

  1. Name of the lecturer
  2. Date
  3. Day of the week
  4. Topic

def report(name, date, day, topic):

print(“name is: ” + name)

print(“date is: ” + date)

print(“day is: ” + day)

print (“topic is: ” + topic)

6 of 38

Argument passing. Keyworded Arguments

You want to write a function that reports news about the DSC20 class for each lecture. The report should include:

  1. Name of the lecturer
  2. Date
  3. Day of the week
  4. Topic

def report(name, date, day, topic):

print(“name is: ” + name)

print(“date is: ” + date)

print(“day is: ” + day)

print (“topic is: ” + topic)

>>> report(“Marina”, “Feb 12”, “Mon”, “args”)

name is: Marina

date is: Feb 12

day is: Mon

topic is: args

7 of 38

Argument passing. Keyworded Arguments

You want to write a function that reports news about the DSC20 class for each lecture. The report should include:

  1. Name of the lecturer
  2. Date
  3. Day of the week
  4. Topic

def report(name, date, day, topic):

print(“name is: ” + name)

print(“date is: ” + date)

print(“day is: ” + day)

print (“topic is: ” + topic)

>>> report(“Marina”, “Feb 14”, “Wed”, “recur”)

name is: Marina

date is: Feb 14

day is: Wed

topic is: recur

8 of 38

Default arguments. Keyworded Arguments

def report(name = ”Marina”, date, day, topic):

print(“name is: ” + name)

print(“date is: ” + date)

print(“day is: ” + day)

print (“topic is: ” + topic)

9 of 38

Default arguments. Order Matters!

def report(name = ”Marina”, date, day, topic):

print(“name is: ” + name)

print(“date is: ” + date)

print(“day is: ” + day)

print (“topic is: ” + topic)

>>> report(“Feb 12”, “Mon”, “args”)

File "/Users/marinalanglois/Desktop/tt.py", line 2

def report(name = "Marina", date, day, topic):

SyntaxError: non-default argument follows default argument

10 of 38

Default arguments. Default => at the end

def report(date, day, topic, name = ”Marina”):

print(“name is: ” + name)

print(“date is: ” + date)

print(“day is: ” + day)

print (“topic is: ” + topic)

>>> report(“Feb 12”, “Mon”, “args”)

name is: Marina

date is: Feb 12

day is: Mon

topic is: args

11 of 38

Default arguments. Default => at the end

def report(date, day, topic, name = "Marina"):

print("name is: " + name)

print("date is: " + date)

print("day is: " + day)

print ("topic is: " + topic)

>>> report("Feb 12", "Mon", "args")

name is: Marina

date is: Feb 12

day is: Mon

topic is: args

Default values are assigned during the function definition. Demo.

12 of 38

Default arguments. Default => at the end

def report(date, day, topic, name = "Marina"):

print("name is: " + name)

print("date is: " + date)

print("day is: " + day)

print ("topic is: " + topic)

>>> report("Feb 14", "Wed", "Recur", "Ben")

name is: Ben

date is: Feb 14

day is: Wed

topic is: Recur

Default values are assigned during the function definition.

Then values are changed if passed something else. Demo.

13 of 38

Checkpoint question

def student(fname, lname ='Potter', house ='Gryffindor'):

print(fname, lname, 'studies in', house)

>>> student('Harry')

>>> student('Draco', 'Malfoy', 'Slytherin')

A: Draco Malfoy studies in Slytherin D: Error

Harry Potter studies in Gryffindor

B: Harry Potter studies in Gryffindor E: Something else

Draco Malfoy studies in Slytherin

C: Harry lname studies in house

Draco Malfoy studies in Slytherin

14 of 38

Checkpoint question

def student(fname, lname ='Potter', house ='Gryffindor'):

print(fname, lname, 'studies in', house)

>>> student("Draco", "Malfoy")

>>> student('Draco', 'Slytherin')

A: Draco Malfoy studies in Gryffindor D: Error

Draco Potter studies in Slytherin

B: Draco Potter studies in Malfoy E: Something else

Draco Potter studies in Slytherin

C: Draco Malfoy studies in Gryffindor

Draco Slytherin studies in Gryffindor

15 of 38

Specify what you need!

def student(fname, lname ='Potter', house ='Gryffindor'):

print(fname, lname, 'studies in', house)

>>> student("Draco", house = "Slytherin")

Draco Potter studies in Slytherin

16 of 38

Specify what you need!

def student(fname, lname ='Potter', house ='Gryffindor'):

print(fname, lname, 'studies in', house)

>>> student("Draco", house = "Slytherin")

Draco Potter studies in Slytherin

>>> student("Draco", house = "Slytherin", lname = "Malfoy")

Draco Malfoy studies in Slytherin

17 of 38

Specify what you need! But watch the order!

def student(fname, lname ='Potter', house ='Gryffindor'):

print(fname, lname, 'studies in', house)

>>> student(fname ='Draco', 'Slytherin')

File "<stdin>", line 1

SyntaxError: positional argument follows keyword argument

Having a positional argument after keyword arguments will result into errors. For example the function call as follows:

18 of 38

Python Arbitrary Arguments

19 of 38

Arbitrary number of arguments.

  • Sometimes, we do not know in advance the number of arguments that will be passed into a function.
  • We use an asterisk (*) before the parameter name to denote this kind of argument.

20 of 38

Arbitrary number of arguments.

  • Sometimes, we do not know in advance the number of arguments that will be passed into a function.
  • We use an asterisk (*) before the parameter name to denote this kind of argument.

def logins(*lnames):

"""This function creates logins to all

the people in given argument"""

#lnames is a tuple with arguments. DEMO

for name in lnames:

login = name[0] + name[::-1]

print(name + " login is: " + login)

21 of 38

Arbitrary number of arguments.

  • Sometimes, we do not know in advance the number of arguments that will be passed into a function.
  • We use an asterisk (*) before the parameter name to denote this kind of argument.
  • These arguments get wrapped up into a tuple before being passed into the function

def logins(*lnames):

"""This function creates logins to all

the people in given argument"""

# lnames is a tuple with arguments

for name in lnames:

login = name[0] + name[::-1]

print(name + " login is: " + login)

>>> logins("Marina","Ben","Bryce","Ella")

Marina login is: ManiraM

Ben login is: BneB

Bryce login is: BecyrB

Ella login is: EallE

22 of 38

Arbitrary number of arguments.

  • Sometimes, we do not know in advance the number of arguments that will be passed into a function.
  • We use an asterisk (*) before the parameter name to denote this kind of argument.
  • These arguments get wrapped up into a tuple before being passed into the function

def logins(*args):

"""This function creates logins to all

the people in given argument"""

# args is a tuple with arguments

for name in args:

login = name[0] + name[::-1]

print(name + " login is: " + login)

Often you will see *args being used.

Just a convention, idea is the same.

23 of 38

Example with *arg

def test_args(f_arg, *args):

print("first normal arg: ", f_arg)

for arg in args:

print("arg through *args :", arg)

>>> test_args('one','two','3','4')

first normal arg: one

arg through *args : two

arg through *args : 3

arg through *args : 4

24 of 38

**kwargs

25 of 38

** Kwargs

  • **kwargs allows you to write functions with arbitrary number of arguments with names (or keywords) associated with it.

  • The number of arguments is variable, because you don’t know ahead how many arguments will the function get.

26 of 38

Usage of **kwargs. Keyworded Arguments

def concatenate(**kwargs):

result = ""

# Iterating over the Python kwargs dictionary

for arg in kwargs.values():

result += arg

return result

>>> print(concatenate(a="Real", b="Python", c="Is", d="Great", e="!"))

RealPythonIsGreat!

27 of 38

Usage of **kwargs. Keyworded Arguments

def name(**kwargs):

if len(kwargs)>0:

for key, value in kwargs.items():

print((key + " -> " + value))

>>> name(marina = "Langlois")

marina -> Langlois

name(marina = "Langlois", donald = "Trump", donald = "Duck")

?

28 of 38

Order matters

If you choose to use and combine the special matching modes, Python has two ordering rules:

  • In the call, keyword arguments must appear after all non keyword arguments.

  • In a function header, the *args must be after normal arguments and defaults, and **kwargs must be last.

def func(regular arguments, *args, **kwargs)

29 of 38

Include all

def my_function(a, b=2, c=3, *args, **kwargs):

print("a:", a)

print("b:", b)

print("c:", c)

print("args:", args)

print("kwargs:", kwargs)

my_function(1)

a: 1

b: 2

c: 3

args: ()

kwargs: {}

30 of 38

def my_function(a, b=2, c=3, *args, **kwargs):

print("a:", a)

print("b:", b)

print("c:", c)

print("args:", args)

print("kwargs:", kwargs)

my_function(1, "demo", "q", kw = "args")

A B C D

a: 1

b: 2

c: 3

args: ("demo", "q")

kwargs: {'kw': 'args'}

a: 1

b: "demo"

c: "q"

args: ()

kwargs: {'kw': 'args'}

a: 1

b: "demo"

c: "q"

args: (kw', args')

kwargs: {}

Something else

31 of 38

Unpacking

32 of 38

Unpacking

def unpacking_example(a, b, c, d):

return a * b * c * d

input_list = [1,2,3,4]

unpacking_example(input_list)

33 of 38

Unpacking

def unpacking_example(a, b, c, d):

return a * b * c * d

input_list = [1,2,3,4]

unpacking_example(input_list)

TypeError: unpacking_example() missing 3 required positional arguments: 'b', 'c', and 'd'

34 of 38

Unpacking

def unpacking_example(a, b, c, d):

return a * b * c * d

input_list = [1,2,3,4]

unpacking_example(input_list)

TypeError: unpacking_example() missing 3 required positional arguments: 'b', 'c', and 'd'

def unpacking_example(a, b, c, d):

return a * b * c * d

input_list = [1,2,3,4]

unpacking_example(*input_list)

24

35 of 38

Unpacking

def unpacking_example(a, b, c, d):

return a * b * c * d

input_list = [1, 2, 3, 4, 5]

unpacking_example(*input_list)

TypeError: unpacking_example() takes 4 positional arguments but 5 were given

36 of 38

Unpacking

def unpacking_example(a, b, c, d):

return a * b * c * d

input_list = [1,2,3,4,5]

unpacking_example(*input_list)

TypeError: unpacking_example() takes 4 positional arguments but 5 were given

def unpacking_example(a, b, c, d):

return a * b * c * d

input_list = [1,2,3]

unpacking_example(*input_list)

TypeError: unpacking_example() missing 1 required positional argument: 'd'

37 of 38

set

38 of 38

Checkpoint practice:

Write a function that finds a union of an arbitrary number of sequences (1 or more), by using *args to collect all arguments passed.

Union: it collects items which appear in any of the lists:

>>> union([1,2,3])

[1, 2, 3]

>>> union([1,2,3], [3,4,5])

[1, 2, 3, 4, 5]

>>> union([1,2,3], [3,4,3])

[1, 2, 3, 4]

>>> union([1,2,3], [3,4,3], [6, 8, 10, 45])

[1, 2, 3, 4, 6, 8, 10, 45]

Done?��A: yes, continue