In [1]:

```
# Don't worry about what this code does, but make sure to run it if you're following along.
from IPython.display import IFrame
def show_nested_eval():
src = 'https://docs.google.com/presentation/d/e/2PACX-1vQpW0NzwT3LjZsIIDAgtSMRM1cl41Gp_Lf8k9GT-gm5sGAIynw4rsgiEFbIybClD6QtxarKaVKLbR9U/embed?start=false&loop=false&delayms=60000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"'
width = 960
height = 569
return IFrame(src, width, height)
```

- Lab 0 is out and is due on
**Tuesday, April 11th at 11:59PM**.- It contains a video 🎥 towards the end: Navigating DataHub and Jupyter Notebooks. Watching it should be a worthwhile investment of your time!
- Post on Ed or come to office hours for help!

- Discussion meets today at 2PM (A) and 3PM (B).
- You can attend either section, as long as there is space for students officially enrolled in that section (so if you can, attend the one you're officially enrolled in). Read more in the syllabus.
- Today's discussion is about getting started with Jupyter Notebooks; the exam-prep format will start next week. Extra credit starts today.

- Please fill out the Welcome Survey!

- What is code? What are Jupyter Notebooks?
- Expressions.
- Variables.
- Call expressions.
- Data types.

There will be lots of programming – follow along in the notebook by clicking the "Expressions and Data Types" link on the course website.

- Instructions for computers are written in
**programming languages**, and are referred to as**code**. - “Computer programs” are nothing more than
**recipes**: we write programs that tell the computer exactly what to do, and it does exactly that – nothing more, and nothing less.

- It's popular!

- It has a variety of use cases.
- Web development.
- Data science and machine learning.

- It's (relatively) easy to dive right in! 🏊

**Jupyter Notebooks**allow us to write and run code within a single document. They also allow us to embed text and code.**We will be using Jupyter Notebooks throughout the quarter**.

- The lecture slides you're viewing right now are also in the form of a Jupyter Notebook – we're just using an extension (called
*RISE*) to make them look like slides. - When you click a lecture DataHub link on the course website, you'll see the lecture notebook in regular notebook form.
- To view it in slides form, click the bar chart button in the toolbar.

- An
**expression**is a combination of values, operators, and functions that**evaluates**to some**value**.

- For now, let's think of Python like a calculator – it takes expressions and evaluates them.

- We will enter our expressions in
**code cells**. To run a code cell, either:**Hit**, or`shift`

+`enter`

(or`shift`

+`return`

) on your keyboard (strongly preferred)- Press the "▶ Run" button in the toolbar.

In [2]:

```
23
```

Out[2]:

23

In [3]:

```
-15 + 2.718
```

Out[3]:

-12.282

In [4]:

```
4 ** 3
```

Out[4]:

64

In [5]:

```
(2 + 3 + 4) / 3
```

Out[5]:

3.0

In [6]:

```
# Only one value is displayed. Why?
9 + 10
13 / 4
21
```

Out[6]:

21

Operation | Operator | Example | Value |
---|---|---|---|

Addition | `+` |
`2 + 3` |
`5` |

Subtraction | `-` |
`2 - 3` |
`-1` |

Multiplication | `*` |
`2 * 3` |
`6` |

Division | `/` |
`7 / 3` |
`2.66667` |

Remainder | `%` |
`7 % 3` |
`1` |

Exponentiation | `**` |
`2 ** 0.5` |
`1.41421` |

In [7]:

```
5 * 2 ** 3
```

Out[7]:

40

In [8]:

```
(5 * 2) ** 3
```

Out[8]:

1000

In the cell below, replace the ellipses with an expression that's equivalent to

$$(19 + 6 \cdot 3) - 15 \cdot \left(\sqrt{100} \cdot \frac{1}{30}\right) \cdot \frac{3}{5} + \frac{4^2}{2^3} + \left( 6 - \frac{2}{3} \right) \cdot 12 $$Try to use parentheses only when necessary.

In [9]:

```
...
```

Out[9]:

Ellipsis

Below, we compute the number of seconds in a year.

In [10]:

```
60 * 60 * 24 * 365
```

Out[10]:

31536000

**This is inconvenient, and prone to introducing errors.**

In [11]:

```
60 * 60 * 24 * 365 * 12
```

Out[11]:

378432000

It would be great if we could **store** the initial value and refer to it later on!

- A
**variable**is a place to store a value so that it can be referred to later in our code. To define a variable, we use an**assignment statement**.

- An assignment statement changes the meaning of the
**name**to the left of the`=`

symbol.

- The expression on the right-hand side of the
`=`

symbol is evaluated before being assigned to the name on the left-hand side.- e.g.
`zebra`

is bound to`9`

(value) not`23 - 14`

(expression).

- e.g.

In [12]:

```
# Note: This is an assignment statement, not an expression.
# Assignment statements don't output anything!
a = 1
```

In [13]:

```
a = 2
```

In [14]:

```
b = 2
```

Note that before we use it in an assignment statement, `triton`

has no meaning.

In [15]:

```
triton
```

After using it in an assignment statement, we can ask Python for its value.

In [16]:

```
triton = 15 - 5
```

In [17]:

```
triton
```

Out[17]:

10

Any time we use `triton`

in an expression, `10`

is substituted for it.

In [18]:

```
triton * -4
```

Out[18]:

-40

**did not change** the value of `triton`

, because **we did not re-assign triton**!

In [19]:

```
triton
```

Out[19]:

10

- Give your variables helpful names so that you know what they refer to.
- Variable names can contain uppercase and lowercase characters, the digits 0-9, and underscores.
- They cannot start with a number.
- They are case sensitive!

The following assignment statements are **valid**, but use **poor** variable names 😕.

In [20]:

```
six = 15
```

In [21]:

```
i_45love_chocolate_9999 = 60 * 60 * 24 * 365
```

The following assignment statements are **valid**, and use **good** variable names ✅.

In [22]:

```
seconds_per_hour = 60 * 60
hours_per_year = 24 * 365
seconds_per_year = seconds_per_hour * hours_per_year
```

The following "assignment statements" are **invalid ❌**.

In [23]:

```
7_days = 24 * 7
```

In [24]:

```
3 = 2 + 1
```

- Unlike in math, where $x = 3$ means the same thing as $3 = x$, assignment statements are
**not**"symmetric". - An assignment statement assigns (or "binds") the name on the left of
`=`

to the value to the right of`=`

, nothing more.

In [25]:

```
x = 3
```

In [26]:

```
3 = x
```

In [27]:

```
uc = 2
sd = 3 + uc
```

Assignment statements are **not promises** – the value of a variable can change!

In [28]:

```
uc = 7
```

Note that even after changing `uc`

, we did not change `sd`

, so it is still the same as before.

In [29]:

```
sd
```

Out[29]:

5

Assume you have run the following three lines of code:

```
side_length = 5
area = side_length ** 2
side_length = side_length + 2
```

What are the values of `side_length`

and `area`

after execution?

A. `side_length = 5`

, `area = 25`

B. `side_length = 5`

, `area = 49`

C. `side_length = 7`

, `area = 25`

D. `side_length = 7`

, `area = 49`

E. None of the above

`tab`

to autocomplete a set name¶In [30]:

```
...
```

Out[30]:

Ellipsis

- In math, functions take in some input and return some output.

- We can determine the output of a function even if we pass in complicated-looking inputs.

- Functions in Python work the same way functions in math do.
- The inputs to functions are called
**arguments**. - To use a function, we run a
**call expression**, which tells a function to "run its recipe".

In [31]:

```
abs(-23)
```

Out[31]:

23

In [32]:

```
max(4, -8)
```

Out[32]:

4

In [33]:

```
max(2, -3, -6, 10, -4)
```

Out[33]:

10

In [34]:

```
max(9)
```

In [35]:

```
# Only two arguments!
max(9 + 10, 9 - 10)
```

Out[35]:

19

`?`

after a function's name to see its documentation 📄¶Or use the `help`

function, e.g. `help(round)`

.

In [36]:

```
round(1.45678)
```

Out[36]:

1

In [37]:

```
round?
```

In [38]:

```
round(1.45678, 3)
```

Out[38]:

1.457

We can **nest** many function calls to evaluate sophisticated expressions.

In [39]:

```
min(abs(max(-1, -2, -3, min(4, -2))), max(5, 100))
```

Out[39]:

1

...how did that work?

In [40]:

```
show_nested_eval()
```

Out[40]:

- Python doesn't have everything we need built in.
- In order to gain additional functionality, we import
**modules**through**import statements**. **Modules**are collections of Python functions and values.- Call these functions using the syntax
`module.function()`

, called "dot notation".

`import math`

¶Some of the many functions built into the `math`

module are `sqrt`

, `pow`

, and `log`

.

In [41]:

```
import math
```

In [42]:

```
math.sqrt(16)
```

Out[42]:

4.0

In [43]:

```
math.pow(2, 5)
```

Out[43]:

32.0

In [44]:

```
# What base is log?
math.log?
```

In [45]:

```
# Tab completion for browsing.
math.
```

`math`

also has constants built in!

In [46]:

```
math.pi
```

Out[46]:

3.141592653589793

Assume you have run the following statements:

```
x = 3
y = -2
```

Which of these examples results in an error?

A. `abs(x, y)`

B. `math.pow(x, abs(y))`

C. `round(x, max(abs(y ** 2)))`

D. `math.pow(x, math.pow(y, x))`

E. More than one of the above

In [47]:

```
4 / 2
```

Out[47]:

2.0

In [48]:

```
5 - 3
```

Out[48]:

2

To us, `2.0`

and `2`

are the same number, $2$. But to Python, these appear to be different!

- Every value in Python has a
**type**.- Use the
`type`

function to check a value's type.

- Use the
- It's important to understand how different types work with different operations, as the results may not always be what we expect.

`int`

and `float`

¶`int`

: An integer of any size.`float`

: A number with a decimal point.

`int`

¶- If you add (
`+`

), subtract (`-`

), multiply (`*`

), or exponentiate (`**`

)`int`

s, the result will be another`int`

. `int`

s have arbitrary precision in Python, meaning that your calculations will always be exact.

In [49]:

```
7 - 15
```

Out[49]:

-8

In [50]:

```
type(7 - 15)
```

Out[50]:

int

In [51]:

```
2 ** 300
```

Out[51]:

2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376

In [52]:

```
2 ** 3000
```

Out[52]:

1230231922161117176931558813276752514640713895736833715766118029160058800614672948775360067838593459582429649254051804908512884180898236823585082482065348331234959350355845017413023320111360666922624728239756880416434478315693675013413090757208690376793296658810662941824493488451726505303712916005346747908623702673480919353936813105736620402352744776903840477883651100322409301983488363802930540482487909763484098253940728685132044408863734754271212592471778643949486688511721051561970432780747454823776808464180697103083861812184348565522740195796682622205511845512080552010310050255801589349645928001133745474220715013683413907542779063759833876101354235184245096670042160720629411581502371248008430447184842098610320580417992206662247328722122088513643683907670360209162653670641130936997002170500675501374723998766005827579300723253474890612250135171889174899079911291512399773872178519018229989376

`float`

¶- A
`float`

is specified using a**decimal**point. - A
`float`

might be printed using scientific notation.

In [53]:

```
3.2 + 2.5
```

Out[53]:

5.7

In [54]:

```
type(3.2 + 2.5)
```

Out[54]:

float

In [55]:

```
# The result is in scientific notation: e+90 means "times 10^90".
2.0 ** 300
```

Out[55]:

2.037035976334486e+90

`float`

¶`floats`

have limited precision; after arithmetic, the final few decimal places can be wrong in unexpected ways.`float`

s have limited size, though the limit is huge.

In [56]:

```
1 + 0.2
```

Out[56]:

1.2

In [57]:

```
1 + 0.1 + 0.1
```

Out[57]:

1.2000000000000002

In [58]:

```
2.0 ** 3000
```

`int`

and `float`

¶- If you mix
`int`

s and`float`

s in an expression, the result will always be a`float`

.- Note that when you divide two
`int`

s, you get a`float`

back.

- Note that when you divide two
- A value can be explicity
**coerced**(i.e. converted) using the`int`

and`float`

functions.

In [59]:

```
2.0 + 3
```

Out[59]:

5.0

In [60]:

```
12 / 2
```

Out[60]:

6.0

In [61]:

```
# Want an integer back.
int(12 / 2)
```

Out[61]:

6

In [62]:

```
# int chops off the decimal point!
int(-2.9)
```

Out[62]:

-2

Our notebook **still** remembers all of the variables we defined earlier in the lecture.

In [63]:

```
triton
```

Out[63]:

10

- However, if you come back to your notebook after a few hours, it will usually "forget" all of the variables it once knew about.
- When this happens, you will need to run the cells in your notebook again.
- See Navigating DataHub and Jupyter Notebooks and Discussion 1 for more.

- Expressions evaluate to values. Python will display the value of the last expression in a cell by default.
- Python knows about all of the standard mathematical operators and follows PEMDAS.
- Assignment statements allow us to bind values to variables.
- We can call functions in Python similar to how we call functions in math.
- Python knows some functions by default, and import statements allow us to bring additional functionality from modules.

- All values in Python have a data type.
`int`

s and`float`

s are numbers.`int`

s are integers, while`float`

s contain decimal points.

- We'll learn about strings, a data type in Python designed to store text.
- We'll also learn how to store sequences, or many pieces of information, in a single variable.

**Note**: We will introduce some code in labs and homeworks as well. Not everything will be in lecture. **You will learn by doing!**