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)

Lecture 2 – Expressions and Data Types¶

DSC 10, Winter 2023¶

Announcements¶

  • Lab 0 is released and is due Saturday at 11:59PM.
    • It contains a video 🎥 towards the end, Navigating DataHub and Jupyter Notebooks. Watching this video should be a worthwhile investment of your time! ⌚
    • Post on EdStem or come to office hours for help!
  • Discussion meets today at 1pm and 2pm.
    • You must attend the discussion you've been assigned to. See this table.
    • Today's discussion is about getting started with Jupyter Notebooks.
  • Fill out the Beginning of Quarter Survey.

Agenda¶

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

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

What is code? What are Jupyter Notebooks? 💻¶

What is code?¶

  • 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.

Why Python?¶

  • Popular.
  • Variety of uses.
    • Web development.
    • Data science and machine learning.
    • Not really used for developing applications.
  • Easy to dive right in!

Jupyter Notebooks 📓¶

  • Often, but not in this class, code is written in a text editor and then run in a command-line interface.
  • 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.
  • DataHub is a server that allows you to run Jupyter Notebooks from your web browser without having to install any software locally.

Aside: lecture slides¶

  • 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" 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.
This button!

Expressions¶

Python as a calculator¶

  • 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 shift + enter (or shift + return) on your keyboard (strongly preferred), or
    • Press the "▶ Run" button in the toolbar.
In [2]:
17
Out[2]:
17
In [3]:
-1 + 3.14
Out[3]:
2.14
In [4]:
2 ** 3
Out[4]:
8
In [5]:
(17 - 14) / 2
Out[5]:
1.5
In [6]:
# Only one value is displayed. Why?
3 * 4
5
Out[6]:
5

Arithmetic operations¶

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

Python uses the typical order of operations – PEMDAS (BEDMAS? 🛏️)¶

In [7]:
3 * 2 ** 2
Out[7]:
12
In [8]:
(3 * 2) ** 2
Out[8]:
36

Activity¶

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

Variables¶

Motivation¶

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

In [10]:
60 * 60 * 24 * 365
Out[10]:
31536000

If we want to use the above value later in our notebook to find, say, the number of seconds in 12 years, we'd have to copy-and-paste the expression. 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!

Variables and assignment statements¶

  • 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.
$$ \overbrace{\texttt{myvariable}}^{\text{name}} = \overbrace{\texttt{2 + 3}}^{\text{any expression}} $$
  • 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. myvariable is bound to 5 (value) not 2 + 3 (expression).

Note that before we use it in an assignment statement, more_than_1 has no meaning.

In [12]:
more_than_1
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/var/folders/ch/hyjw6whx3g9gshnp58738jc80000gp/T/ipykernel_2277/3210039468.py in <module>
----> 1 more_than_1

NameError: name 'more_than_1' is not defined

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

In [13]:
# Note that an assignment statement doesn't output anything!
more_than_1 = 15 - 5
In [14]:
more_than_1
Out[14]:
10

Any time we use more_than_1 in an expression, 10 is substituted for it.

In [15]:
more_than_1 * 2
Out[15]:
20

Note that the above expression did not change the value of more_than_1, because we did not re-assign more_than_1!

In [16]:
more_than_1
Out[16]:
10

Naming variables¶

  • Generally, 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 [17]:
six = 15
In [18]:
i_45love_chocolate_9999 = 60 * 60 * 24 * 365

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

In [19]:
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 [20]:
6 = 15
  File "/var/folders/ch/hyjw6whx3g9gshnp58738jc80000gp/T/ipykernel_2277/2046484920.py", line 1
    6 = 15
    ^
SyntaxError: cannot assign to literal
In [21]:
3 = 2 + 1
  File "/var/folders/ch/hyjw6whx3g9gshnp58738jc80000gp/T/ipykernel_2277/2449763097.py", line 1
    3 = 2 + 1
    ^
SyntaxError: cannot assign to literal

Assignment statements are not mathematical equations!¶

  • 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 [ ]:
x = 3
x
In [ ]:
4 = x

A variable's value is set at the time of assignment¶

In [22]:
uc = 2
sd = 3 + uc

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

In [23]:
uc = 7

Note that even after changing uc, we did not change sd, so it is still the same as before.

In [24]:
sd
Out[24]:
5

A helpful analogy¶

  • A common metaphor is that variables are like boxes or containers (source).
  • Another analogy: an assignment statement is like placing a sticker on a value.

Concept Check ✅ – Answer at cc.dsc10.com¶

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

In [ ]:
 

Aside: hit tab to autocomplete a set name¶

In [25]:
...
Out[25]:
Ellipsis

Call expressions 📞¶

Algebraic functions¶

  • In math, functions take in some input and return some output.
$$f(x, y) = 2x^2 + 3xy - 1$$
  • We can determine the output of a function even if we pass in complicated things.
$$f\left(\frac{1+2}{3+4}, (-1)^{15}\right)$$

Call expressions¶

  • Call expressions in Python invoke functions – they tell a function to "run its recipe".
  • Functions in Python work the same way functions in math do.
  • The inputs to functions are called arguments.
In [26]:
abs(-12)
Out[26]:
12

Some functions can take a variable number of arguments¶

