← Python

Python from zero · Part 3 of 6 · No experience needed

The full story · about 13 minutes

Python from zero, part 3: functions and reading errors

1 · Observe

You have already used functions

Words used in this lesson
WordWhat it means
FunctionA named recipe that takes inputs and gives back an answer. print and len are functions.
ArgumentA value you give a function when you use it: in len(prices), prices is the argument.
ReturnThe answer a function hands back to the line that used it.
MethodA function that belongs to a value, written with a dot: "pune".upper().
Error (exception)Python stopping because it could not do what a line asked. It prints the kind and a message.
TracebackThe report Python prints with an error: where it stopped and why.

Every time you wrote print(...) or len(...) you used a function: a recipe someone wrote once so everyone could reuse it. You can write your own. If you find yourself copying the same three lines with different numbers, that is a function waiting to be named.

2 · Express

def, return and the dot

def name(input1, input2):
steps using the inputs
return the_answer
def starts the recipe, the indented lines are the steps, and return hands back the answer.

Using the function is called calling it: write its name, then the inputs in brackets. The inputs you pass in are matched to the names in the def line, in order.

The functions you will use constantly
FunctionWhat it doesExampleGives
print(x)shows xprint(5)shows 5
len(x)how many itemslen([4, 8, 9])3
type(x)what kind of valuetype(2.5)float
round(x, n)round to n decimalsround(3.14159, 2)3.14
sum(list)adds the valuessum([1, 2, 3])6
min(list), max(list)smallest, largestmax([4, 8, 9])9
sorted(list)a sorted copysorted([3, 1, 2])[1, 2, 3]
int(x), float(x), str(x)convert typeint("42")42
abs(x)distance from zeroabs(-7)7

A method is a function that belongs to a value. You write the value, a dot, the method, and brackets: "pune".upper() gives "PUNE", and prices.append(80.0) adds a value to a list.

Check yourself

What is the difference between print(x) and return x?

3 · Visualize

What happens when you call a function

Tracing price_per_sqft(62.5, 1075)
StepWhat happensNames inside the function
1The inputs are matched in order to the names in the def lineprice_lakh → 62.5, area_sqft → 1075
2rupees = price_lakh * 100000rupees → 6250000.0
3return rupees / area_sqftAnswer 5813.95… is handed back
4The line that called the function receives itrate → 5813.95…

4 · Discover

Write one and call it

def: give a recipe a name
def price_per_sqft(price_lakh, area_sqft):     # the recipe: two inputs
    rupees = price_lakh * 100000
    return rupees / area_sqft                  # the answer it hands back

print(price_per_sqft(62.5, 1075))              # use the recipe
print(price_per_sqft(48.0, 900))               # use it again with new inputs
rate = price_per_sqft(55.5, 1000)              # store what it hands back
print(round(rate, 1))
5813.953488372093
5333.333333333333
5550.0
Edit and run this code in your browser

Live Python

def: give a recipe a name

Runs in your browser on your device. Nothing you type is sent anywhere, and nothing here changes your saved progress.

Press Ctrl+Enter (⌘+Enter on Mac) to run. Tab moves focus to the next control, as usual; use spaces to indent.

The first call prints 5813.953488372093, because Python shows a float with all its digits. Use round() when you only want a few. Now the difference between showing and handing back.

print shows, return hands back
def shows_it(x):
    print("showing:", x * 2)

def hands_it_back(x):
    return x * 2

a = shows_it(5)           # prints, but gives back nothing useful
b = hands_it_back(5)      # gives back 10
print("a is", a)
print("b is", b)
print("b plus 1 is", b + 1)
showing: 10
a is None
b is 10
b plus 1 is 11
Edit and run this code in your browser

Live Python

print shows, return hands back

Runs in your browser on your device. Nothing you type is sent anywhere, and nothing here changes your saved progress.

Press Ctrl+Enter (⌘+Enter on Mac) to run. Tab moves focus to the next control, as usual; use spaces to indent.

The function that only printed gave back nothing useful: a is None, which is Python's word for 'no value'. The function with return gave back 10, which we could add to. In data work you almost always want return.

Functions that come with Python
prices = [62.5, 48.0, 71.2, 55.5]
print(len(prices), min(prices), max(prices), sum(prices))
print(sorted(prices))
print(round(3.14159, 2), abs(-7))
print(int("42") + 1, float("2.5") * 2, str(100) + " lakh")
print("pune".upper(), "  Pune ".strip(), "a,b,c".split(","))
4 48.0 71.2 237.2
[48.0, 55.5, 62.5, 71.2]
3.14 7
43 5.0 100 lakh
PUNE Pune ['a', 'b', 'c']
Edit and run this code in your browser

Live Python

