Discussion 1: Control, Environment Diagrams
Control structures
Control structures direct the flow of a program using logical statements.
For example, conditionals (if-elif-else
) allow a program to skip sections of
code, and iteration (while
), allows a program to repeat a section.
Conditional statements
Conditional statements let programs execute different lines of code
depending on certain conditions. Let’s review the if-elif-else
syntax:
- The
elif
andelse
clauses are optional, and you can have any number ofelif
clauses. - A conditional expression is an expression that evaluates to either a
truthy value (
True
, a non-zero integer, etc.) or a falsy value (False
,0
,None
,""
,[]
, etc.). - Only the first
if
/elif
expression that evaluates to a truthy value will have its corresponding indented suite be executed. - If none of the conditional expressions evaluate to a true value, then the
else
suite is executed. There can only be oneelse
clause in a conditional statement.
Here's the general form:
if <conditional expression>:
<suite of statements>
elif <conditional expression>:
<suite of statements>
else:
<suite of statements>
Boolean Operators
Python also includes the boolean operators and
, or
, and not
. These
operators are used to combine and manipulate boolean values.
not
returns the opposite boolean value of the following expression, and will always return eitherTrue
orFalse
.and
evaluates expressions in order and stops evaluating (short-circuits) once it reaches the first falsy value, and then returns it. If all values evaluate to a truthy value, the last value is returned.or
evalutes expressions in order and short-circuits at the first truthy value and returns it. If all values evaluate to a falsy value, the last value is returned.
For example:
>>> not None
True
>>> not True
False
>>> -1 and 0 and 1
0
>>> False or 9999 or 1/0
9999
Q1: Case Conundrum
In this question, we will explore the difference between if
and elif
.
What is the result of evaluating the following code?
def special_case():
x = 10
if x > 0:
x += 2
elif x < 13:
x += 3
elif x % 2 == 1:
x += 4
return x
special_case()
What is the result of evaluating this piece of code?
def just_in_case():
x = 10
if x > 0:
x += 2
if x < 13:
x += 3
if x % 2 == 1:
x += 4
return x
just_in_case()
How about this piece of code?
def case_in_point():
x = 10
if x > 0:
return x + 2
if x < 13:
return x + 3
if x % 2 == 1:
return x + 4
return x
case_in_point()
Which of these code snippets result in the same output, and why? Based on your
findings, when do you think using a series of if
statements has the same
effect as using both if
and elif
cases?
Q2: Jacket Weather?
Alfonso will only wear a jacket outside if it is below 60 degrees or it is raining.
Write a function that takes in the current temperature and a boolean value
telling if it is raining. This function should return True
if Alfonso will
wear a jacket and False
otherwise.
Try solving this problem using an if
statement.
Run in 61A CodeNote: Since we'll either return
True
orFalse
based on a single condition, whose truthiness value will also be eitherTrue
orFalse
. Knowing this, try to write this function using a single line.
Q3: If Function vs Statement
Now that we've learned about how if
statements work, let's see if we
can write a function that behaves the same as an if
statement.
def if_function(condition, true_result, false_result):
"""Return true_result if condition is a true value, and
false_result otherwise.
>>> if_function(True, 2, 3)
2
>>> if_function(False, 2, 3)
3
>>> if_function(3==2, 'equal', 'not equal')
'not equal'
>>> if_function(3>2, 'bigger', 'smaller')
'bigger'
"""
if condition:
return true_result
else:
return false_result
Despite the doctests above, this function actually does not always
do the same thing as an if
statement.
We want to find a case where this if_function
will
behave differently from an if
statement.
To do so, implement the following functions,
cond
: Callingcond
should act as theif
condition.true_func
: Callingtrue_func
should represent the result of the truthy case.false_func
: Callingfalse_func
should represent the result of the falsey case.
so that with_if_function
does not behave the same as
with_if_statement
, written in the doctests and here below:
- When
with_if_statement
is called, we print out61A
. - When
with_if_function
is called, we print out bothWelcome to
and61A
on separate lines.
Implement cond
, true_func
, and false_func
below.
Run in 61A CodeHint: If you are having a hard time identifying how
with_if_statement
andwith_if_function
would differ in behavior, consider the rules of evaluation forif
statements and call expressions.
While loops
To repeat the same statements multiple times in a program, we can use iteration. In Python, one way we can do this is with a while loop.
while <conditional clause>:
<statements body>
As long as <conditional clause>
evaluates to a true value,
<statements body>
will continue to be executed. The conditional clause
gets evaluated each time the body finishes executing.
Q4: Square So Slow
What is the result of evaluating the following code?
def square(x):
print("here!")
return x * x
def so_slow(num):
x = num
while x > 0:
x = x + 1
return x / 0
square(so_slow(5))
Hint: What happens to
x
over time?
Q5: Is Prime?
Write a function that returns True
if a positive integer n
is a prime
number and False
otherwise.
A prime number n is a number that is not divisible by any numbers other than 1 and n itself. For example, 13 is prime, since it is only divisible by 1 and 13, but 14 is not, since it is divisible by 1, 2, 7, and 14.
Run in 61A CodeHint: Use the
%
operator:x % y
returns the remainder ofx
when divided byy
.
Q6: Fizzbuzz
Implement the fizzbuzz sequence, which prints out a single statement for each
number from 1 to n
. For a number i
,
- If
i
is divisible by 3 only, then we print "fizz". - If
i
is divisible by 5 only, then we print "buzz". - If
i
is divisible by both 3 and 5, then we print "fizzbuzz". - Otherwise, we print the number
i
by itself.
Implement fizzbuzz(n)
here:
Environment Diagrams
An environment diagram is a model we use to keep track of all the variables that have been defined and the values they are bound to. We will be using this tool throughout the course to understand complex programs involving several different assignments and function calls.
One key idea in environment diagrams is the frame. A frame helps us keep track of what variables have been defined in the current execution environment, and what values they hold. The frame we start off with when executing a program from scratch is what we call the Global frame. Later, we'll get into how new frames are created and how they may depend on their parent frame.
Here's a short program and its corresponding diagram:
Remember that programs are mainly just a set of statements or instructions— so drawing diagrams that represent these programs also involves following sets of instructions! Let’s dive in...
Assignment Statements
Assignment statements, such as x = 3
, define variables in programs. To
execute one in an environment diagram, record the variable name and the value:
- Evaluate the expression on the right side of the
=
sign. - Write the variable name and the expression’s value in the current frame.
Q7: Assignment Diagram
Use these rules to draw an environment diagram for the assignment statements below:
x = 11 % 4
y = x
x **= 2
def Statements
A def
statement creates ("defines") a function object and binds it to a name.
To diagram def
statements, record the function name and bind the function
object to the name. It’s also important to write the parent frame of the
function, which is where the function is defined.
A very important note:
Assignments for def
statements use pointers to functions, which can have
different behavior than primitive assignments (such as variables bound
to numbers).
- Draw the function object to the right-hand-side of the frames, denoting
the intrinsic name of the function, its parameters, and the parent frame (e.g.
func square(x) [parent = Global]
. - Write the function name in the current frame and draw an arrow from the name to the function object.
Q8: def Diagram
Use these rules for defining functions and the rules for assignment statements to draw a diagram for the code below.
def double(x):
return x * 2
def triple(x):
return x * 3
hat = double
double = triple