Solutions

What about the following?

If you try executing these blocks of code you'll get an "unsupported operand" error:

In [10]:
print(1 + "2")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-f5a1f3a83b1d> in <module>
----> 1 print(1 + "2")
TypeError: unsupported operand type(s) for +: 'int' and 'str'
In [11]:
print("Hello" - "world")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-a3a7e1a6684b> in <module>
----> 1 print("Hello" - "world")
TypeError: unsupported operand type(s) for -: 'str' and 'str'

This arises because the operation we are telling Python to perform isn't well-defined on these types of variables.

print(1+"2")

Is trying to add an integer to a string - but what does that mean? It's like asking someone "what's 50metres plus 25kg"?

print("Hello"-"world")

Here we are trying to manipulate two strs, so the type matches at least. But words don't have a definition of subtraction, so we get the same error - this time the problem is that the type we are using doesn't have - defined, rather than the variables being different types.

Now try these:

Whilst we saw in the previous exercise that strs don't have a subtraction operation (-), they in fact do have an "addition" and "multiplication" operation.

  • + or addition of strs is interpreted as "concatenate" - stick the two strings together in the order they are given. Note that this means that "Hello" + "world" is different to "world"+"Hello":
In [12]:
print("Hello" + "world")
print("world" + "Hello")
Helloworld
worldHello
  • * or multiplication of str is interpreted as "repeat" or "repeat concatenation" - copy the str as many times as is requested. Note that you must multiply by an int - if you try to multiply by a float you'll get an other error!
In [13]:
print("Hello"*3)
print("Hello"*3.0)
HelloHelloHello
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-2e3206bed52e> in <module>
      1 print("Hello"*3)
----> 2 print("Hello"*3.0)
TypeError: can't multiply sequence by non-int of type 'float'

Decimals and fractions

In [20]:
print(type(3.4))
print(type(1/3))
print(type(4/4))
<class 'float'>
<class 'float'>
<class 'float'>

Choose a Type

Possible 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)? Number of seconds since creation (integer/float)
  5. Choose floating point to represent population as large aggreates (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.

Values and types

For each line we can print the result of the calculation, and then the type of the result. We can also save the result of the calculation to a variable, for ease when calling type().

In [21]:
print(3.25 + 4)
print(type(3.25 + 4))
7.25
<class 'float'>
In [22]:
print(4 + 3.25)
print(type(4 + 3.25))
7.25
<class 'float'>

In Python 3 the whole calculation is treated as floating point, irrespective of the order of the values.

In [23]:
value = int(4/3)
print(value, type(value))
1 <class 'int'>

The calculation is performed using floats (in Python 3), and then converted to an int.

In [24]:
print(int("3.4"))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-24-ba8d7dd18d3b> in <module>
----> 1 print(int("3.4"))
ValueError: invalid literal for int() with base 10: '3.4'

Python is unable to convert from a str to int unless the str is explictly an 'integer'.

In [25]:
value = int(float("3.4"))
print(value, type(value))
3 <class 'int'>

Python is able to convert to a float first, and then to an int, though.

In [26]:
print(int(3.99))
print(type(int(3.99)))
3
<class 'int'>

When converting to an int, Python does not "round the value to the nearest integer" but instead effectively ignores the fractional/decimal part.

In [27]:
float("Hello world!")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-27-60ceaa9fe6dd> in <module>
----> 1 float("Hello world!")
ValueError: could not convert string to float: 'Hello world!'

There is no logical way to convert a phrase or segment of prose into a float - there aren't even any numbers in the str to start with anyway!

Calculating with variables with different types

1 and 4 give the result 2.0. The complete results should be:

In [29]:
first + float(second)
Out[29]:
2.0
In [30]:
float(second) + float(third)
Out[30]:
2.1
In [31]:
first + int(third)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-31-74cfd3d440ed> in <module>
----> 1 first + int(third)
ValueError: invalid literal for int() with base 10: '1.1'
In [32]:
first + int(float(third))
Out[32]:
2.0
In [33]:
int(first) + int(float(third))
Out[33]:
2
In [34]:
2.0 * second
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-34-bb62fc1f9804> in <module>
----> 1 2.0 * second
TypeError: can't multiply sequence by non-int of type 'float'

Division Types

In [35]:
print('5 // 3:', 5//3, type(5//3))
print('5 / 3:', 5/3, type(5/3))
print('5 % 3:', 5%3, type(5%3))
5 // 3: 1 <class 'int'>
5 / 3: 1.6666666666666667 <class 'float'>
5 % 3: 2 <class 'int'>