How can I most easily sum the 2 sums with a function?

def bill(fun, value):

    tot = fun(value)
    print(tot)

def add_dds(tot):

    tip = tot * .2
    new_total = tot + tip
    return new_total

bill(add_dds, 100)
bill(add_dds, 150)

It really isn’t even clear what you are asking, I’m afraid!

sum(bill(add_dds, i) for i in (100, 150)) would be the right sort of thing, except that bill() doesn’t return a value…

1 Like

Isin’t it unnecessarily complicated? If the only need is to calculate from bill amount total payment then why two functions (is dds tip or VAT?)?

def total_payment(bill, tip=20):
    return bill + (bill/100*tip)


print(total_payment(100))
print(total_payment(100, tip=30))
1 Like

I would like every time I have a new value to sum them all. I hope you understand now. ( ```
bill(add_dds, 150)

The idea is as follows:

def bill(fun, value):

    tot = fun(value)
    print(tot)

def add_dds(tot):

    tip = tot * .2
    new_total = tot + tip
    return new_total

"""
print here => Daily Total: 420

if we get another order: bill(add_dds, 50) => Daily Total: 540
"""

# Order 1
bill(add_dds, 100)

# Order 2
bill(add_dds, 150)

# Order 3
bill(add_dds, 100)

I assume you want to keep track of and return the running total, when doing multiple calls to add_dds?
If so, then in add_dds the new_total needs to be a global variable, and you need to add tot + tip to that new_total:

new_total = 0

def add_dds(tot, reset=False):
    global new_total
    if reset:
        new_total = 0
    new_total += 1.2 * tot
    return new_total

If you want to avoid global variables, there is also a funky way to do this like this (funky because normally it’s not good to use lists as default arguments, but here it’s done deliberately):

def add_dds(tot, total=[0], reset=False):
    if reset:
        total[0] = 0
    total[0] += 1.2 * tot
    return total[0]

For both you get

>>> add_dds(100)
120.0
>>> add_dds(150)
300.0
>>> add_dds(100, reset=True)
120.0
4 Likes

Great! And is it possible for each call to have the output be:

add_dds(100)
120.0
add_dds(150)
180.0             => not here to be the final price 300!
------------
Totals: 300.0

Yes, you could for instance add another argument to the add_dds function to return either the current addition or the running total. For instance,

def add_dds(tot=0, total=[0], reset=False, show_totals=False):
     if reset:
        # print("Start new bill")
        total[0] = 0  
     dds = 1.2 * tot
     total[0] += dds
     if show_totals:
         return total[0]   # or print("Added ", total[0]) if you just want to print
     else:
         return dds  # or print("Totals: ", dds)

The you get

>>> add_dds(100)
120.0
>>> add_dds(150)
180.0
>>> add_dds(show_totals=True)
300.0
>>> add_dds(200)
240.0
>>> add_dds(show_totals=True)
540.0

If you use the earlier function with a global variable to keep track of the running total, you can modify it in a similar way. One thing to notice about the implementation here is that it is not intended to be called as (for instance) add_dds(100, total=[300]). Calling like that will not reset the original total to a different value; the only way to do so is to call it as add_dds(reset=True).

1 Like

I feel like an idiot :slight_smile: (I’m a beginner though and learning now)
but it doesn’t work as expected for me. I’m definitely missing something.

def bill(fun, value):

    tot = fun(value)
    print(tot)

#def add_dds(tot):

#    tip = tot * .2
#    new_total = tot + tip
#    return new_total

def add_dds(tot=0, total=[0], reset=False, show_totals=False):
    if reset:
        # print("Start new bill")
        total[0] = 0
    dds = 1.2 * tot
    total[0] += dds
    if show_totals:
        return total[0]  # or print("Added ", total[0]) if you just want to print
    else:
        return dds  # or print("Totals: ", dds)

bill(add_dds, 100)
bill(add_dds, 100)
bill(add_dds, 150)

#bill(add_dds(show_totals=True))

Your code works as expected up to the last line – which you commented out – right?

bill(add_dds(show_totals=True))

cannot work because of the way bill is defined (it takes a function and a value as arguments, while
here it is only given some value).
Also

bill(add_dds, show_totals=True)

would not work, since show_totals is not a keyword argument of bill.
One way to make things work is to kill bill and replace him by print:

bill = print
...
bill(add_dds(100))
bill(add_dds(100))
bill(add_dds(150))
bill(add_dds(show_totals=True)

# or better go one step further, nuke 'bill' and just write `print` 

If you insert the print statements into the add_dds function itself, you also don’t need bill anymore.
But if for some reason you want to keep bill similar to what you had, then you need to modify it so that it also can take keyword arguments (like “show_totals”).

2 Likes

Now it works, thank you very much!