2

For reference I am referring to the answer in this post

The author of the answer gives the following code

def sum(*values, **options):
    s = 0
    for i in values:
        s = s + i
    if "neg" in options:
        if neg:
            s = -s
    return s

s = sum(1, 2, 3, 4, 5)            # returns 15
s = sum(1, 2, 3, 4, 5, neg=True)  # returns -15
s = sum(1, 2, 3, 4, 5, neg=False) # returns 15

However when I run on mine I get the following error

NameError: global name 'neg' is not defined

Can anyone explain this. And in general, how does the function know when values ends and when options begins

Community
  • 1
  • 1
sedavidw
  • 11,116
  • 13
  • 61
  • 95

2 Answers2

4
if neg:

That line is buggy. It should be:

if options["neg"]:

How does the function know when values ends and when options begins?

Unnamed values go in *values. Keyword arguments go in **options.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
4

You have made a small mistake. Change your code to the following and it should work. Just get the value of "neg" from the options dictionary, (values holds the unnamed arguments and options holds the keyword arguments)

>>> def sum(*values, **options):
        s = 0
        for i in values:
            s = s + i
        if "neg" in options:
            if options["neg"]:
                s = -s
        return s

>>> s = sum(1, 2, 3, 4, 5, neg=True)
>>> s
-15
>>> sum(1, 2, 3, 4, 5)
15
>>> sum(1, 2, 3, 4, 5, neg=True)
-15
>>> sum(1, 2, 3, 4, 5, neg=False)
15

Although, as @glglgl pointed out, changing your code to the following consumes both the if statements into one.

>>> def sum(*values, **options):
    s = 0
    for i in values:
        s = s + i
    if options.get("neg", False):
            s = -s
    return s

How does get(...) work?

If the options dictionary doesn't have a key "neg", (as handled by your first if condition), then, get(...) returns the default value of False and s is not negated, and if options contains "neg", then it's value is returned, in which case, s is negated depending on the value in the dictionary.

Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71