# Subsections of Numbers & Math

# Integers

YouTube Video#### Resources

So far, we’ve only worked with **string** values in Python. Strings are a very useful **data type** in programming languages such as Python, but they are very limited in their use. Recall that a **data type** simply defines how a particular value is stored in a computer. The ** str** data type is used to store string values in Python.

Python supports many different data types for handling various data that we’d like to store and manipulate in our programs. In this lab, we’re going to cover the two basic types used for storing numbers in Python, the ** int** or integer type, and the

**or floating-point type.**

`float`

## Integers

In mathematics, an **integer** is a whole number, such as
$ 3 $,
$ -5 $, or even
$ 0 $. Basically, any positive or negative number that doesn’t include a fractional or decimal portion is a whole number, and therefore it is an **integer**. In Python, those numbers can be stored in the ** int** data type.

In Python, we can store an integer value in a variable using an assignment statement:

`x = 5`

That statement will store the integer value
$ 5 $ in the variable `x`

. Notice that the value
$ 5 $ does not have quotation marks around it. This is because we want to store the integer value
$ 5 $ and not the string value `"5"`

in the variable. Also, as we learned earlier, this is why we cannot create variable names that begin with a number - since numerical values start with a number, this is how Python can tell the difference between a numerical value and a variable.

We can also store negative numbers in a variable by placing a negative symbol `-`

in front of the numerical value:

`y = -8`

We’ll need to be careful and make sure that there is a space after the equals sign `=`

, but no space between the negative symbol `-`

and the number after it. Otherwise, the negative symbol could be confused for the minus symbol, which is an operator that we’ll learn about later in this lab.

In Python, there is effectively no maximum size for an integer, so we can store any arbitrarily large whole number (either positive or negative) in an `int`

variable.

# Subsections of Integers

# Floats

YouTube Video#### Resources

The other type of number we can store in Python is a **floating-point** number. We won’t go into too much detail about floating-point values here, since you’ll learn about them elsewhere in this class. For the purposes of programming, the only thing to know about floating-point numbers is that they are used to represent numbers that include a fractional or decimal portion. In Python, these values are stored in the ** float** data type.

To create a variable that stores a floating-point value in Python, we can use an assignment statement that includes a value with a decimal point, like this:

`a = 5.8`

We can also create negative values using the negative symbol `-`

:

`b = -7.987`

Finally, it is possible to store a whole number in a floating-point value by simply adding a decimal point and a `0`

at the end of the value, as in this example:

`c = 42.0`

Later in this lab, we’ll see a couple of situations where that may be useful.

For now, we’re just going to assume that Python can easily handle any reasonable number we want it to store in a `float`

variable, but there are some limits to the size and accuracy of those numbers. To reach these limits, we usually have to be dealing with numbers that have
$ 100 $ or more digits, either before or after the decimal place. So, for the purposes of this class, those limits really won’t apply to what we’re doing. You’ll learn about these limits in detail in later programming classes.

# Subsections of Floats

# Types

YouTube Video#### Resources

## Determining Variable Type

One thing that is very useful to know how to do in Python is determining the type of data stored in a variable. Python is very flexible, and we can store any type of data in any variable. In fact, a variable’s data type can even change in Python, which is something that many other programming languages won’t allow. Technically speaking, we would say that Python uses **strong typing**, which means that each variable has a known data type that we can find, and **dynamic typing**, meaning that the type of the variable can change while the program is running.

To determine the type of a variable, we can use the `type(expression)`

function in Python. We can simply place any variable or expression in the `expression`

argument, and then it will tell us the type of the value that results from evaluating that expression. Then, we can simply use the `print()`

function to print it to the screen. We won’t use this in our programs themselves, but it can be helpful for debugging purposes or to just better understand what is going on with data types.

Here’s a quick example program showing the `type()`

function in Python:

```
x = "Hello"
y = 5
z = 6.7
print(type(x))
print(type(y))
print(type(z))
```

When we execute this code in Python, we should see the following output:

```
<class 'str'>
<class 'int'>
<class 'float'>
```

Based on that output, we can assume that the variable `x`

is the `str`

data type for strings, `y`

is the `int`

