{{announcement.body}}
{{announcement.title}}

Optional Arguments MUST Use Keywords (Python3)

DZone 's Guide to

Optional Arguments MUST Use Keywords (Python3)

In this article, we discuss the importance of optional arguments and walk through a tutorial on how and when to use them in Python.

· Web Dev Zone ·
Free Resource


Imagine that you are developing software for a big shipping company (why would you imagine a small one anyway), and you got a task to create a function for calculating a charge for ships based on their cargo weight. Easy breezy:

WEIGHT_RATES = [
    ( 10, 10.55),
    (  5, 5.05),
    (  2, 3.35),
    (  0, 1.25)
]

def shipping_charge(weight):
    if weight < 0:
        raise ValueError("Can't calculate shipping charge of negative weights")
    for min_weight, rate in WEIGHT_RATES:
        if weight > min_weight:
            return weight * rate


Simple enough.

But then, one day, your program eventually is going to work in another country, say the USA. One problem arises: we need to use pounds instead of kilograms for charging. No problem, here you are:

def shipping_charge(weight, pnds):
    if pnds:
       weight /= 2.2
    if weight < 0:
       raise ValueError("Can't calculate shipping charge of negative weights")
    for min_weight, rate in WEIGHT_RATES:
        if weight > min_weight:
            return weight * rate


This is getting complicated, but then one more requirement — you need to raise an exception if weight exceeds 1,000 kilograms for specific directions:

def shipping_charge(weight, pnds, exceed):
    if pnds:
       weight /= 2.2
    if exceed and weight > 1000:
       raise Exception("Weight can't exceed 1000 kg")
    if weight < 0:
       raise ValueError("Can't calculate shipping charge of negative weights")
    for min_weight, rate in WEIGHT_RATES:
        if weight > min_weight:
            return weight * rate


You may also like: 10 Reasons to Learn Python in 2019.

Do you see the problem? In this example, you came up to function with three positional arguments, two of them with the same type. The end-user, or you as a developer, can easily forget which one needs to come first and can mess them up. Due to the same type, the program will not fail, and you will get a logic error:

shipping_charge(2000, True, False)


or

shipping_charge(2000, False, True)


You can add keyword arguments with default values. This is good practice:

def shipping_charge(weight, pnds=False, exceed=False):
    if pnds:
       weight /= 2.2
    if exceed and weight > 1000:
       raise Exception("Weight can't exceed 1000 kg")
    if weight < 0:
       raise ValueError("Can't calculate shipping charge of negative weights")
    for min_weight, rate in WEIGHT_RATES:
        if weight > min_weight:
            return weight * rate


But, the problem is not solved. To resolve this issue, you need to add one star in the argument list:

def shipping_charge(weight, *, pnds=False, exceed=False):
    if pnds:
       weight /= 2.2
    if exceed and weight > 1000:
       raise Exception("Weight can't exceed 1000 kg")
    if weight < 0:
       raise ValueError("Can't calculate shipping charge of negative weights")
    for min_weight, rate in WEIGHT_RATES:
        if weight > min_weight:
            return weight * rate


That’s it, the next time you call this function, you will get an error:

>>>shipping_charge(2000, True, False)
TypeError: shipping_charge() takes 1 positional argument but 3 were given


More info: PEP-3102.


Thank you for reading!

Any questions? Leave your comment below to start fantastic discussions!

Check out my blog or come to say hi on Twitter or subscribe to my telegram channel.

Plan your best!


Further Reading

Topics:
python ,arguments ,python3 ,web dev ,keyword ,ARGS

Published at DZone with permission of luminousmen _ . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}