Python from zero · Part 3 of 6 · No experience needed
Python from zero, part 3: functions and reading errors
1 · Observe
You have already used functions
| Word | What it means |
|---|---|
| Function | A named recipe that takes inputs and gives back an answer. print and len are functions. |
| Argument | A value you give a function when you use it: in len(prices), prices is the argument. |
| Return | The answer a function hands back to the line that used it. |
| Method | A 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. |
| Traceback | The 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
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.
| Function | What it does | Example | Gives |
|---|---|---|---|
| print(x) | shows x | print(5) | shows 5 |
| len(x) | how many items | len([4, 8, 9]) | 3 |
| type(x) | what kind of value | type(2.5) | float |
| round(x, n) | round to n decimals | round(3.14159, 2) | 3.14 |
| sum(list) | adds the values | sum([1, 2, 3]) | 6 |
| min(list), max(list) | smallest, largest | max([4, 8, 9]) | 9 |
| sorted(list) | a sorted copy | sorted([3, 1, 2]) | [1, 2, 3] |
| int(x), float(x), str(x) | convert type | int("42") | 42 |
| abs(x) | distance from zero | abs(-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.
3 · Visualize
What happens when you call a function
| Step | What happens | Names inside the function |
|---|---|---|
| 1 | The inputs are matched in order to the names in the def line | price_lakh → 62.5, area_sqft → 1075 |
| 2 | rupees = price_lakh * 100000 | rupees → 6250000.0 |
| 3 | return rupees / area_sqft | Answer 5813.95… is handed back |
| 4 | The line that called the function receives it | rate → 5813.95… |
4 · Discover
Write one and call it
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.0Edit 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.
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 11Edit 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.
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.
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 ftEdit 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.
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.
| Error | Usually means | First thing to check |
|---|---|---|
| SyntaxError | The line is not valid Python | Missing colon, bracket or quote; = where == was meant |
| NameError | A name that does not exist yet | Spelling, capital letters, quotes missing around text, run order |
| TypeError | Wrong kind of value for the job | Mixing text and numbers; wrong number of inputs |
| IndexError | A list position that does not exist | Counting from 0; the list is shorter than you think |
| KeyError | A dictionary key that is not there | Spelling of the key |
| ZeroDivisionError | Dividing by zero | The divisor; an empty list |
| ValueError | Right type, wrong content | int("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.
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, expensiveEdit 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.
- Change the limit from 6000 to 5000. Which flats change verdict?
- Add a fourth flat to the list and run it again.
- 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.