5Vectors, Matrices, Arrays, and Control Structures
This chapter introduces some of the most important tools for working with data: vectors, matrices, loops, and if statements. It would be nice to gradually introduce each one of these topics separately, but they tend to go together, especially when you’re talking about programming in the context of data processing.
5.1 Mathematical Logic
Before we start talking about data structures and control structures, though, we’re going to take a minute to review some concepts from mathematical logic. This will be useful for both data structures and control structures, so stick with me for a few minutes.
5.1.1 And, Or, and Not
We can combine logical statements using and, or, and not.
(X AND Y) requires that both X and Y are true.
(X OR Y) requires that one of X or Y is true.
(NOT X) is true if X is false, and false if X is true. Sometimes called negation.
In R, we use ! to symbolize NOT, in Python, we use ~ for vector-wise negation (NOT).
Order of operations dictates that NOT is applied before other operations. So NOT X AND Y is read as (NOT X) AND (Y). You must use parentheses to change the way this is interpreted.
A venn diagram illustration of De Morgan’s laws showing that the region that is outside of the union of A OR B (aka NOT (A OR B)) is the same as the region that is outside of (NOT A) and (NOT B)
A venn diagram illustration of De Morgan’s laws showing that the region that is outside of the union of A AND B (aka NOT (A AND B)) is the same as the region that is outside of (NOT A) OR (NOT B)
5.2 Data Structures
In the previous chapter, we discussed 4 different data types: strings/characters, numeric/double/floats, integers, and logical/booleans. As you might imagine, things are about to get more complicated.
Data structures are more complicated arrangements of information.
Homogeneous
Heterogeneous
1D
vector
list
2D
matrix
data frame
N-D
array
5.2.1 Lists
A list is a one-dimensional column of heterogeneous data - the things stored in a list can be of different types.
A lego list: the bricks are all different types and colors, but they are still part of the same data structure.
x[1:2] # This returns multiple elements in the list
[[1]]
[1] "a"
[[2]]
[1] 3
x[[1]] # This returns the item
[1] "a"
x[[1:2]] # This doesn't work - you can only use [[]] with a single index
Error in x[[1:2]]: subscript out of bounds
In R, list indexing with [] will return a list with the specified elements.
To actually retrieve the item in the list, use [[]]. The only downside to [[]] is that you can only access one thing at a time.
In Python, we count from 0.
A python-indexed lego list, counting from 0 to 4
x = ["a", 3, False]x[0]
'a'
x[1]
3
x[0:2]
['a', 3]
In Python, we can use single brackets to get an object or a list back out, but we have to know how slices work. Essentially, in Python, 0:2 indicates that we want objects 0 and 1, but want to stop at 2 (not including 2). If you use a slice, Python will return a list; if you use a single index, python just returns the value in that location in the list.
We’ll talk more about indexing as it relates to vectors, but indexing is a general concept that applies to just about any multi-value object.
5.2.2 Vectors
A vector is a one-dimensional column of homogeneous data. Homogeneous means that every element in a vector has the same data type.
We can have vectors of any data type and length we want:
5.2.2.1 Indexing by Location
Each element in a vector has an index - an integer telling you what the item’s position within the vector is. I’m going to demonstrate indices with the string vector
# R is 1-indexed - a list of 11 things goes from 1 to 11digits_pi[0]
numeric(0)
digits_pi[11]
[1] 5
# Print out the vectordigits_pi
[1] 3 1 4 1 5 9 2 6 5 3 5
In python, we create vectors using the array function in the numpy module. To add a python module, we use the syntax import <name> as <nickname>. Many modules have conventional (and very short) nicknames - for numpy, we will use np as the nickname. Any functions we reference in the numpy module will then be called using np.fun_name() so that python knows where to find them.2
digits_pi[2]# Python is 0 indexed - a list of 11 things goes from 0 to 10
4
digits_pi[0]
3
digits_pi[11] # multiplication works on the whole vector at once
Error in py_call_impl(callable, dots$args, dots$keywords): IndexError: index 11 is out of bounds for axis 0 with size 11
Detailed traceback:
File "<string>", line 1, in <module>
digits_pi *2# Print out the vector
array([ 6, 2, 8, 2, 10, 18, 4, 12, 10, 6, 10])
print(digits_pi)
[3 1 4 1 5 9 2 6 5 3 5]
Python has multiple things that look like vectors, including the pandas library’s Series structure. A Series is a one-dimensional array-like object containing a sequence of values and an associated array of labels (called its index).
import pandas as pddigits_pi = pd.Series([3,1,4,1,5,9,2,6,5,3,5])# Access individual entriesdigits_pi[0]
3
digits_pi[1]
1
digits_pi[2]# Python is 0 indexed - a list of 11 things goes from 0 to 10
4
digits_pi[0]
3
digits_pi[11] # logical indexing works here too
Error in py_call_impl(callable, dots$args, dots$keywords): KeyError: 11
Detailed traceback:
File "<string>", line 1, in <module>
File "/__w/Stat151/Stat151/renv/python/virtualenvs/renv-python-3.8/lib/python3.8/site-packages/pandas/core/series.py", line 958, in __getitem__
return self._get_value(key)
File "/__w/Stat151/Stat151/renv/python/virtualenvs/renv-python-3.8/lib/python3.8/site-packages/pandas/core/series.py", line 1069, in _get_value
loc = self.index.get_loc(label)
File "/__w/Stat151/Stat151/renv/python/virtualenvs/renv-python-3.8/lib/python3.8/site-packages/pandas/core/indexes/range.py", line 387, in get_loc
raise KeyError(key) from err
digits_pi[digits_pi >3]# simple multiplication works in a vectorized manner# that is, the whole vector is multiplied at once
The Series object has a list of labels in the first printed column, and a list of values in the second. If we want, we can specify the labels manually to use as e.g. plot labels later:
weekdays.index[6] ='Z'# you can't assign things to the index to change it
Error in py_call_impl(callable, dots$args, dots$keywords): TypeError: Index does not support mutable operations
Detailed traceback:
File "<string>", line 1, in <module>
File "/__w/Stat151/Stat151/renv/python/virtualenvs/renv-python-3.8/lib/python3.8/site-packages/pandas/core/indexes/base.py", line 5021, in __setitem__
raise TypeError("Index does not support mutable operations")
weekdays
S Sunday
M Monday
T Tuesday
W Wednesday
R Thursday
F Friday
Sat Saturday
dtype: object
We can pull out items in a vector by indexing, but we can also replace specific things as well:
If you’re curious about any of these cats, see the footnotes3.
5.2.2.2 Indexing with Logical Vectors
As you might imagine, we can create vectors of all sorts of different data types. One particularly useful trick is to create a logical vector that goes along with a vector of another type to use as a logical index.
lego vectors - a pink/purple hued set of 1x3 bricks representing the data and a corresponding set of 1x1 grey and black bricks representing the logical index vector of the same length
If we let the black lego represent “True” and the grey lego represent “False”, we can use the logical vector to pull out all values in the main vector.
Black = True, Grey = False
Grey = True, Black = False
Note that for logical indexing to work properly, the logical index must be the same length as the vector we’re indexing. This constraint will return when we talk about data frames, but for now just keep in mind that logical indexing doesn’t make sense when this constraint isn’t true.
np.array([2, False, 3.1415]) # converted to floats
array([2. , 0. , 3.1415])
np.array([2, False]) # converted to integers
array([2, 0])
As a reminder, this is an example of implicit type conversion - R and python decide what type to use for you, going with the type that doesn’t lose data but takes up as little space as possible.
In python, matrices are just a special case of a class called ndarray - n-dimensional arrays.
import numpy as np# Minimal ndarray in python by typing in the values in a structured formatnp.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])# This syntax creates a list of the rows we want in our matrix# Matrix in python using a data vector and size parameters
In python, we create 2-dimensional arrays (aka matrices) either by creating a list of rows to join together or by reshaping a 1-dimensional array. The trick with reshaping the 1-dimensional array is the order argument: ‘F’ stands for “Fortran-like” and ‘C’ stands for “C-like”… so to go by column, you use ‘F’ and to go by row, you use ‘C’. Totally intuitive, right?
This class comes before linear algebra in the required course sequence, so most of the problems we’re going to work on will not require much in the way of matrix or array operations. For now, you need the following:
Know that matrices exist and what they are (2-dimensional arrays of numbers)
Understand how they are indexed (because it is extremely similar to data frames that we’ll work with in the next chapter)
Be aware that there are lots of functions that depend on matrix operations at their core (including linear regression)
5.2.3.1 Indexing in Matrices
Both R and python use [row, column] to index matrices. To extract the bottom-left element of a 3x4 matrix in R, we would use [3,1] to get to the third row and first column entry; in python, we would use [2,0] (remember that Python is 0-indexed).
As with vectors, you can replace elements in a matrix using assignment.
transpose - flip the matrix across the left top -> right bottom diagonal. \[t(\textbf{X}) = \left[\begin{array}{cc} x_{1,1} & x_{1, 2}\\x_{2,1} & x_{2,2}\end{array}\right]^T = \left[\begin{array}{cc} x_{1,1} & x_{2,1}\\x_{1,2} & x_{2,2}\end{array}\right]\]
matrix multiplication (dot product) - you will learn more about this in linear algebra, but here’s a preview. Here is a better explanation of the cross product\[\textbf{X}*\textbf{Y} = \left[\begin{array}{cc} x_{1,1} & x_{1, 2}\\x_{2,1} & x_{2,2}\end{array}\right] * \left[\begin{array}{cc} y_{1,1} \\y_{2,1} \end{array}\right] = \left[\begin{array}{c}x_{1,1}*y_{1,1} + x_{1,2}*y_{2,1} \\x_{2, 1}*y_{1,1} + x_{2,2}*y_{2,1}\end{array}\right]\] Note that matrix multiplication depends on having matrices of compatible dimensions. If you have two matrices of dimension \((a \times b)\) and \((c \times d)\), then \(b\) must be equal to \(c\) for the multiplication to work, and your result will be \((a \times d)\).
import numpy as npx = np.array([[1,2],[3,4]])y = np.array([[5],[6]])# scalar multiplicationx*3
array([[ 3, 6],
[ 9, 12]])
3*x# transpose
array([[ 3, 6],
[ 9, 12]])
x.T # shorthand
array([[1, 3],
[2, 4]])
x.transpose() # Long form# Matrix multiplication (dot product)
array([[1, 3],
[2, 4]])
np.dot(x, y)
array([[17],
[39]])
5.2.4 Arrays
Arrays are a generalized n-dimensional version of a vector: all elements have the same type, and they are indexed using square brackets in both R and python: [dim1, dim2, dim3, ...]
I don’t think you will need to create 3+ dimensional arrays in this class, but if you want to try it out, here is some code.
Note that displaying this requires 2 slices, since it’s hard to display 3D information in a 2D terminal arrangement.
import numpy as npnp.array([[[1,2],[3,4]],[[5,6], [7,8]]])
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
5.3 Control Structures
Control structures are statements in a program that determine when code is evaluated (and how many times it might be evaluated). There are two main types of control structures: if-statements and loops.
Before we start on the types of control structures, let’s get in the right mindset. We’re all used to “if-then” logic, and use it in everyday conversation, but computers require another level of specificity when you’re trying to provide instructions.
Check out this video of the classic “make a peanut butter sandwich instructions challenge”:
Here’s another example:
‘If you’re done being pedantic, we should get dinner.’ ‘You did it again!’ ‘No, I didn’t.’
The key takeaways from these bits of media are that you should read this section with a focus on exact precision - state exactly what you mean, and the computer will do what you say. If you instead expect the computer to get what you mean, you’re going to have a bad time.
5.3.1 Conditional Statements
Conditional statements determine if code is evaluated.
They look like this:
if (condition)
then
(thing to do)
else
(other thing to do)
The else (other thing to do) part may be omitted.
When this statement is read by the computer, the computer checks to see if condition is true or false. If the condition is true, then (thing to do) is also run. If the condition is false, then (other thing to do) is run instead.
x <-3y <-1if (x >2) { y <-8} else { y <-4}print(paste("x =", x, "; y =", y))
[1] "x = 3 ; y = 8"
In R, the logical condition after if must be in parentheses. It is common to then enclose the statement to be run if the condition is true in {} so that it is clear what code matches the if statement. You can technically put the condition on the line after the if (x > 2) line, and everything will still work, but then it gets hard to figure out what to do with the else statement - it technically would also go on the same line, and that gets hard to read.
x <-3y <-1if (x >2) y <-8else y <-4print(paste("x =", x, "; y =", y))
[1] "x = 3 ; y = 8"
So while the 2nd version of the code technically works, the first version with the brackets is much easier to read and understand. Please try to emulate the first version!
x =3y =1if x >2: y =8else: y =4print("x =", x, "; y =", y)
x = 3 ; y = 8
In python, all code grouping is accomplished with spaces instead of with brackets. So in python, we write our if statement as if x > 2: with the colon indicating that what follows is the code to evaluate. The next line is indented with 2 spaces to show that the code on those lines belongs to that if statement. Then, we use the else: statement to provide an alternative set of code to run if the logical condition in the if statement is false. Again, we indent the code under the else statement to show where it “belongs”.
Python will throw errors if you mess up the spacing. This is one thing that is very annoying about Python… but it’s a consequence of trying to make the code more readable.
5.3.1.1 Representing Conditional Statements as Diagrams
A common way to represent conditional logic is to draw a flow chart diagram.
In a flow chart, conditional statements are represented as diamonds, and other code is represented as a rectangle. Yes/no or True/False branches are labeled. Typically, after a conditional statement, the program flow returns to a single point.
Program flow diagram outline of a simple if/else statement
The US Tax code has brackets, such that the first $10,275 of your income is taxed at 10%, anything between $10,275 and $41,775 is taxed at 12%, and so on.
Here is the table of tax brackets for single filers in 2022:
rate
Income
10%
$0 to $10,275
12%
$10,275 to $41,775
22%
$41,775 to $89,075
24%
$89,075 to $170,050
32%
$170,050 to $215,950
35%
$215,950 to $539,900
37%
$539,900 or more
Note: For the purposes of this problem, we’re ignoring the personal exemption and the standard deduction, so we’re already simplifying the tax code.
Write a set of if statements that assess someone’s income and determine what their overall tax rate is.
Hint: You may want to keep track of how much of the income has already been taxed in a variable and what the total tax accumulation is in another variable.
# Start with total incomeincome <-200000# x will hold income that hasn't been taxed yetx <- income# y will hold taxes paidy <-0if (x <=10275) { y <- x*.1# tax paid x <-0# All money has been taxed} else { y <- y +10275* .1 x <- x -10275# Money remaining that hasn't been taxed}if (x <= (41775-10275)) { y <- y + x * .12 x <-0} else { y <- y + (41775-10275) * .12 x <- x - (41775-10275) }if (x <= (89075-41775)) { y <- y + x * .22 x <-0} else { y <- y + (89075-41775) * .22 x <- x - (89075-41775)}if (x <= (170050-89075)) { y <- y + x * .24 x <-0} else { y <- y + (170050-89075) * .24 x <- x - (170050-89075)}if (x <= (215950-170050)) { y <- y + x * .32 x <-0} else { y <- y + (215950-170050) * .32 x <- x - (215950-170050)}if (x <= (539900-215950)) { y <- y + x * .35 x <-0} else { y <- y + (539900-215950) * .35 x <- x - (539900-215950)}if (x >0) { y <- y + x * .37}print(paste("Total Tax Rate on $", income, " in income = ", round(y/income, 4)*100, "%"))
[1] "Total Tax Rate on $ 2e+05 in income = 22.12 %"
Total Tauntaxed Rate on $ 200000 in income = 22.12 %
We will find a better way to represent this calculation once we discuss loops - we can store each bracket’s start and end point in a vector and loop through them. Any time you find yourself copy-pasting code and changing values, you should consider using a loop (or eventually a function) instead.
Let’s explore using program flow maps for a slightly more complicated problem: The tax bracket example that we used to demonstrate if statement syntax.
The control flow diagram for the code in the previous example
Control flow diagrams can be extremely helpful when figuring out how programs work (and where gaps in your logic are when you’re debugging). It can be very helpful to map out your program flow as you’re untangling a problem.
5.3.1.2 Chaining Conditional Statements: Else-If
In many cases, it can be helpful to have a long chain of conditional statements describing a sequence of alternative statements.
For instance, suppose I want to determine what categorical age bracket someone falls into based on their numerical age. All of the bins are mutually exclusive - you can’t be in the 25-40 bracket and the 41-55 bracket.
Program flow map for a series of mutually exclusive categories. If our goal is to take a numeric age variable and create a categorical set of age brackets, such as <18, 18-25, 26-40, 41-55, 56-65, and >65, we can do this with a series of if-else statements chained together. Only one of the bracket assignments is evaluated, so it is important to place the most restrictive condition first.
The important thing to realize when examining this program flow map is that if age <= 18 is true, then none of the other conditional statements even get evaluated. That is, once a statement is true, none of the other statements matter. Because of this, it is important to place the most restrictive statement first.
Program flow map for a series of mutually exclusive categories, emphasizing that only some statements are evaluated. When age = 40, only (age <= 18), (age <= 25), and (age <= 40) are evaluated conditionally. Of the assignment statements, only bracket = ‘26-40’ is evaluated when age = 40.
If for some reason you wrote your conditional statements in the wrong order, the wrong label would get assigned:
Program flow map for a series of mutually exclusive categories, with category labels in the wrong order - <40 is evaluated first, and so <= 25 and <= 18 will never be evaluated and the wrong label will be assigned for anything in those categories.
In code, we would write this statement using else-if (or elif) statements.
age <-40# change this as you will to see how the code worksif (age <18) { bracket <-"<18"} elseif (age <=25) { bracket <-"18-25"} elseif (age <=40) { bracket <-"26-40"} elseif (age <=55) { bracket <-"41-55"} elseif (age <=65) { bracket <-"56-65"} else { bracket <-">65"}bracket
[1] "26-40"
Python uses elif as a shorthand for else if statements. As always, indentation/white space in python matters. If you put an extra blank line between two elif statements, then the interpreter will complain. If you don’t indent properly, the interpreter will complain.
age =40# change this to see how the code worksif age <18: bracket ="<18"elif age <=25: bracket ="18-25"elif age <=40: bracket ="26-40"elif age <=55: bracket ="41-55"elif age <=65: bracket ="56-65"else: bracket =">65"bracket
'26-40'
5.3.2 Loops
Often, we write programs which update a variable in a way that the new value of the variable depends on the old value:
x = x + 1
This means that we add one to the current value of x.
Before we write a statement like this, we have to initialize the value of x because otherwise, we don’t know what value to add one to.
x = 0
x = x + 1
We sometimes use the word increment to talk about adding one to the value of x; decrement means subtracting one from the value of x.
A particularly powerful tool for making these types of repetitive changes in programming is the loop, which executes statements a certain number of times. Loops can be written in several different ways, but all loops allow for executing a block of code a variable number of times.
5.3.2.1 While Loops
In the previous section, we discussed conditional statements, where a block of code is only executed if a logical statement is true.
The simplest type of loop is the while loop, which executes a block of code until a statement is no longer true.
Flow map showing while-loop pseudocode (while x <= N) { # code that changes x in some way} and the program flow map expansion where we check if x > N (exiting the loop if true); otherwise, we continue into the loop, execute the main body of #code and then change x and start over.
Write a while loop that verifies that \[\lim_{N \rightarrow \infty} \prod_{k=1}^N \left(1 + \frac{1}{k^2}\right) = \frac{e^\pi - e^{-\pi}}{2\pi}.\]
Terminate your loop when you get within 0.0001 of \(\frac{e^\pi - e^{-\pi}}{2\pi}\). At what value of \(k\) is this point reached?
Breaking down math notation for code:
If you are unfamiliar with the notation \(\prod_{k=1}^N f(k)\), this is the product of \(f(k)\) for \(k = 1, 2, ..., N\), \[f(1)\cdot f(2)\cdot ... \cdot f(N)\]
To evaluate a limit, we just keep increasing \(N\) until we get arbitrarily close to the right hand side of the equation.
In this problem, we can just keep increasing \(k\) and keep track of the cumulative product. So we define k=1, prod = 1, and ans before the loop starts. Then, we loop over k, multiplying prod by \((1 + 1/k^2)\) and then incrementing \(k\) by one each time. At each iteration, we test whether prod is close enough to ans to stop the loop.
In R, you will use pi and exp() - these are available by default without any additional libraries or packages.
k <-1prod <-1ans <- (exp(pi) -exp(-pi))/(2*pi)delta <-0.0001while (abs(prod - ans) >=0.0001) { prod <- prod * (1+1/k^2) k <- k +1}k
[1] 36761
prod
[1] 3.675978
ans
[1] 3.676078
Note that in python, you will have to import the math library to get the values of pi and the exp function. You can refer to these as math.pi and math.exp() respectively.
import mathk =1prod =1ans = (math.exp(math.pi) - math.exp(-math.pi))/(2*math.pi)delta =0.0001whileabs(prod - ans) >=0.0001: prod = prod * (1+ k**-2) k = k +1if k >500000:breakprint("At ", k, " iterations, the product is ", prod, "compared to the limit ", ans,".")
At 36761 iterations, the product is 3.675977910975878 compared to the limit 3.676077910374978 .
5.3.2.2 For Loops
Another common type of loop is a for loop. In a for loop, we run the block of code, iterating through a series of values (commonly, one to N, but not always). Generally speaking, for loops are known as definite loops because the code inside a for loop is executed a specific number of times. While loops are known as indefinite loops because the code within a while loop is evaluated until the condition is falsified, which is not always a known number of times.
Flow map showing for-loop pseudocode (for j in 1 to N) { # code} and the program flow map expansion where j starts at 1 and we check if j > N (exiting the loop if true); otherwise, we continue into the loop, execute the main body of #code and then increment j and start over.
for (i in1:5 ) {print(i)}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
for i inrange(5):print(i)
0
1
2
3
4
By default range(5) goes from 0 to 5, the upper bound. When i = 5 the loop exits. This is because range(5) creates a vector [0, 1, 2, 3, 4].
For loops are often run from 1 to N (or 0 to N-1 in python) but in essence, a for loop is run for every value of a vector (which is why loops are included in the same chapter as vectors).
For instance, in R, there is a built-in variable called month.name. Type month.name into your R console to see what it looks like. If we want to iterate along the values of month.name, we can:
In python, we have to define our vector or list to start out with, but that’s easy enough:
futurama_crew = ['Fry', 'Leela', 'Bender', 'Amy', 'the Professor', 'Hermes', 'Zoidberg', 'Nibbler']for i in futurama_crew:print(i)
Fry
Leela
Bender
Amy
the Professor
Hermes
Zoidberg
Nibbler
5.3.2.3 Avoiding Infinite Loops
It is very easy to create an infinite loop when you are working with while loops. Infinite loops never exit, because the condition is always true. If in the while loop example we decrement x instead of incrementing x, the loop will run forever.
You want to try very hard to avoid ever creating an infinite loop - it can cause your session to crash.
One common way to avoid infinite loops is to create a second variable that just counts how many times the loop has run. If that variable gets over a certain threshold, you exit the loop.
This while loop runs until either x < 10 or n > 50 - so it will run an indeterminate number of times and depends on the random values added to x. Since this process (a ‘random walk’) could theoretically continue forever, we add the n>50 check to the loop so that we don’t tie up the computer for eternity.
x <-0n <-0# count the number of times the loop runswhile (x <10) { print(x) x <- x +rnorm(1) # add a random normal (0, 1) draw each time n <- n +1if (n >50) break# this stops the loop if n > 50}
import numpy as np;# for the random normal drawx =0n =0# count the number of times the loop runswhile x <10:print(x) x = x + np.random.normal(0, 1, 1) # add a random normal (0, 1) draw each time n = n +1if n >50:break# this stops the loop if n > 50
In both of the examples above, there are more efficient ways to write a random walk, but we will get to that later. The important thing here is that we want to make sure that our loops don’t run for all eternity.
5.3.2.4 Controlling Loops
Sometimes it is useful to control the statements in a loop with a bit more precision. You may want to skip over code and proceed directly to the next iteration, or, as demonstrated in the previous section with the break statement, it may be useful to exit the loop prematurely.
for (i in1:20) {if (i %%15==0) {print("Exiting now")break } elseif (i %%3==0) { print("Divisible by 3")nextprint("After the next statement") # this should never execute } elseif (i %%5==0) {print("Divisible by 5") } else {print(i) }}
[1] 1
[1] 2
[1] "Divisible by 3"
[1] 4
[1] "Divisible by 5"
[1] "Divisible by 3"
[1] 7
[1] 8
[1] "Divisible by 3"
[1] "Divisible by 5"
[1] 11
[1] "Divisible by 3"
[1] 13
[1] 14
[1] "Exiting now"
for i inrange(1, 20):if i%15==0:print("Exiting now")breakelif i%3==0:print("Divisible by 3")continueprint("After the next statement") # this should never executeelif i%5==0:print("Divisible by 5")else: print(i)
1
2
Divisible by 3
4
Divisible by 5
Divisible by 3
7
8
Divisible by 3
Divisible by 5
11
Divisible by 3
13
14
Exiting now
To be quite honest, I haven’t really ever needed to use next/continue statements when I’m programming, and I rarely use break statements. However, it’s useful to know they exist just in case you come across a problem where you could put either one to use.
Footnotes
Throughout this section (and other sections), lego pictures are rendered using https://www.mecabricks.com/en/workshop. It’s a pretty nice tool for building stuff online!↩︎
A similar system exists in R libraries, but R doesn’t handle multiple libraries having the same function names well, which leads to all sorts of confusion. At least python is explicit about it.↩︎