Primitive Data Types

In programing data is organized in structures called data types. The most simple data types are called primitive data types and represent the smallest possible unit for information. In contrast, non-primitive data types consist of primitive ones and are used to organize more complex or larger amounts of data. To get the type of an object in Python you can use the built-in function type().

As in most languages, the primitive data types in Python are:

  • Boolean

  • Integer

  • Float

  • Complex

  • String

Boolean

Booleans are used for truth values of a binary logic. A boolean variable can take two different values, true or false, represented in Python by two constant objects: True and False. Note the capitalization! The type, that is the kind of data, of a boolean or logical variable is bool. Typically, booleans are returned if comparative operations are performed.

print(type(True), type(False))

print(type(1 == 1))
print(1 + 1 == 2)

x = 5
print(3 < x <= 5)
<class 'bool'> <class 'bool'>
<class 'bool'>
True
True

Python knows the following comparative operators:

Operator

Meaning

<

less then

<=

less or equal

>

greater

>=

greater or equal

==

equal

!=

unequal

is

same object

is not

not the same object

Additionally, boolean expressions can be written with the logical operators and, or and not:

print((3 < 4) and (5 > 2))

x = 21
print((x % 7 == 0) or (x % 5 == 0))

print((x % 7 == 0) and not (x % 5 == 0))
True
True
True

The function bool() transforms any object to a booleans. Any object is considered “to be True” except:

  • None and False.

  • zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)

  • empty sequences and collections: '', (), [], {}, set(), range(0) which are considered to be False.

Integer

Integers correspond to the set of natural numbers in mathematics. They include the zero and can be positive or negative.

positive_number = 42
negative_number = -13
null = 0

In most programming languages, there are several integer data types, depending if they can be negative and how large the value range may be. As all data, integer numbers are stored in the memory of a computer in a binary representation as a sequence of 0 and 1, called bits. A sequence of 1011 converts to an unsigned integer as \(1 \cdot 2^3 + 0 \cdot 2^2 + 1 \cdot 2^1 + 1 \cdot 2^0 = 8 + 2 + 1 = 11\). If we also include a sign the first bit determines whether the number is positive or negate.

In this example, we have four bits. Eight bits are called a byte. A typical integer is encoded as either four or eight bytes, that are 32 or 64 bits. This gives a maximum value of either \(2^{32}=4294967296\) or \(2^{64}=18446744073709551616\) for unsigned integer and \(2^{31}=2147483648\) or \(2^{63}=9223372036854775808\) for signed integer. The fixed value range can be dangerous. If we add two very large integers, the result may be outside the valid range. This is called a overflow and might cause program malfunction.

Unlike other programing languages, Python only has one integer data type that does not have a fixed length in memory. Hence, we can store as big integers as we like and we do not have to care about overflows.

# This interger would be to big for many other programming languages
big_number = 1000000000000000000000000000000000
print(type(big_number))
<class 'int'>

It is possible to transform other primitive data types to integer using the function int.

decimal_number = 42.1
print(int(decimal_number))

year = "1999"
print(int(year))

print(int('101', 2))
42
1999
5

Float

Floats are real numbers and have the type float. They are used to represent decimal numbers.

dezimal_number = 42.33
different_dezimal_number = -34.2424
print(type(dezimal_number))
<class 'float'>

The function isinstance() can be used to check whether an object is a float (or actually of any other data type).

print(isinstance(4.5, float))
True

Integers need to be written without a decimal point, but floats always need the dot! The numbers 55 and 55.0 have the same value, but are of different type!

a = 55
b = 55.0
print(a == b)
print(a is b)
True
False

The function float() transforms different data types to floats

number = 5
print(float(number))

address_number = "33"
print(float(address_number))
5.0
33.0

When we do calculations with floats, we may encounter a situation like this:

0.1 + 0.2
0.30000000000000004

The reason for the inexact result is the internal representation of floats in memory. These errors are called round off errors and are inevitable. Situations where they may have a significant effect on the result of a calculation must be avoided, such as adding very large and very small numbers.

Complex

Complex numbers have the type complex and are written as <real part>+<imaginary part>j. Note the j right after the imaginary part which represents the imaginary unit. There is also the built-in function complex() for creating a complex number.

# this is a complex number
3 + 1j
print(3 + 1j == complex(3, 1))
print(type(3+1j))
True
<class 'complex'>
# this is a syntax error
3 + 1 j
  File "<ipython-input-26-4d6b0a85eab6>", line 7
    3 + 1 j
          ^
SyntaxError: invalid syntax

We can do any kind of arithmetics with complex numbers.

z = 1j
print(2 * z)
print(z + 1 + 3j)
print(z**3)
2j
(1+4j)
(-0-1j)

Unlike floats and integers, the complex data type offers so called attributes to access the real and imaginary part of the complex number. An Attribute is some peace of data that is part of an object. To access the data of the attribute one uses the dot notation: <object>.<attribute>. The real and imaginary part of a complex number is accessible as the attribute real and imag.

z = 3 + 2j
print(z.real, z.imag)
3.0 2.0

In addition to attributes, the complex data type also has a method called conjugate. A method is something like a function that is attached to an object and that does something with the data of the object. In case of conjugate, the method compute the complex conjugate of the number. Note the brackets when conjugate is called. Since the returned value is of type complex, we can directly access its imaginary part for example.

print(z.conjugate())
print(z.conjugate().imag)
(3-2j)
-2.0

Strings

A string is simply a sequence of characters (so basically text) and need to be enclosed by single or double quotation marks.

text = "This is a string"
print(text)

text2 = 'This is also a string'
text3 = 'This is a text that contains "quotation marks"'
print(text3)
This is a string
This is a text that contains "quotation marks"

In Python 3, all strings are encoded in Unicode. So they can contain special characters.

coordinates = "0°N 23°W"
equations   = "∂η/∂t + ∂(Hu)/∂x + ∂(Hv)/∂y = 0"
print(equations)
∂η/∂t + ∂(Hu)/∂x + ∂(Hv)/∂y = 0

In fact, in Python 3 also the source code may contain Unicode characters.

Ψ = 3 ** 2
print(Ψ)
9

Strings have very useful methods to work with, e.g. capitalize(). Processing text, that is string manipulation, is an important everyday task in programming, also in scientific programming. So take some time an have a look at the available string methods.

first_name = 'bernd'
print(first_name.capitalize())
Bernd

A extremely useful string method is format. It is used to insert data into string templates. Take a look at the method documentation and the format string syntax. Do not forget to also have a look at formatting examples.

"The sum of 5 + 5 is {0}".format(5+5)
'The sum of 5 + 5 is 10'