# Review of control flow / basic for loops¶

In [1]:
# Fill in based off of confusion from yesterday


In [6]:
# This is a reminder of what a loop looks like

for i in range(20):
print(i)
print('Loop completed!')

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Loop completed!

In [7]:
# There are two keywords for loops that you will need to know
# The first is "break"
# Notice "break" is in green
# Break will exit a for loop once it is executed

for i in range(20):
if i == 10:
break
print(i)
print('Loop completed!')

0
1
2
3
4
5
6
7
8
9
Loop completed!

In [8]:
# The other keyword you need to know is "continue"
# "continue" will make it so that the rest of the loop body is not executed
# but ONLY for the time it is called
# Notice that "10" is not printed

for i in range(20):
if i == 10:
continue
print(i)
print('Loop completed!')

0
1
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19
Loop completed!

In [9]:
# You can have continue and break in the same loop

for i in range(20):
if i == 10:
continue
if i == 15:
break
print(i)
print('Loop completed!')

0
1
2
3
4
5
6
7
8
9
11
12
13
14
Loop completed!


# While loops¶

In [ ]:
# This is the generic syntax for a while loop

while CONTIDION:
LOOP_BODY

In [10]:
# A "while loop" is a loop that executes while CONDITION is true
# The CONDITION is evaluated once the loop body finishes, and only then

i = 0
while i < 10:
print(i)
i += 1
print('Loop completed!')

0
1
2
3
4
5
6
7
8
9
Loop completed!

In [1]:
# If CONDITION is False at the start of the loop, the loop body will not execute!

i = 0
while i < 0:
print(i)
i += 1
print('Loop completed!')

Loop completed!

In [12]:
# What is different about this and the one two above?

i = 0
while i < 10:
i += 1
print(i)
print('Loop completed!')

1
2
3
4
5
6
7
8
9
10
Loop completed!

In [14]:
# WARNING!!!!
# You can have loops that run forever.
# These are really really bad.
# Make sure the loop terminates.

while True:
print('hi!')

hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!
hi!

---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-14-06f2361de3ce> in <module>()
1 while True:
----> 2     print('hi!')

/usr/local/lib/python3.5/dist-packages/ipykernel/iostream.py in write(self, string)
372                 string = string.decode(self.encoding, 'replace')
373
--> 374             is_child = (not self._is_master_process())
375             # only touch the buffer in the IO thread to avoid races

/usr/local/lib/python3.5/dist-packages/ipykernel/iostream.py in _is_master_process(self)
299
300     def _is_master_process(self):
--> 301         return os.getpid() == self._master_pid
302
303     def set_parent(self, parent):

KeyboardInterrupt: 
In [15]:
# WARNING!!!!!
# Even if you don't mean to, the loop can run forever.
# DO NOT do this.

i = 0
while i < 10:
print(i)
print('Loop completed!') # This will never execute!

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-15-108318566107> in <module>()
2 i = 0
3 while i < 10:
----> 4     print(i)
5 print('Loop completed!')

/usr/local/lib/python3.5/dist-packages/ipykernel/iostream.py in write(self, string)
374             is_child = (not self._is_master_process())
375             # only touch the buffer in the IO thread to avoid races
377             if is_child:
378                 # newlines imply flush in subprocesses

/usr/local/lib/python3.5/dist-packages/ipykernel/iostream.py in schedule(self, f)
201             self._events.append(f)
202             # wake event thread (message content is ignored)
--> 203             self._event_pipe.send(b'')
204         else:
205             f()

/usr/local/lib/python3.5/dist-packages/zmq/sugar/socket.py in send(self, data, flags, copy, track, routing_id, group)
389                                  copy_threshold=self.copy_threshold)
390             data.group = group
--> 391         return super(Socket, self).send(data, flags=flags, copy=copy, track=track)
392
393     def send_multipart(self, msg_parts, flags=0, copy=True, track=False, **kwargs):

zmq/backend/cython/socket.pyx in zmq.backend.cython.socket.Socket.send()

zmq/backend/cython/socket.pyx in zmq.backend.cython.socket.Socket.send()

zmq/backend/cython/socket.pyx in zmq.backend.cython.socket._send_copy()

/usr/local/lib/python3.5/dist-packages/zmq/backend/cython/checkrc.pxd in zmq.backend.cython.checkrc._check_rc()

KeyboardInterrupt: 
In [18]:
# You can use "continue" in while loops
# The syntax and behavior is exactly the same as in for loop

i = 0
while i < 10:
i += 1
if i == 5:
continue
print(i)
print('Loop completed!')

1
2
3
4
6
7
8
9
10
Loop completed!

In [19]:
# WARNING!!!!
# This loop will also run forever. Why?
# Don't do this.

i = 0
while i < 10:
if i == 5:
continue
print(i)
i += 1
print('Loop completed!')

0
1
2
3
4

---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-19-33c68528fb8a> in <module>()
2 i = 0
3 while i < 10:
----> 4     if i == 5:
5         continue
6     print(i)

KeyboardInterrupt: 
In [20]:
# You can also use "break" in while loops
# The syntax and usage is exactly the same as in for loops

i = 0
while True:
if i > 10:
break
print(i)
i += 1

0
1
2
3
4
5
6
7
8
9
10

In [21]:
# What will happen?

i = 0
while True:
i += 1
if i > 10:
break
print(i)

1
2
3
4
5
6
7
8
9
10


# Functions (variable scoping)¶

In [2]:
# WARNING!!!
# Variables are "scoped"
# This is a complex topic, and we won't have time to cover all of it in lecture
# We will only cover the basics: variables inside a function
# Variables inside a function have no relation to variables outside the function
# See what happens when "i" is printed inside and outside the function

i = 0
def func(x):
i = 10
print(i, x)

func(5)
print(i)

10 5
0

In [23]:
# Variables across functions have no relation to each other
# A variable declared inside a function will have no relation to outside the function
# Why is there an error?

def func1(x):
j = 10
print(j, x)

def func2(x):
j = 5
func1(x)
print(x)

func2(3)
print(j)

10 3
3

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-23-012d2fd7e23e> in <module>()
9
10 func2(3)
---> 11 print(j)

NameError: name 'j' is not defined
In [24]:
# WARNING: Indentation is not the same scoping
# Scoping only applies to functions
# If blocks, for loops, and while loops ARE NOT functions

i = 0
for i in range(3):
print(i)

0
1
2

In [25]:
# Why is this the output?

k = 0
for i in range(3):
print(k)

0
0
0

In [26]:
# How about here?

k = 0
for i in range(3):
k = 6
print(k)

6
6
6