Continuation Course in Programming in Python
Lecture 11:
The rest of Python
Chalmers/GU CSE (DAT516/DIT515)
Version 20241210
Aarne Ranta
1
Plan
One of the goals of this course is to cover all of Python, at least in the reading mode.
This lecture will cover the rest of Python constructs, some quite new, some older:
None of these is necessary in the labs, and they will not be asked in the exam!
2
:=
3
Assignment expression x := e
4
Using the "walrus symbol" :=
In many other languages (C, Java, …) ordinary assignments x = e do the same. Hence they are expressions, not just statements.
But Python forbids this to avoid unwanted errors, such as
if x = 42:
print(x) # always prints 42
This is a syntax error, because x = 42 is a statement.
https://peps.python.org/pep-0572/
The three equality signs: = == :=
5
x = 7
x == 42
if x == 42:
print(x)
if x := 42:
print(x)
if x := 0:
print(x)
Assignment statement, sets the value of x to 7
Equality expression, value False
Nothing is printed, because x != 42
Prints 42, sets the value of x to 42
Quiz: what is printed here?
match
6
Pattern matching: match and case
7
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case 200|201|202:
return "Some kind of success"
case x if 300 <= x < 400:
return "Some kind of redirection"
case _:
return "Something's wrong with the Internet"
Matching with integers
disjunctive patterns
if conditions to patterns
matching anything not yet covered
Could be mimicked with an if-elif-else block but would be a bit more complicated.
https://peps.python.org/pep-0636/
Matching lists
8
while True:
command = input('> ')
match command.split():
case ['reverse', s]:
print(s[-1::-1])
case ['reverse', *s]:
print('cannot reverse multiple words')
case ['echo', *s]:
print(*s)
case ['quit'|'bye']:
print('bye')
break
case _:
print('try again')
A dialogue interpreter; cf. Lab 1.
Testing with different sequences of words
Also other structures can be matched, including objects of your own classes.
yield
9
Generators: yield and next
10
def fibonacci():
lo, hi = 1, 1
while True:
yield lo
lo, hi = hi, lo+hi
fs = fibonacci()
while not input():
print(next(fs), end='')
This generates an "infinite" list of Fibonacci numbers
To test: get one number at the time, the next one, by pressing just enter.
Any other input terminates.
Common use: reading large files line by line (this is what standard open() actually does)
& | ^ ~ << >>
11
Binary numbers and bitwise operators: logic
12
x = 0b101010
int(x) # == 42
bin(42) # == '0b101010'
20 & 10 # == 0b10100 & 0b1010 == 0b0
20 | 10 # == 0b11110 == 30
20 ^ 10 # == 0b11110 == 30
~ 20 # -21
Literals for binary numbers
value shown as decimal (= base 10)
converted to binary
bitwise and (x * y for each bit)
bitwise or (x + y - x * y for each bit)
bitwise xor ((x + y) % 2 for each bit)
bitwise negation (should be 1 - x logically, but different in Python)
https://realpython.com/python-bitwise-operators/
Bitwise operators: shifts
13
10 << 2 # 40
10 << 3 # 80
100 >> 2 # 25
101 >> 2 # 25
Left shift x << n (x * (2**n))
Right shift x >> n (x // (2**n))
Shift operations are used in ultimate optimizations to replace multiplications and divisions, because they are much simpler than cheaper when n is a power of 2.
x: int
14
Type hints
Good for documenting functions in an API.
Also used in static type checking
https://docs.python.org/3/library/typing.html
Normal execution: the first error found when running the code is reported
With static type checking: all errors found are reported before running the code
15
def greeting(name: str, n: int) -> str:
return n * 'Hello ' + name
# a violation
print(greeting('world', '3'))
$ python3 lecture11.py
TypeError: can't multiply sequence by non-int of type 'str'
$ mypy lecture11.py
lecture11.py:59: error: Argument 2 to "greeting" has incompatible type "str"; expected "int" [arg-type]
Found 1 error in 1 file (checked 1 source file)
E(Exception)
16
Defining and raising exceptions
17
class AsciiException(Exception):
def __str__(self):
return 'non-ascii characters in string'
def get_username():
name = input('username: ')
if any([ord(c) > 127 for c in name]):
raise AsciiException
return name
A user-defined exception is a subclass of the Exception class.
To make the execution with a certain exception, raise it.
https://docs.python.org/3/tutorial/errors.html
Defining and raising meaningful exceptions is better than returning error strings or None values.
Other functions can then catch them in try-except blocks.
re
18
Regular expressions
19
import re
re.match('\d+', '123abc')
# <re.Match object; span=(0, 3), match='123'>
Inherited from the Perl language, reflecting the origin of Python as a scripting language.
https://docs.python.org/3/howto/regex.html#regex-howto
https://docs.python.org/3/library/re.html
re.match(<pattern>, <str>) matches in the beginning
re.search(...) returns the first match
re.findall(...) returns a list of all matches
re.finditer(...) yields all matches
async
20
Asynchronous IO
21
import asyncio
async def hello(i):
print(f"hello {i} started")
await asyncio.sleep(4)
print(f"hello {i} done")
async def main():
task1 = asyncio.create_task(hello(1))
await asyncio.sleep(3)
task2 = asyncio.create_task(hello(2))
await task1
await task2
asyncio.run(main())
Asynchronous programs: tasks running at the same time without blocking each other
https://docs.python.org/3/library/asyncio.html
Simple example from
https://stackoverflow.com/questions/50757497/simplest-async-await-example-possible-in-python
Much more in
https://realpython.com/async-io-python/