data type for whole numbers, and `z`

is the `float`

data type for decimal numbers. The `type()`

function is pretty handy!

## Converting Between Data Types

We can also convert values between the various data types in Python. To do this, there are special functions that match the name of the data types themselves. So, to convert any value to a string, we can use the `str()`

function. Likewise, to convert anything to an integer, we can use the `int()`

function. And finally, to convert anything to a floating-point value, we can use the `float()`

function.

So, we can extend the previous example a bit by showing how we can convert values between different data types:

```
x = "5.7"
print(x)
print(type(x))
print()
y = float(x)
print(y)
print(type(y))
print()
z = int(y)
print(z)
print(type(z))
```

When we run this program, we’ll get this output:

```
5.7
<class 'str'>
5.7
<class 'float'>
5
<class 'int'>
```

In this program, we’re starting with the string value `"5.7"`

stored in variable `x`

. So, the first two `print()`

statements will print that string value, and show that `x`

is indeed storing a `str`

data type. Then, we’ll use the `float()`

function to convert the string value `"5.7"`

stored in `x`

to the floating-point value
$ 5.7 $ and store that in `y`

. The next two print statements will print that value, and show that `y`

is storing a `float`

data type. Notice that the value printed for both variables `x`

and `y`

looks identical, but the data type of each variable is different!

Finally, we can use the `int()`

function to convert the floating-point value
$ 5.7 $ to an integer. In math, when we are asked to convert the number
$ 5.7 $ to a whole number, our first instinct is probably to just round up to
$ 6 $, since that is the closest value. However, in Python, as in most other programming languages, this function will simply **truncate** the value instead. **Truncating** a value simply means we take off the end of the value, so to convert
$ 5.7 $ to an integer we just remove the decimal portion, and we’re left with the value
$ 5 $. So, in the output above, we see that `z`

stores the integer value
$ 5 $, and it is the `int`

data type.

Notice that we are careful to say that the `int()`

function will **truncate** the value, and not that it will round down. This is due to how Python handles negative numbers like
$ -5.7 $. When converting that to an integer, it will also truncate it to
$ -5 $ instead of rounding down to
$ -6 $. So, we use the word **truncate** as the best way to describe the `int()`

function.

## Exceptions

Since we are running our Python programs on a real computer, we have to be a bit careful about how we use these functions. Specifically, if we try to convert a value to a different data type and Python can’t figure out how to do that, we’ll cause an **exception** to occur. An **exception** in programming is any error that happens when the computer tries to run our code.

For example, what if we try to convert the string value `"5.7"`

directly to an `int`

data type, as in this example:

```
a = "5.7"
print(a)
print(type(a))
print()
b = int(a)
print(b)
print(type(b))
```

When we try to run this code in a file, such as the `tutor.py`

file shown here, we’ll see this output printed on the terminal:

```
5.7
<class 'str'>
Traceback (most recent call last):
File "tutor.py", line 5, in <module>
b = int(a)
ValueError: invalid literal for int() with base 10: '5.7'
```

Uh oh! That’s not good. In the output, we can see that we’ve caused a `ValueError`

, which is an exception that happens when we try to use a value in an incorrect way. So, we’ll need to carefully look at our code to see if we can find and fix the error.

Thankfully, in the output, it will tell us that the error occurred on line 5 of the file `tutor.py`

, so we can open that file and scroll to that line of code:

`b = int(a)`

This is where the error occurred. There are several ways we can fix it. The easiest would be to simply convert `a`

to a floating-point value using the `float()`

function instead.

Learning how to find and fix these exceptions is a key part of learning how to program. We’ll inevitably run into a few exceptions as we start to build larger and more complex programs. In this course, most exceptions can be easily handled simply by working carefully through the code, but every once in a while we may run into an exception that is truly difficult to solve. That’s one of the important things to remember when learning how to program - it is sometimes much easier to cause an exception than it is to figure out how to fix it, and sometimes you may need to reach out for help to get past a particularly tricky exception. So, don’t be afraid to ask the instructors or TAs for help if you get stuck on an exception. Many times, it’s a great chance for you to learn some new programming skills.

# Subsections of Types

# Basic Operators

YouTube Video#### Resources