Functions that come with Python

Runs in your browser on your device. Nothing you type is sent anywhere, and nothing here changes your saved progress.

Press Ctrl+Enter (⌘+Enter on Mac) to run. Tab moves focus to the next control, as usual; use spaces to indent.

5 · Apply

Reuse the recipe, then read the errors

Example 1: use the same function on a whole list of flats. Each item is a pair, and a for loop can unpack the pair into two names.

A function used inside a loop
def price_per_sqft(price_lakh, area_sqft):
    return price_lakh * 100000 / area_sqft

flats = [(62.5, 1075), (48.0, 900), (55.5, 1000)]    # (price in lakh, area in sq ft)
for price, area in flats:
    print(price, "lakh for", area, "sq ft =", round(price_per_sqft(price, area)), "a sq ft")
62.5 lakh for 1075 sq ft = 5814 a sq ft
48.0 lakh for 900 sq ft = 5333 a sq ft
55.5 lakh for 1000 sq ft = 5550 a sq ft
Edit and run this code in your browser

Live Python

A function used inside a loop

Runs in your browser on your device. Nothing you type is sent anywhere, and nothing here changes your saved progress.

Press Ctrl+Enter (⌘+Enter on Mac) to run. Tab moves focus to the next control, as usual; use spaces to indent.

Example 2 is the habit that matters most for beginners: when Python stops, read the last line of the error. It has two parts, the kind of error and a message. Here are the six you will meet most, each caused on purpose.

Each error has a name and a message
def show(label, fn):
    try:
        fn()
    except Exception as e:
        print(f"{label}: {type(e).__name__}: {e}")

prices = [62.5, 48.0]
show("missing name ", lambda: print(pirce))
show("wrong type   ", lambda: "5" + 5)
show("bad position ", lambda: prices[5])
show("missing key  ", lambda: {"city": "Pune"}["state"])
show("divide by 0  ", lambda: 1 / 0)
show("bad number   ", lambda: int("twelve"))
missing name : NameError: name 'pirce' is not defined
wrong type   : TypeError: can only concatenate str (not "int") to str
bad position : IndexError: list index out of range
missing key  : KeyError: 'state'
divide by 0  : ZeroDivisionError: division by zero
bad number   : ValueError: invalid literal for int() with base 10: 'twelve'
Edit and run this code in your browser

Live Python

Each error has a name and a message

Runs in your browser on your device. Nothing you type is sent anywhere, and nothing here changes your saved progress.

Press Ctrl+Enter (⌘+Enter on Mac) to run. Tab moves focus to the next control, as usual; use spaces to indent.

What each error usually means
ErrorUsually meansFirst thing to check
SyntaxErrorThe line is not valid PythonMissing colon, bracket or quote; = where == was meant
NameErrorA name that does not exist yetSpelling, capital letters, quotes missing around text, run order
TypeErrorWrong kind of value for the jobMixing text and numbers; wrong number of inputs
IndexErrorA list position that does not existCounting from 0; the list is shorter than you think
KeyErrorA dictionary key that is not thereSpelling of the key
ZeroDivisionErrorDividing by zeroThe divisor; an empty list
ValueErrorRight type, wrong contentint("twelve") cannot become a number

6 · Where it goes wrong

Habits that save hours

When stuck, print the value you are unsure about. print(type(x), x) is the quickest way to see what Python actually holds.

7 · In Python

Everything together

This program has a function, a decision inside it, a loop and an f-string: every idea from the three parts.

Parts 1 to 3 together
def price_per_sqft(price_lakh, area_sqft):
    return price_lakh * 100000 / area_sqft

def verdict(rate, limit):
    if rate <= limit:
        return "good value"
    return "expensive"

flats = [("Baner", 62.5, 1075), ("Hadapsar", 48.0, 900), ("Kothrud", 71.2, 1000)]
for name, price, area in flats:
    rate = price_per_sqft(price, area)
    print(f"{name}: {round(rate)} a sq ft, {verdict(rate, 6000)}")
Baner: 5814 a sq ft, good value
Hadapsar: 5333 a sq ft, good value
Kothrud: 7120 a sq ft, expensive
Edit and run this code in your browser

Live Python

Parts 1 to 3 together

Runs in your browser on your device. Nothing you type is sent anywhere, and nothing here changes your saved progress.

Press Ctrl+Enter (⌘+Enter on Mac) to run. Tab moves focus to the next control, as usual; use spaces to indent.

  1. Change the limit from 6000 to 5000. Which flats change verdict?
  2. Add a fourth flat to the list and run it again.
  3. Break it on purpose: delete the colon after def verdict(rate, limit) and read the error. Then put it back.

Stuck on a symbol? Keep the Python cheat sheet open in another tab.