πŸ–₯️
Berkeley CS61A: Notes
  • 🌍Hello, World!
  • πŸ’­Learn to Think Like Your Computer
  • Building Blocks
    • ❗Expressions in Python
      • ℹ️Mathematical Statements
      • 🀫Variables
      • πŸ‘Data Types in Python
    • 🚧Introduction to Functions
      • πŸƒβ€β™€οΈHow Python Executes a Function Call
      • 🚱Functions that Don't Return Anything
    • 🌊Control Flow
      • ⁉️What is an if statement?
      • πŸ’ΎWhat is a Loop?
      • 🚨What are Logical Operators?
        • πŸ˜–Logical Operators, Seemingly Illogical Behavior
      • 🚰How Does Control Flow?
    • ⚑Higher-Order Functions
      • ⏸️What are Higher-Order Functions Used For?
      • πŸ‘†Self-Reference
    • πŸ‘ΎEnvironments and Scope
      • πŸ–ŠοΈHow to Make Environment Diagrams
  • STRUCTURES OF DATA
    • ➰Recursion
      • πŸ«€Anatomy of Recursion
      • β›½Recursive Leap of Faith
    • πŸŽ„Tree Recursion
      • ⬇️The Use It/Lose It Principle
    • πŸ“€Iterables
      • βœ‚οΈList Slicing
      • πŸ’€Deep Lists
      • πŸŒ‹Iterable Functions
      • πŸ’½List Comprehensions
    • πŸ™ˆAbstraction
    • Trees
    • Linked Lists
    • Iterators and Generators
    • Efficiency
  • Extra Topics
    • 🎭Errors and their Types
      • 🏹Error vs Exception
      • πŸ”™What is Backtracing?
    • 🚑How the Terminal and the File are Different
    • 🍬Decorators
  • Debugging Tools
    • πŸ–¨οΈDebugging with Print Statements
    • πŸ›Debugging with the Debugger
Powered by GitBook
On this page
  • Direct Control Flow
  • Breaking Control Flow With If
  • Breaking Control Flow With While
  • Breaking Flow Of Control With Functions
  • Frames Are Independent Of Each Other

Was this helpful?

  1. Building Blocks
  2. Control Flow

How Does Control Flow?

Control flows downwards... mostly.

PreviousLogical Operators, Seemingly Illogical BehaviorNextHigher-Order Functions

Last updated 3 years ago

Was this helpful?

Direct Control Flow

In the simplest of functions, control simply flows downward.

a = 3
print(a) # prints 3

The reason this works is because the control goes up to down –– 3 is bound to a, and then looked up in line 2. This is quite like English, so we do it intuitively.

Breaking Control Flow With If

The first way you learn how to break control is through if. If is known as the "conditional", because one of many statements is conditionally executed.

if (3 > 4):
    print("suite 1") # this does not get executed
else:
    print("suite 2") # this gets executed

As you can see, the control arrow jumps from line 1 to line 3, skipping line 2 entirely. You could add anything to that line, and it won't error –– because it will never execute.

if (3 > 4):
    print(1/0) # should throw error but never executed
else:
    print("suite 2") # this gets executed

Breaking Control Flow With While

Another way we could change the flow of control is to make it go over the same block of code over and over again.

n = 1
while (n < 4):
    print("Hello") # prints thrice
    n = n + 1

The fundamental idea behind the loop is to do the same thing over and over again with small changes each time.

There are four parts to the loop –– the initial assignment (n = 1), the iterative condition (while n < 4), the execution (printing Hello) and the updation (n = n + 1). When we combine all four of these, we get a block of code that operates iteratively.

Breaking Flow Of Control With Functions

Another, more complicated way, the control flow is broken is through functions. Take this simple example.

def f(x):
    print("Inside the function") # doesn't get executed
    return 1/0 # does not error

print("Outside the function") # gets executed

So the function signature (that's the def line) is read, but not the function itself. The error inside the function doesn't execute, nor is the print statement. While the function's name and number of arguments are read and saved, the body of the function is not.

Now let's think about what happens when you call the function.

def f(x):
    print(a) # is executed
    return x+1

a = 3
print(f(a)) # prints 4
print(a) # prints 3

First, we bind a function with one argument to f. Then, we bind a to 3. Then, we call f with a (which is 3).

This call takes you out of your "main" control flow, and creates a separate flow. You've previously thought about this in terms of a new frame.

In this frame, everything inside of the frame is accessible, and everything in all its parent frames is also accessible. Moreover, anything that gets passed into this frame is a new copy –– the x inside of the function is not the same as the a that is passed in (This idea will grow in importance as the things we pass in get more and more complicated).

def f(x):
    x = x+1
    print(a) # prints 3
    return x

a = 3
print(f(a)) # prints 4
print(a) # prints 3

As seen, the value a is accessible despite not being in the function's flow, because it is in the parent flow. Of course, x itself is accessible. Changing x does not change a, because x is an independent copy of a.

The return value ends the function's frame and leads you back into the main flow ("global frame"). Even functions that don't explicitly have a return value have an implicit return None statement.

When the function returns to its own frame, it brings a value with it, and normal control flow resumes.

Frames Are Independent Of Each Other

Consider the following example:

def f(x):
    a = 4
    return x

a = 3
print(f(a)) # Print 1
print(a) # Print 2

You'll notice that Print 2 will return 3! So what happened to the a=4 that we defined. This is the idea of framing. The universe that f(x) operates in is different (but not completely divorced) from the universe of the main program (the global universe, if I may). The a that is defined in the function is completely different from the a that is defined before the function call. That's right –– there are two different a s existing!

This is what I mean by "the independence of frames". That is to say, a different frame has its own defined variables that may have the same name as a parent frame.

You may feel like this idea is starting to get familiar –– and it rightly should–– it's the idea behind environment diagrams! I think understanding this concept makes environment diagrams a lot more simple. Check out the quick note on those to understand how to use these concepts!

What do you think will be printed?

🌊
🚰
Try it out yourself in PythonTutor.
Try it out yourself in Python Tutor
Take a moment to try it out in PythonTutor.