# Variables only change value when something is assigned to them.¶

• If we make one cell in a spreadsheet depend on another, and update the latter, the former updates automatically.

• This does not happen in programming languages.

```first = 1
second = 5 * first
first = 2
print('first is', first, 'and second is', second)
```

{: .language-python}

```first is 2 and second is 5
```

{: .output}

• The computer reads the value of `first` when doing the multiplication, creates a new value, and assigns it to `second`.

• After that, `second` does not remember where it came from.

# Fractions¶

What type of value is 3.4? How can you find out?

# Solution¶

It is a floating-point number (often abbreviated “float”).

```print(type(3.4))
```

{: .language-python}

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

{: .output} {: .solution} {: .challenge}

# Automatic Type Conversion¶

What type of value is 3.25 + 4?

# Solution¶

It is a float: integers are automatically converted to floats as necessary.

```result = 3.25 + 4
print(result, 'is', type(result))
```

{: .language-python}

```7.25 is <class 'float'>
```

{: .output} {: .solution} {: .challenge}

# Choose a Type¶

What type of value (integer, floating point number, or character string) would you use to represent each of the following? Try to come up with more than one good answer for each problem. For example, in # 1, when would counting days with a floating point variable make more sense than using an integer?

1. Number of days since the start of the year.

2. Time elapsed from the start of the year until now in days.

3. Serial number of a piece of lab equipment.

4. A lab specimen’s age

5. Current population of a city.

6. Average population of a city over time.

# Solution¶

The answers to the questions are:

1. Integer, since the number of days would lie between 1 and 365.

2. Floating point, since fractional days are required

3. Character string if serial number contains letters and numbers, otherwise integer if the serial number consists only of numerals

4. This will vary! How do you define a specimen’s age? whole days since collection (integer)? date and time (string)?

5. Choose floating point to represent population as large aggregates (eg millions), or integer to represent population in units of individuals.

6. Floating point number, since an average is likely to have a fractional part. {: .output} {: .solution} {: .challenge}

# Division Types¶

In Python 3, the `//` operator performs integer (whole-number) floor division, the `/` operator performs floating-point division, and the `%` (or modulo) operator calculates and returns the remainder from integer division:

```print('5 // 3:', 5//3)
print('5 / 3:', 5/3)
print('5 % 3:', 5%3)
```

{: .language-python}

```5 // 3: 1
5 / 3: 1.6666666666666667
5 % 3: 2
```

{: .output}

However in Python2 (and other languages), the `/` operator between two integer types perform a floor (`//`) division. To perform a float division, we have to convert one of the integers to float.

```print('5 // 3:', 1)
print('5 / 3:', 1 )
print('5 / float(3):', 1.6666667 )
print('float(5) / 3:', 1.6666667 )
print('float(5 / 3):', 1.0 )
print('5 % 3:', 2)
```

If `num_subjects` is the number of subjects taking part in a study, and `num_per_survey` is the number that can take part in a single survey, write an expression that calculates the number of surveys needed to reach everyone once.

# Solution¶

We want the minimum number of surveys that reaches everyone once, which is the rounded up value of `num_subjects/ num_per_survey`. This is equivalent to performing a floor division with `//` and adding 1. Before the division we need to subtract 1 from the number of subjects to deal with the case where `num_subjects` is evenly divisible by `num_per_survey`.

```num_subjects = 600
num_per_survey = 42
num_surveys = (num_subjects - 1) // num_per_survey + 1

print(num_subjects, 'subjects,', num_per_survey, 'per survey:', num_surveys)
```

{: .language-python}

```600 subjects, 42 per survey: 15
```

{: .output} {: .solution} {: .challenge}

# Strings to Numbers¶

Where reasonable, `float()` will convert a string to a floating point number, and `int()` will convert a floating point number to an integer:

```print("string to float:", float("3.4"))
print("float to int:", int(3.4))
```

{: .language-python}

```string to float: 3.4
float to int: 3
```

{: .output}

If the conversion doesn’t make sense, however, an error message will occur

```print("string to float:", float("Hello world!"))
```

{: .language-python}

```---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-df3b790bf0a2> in <module>()
----> 1 print("string to float:", float("Hello world!"))

ValueError: could not convert string to float: 'Hello world!'
```

{: .error}

Given this information, what do you expect the following program to do?

What does it actually do?

Why do you think it does that?

```print("fractional string to int:", int("3.4"))
```

{: .language-python}

# Solution¶

What do you expect this program to do? It would not be so unreasonable to expect the Python 3 `int` command to convert the string “3.4” to 3.4 and an additional type conversion to 3. After all, Python 3 performs a lot of other magic - isn’t that part of its charm?

However, Python 3 throws an error. Why? To be consistent, possibly. If you ask Python to perform two consecutive typecasts, you must convert it explicitly in code.

```int("3.4")
int(float("3.4"))
```

{: .language-python}

```In : int("3.4")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-ec6729dfccdc> in <module>()
----> 1 int("3.4")
ValueError: invalid literal for int() with base 10: '3.4'
3
```

{: .output} {: .solution} {: .challenge}

# Arithmetic with Different Types¶

Which of the following will return the floating point number `2.0`? Note: there may be more than one right answer.

```first = 1.0
second = "1"
third = "1.1"
```

{: .language-python}

1. `first + float(second)`

2. `float(second) + float(third)`

3. `first + int(third)`

4. `first + int(float(third))`

5. `int(first) + int(float(third))`

6. `2.0 * second`

# Solution¶

Answer: 1 and 4 {: .solution} {: .challenge}

# Complex Numbers¶

Python provides complex numbers, which are written as `1.0+2.0j`. If `val` is a complex number, its real and imaginary parts can be accessed using dot notation as `val.real` and `val.imag`.

```complex = 6 + 2j
print(complex.real)
print(complex.imag)
```

{: .language-python}

```6.0
2.0
```

{: .output}

1. Why do you think Python uses `j` instead of `i` for the imaginary part?

2. What do you expect `1+2j + 3` to produce?

3. What do you expect `4j` to be? What about `4 j` or `4 + j`?

# Solution¶

1. Standard mathematics treatments typically use `i` to denote an imaginary number. However, from media reports it was an early convention established from electrical engineering that now presents a technically expensive area to change. Stack Overflow provides additional explanation and discussion.

2. `(4+2j)`

3. `4j`, `Syntax Error: invalid syntax`, in this case j is considered a variable and this depends on if j is defined and if so, its assigned value {: .solution} {: .challenge} tor