The special value None
represents nothingness in Python.
Any function that doesn't explicitly return a value will return
None
:
def square_it(x):
x * x
When a function returns None
, the console shows no output at
all:
square_it(4)
Attempting to treat the None
like a number will result in an
error:
sixteen = square_it(4)
sum = sixteen + 4 # 🚫 TypeError!
A side effect is when something happens as a result of calling a function besides just returning a value.
The most common side effect is logging to the console, via the built-in
print()
function.
print(-2)
A similar side effect is writing to a file:
f = open('songs.txt', 'w')
f.write("Dancing On My Own, Robyn")
f.close()
def square_num1(number):
return pow(number, 2)
def square_num2(number):
print(number ** 2)
None
.
Arguments | Return value | ||
---|---|---|---|
Pure functions just return values. |
-2 | 2 | |
2, 10 | 1024 | ||
Non-pure functions have side effects. |
-2 |
Python displays output "-2" |
None
|
What will this display?
print(print(1), print(2))
In the function signature, a parameter can specify a default value. If that argument isn't passed in, the default value is used instead.
def calculate_dog_age(human_years, multiplier = 7):
return human_years * multiplier
These two lines of code have the same result:
calculate_dog_age(3)
calculate_dog_age(3, 7)
Default arguments can be overriden two ways:
calculate_dog_age(3, 6)
calculate_dog_age(3, multiplier=6)
A function can specify multiple return values, separated by commas.
def divide_exact(n, d):
quotient = n // d
remainder = n % d
return quotient, remainder
Any code that calls that function must also "unpack it" using commas:
q, r = divide_exact(618, 10)
Doctests check the input/output of functions.
def divide_exact(n, d):
"""
>>> q, r = divide_exact(2021, 10)
>>> q
202
>>> r
1
"""
quotient = n // d
remainder = n % d
return quotient, remainder
See more in Python doctests documentation.
A Boolean value is either True
or
False
and is used frequently in computer programs.
Google Maps uses a boolean to decide whether to avoid highways in driving directions:
avoid_highways = True
Twitter uses a boolean to remember where the user allows personalized ads:
personalized_ads = False
An expression can evaluate to a Boolean. Most Boolean expressions use either comparison or logical operators.
An expression with a comparison operator:
passed_class = grade > 65
An expression with a logical operator:
wear_jacket = is_raining or is_windy
Operator | Meaning | True expressions |
== | Equality |
32 == 32
|
!= | Inequality |
30 != 32
|
> | Greater than |
60 > 32
|
>= | Greater than or equal |
60 >= 32 ,
32 >= 32
|
< | Less than | 20 < 32 |
<= | Less than or equal | 20 <= 32 , 32 <= 32 |
⚠️ Common mistake: Do not confuse =
(the assignment operator)
with ==
(the equality operator).
Operator | True expressions | Meaning |
---|---|---|
and |
4 > 0 and -2 < 0 |
Evaluates to True if both conditions are true. If one is
False evaluates to False .
|
or |
4 > 0 or -2 > 0 |
Evaluates to True if either condition is true. Evaluates
to False only if both are false.
|
not |
not (5 == 0) |
Evaluates to True if condition is false; evaluates to
False if condition is true.
|
When combining multiple operators in a single expression, use parentheses to group:
may_have_mobility_issues = (age >= 0 and age < 2) or age > 90
A function can use a Boolean expression to return a result based on the values of the parameters.
def passed_class(grade):
return grade > 65
def should_wear_jacket(is_rainy, is_windy):
return is_rainy or is_windy
These are un-graded exercises you can do after the lecture to make sure you grok the basics:
A statement is executed by the interpreter to perform an action.
So far we've seen a few...
Statement type | Example |
---|---|
Assignment statement |
|
Def statement |
|
Return statement |
|
A compound statement contains groups of other statements.
<header>: # CLAUSE
<statement> # SUITE
<statement>
...
<separating header>: # CLAUSE
<statement> # SUITE
<statement>
...
The first header determines a statement's type, and the header of each clause controls the suite that follows.
A suite is a sequence of statements.
<header>:
<statement> # SUITE
<statement>
...
<separating header>:
<statement> # SUITE
<statement>
...
Execution rule for a sequence of statements:
A conditional statement gives your code a way to execute a different suite of code statements based on whether certain conditions are true or false.
if <condition>:
<statement>
<statement>
...
A simple conditional:
clothing = "shirt"
if temperature < 32:
clothing = "jacket"
A conditional can include any number of elif
statements to
check other conditions.
if <condition>:
<statement>
...
elif <condition>:
<statement>
...
elif <condition>:
<statement>
...
clothing = "shirt"
if temperature < 0:
clothing = "snowsuit"
elif temperature < 32:
clothing = "jacket"
A conditional can include an else
to specify code to execute if
no previous conditions are true.
if <condition>:
<statement>
...
elif <condition>:
<statement>
...
else:
<statement>
...
if temperature < 0:
clothing = "snowsuit"
elif temperature < 32:
clothing = "jacket"
else:
clothing = "shirt"
if num < 0:
sign = "negative"
elif num > 0:
sign = "positive"
else:
sign = "neutral"
Syntax tips:
if
clause.elif
clauses.else
clause, always at the end.Each clause is considered in order.
It's common for a conditional to be based on the value of the parameters to a function.
def get_number_sign(num):
if num < 0:
sign = "negative"
elif num > 0:
sign = "positive"
else:
sign = "neutral"
return sign
get_number_sign(50) # "positive"
get_number_sign(-1) # "negative"
get_number_sign(0) # "neutral"
A branch of a conditional can end in a return, which exits the function entirely.
def get_number_sign(num):
if num < 0:
return "negative"
elif num > 0:
return "positive"
else:
return "neutral"
get_number_sign(50) # "positive"
get_number_sign(-1) # "negative"
get_number_sign(0) # "neutral"
These are un-graded exercises you can do after the lecture to make sure you grok the basics:
Consider the following code...
print(9 * 1)
print(9 * 2)
print(9 * 3)
print(9 * 4)
print(9 * 5)
This code is repetitive and variable, but the variability is sequential - it just adds one to the right-hand side number each time. In English, we could describe this as "print out the first 5 multiples of 9".
We can simplify this code with a loop!
The while loop syntax:
while <condition>:
<statement>
<statement>
As long as the condition is true, the statements below it are executed.
multiplier = 1
while multiplier <= 5:
print(9 * multiplier)
multiplier += 1
The code is significantly shorter, and it can easily be extended to loop for more or less iterations.
You can change the initial values of the variables used in the condition:
multiplier = 3
while multiplier <= 5:
print(9 * multiplier)
multiplier += 1
You can change the condition:
multiplier = 3
while multiplier <= 10:
print(9 * multiplier)
multiplier += 1
You can change how much the values change between iterations:
multiplier = 3
while multiplier <= 10:
print(9 * multiplier)
multiplier += 2
You can change the computation inside the while loop:
multiplier = 3
while multiplier <= 10:
print(10 * multiplier)
multiplier += 2
It's common to use a counter variable whose job is keeping track of the number of iterations.
total = 0
counter = 0
while counter < 5:
total += pow(2, 1)
counter += 1
The counter variable may also be involved in the loop computation:
total = 0
counter = 0
while counter < 5:
total += pow(2, counter)
counter += 1
Uh oh..
counter = 1
while counter < 5:
total += pow(2, counter)
What one line of code would fix this? counter += 1
counter = 6
while counter > 5:
total += pow(2, counter)
counter += 1
How do we save this code?
Intentions are unclear! Change the initial value and condition?
A loop in a function will commonly use a parameter to determine some aspect of its repetition.
def sum_up_squares(start, end):
counter = start
total = 0
while counter <= end:
total += pow(counter, 2)
counter += 1
return total
sum_up_squares(1, 5)
To prematurely exit a loop, use the break
statement:
counter = 100
while counter < 200:
if counter % 7 == 0:
first_multiple = counter
break
counter += 1
If you are brave, you can write while loops like this:
counter = 100
while True:
if counter % 62 == 0:
first_multiple = counter
break
counter += 1
⚠️ Be very sure that you're not coding an infinite loop!
These are un-graded exercises you can do after the lecture to make sure you grok the basics:
A prime number is an integer greater than 1 whose only factors are 1 and the number itself (e.g., 3, 5, 7, 11).
def is_prime(n):
"""Return True iff N is prime."""
return n > 1 and smallest_factor(n) == n
def smallest_factor(n):
"""Returns the smallest value k>1 that evenly divides N."""
???
def print_factors(n):
"""Print the prime factors of N."""
???
Let's implement them together.