Number Types and Operations in Python

PythonBeginner
Practice Now

Introduction

In this lab, you will gain a fundamental understanding of number types and operations in Python. We will explore the characteristics of integer, boolean, floating-point, and complex number types, including their immutability and how to check their types and memory addresses. Through hands-on exercises, you will learn how to convert between different number types and perform basic arithmetic operations, solidifying your knowledge of Python's numerical capabilities.

Explore Integer and Boolean Types

In this step, we will explore the integer (int) and boolean (bool) data types in Python. Integers are whole numbers, such as 10, -5, or 0. Booleans represent one of two values: True or False, and are a subtype of integers.

An important concept in Python is immutability. Number types are immutable, which means that once a number object is created, its value cannot be changed. If you reassign a variable to a new number, it will point to a new object in memory. We can verify this using the built-in id() function, which returns an object's unique memory address, and the type() function, which shows its data type.

The lab environment has already created a file for you. In the WebIDE file explorer on the left, open the ~/project/number_types.py file. Add the following code to it:

## Demonstrate immutability of integers
a = 5
print(f"Initial value of a: {a}")
print(f"Type of a: {type(a)}")
print(f"ID of a: {id(a)}")

## Reassign 'a' to a new value
a = 6
print(f"\nNew value of a: {a}")
print(f"New ID of a: {id(a)}")

## Demonstrate boolean type
print("\n--- Boolean Types ---")
is_true = True
is_false = False
print(f"Value of is_true: {is_true}, Type: {type(is_true)}")
print(f"Value of is_false: {is_false}, Type: {type(is_false)}")

## Booleans behave like integers (1 and 0) in arithmetic
print(f"\nTrue + 5: {True + 5}")
print(f"False * 3: {False * 3}")

After adding the code, save the file. To run the script, open the integrated terminal in the WebIDE and execute the following command:

python ~/project/number_types.py

You should see output similar to the following. Note that the memory addresses (ID) will be different on your system.

Initial value of a: 5
Type of a: <class 'int'>
ID of a: <memory_address_1>

New value of a: 6
New ID of a: <memory_address_2>

--- Boolean Types ---
Value of is_true: True, Type: <class 'bool'>
Value of is_false: False, Type: <class 'bool'>

True + 5: 6
False * 3: 0

The output shows that when a was reassigned from 5 to 6, its ID changed, confirming that a new integer object was created. It also demonstrates that True is treated as 1 and False as 0 in calculations.

Work with Floating-Point Numbers

In this step, we will work with floating-point numbers (float), which represent real numbers with a decimal point. A common issue with floats is their limited precision, as they are stored in binary format. This can sometimes lead to small inaccuracies in calculations.

Let's explore this behavior. Open ~/project/number_types.py again and add the following code to the end of the file. This code will demonstrate the precision issue and introduce two ways to handle it: the round() function for simple rounding and the decimal module for high-precision arithmetic.

## Demonstrate floating-point numbers and precision
print("\n--- Floating-Point Numbers ---")
result = 1.1 + 2.2
print(f"1.1 + 2.2 = {result}")

## Using round() for approximation
print(f"round(result, 1) = {round(result, 1)}")

## Using the decimal module for accurate calculations
from decimal import Decimal

## Pass numbers as strings to Decimal to avoid initial float inaccuracy
d1 = Decimal('1.1')
d2 = Decimal('2.2')
decimal_result = d1 + d2
print(f"Decimal('1.1') + Decimal('2.2') = {decimal_result}")

Save the file and run the script again from the terminal:

python ~/project/number_types.py

Your output will now include the following section:

--- Floating-Point Numbers ---
1.1 + 2.2 = 3.3000000000000003
round(result, 1) = 3.3
Decimal('1.1') + Decimal('2.2') = 3.3

As you can see, the standard float addition 1.1 + 2.2 does not yield exactly 3.3. While round() can help format the output, the decimal module provides a way to perform calculations with the exact decimal representation, giving the precise answer.

Introduce Complex Numbers

Python has built-in support for complex numbers, which are essential in many scientific and engineering fields. A complex number has a real part and an imaginary part, written in the form a + bj, where j represents the imaginary unit.

You can create complex numbers using this notation or with the complex(real, imag) constructor. The real and imaginary parts can be accessed using the .real and .imag attributes.

Continue editing the ~/project/number_types.py file. Add the following code to the end to explore complex numbers:

## Demonstrate complex numbers
print("\n--- Complex Numbers ---")
c1 = 3 + 4j
print(f"Complex number c1: {c1}")
print(f"Type of c1: {type(c1)}")
print(f"Real part of c1: {c1.real}")
print(f"Imaginary part of c1: {c1.imag}")

