Functions

INPUT · Slides

Deciding what to make a function

01 / 06

Lay out the tools you have

Lay out what this chapter gave you.

  • def … give a chunk of work a name
  • arguments … hand a value from outside to inside
  • return … hand a value from inside to outside
  • scope … a name made inside belongs inside
  • keyword arguments and defaults … pass by name, settle what to use when nothing is passed

That is all the grammar. From here it is about how you use it. Two pieces of code with the same output can read completely differently depending on where the parts are cut.

02 / 06

When the same code turns up twice

The clearest signal of all, when you cannot decide whether to make something a function: the moment you write a similar piece of work for the second time.

Two copies means fixing both when something changes. Fix one and forget the other — that is the thickest source of bugs there is.

The code below works out a price with tax twice. Change the rate and you are editing two places.

print(int(1000 * 1.1))print(int(2500 * 1.1))

Result

1100
2750

03 / 06

Bring it into one place

Make it a function and there is one place to fix. The tax rate is known only inside the function now, so the caller can forget about it.

There are other signals besides "I wrote that twice". Wanting to explain it with a comment is one. If you find yourself about to write "this bit works out the price with tax", make that bit a function and let the name do the explaining.

def with_tax(price):    return int(price * 1.1)print(with_tax(1000))print(with_tax(2500))

Result

1100
2750

04 / 06

A good name says what it does

Name a function so that you can tell what happens without looking inside.

  • poor … f, proc, data, calc2
  • good … with_tax, judge, total_up, join_words

A good name is one you can say as a verb. When a name will not come, it is usually because the function is doing two jobs or more. Stuck for a name? See whether it splits.

Python's habit is small letters and underscores. Not calculateWithTax but calculate_with_tax.

05 / 06

One function, one job

The common mistake is cramming the working out and the showing into a single function.

print the result inside and the value never comes out. Want a total later, or a different order? Too late — there is nothing to use.

A function that works something out returns it. The showing happens at the call. Keep to that alone and your parts stay reusable.

def subtotal(unit_price, count):    return unit_price * counttotal = subtotal(160, 2) + subtotal(220, 1)print(f"total ${total}")

Result

total $540

06 / 06

Build up from small parts

When you write something big, start with small functions and build the ones that call them on top. Do not try to write the whole thing as one function.

Below, subtotal works out an amount and line uses it to build one line of text. Each is short, and each can be checked on its own.

So: ten questions. They grow as you go, and the last is a small program made of several functions together.

def subtotal(unit_price, count):    return unit_price * countdef line(name, unit_price, count):    return f"{name} x{count} ${subtotal(unit_price, count)}"print(line("bread", 160, 2))

Result

bread x2 $320