A way of storing a number. You create a variable by assigning (`=`

) an expression (right-hand-side) to a name (left-hand-side).

In [1]:

```
x = 2
print(x)
```

In [2]:

```
print(x * 4)
```

In [3]:

```
x = x + 2
print(x)
```

In [4]:

```
import math
x = math.cos(43)
print(x)
```

In [5]:

```
a = 2
a = a * b
b = 4
```

Just like you remember to save you documents, be sure to store what you want in your variables.

In [6]:

```
x = 2
x * 2
print(x)
```

What's the point of having variables if we can't tell anyone about them?!?!

In [7]:

```
x = 4
print('This is the simple way of printing x', x)
```

In [8]:

```
y = 2.3
print('This is how we print x', x, 'and y', y, '. Notice spaces are inserted for us')
```

In [9]:

```
print('What if I want to print y ({}) without spaces?'.format(y))
```

In [10]:

```
z = 0.489349842432423829328933 * 10**32
print('{}'.format(z))
```

By using special character inside the `{}`

expression, we can modify how variables are output.

In [11]:

```
print('What if I want to print x twice, like this {0:} {0:}, and y once, {1:}?'.format(x,y))
```

In [12]:

```
print('With a fixed precision (number of digits): {:.4}'.format(z))
```

In [13]:

```
print('Make it take up exactly 10 spaces: {:10.4}'.format(z))
print('Make it take up exactly 10 spaces: {:10.4}'.format(math.pi))
print('Make it take up exactly 10 spaces: {:10.4}'.format(z*math.pi))
```

In [14]:

```
print('You can demand to show without scientific notation too: {:f}'.format(z))
```

In [15]:

```
print('or demand to use scientific notation: {:e}'.format(math.pi))
```

In [16]:

```
print('There are many more formatting tags, such as binary: {:b} and percentage: {:%}'.format(43, 0.23))
```

Consider a model where the computer uses 8 bit numbers (1 byte). You could represent $[0,2^8-1]$.

In [17]:

```
%%bash
pip install fixedint
```

In [18]:

```
from fixedint import *
def bprint(x):
print('{0:08b} ({0:})'.format(x))
```

In [19]:

```
i = UInt8(8)
bprint(i)
```

In [20]:

```
i = UInt8(24)
bprint(i)
```

In [21]:

```
i = UInt8(2**8 - 1)
bprint(i)
```

In [22]:

```
i = UInt8(2**8)
bprint(i)
```

This effect, where if we add 1 too many to a number and "roll-over" to the beginnig is called **integer overflow**. This is a common bug in programming, where a number becomes too large and then rolls-back.

Ineger overflow can result in negative numbers, if we have signed numbers.

In [23]:

```
i = Int8(2**7 - 1)
bprint(i)
bprint(i + 1)
```

Notice here that our max is half previously, because one of our 8 bits is for sign, so only 7 bits are available for integers. *The key takeaway from integer overflow is that if we have integers with not enough bytes, we can suddenly have negative numbers or zero when adding large numbers*. Real world examples of integer overflow include view counts becoming 0, having data usage become negative on a cellphone, the Y2K bug, a step counter going to 0 steps.