## Creating a complex number with the constructor
c2 = complex(5, -2)
print(f"\nComplex number c2: {c2}")
print(f"Real part of c2: {c2.real}")
print(f"Imaginary part of c2: {c2.imag}")

Save the file and run the script from the terminal:

python ~/project/number_types.py

The new output will be:

--- Complex Numbers ---
Complex number c1: (3+4j)
Type of c1: <class 'complex'>
Real part of c1: 3.0
Imaginary part of c1: 4.0

Complex number c2: (5-2j)
Real part of c2: 5.0
Imaginary part of c2: -2.0

Notice that both the real and imaginary parts are stored as floating-point numbers, even if you define them with integers.

Convert Between Number Types

Python provides built-in functions to convert between different number types, such as int(), float(), and complex(). This is known as type casting.

  • int(x): Converts x to an integer. When converting a float, it truncates (cuts off) the decimal part, it does not round.
  • float(x): Converts x to a floating-point number.
  • complex(real, imag): Creates a complex number.

Let's practice type conversion. Add the following code to the end of your ~/project/number_types.py script:

## Demonstrate type conversion
print("\n--- Type Conversion ---")

## Convert float to int (truncation)
float_num = 9.9
int_num = int(float_num)
print(f"float_num = {float_num}")
print(f"int(float_num) = {int_num}")

## Convert int to float
int_val = 10
float_val = float(int_val)
print(f"\nint_val = {int_val}")
print(f"float(int_val) = {float_val}")

## Convert string to number
str_num = "123.45"
converted_float = float(str_num)
converted_int = int(float(str_num)) ## Must convert to float first
print(f"\nstr_num = '{str_num}'")
print(f"float(str_num) = {converted_float}")
print(f"int(float(str_num)) = {converted_int}")

Save the file and run the script one more time:

python ~/project/number_types.py

The output will now include this section:

--- Type Conversion ---
float_num = 9.9
int(float_num) = 9

int_val = 10
float(int_val) = 10.0

str_num = '123.45'
float(str_num) = 123.45
int(float(str_num)) = 123

This output clearly shows how int() truncates the decimal from 9.9 to 9. It also illustrates the two-step process required to convert a string containing a decimal into an integer.

Perform Basic Arithmetic Operations

Python supports all standard arithmetic operations. When you perform an operation with operands of different numeric types (e.g., an int and a float), Python automatically "widens" the result to the more general type. The hierarchy is int -> float -> complex.

Here are the common operators:

  • + (Addition)
  • - (Subtraction)
  • * (Multiplication)
  • / (Division - always results in a float)
  • // (Floor Division - divides and rounds down to the nearest integer)
  • % (Modulo - returns the remainder of a division)
  • ** (Exponentiation)

To conclude our exploration, let's add a final section to ~/project/number_types.py to practice these operations.

## Demonstrate basic arithmetic operations
print("\n--- Basic Arithmetic Operations ---")
a = 10
b = 3

print(f"{a} + {b} = {a + b}")
print(f"{a} - {b} = {a - b}")
print(f"{a} * {b} = {a * b}")
print(f"{a} / {b} = {a / b}")
print(f"{a} // {b} = {a // b}")
print(f"{a} % {b} = {a % b}")
print(f"{a} ** {b} = {a ** b}")

## Demonstrate mixed-type operations
print("\n--- Mixed-Type Operations ---")
int_op = 5
float_op = 2.5
result_mixed = int_op * float_op
print(f"{int_op} (int) * {float_op} (float) = {result_mixed} ({type(result_mixed)})")

Save the file and run the complete script:

python ~/project/number_types.py

The final output will include:

--- Basic Arithmetic Operations ---
10 + 3 = 13
10 - 3 = 7
10 * 3 = 30
10 / 3 = 3.3333333333333335
10 // 3 = 3
10 % 3 = 1
10 ** 3 = 1000

--- Mixed-Type Operations ---
5 (int) * 2.5 (float) = 12.5 (<class 'float'>)

This output confirms the behavior of each operator. Notice that standard division / produces a float, while floor division // produces an integer. The mixed-type operation between an integer and a float results in a float, as expected.

Summary

In this lab, you have gained a solid foundation in Python's numerical data types. You have learned about integers, booleans, floats, and complex numbers. You explored the concept of immutability and used the id() and type() functions to inspect objects. You practiced handling floating-point precision issues with the decimal module, converting between different number types using int(), float(), and complex(), and performing a range of arithmetic operations. This knowledge is crucial for any further programming or data analysis tasks in Python.