Now that we have the ability to store numerical data in variables in Python, we should also learn how to manipulate that data into something new. To do that, let’s learn about **operators**. An **operator** in programming is a special symbol that can be used in an expression to manipulate the data in some way.

Most operators are **binary operators**, which means they perform an operation that uses two values as input and produces a single value as output. In fact, in some programming languages, the operators themselves are implemented as functions in the language! Finally, we have to be careful not to confuse these with **bitwise operators**, which are operators perform operations on the binary value stored in a variable. We won’t cover those operators in this class, but the terminology is a bit confusing.

An expression containing a binary operator typically follows this format:

`<expression> <operator> <expression>`

As before, the `<expression>`

parts can be any valid expression in the language that can be reduced to a single value, and the `<operator>`

part is typically a single symbol, but it can also be a short keyword as well.

Thankfully, these operators should all be very familiar to us from mathematics already, so this is just a quick discussion of how they can be used in programming.

## Addition and Subtraction

For starters, we can use the plus `+`

and minus `-`

symbols as operators to perform addition and subtraction in Python, just like in math. For example, we can add two variables together to create a third variable as shown in this example:

```
a = 5
b = 7
c = a + b
print(c)
```

When we run this code in the Python interpreter, we should get this result:

`12`

Likewise, we can subtract two variables using the minus symbol `-`

as shown here:

```
x = 24
y = 10
z = x - y
print(z)
```

This code should produce this output:

`14`

## Multiplication and Division

In Python, we use the asterisk `*`

, sometimes referred to as the star symbol, to multiply two values together. For example, we can find the product of two values as shown in this Python block:

```
a = 6
b = 7
c = a * b
print(c)
```

When we run this code, we should see the following result displayed to the user:

`42`

Division is performed using the slash `/`

symbol. A great way to think of division in programming is just like a fraction, since it uses the same symbol between the two numbers. For example, if we execute this code:

```
x = 27
y = 3
z = x / y
print(z)
```

we would see this output:

`9.0`

What if the division would result in a remainder? In that case, we’ll simply use decimal values in Python so that the result is exactly correct. For example, if we try to divide $ 19 $ by $ 5 $, as in this example:

```
a = 19
b = 5
c = a / b
print(c)
```

When we run this code, the Python interpreter will produce the following output:

`3.8`

So, as we can see, all of these operators in Python work exactly like their counterparts in math. So, we can easily use them in a way that should be very familiar to us.

# Subsections of Basic Operators

# New Operators

YouTube Video#### Resources

## Modulo Operator

The Python programming language also includes a few math operators that are not commonly used outside of programming.

The first one is the **modulo operator**. The **modulo operator** is used to find the **remainder** of a division operation. If we think back to math again, we’ve probably learned how to perform long division when dividing two values. At the end, we might be left with a remainder, or a portion of the first number that is left over after the operation is complete. In many computer programs, that value is very useful, so we have a special operator we can use to find that value. In Python, we use the percent symbol `%`

as the modulo operator.

For example, if we want to find the remainder after dividing $ 19 $ by $ 5 $, we would use the following code:

```
x = 19
y = 5
z = x % y
print(z)
```

When we run this code, we would get the following output:

`4`

This is because the value $ 5 $ will fit into the value $ 19 $ only $ 3 $ times, and then we’ll have the value $ 4 $ left over. Mathematically, we are saying that $ 19 / 5 = (3 * 5) + 4 $. Since $ 4 $ is the leftover portion, it is the resulting value when we use the modulo operator.

In this course, we’ll only worry about how the modulo operator works when applied to positive whole numbers. In practice, it can be applied to any numerical value, including decimal values and negative numbers, but those values are not really useful in most cases. So, to keep things simple, we’ll only use positive whole numbers with this operator.

## Exponentiation Operator

The next operator introduced by Python is the **exponentiation operator**. The double star `**`

operator is used to represent exponentiation, sometimes referred to the power operator. In Python, the expression `2 ** 3`

would be written mathematically as
$ 2^3 $, which is the operation of taking
$ 2 $ to the power of
$ 3 $, or multiplying
$ 2 $ by itself
$ 3 $ times.

