Chapter 4 · Objects and robust code

Exceptions

You are reading the whole lesson on one page. Back to one step at a time

Step 1 of 22 · Concept

try runs code that might fail

By the end of this lesson, your programs survive bad input and refuse bad requests.

text = input("Age: ")
try:
    age = int(text)
    print("Next year:", age + 1)
except ValueError:
    print("Not a number:", text)
print("Done")

When a line in the try block raises a ValueError, Python skips the rest of the block. It runs the except block instead of a traceback.

text = input("Age: ")
try:
    age = int(text)
    print("Next year:", age + 1)
except ValueError:
    print("Not a number:", text)
print("Done")
while True:
    text = input("People: ")
    try:
        each = 12 // int(text)
        break
    except ValueError as e:
        print("Try again:", e)
    except ZeroDivisionError:
        print("Zero people: try again")
print("Each gets", each)
for i in range(3):
    text = input("100 / ")
    print(100 / int(text))
class InsufficientFunds(Exception):
    pass

def withdraw(balance, amount):
    if amount > balance:
        msg = f"cannot take {amount} from {balance}"
        raise InsufficientFunds(msg)
    return balance - amount

try:
    print(withdraw(50, 20))
    print(withdraw(50, 80))
except InsufficientFunds as e:
    print("Refused:", e)
class InsufficientFunds(Exception):
    pass

class Account:
    def __init__(self, owner):
        self.owner = owner
        self.balance = 0

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if amount > self.balance:
            print("Refused")
            return False
        else:
            self.balance -= amount
            return True

    def __str__(self):
        return f"{self.owner}: {self.balance}"

a = Account("Ada")
a.deposit(50)
for amount in [20, 40, 10]:
    a.withdraw(amount)
    print("Took", amount)
print(a)
def check(text):
    try:
        n = int(text)
    except ValueError:
        print("Not a number:", text)
    else:
        print("Got", n)
    finally:
        print("Checked", text)

check("7")
check("x")
class InsufficientFunds(Exception):
    pass

class Account:
    def __init__(self, owner):
        self.owner = owner
        self.balance = 0

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if amount > self.balance:
            msg = f"cannot take {amount} from {self.balance}"
            raise InsufficientFunds(msg)
        self.balance -= amount

    def __str__(self):
        return f"{self.owner}: {self.balance}"

a = Account("Ada")
# read orders until quit
class BadAmount(Exception):
    pass

def parse_amount(text):
    return int(text)

parse_amount("ten")
Terminal
Step 1 of 8A safe int

Keyboard shortcuts

The step

ContinueEnter
Previous / next stepAlt+[ · Alt+]
Move along the steps bar← → Home End, then Enter
From a quiz's title to its answers↓
Skip to the stepTab, then Enter (first on the page)
Course outlineAlt+O
These shortcuts?

The workspace

Run the stepCtrl+Enter (⌘↵ on a Mac)
Lesson → editor → consoleF6 (Shift+F6 back)
Output ↔ TerminalCtrl+`
Focus the editorCtrl+. (⌘. on a Mac)
Hide or show the lessonAlt+L
Restore, close a messageEsc (outside the editor and the terminal)

The editor

Leave the editorF6 (Shift+F6 back); or Ctrl+M (⌃⇧M on a Mac), then Tab moves the focus (not in the vim mode)
Open a file by nameCtrl+P (⌘P on a Mac)
All commandsCtrl+Shift+P (⌘⇧P on a Mac) or F1
Go to a lineCtrl+G (⌃G on a Mac)
Show or hide the filesCtrl+B (⌘B on a Mac)
Previous / next file tabCtrl+Shift+[ · Ctrl+Shift+] (⌘⇧[ · ⌘⇧] on a Mac)
The file tabs← → Home End on a tab; Delete closes it
Save the files nowCtrl+S (⌘S on a Mac)
Go to a symbol in the fileCtrl+Shift+O (⌘⇧O on a Mac)
Go to the definitionF12
Format the fileCtrl+Shift+F (⌘⇧F on a Mac), or Shift+Alt+F
Go back / forward after a jumpAlt+← · Alt+→ (⌃- · ⌃⇧- on a Mac)