In [27]:
max(3, -4)
Out[27]:
3
In [28]:
max(2, -3, -6, 10, -4)
Out[28]:
10
In [29]:
# Only two arguments!
max(4 + 5, 5 - 4)
Out[29]:
9

Use the ? after a function to see the documentation for a function¶

Or, use the help function, e.g. help(max).

In [30]:
max?

Example: round¶

In [31]:
my_number = 1.22
round(my_number)
Out[31]:
1
In [32]:
round?
In [33]:
round(1.22222, 3)
Out[33]:
1.222

Nested evaluation¶

We can nest many function calls to evaluate sophisticated expressions.

In [34]:
min(abs(max(-1, -2, -3, min(4, -2))), max(5, 100))
Out[34]:
1

...how did that work?

In [35]:
show_nested_eval()
Out[35]:

Import statements¶

  • Python doesn't have everything we need built in.
  • In order to gain additional functionality, we import modules via import statements.
  • Modules can be thought of as collections of Python functions and values.
  • Call these functions using the syntax module.function(), called "dot notation".

Example: import math¶

sqrt, log, pow, etc.

In [36]:
import math
In [37]:
math.sqrt(9)
Out[37]:
3.0
In [38]:
math.pow(3, 2)
Out[38]:
9.0
In [39]:
# What base is log?
math.log?http://localhost:8888/notebooks/Documents/GitHub/dsc10-2023-wi-private/lectures/lec02/lec02.ipynb#
In [40]:
# Tab completion for browsing
math.
  File "/var/folders/ch/hyjw6whx3g9gshnp58738jc80000gp/T/ipykernel_2277/3814339723.py", line 2
    math.
         ^
SyntaxError: invalid syntax

It also has constants built-in!

In [41]:
math.pi
Out[41]:
3.141592653589793

Concept Check ✅ – Answer at cc.dsc10.com¶

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 [ ]:
 

Data types¶

What's the difference? 🧐¶

In [42]:
4 / 2
Out[42]:
2.0
In [43]:
5 - 3
Out[43]:
2

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

Data types¶

  • Every value in Python has a type.
    • Use the type function to check a value's type.
  • It's important to understand how different types work with different operations, as the results may not always be what we expect.

Two numeric data types: int and float¶

  • int : An integer of any size.
  • float: A number with a decimal point.

int¶

  • If you use these operations between ints (+, -, *, **), the result will be another int.
  • ints have arbitrary precision in Python, meaning that your calculations will always be exact.
In [44]:
3 + 5
Out[44]:
8
In [45]:
type(3 + 5)
Out[45]:
int
In [46]:
2 ** 300
Out[46]:
2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376
In [47]:
2 ** 3000
Out[47]:
1230231922161117176931558813276752514640713895736833715766118029160058800614672948775360067838593459582429649254051804908512884180898236823585082482065348331234959350355845017413023320111360666922624728239756880416434478315693675013413090757208690376793296658810662941824493488451726505303712916005346747908623702673480919353936813105736620402352744776903840477883651100322409301983488363802930540482487909763484098253940728685132044408863734754271212592471778643949486688511721051561970432780747454823776808464180697103083861812184348565522740195796682622205511845512080552010310050255801589349645928001133745474220715013683413907542779063759833876101354235184245096670042160720629411581502371248008430447184842098610320580417992206662247328722122088513643683907670360209162653670641130936997002170500675501374723998766005827579300723253474890612250135171889174899079911291512399773872178519018229989376

float¶

  • A float is specified using a decimal point.
  • A float might be printed using scientific notation.
In [48]:
2.0 + 3.2
Out[48]:
5.2
In [49]:
type(2.0 + 3.2)
Out[49]:
float
In [50]:
2.0 ** 300
Out[50]:
2.037035976334486e+90

The pitfalls of float¶

  • floats have limited size (but the limit is huge).
  • floats have limited precision of 15-16 decimal places.
  • After arithmetic, the final few decimal places can be wrong in unexpected ways (limited precision!).
In [51]:
1 + 0.2
Out[51]:
1.2
In [52]:
1 + 0.1 + 0.1
Out[52]:
1.2000000000000002
In [53]:
2.0 ** 3000
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
/var/folders/ch/hyjw6whx3g9gshnp58738jc80000gp/T/ipykernel_2277/1310821553.py in <module>
----> 1 2.0 ** 3000

OverflowError: (34, 'Result too large')

Type coercion between int and float¶

  • By default, Python changes an int to a float in a mixed expression involving both types.
    • Note that the division of two ints automatically returns a float value.
  • A value can be explicity coerced (i.e. converted) using the int and float functions.
In [54]:
2.0 + 3
Out[54]:
5.0
In [55]:
2 / 1
Out[55]:
2.0
In [56]:
# Want an integer back
int(2 / 1)
Out[56]:
2
In [57]:
# int chops off the decimal point, effectively rounding DOWN
int(3.9)
Out[57]:
3

Aside: Jupyter memory model¶

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

In [58]:
more_than_1
Out[58]:
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 for more.

Summary, next time¶

Summary¶

  • 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.
    • ints and floats are numbers.
    • ints are integers, while floats contain decimal points.

Next time¶

  • 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!