Here’s a quick example of using the `**`

operator in code:

```
x = 5 ** 3
print(x)
print(type(x))
```

When this code is run, we see the following output:

```
125
<class 'int'>
```

||| growthhack

# Don’t Use the Carat `^`

!

Many other programming languages and tools use the carat `^`

character to represent the exponentiation operation. However, in Python, the carat `^`

character is used to represent the bitwise XOR operation. So, we must be careful not to accidentally use the `^`

operator when we actually mean to use the `**`

operator for exponentiation.

|||

## Integer Division Operator

Finally, Python also includes the integer division operator, represented by two forward slashes `//`

, which is used to perform division that **truncates** the result to an integer. However, as we’ll see on the next page, if either of the values in the operation is a `float`

value, it will return a value that is a `float`

data type, even though the result is an integer value.

Let’s look at an example with that operator in code:

```
a = 17.5 // 4.5
print(a)
print(type(a))
```

As we expect, when we run this program, we’ll get the following output:

```
3.0
<class 'float'>
```

So, we see that this operator will return a `float`

value, even though it is truncating the result to an integer, simply because the input values contained a `float`

.

# Subsections of New Operators

# Resulting Types

YouTube Video#### Resources

Since Python has multiple numeric data types, there are some rules that govern which data type is produced as a result of various math operations. Thankfully, the rules themselves are pretty straightforward once they are explained.

## Resulting Data Types - Same Type

The basic rule to remember, **if a mathematical operator is applied to two variables of the same data type, the result will also be that data type.**

Let’s see what that means in practice. Here’s a quick example in Python using the multiplication operator on two integer values:

```
x = 5
y = 10
z = x * y
print(z)
print(type(z))
```

When we run this code, we should see the following output:

```
50
<class 'int'>
```

Since both `x`

and `y`

are the `int`

data type, the result of `x * y`

will also be an `int`

value, so the variable `z`

will have that data type, as shown in this example.

However, there is **one exception** to this rule, which is the division operator `/`

. In Python, the division operator will always return a `float`

value, even if it is a whole number. Here’s an example that demonstrates that:

```
a = 9
b = 3
c = 4
x = a / b
print(x)
print(type(x))
print()
y = a / c
print(y)
print(type(y))
```

When we run this program, we’ll see the following output:

```
3.0
<class 'float'>
2.25
<class 'float'>
```

So, as we can see, even though we are dividing two `int`

values, we’ll get a `float`

value as a result each time we use the division operator.

Following the rule above, if we perform a mathematical operation between two `float`

values, the resulting value will always be a `float`

as well:

```
a = 2.5
b = 4.5
c = a + b
print(c)
print(type(c))
```

Running this code will produce this output:

```
7.0
<class 'float'>
```

So, even though the result is a whole number, the value that is stored is the `float`

data type.

## Resulting Data Types - Different Type

The other rule to remember is **anytime an operation involves a float value and an int value, the result will be a float**. So, if there are mixed types, Python will default to the

`float`

data type.This can be seen in the following example:

```
a = 5
b = 2.0
c = a - b
print(c)
print(type(c))
```

When this code is executed, the output should look like this:

```
3.0
<class 'float'>
```

Once again, even though the result is a whole number, because the variable `b`

is a `float`

value, the entire result will also be a `float`

value.

Learning the data types that are returned by a mathematical operator can be tricky, but most programmers slowly develop an intuition of how each operator works and what to expect. So, don’t worry too much if this is confusing right now, since it will become much clearer with practice! Also, don’t forget that we can always create a simple test program like the examples shown above to confirm the result for any operation.

# Subsections of Resulting Types

# Order of Operations

YouTube Video#### Resources

Finally, just like in mathematics, we must also be aware of the order that these operators are applied, especially if they are combined into a single expression. Thankfully, the same rules we learned in mathematics apply in programming as well. Specifically, operators in Python are applied in this order:

- Operations in parentheses are resolved first, moving from left to right.
`**`

is resolved second, moving from left to right`*`

,`/`

,`//`

and`%`

are resolved third, moving from left to right.`+`

and`-`

are resolved fourth, moving from left to right.

You might recall the “PEMDAS” acronym for remembering the order of operations in math, and thankfully it still applies here. Of course, this means that there are now 4 operators that all fit in the “multiplication and division” portion, so we have to carefully make sure they are all taken care of in the correct way.

Also, as you’ve probably already learned in math, it is always best to add extra parentheses to any expression to make the intent very clear instead of relying on the order of operations. So, when in doubt, use extra parentheses wherever needed!

Let’s work through a quick example just to see the order of operations in practice. Here’s a complex expression in Python that we can try to evaluate:

`x = 8 / 4 + 5 * (3 + 1) - 7 % 4`

Looking at our order of operations, the first step is to handle any expressions inside of parentheses. So, we’ll first start with the expression `(3 + 1)`

and evaluate it to `4`

.

`x = 8 / 4 + 5 * 4 - 7 % 4`

Then, we’ll go left to right and perform any multiplication, division, and modulo operations. This means we’ll evaluate `8 / 4`

, `5 * 4`

and `7 % 4`

and replace them with the resulting values:

`x = 2.0 + 20 - 3`

Notice that `8 / 4`

was reduced to `2.0`

instead of just `2`

. This is because the division operator is the one exception to the rule where an operator applied to two integers will result in an integer. The division operator always produces a floating-point value.

Finally, we’ll perform addition and subtraction from left to right. So, we’ll evaluate `2.0 + 20`

first, and then subtract `3`

from the result of that operation. At the end, we’ll have this statement:

`x = 19.0`

So, we were able to use our knowledge of the order of operations to evaluate that complex expression to a single value,
$ 19.0 $, which will be stored in the variable `x`

.

# Subsections of Order of Operations

# Math Practice

Let’s try some simple practice problems. These problems are not graded - they are just for you to practice before doing the real exercises in the lab itself. You can find the answers below each question by clicking the button below each question.

#### 2.1 Reading Code

Write the output that is displayed to the user after running the following Python code:

```
x = 13
z = "5"
y = int(z)
var = (x + y) % y * y - x
var = var / 2
print(var)
```

*Pay special attention to data types! Make sure the answer is presented as the correct type.*

#### 2.2 Reading Code

Write the output that is displayed to the user after running the following Python code:

```
x = 9
y = 3.0
z = 5
ans = (x - z) % 2 // y + z ** (y - 1)
print(ans)
```

*Pay special attention to data types! Make sure the answer is presented as the correct type.*

#### 2.3 Writing Code

You are teaching a class and would like to put your students into a number of groups. You know how many students are in the class and the number of groups to create, but you aren’t sure how many students should be in each group.

We’ll assume that these values are stored in the `students`

and `groups`

variables, respectively.

Write a Python program to compute the ideal group size for each group in the class. When divided, the groups in the class should have no fewer than `size`

people, and no more than `size+1`

people, and there should be exactly `groups`

groups total. For example, if there are
$ 15 $ people and the desired number of groups is
$ 4 $, then code should start with the following two variable assignments.

```
students = 15
groups = 4
# more code goes here
```

Your code should produce the following output for these values:

`groups of 3 or 4`

This is because the ideal group size for $ 4 $ groups out of $ 15 $ people is $ 3 $, and all groups should have either $ 3 $ or $ 4 $ members (in this case, one group of $ 3 $ and the rest groups of $ 4 $).

Write the rest of this Python program. Try different values for the `students`

and `groups`

variables to make sure that your answers are correct!

# Summary

In this lab, we covered several major important topics. Let’s quickly review them.

## Data Types in Python

`str`

data type stores text (strings). Use`str(expression)`

to convert an expression to a string if possible.`int`

data type stores whole numbers (integers). Use`int(expression)`

to convert an expression to an integer if possible.`float`

data type stored decimal numbers (floating-point). Use`float(expression)`

to convert an expression to a floating-point value, if possible.

## Math Operators in Python

`+`

Addition`-`

Subtraction`*`

Multiplication`**`

Exponentiation (Power)`/`

Division`//`

Integer Division`%`

Modulo (the remainder of division)

## Python Order of operations

- Parentheses
- Exponentiation
- Multiplication, Division, Integer Division, and Modulo from left to right
- Addition and Subtraction from left to right