Skip to content

2.1.2 Data Types and Variables

Diagram of the relationship between variables, objects, and references

This section helps you understand how Python represents and stores data. Variables, numbers, strings, booleans, and type conversion are the foundation for writing conditionals, processing tabular data, and calling model APIs later on. First, get familiar with these “smallest units of data.”

  • Understand what variables are and learn the rules for naming them
  • Master Python’s basic data types: integers, floating-point numbers, strings, and booleans
  • Learn how to convert between data types
  • Understand what dynamic typing means

Think of a variable as a labeled box. You can put something inside it and use the label to find it later.

service_name = "Login API" # The box has a "service_name" label
latency_ms = 185 # The box has a "latency_ms" label
timeout_seconds = 2.5 # The box has a "timeout_seconds" label

In Python, = does not mean “equal to” — it means assignment. It puts the value on the right into the box on the left.

# Assignment direction: from right to left
x = 10 # Put 10 into the box named x
# You can change the contents of the box
x = 20 # Now x contains 20 (10 is gone)
# You can use a variable’s value to calculate something
y = x + 5 # y = 20 + 5 = 25
print(y) # Output: 25

Python has a few rules for variable names:

RuleCorrect ExamplesIncorrect Examples
Can only contain letters, numbers, and underscoresservice_name, task2service-name, task!
Cannot start with a numbertask11task
Cannot use Python keywordsmy_classclass, if, for
Case-sensitiveService and service are different variables

Naming Conventions (Not Required, but Widely Used)

Section titled “Naming Conventions (Not Required, but Widely Used)”
# Good names ✅ — use lowercase letters with underscores (snake_case)
service_name = "Login API"
learning_rate = 0.001
max_epochs = 100
# Poor names ❌ — not invalid, just unclear
a = "Login API" # You can't tell what a means
x1 = 0.001 # What does x1 represent?
SN = "Login API" # Too abbreviated to understand easily

Integers are numbers without decimal points. They can be positive, negative, or zero.

retry_count = 3
queue_delta = -10
count = 0
big_number = 1_000_000 # Underscores improve readability; same as 1000000
print(type(retry_count)) # <class 'int'>

Python integers have no size limit (unlike int in C/Java, which has a fixed range):

huge = 99999999999999999999999999999999
print(huge + 1) # No problem at all

Floating-point numbers are numbers with decimal points.

pi = 3.14159
timeout_seconds = 2.5
negative = -0.001
print(type(pi)) # <class 'float'>

Be careful about floating-point precision — this is a problem in all programming languages:

>>> 0.1 + 0.2
0.30000000000000004 # Not exactly 0.3!

This is not a Python bug. It is an inherent issue caused by storing decimals in binary form on computers. In AI development, this tiny error usually does not affect the result. But if you need exact results for financial calculations, use the decimal module.

a = 10
b = 3
print(a + b) # 13 addition
print(a - b) # 7 subtraction
print(a * b) # 30 multiplication
print(a / b) # 3.333... division (result is always float)
print(a // b) # 3 floor division
print(a % b) # 1 remainder
print(a ** b) # 1000 exponentiation (10 to the 3rd power)

A common pitfall:

# The result of / is always float, even when division is exact
>>> 10 / 2
5.0 # Not 5, but 5.0
# If you want an integer result, use //
>>> 10 // 2
5

A string is text — a sequence of characters. It is wrapped in quotes.

# Single and double quotes both work; they are equivalent
service = 'Login API'
status = "ready"
# If the string contains quotes, wrap it with the other kind
sentence = "The reviewer said: 'Looks good'"
command = 'The CLI flag is "--dry-run"'
# Triple quotes: can write multi-line text
release_notes = """
Login API
- timeout adjusted
- retry logging enabled
"""
print(release_notes)
print(type(service)) # <class 'str'>
module_name = "ticket"
endpoint_name = "-api"
# Method 1: use + to concatenate
full_endpoint = module_name + endpoint_name
print(full_endpoint) # ticket-api
# Method 2: use f-string (recommended! Python 3.6+)
version = "v1"
intro = f"{full_endpoint} runs on {version}"
print(intro) # ticket-api runs on v1
# Method 3: use format()
intro2 = "{} runs on {}".format(full_endpoint, version)
print(intro2) # ticket-api runs on v1
text = "Hello, Python!"
# Length
print(len(text)) # 14
# Case conversion
print(text.upper()) # HELLO, PYTHON!
print(text.lower()) # hello, python!
# Find a substring
print(text.find("Python")) # 7 (starts at position 7)
print("Python" in text) # True
# Replace
print(text.replace("Python", "AI")) # Hello, AI!
# Strip whitespace from both ends
messy = " hello "
print(messy.strip()) # "hello"
# Split
csv_line = "Login API,185,ready"
parts = csv_line.split(",")
print(parts) # ['Login API', '185', 'ready']

String index and slice diagram

Each character in a string has a position number (index) starting from 0:

text = "Python"
# P y t h o n
# index: 0 1 2 3 4 5
# negative index: -6 -5 -4 -3 -2 -1
print(text[0]) # P (first character)
print(text[5]) # n (sixth character)
print(text[-1]) # n (last character)
print(text[-2]) # o (second to last character)

Slicing lets you extract a substring:

text = "Python"
print(text[0:3]) # Pyt (from index 0 to index 3, excluding 3)
print(text[2:5]) # tho
print(text[:3]) # Pyt (from the start; 0 can be omitted)
print(text[3:]) # hon (to the end; the stop position can be omitted)
print(text[:]) # Python (a copy of the whole string)
print(text[::2]) # Pto (take every other character)
print(text[::-1]) # nohtyP (reverse the string!)
text = "Hello"
# text[0] = "h" # Error! TypeError: 'str' object does not support item assignment
# If you want to modify it, create a new string
text = "h" + text[1:] # "hello"

A boolean has only two values: True and False. Note the capital first letter.

is_deployed = True
has_errors = False
print(type(is_deployed)) # <class 'bool'>

Booleans often come from comparison operations:

print(5 > 3) # True
print(5 < 3) # False
print(5 == 5) # True (note the two equals signs; one equals sign is assignment)
print(5 != 3) # True (`!=` means not equal)
print("abc" == "abc") # True

Booleans will be used heavily later when you learn control flow (if/else).

In Python, many things can be used as boolean values. The following are considered “false”:

# All of the following are "falsy" values
bool(0) # False
bool(0.0) # False
bool("") # False (empty string)
bool([]) # False (empty list)
bool(None) # False
# Everything else is "truthy"
bool(1) # True
bool(-1) # True (any non-zero number is true)
bool("hello") # True (any non-empty string is true)
bool([1, 2]) # True (any non-empty list is true)

None is a special value in Python that means “nothing here”.

result = None
print(result) # None
print(type(result)) # <class 'NoneType'>

None is often used to mean “no value yet” or “no result”:

# When a function has no return value, it returns None by default
def say_hello():
print("Hello!")
result = say_hello() # Prints Hello!
print(result) # None

Sometimes you need to convert one type into another.

# String → number
latency_str = "185"
latency_ms = int(latency_str) # Convert string to integer
print(latency_ms + 10) # 195
timeout_str = "2.5"
timeout_seconds = float(timeout_str) # Convert string to float
print(timeout_seconds) # 2.5
# Number → string
task_count = 12
task_count_str = str(task_count) # Convert integer to string
print("Tasks: " + task_count_str) # Tasks: 12
# Integer ↔ float
x = int(3.7) # 3 (directly truncates the decimal part, not rounding)
y = float(5) # 5.0

Common mistake: strings and numbers cannot be concatenated directly with +

latency_ms = 185
# print("Latency: " + latency_ms) # Error! TypeError
# Correct method 1: convert to string
print("Latency: " + str(latency_ms))
# Correct method 2: use an f-string (recommended)
print(f"Latency: {latency_ms}")
# Correct method 3: separate with commas (print will add spaces automatically)
print("Latency:", latency_ms)
ConversionFunctionExampleResult
→ Integerint()int("25")25
→ Floatfloat()float("3.14")3.14
→ Stringstr()str(100)"100"
→ Booleanbool()bool(0)False

Python is a dynamically typed language — you do not need to declare a variable’s type in advance, and the same variable can change types at any time.

x = 10 # x is an integer
print(type(x)) # <class 'int'>
x = "hello" # now x is a string
print(type(x)) # <class 'str'>
x = True # now x becomes a boolean
print(type(x)) # <class 'bool'>

This is flexible, but be careful — do not accidentally change a variable that was supposed to store a number into a string.

Compare this with Java, a statically typed language:

int x = 10; // Declare x as an integer
x = "hello"; // Error! Java does not allow changing the type

Python supports some convenient assignment patterns:

# Assign values to multiple variables at once
a, b, c = 1, 2, 3
print(a, b, c) # 1 2 3
# Swap the values of two variables (a concise Python-only style)
a, b = b, a
print(a, b) # 2 1
# Assign the same value to multiple variables
x = y = z = 0
print(x, y, z) # 0 0 0

This way of swapping variables is very Pythonic, and in other languages you usually need a temporary variable:

# Other languages
temp = a
a = b
b = temp
# Python
a, b = b, a # Done in one line!

Create variables to store a service’s status, then print them with f-strings:

service = "Login API"
latency_ms = 185
timeout_seconds = 2.5
is_ready = True
print(f"Service: {service}")
print(f"Latency: {latency_ms} ms")
print(f"Timeout: {timeout_seconds} seconds")
print(f"Ready to demo: {is_ready}")
print(f"Alert threshold: {latency_ms + 15} ms")

Formula for converting milliseconds to seconds: seconds = milliseconds / 1000

latency_ms = 375.0
latency_seconds = latency_ms / 1000
print(f"{latency_ms} ms = {latency_seconds} seconds")

Try changing the value of latency_ms and calculate a few different latency values.

email = " [email protected] "
# 1. Remove leading and trailing spaces
# 2. Convert to lowercase
# 3. Find the position of @
# 4. Extract the username part (the part before @)

Hint: You can combine .strip(), .lower(), .find(), and slicing.

Use type() to check the type of each value below. Guess first, then verify:

print(type(42))
print(type(3.14))
print(type("3.14"))
print(type(True))
print(type(None))
print(type(1 + 2))
print(type(1 + 2.0)) # Integer + float = ?
print(type("1" + "2")) # String + string = ?
Reference implementation and walkthrough
  1. The service status card should use str, int, float, and bool. f-strings should show variable values and an expression such as latency_ms + 15.
  2. 375.0 ms gives 0.375 seconds. Keep the formula in code so changing latency_ms changes latency_seconds.
  3. The normalized email is [email protected]. The @ index after stripping and lowercasing is 11, and the username is support.api.
  4. The type outputs are int, float, str, bool, NoneType, int, float, and str.
  5. A common mistake is treating "1" + "2" as arithmetic. It is string concatenation, so the result is "12".

Keep this page’s proof of learning as a small evidence card:

Concept
variable, type, operator, input/output, branch, loop, structure, function, or module
Code
smallest runnable Python snippet for the concept
Output
printed value, type, branch result, loop trace, or returned value
Failure Check
type mismatch, indentation, off-by-one, mutable data, or import path issue
Expected Output
code plus printed result that proves the concept works
TypeKeywordExampleUse
Integerint42, -10, 0Counting, indexing
Floatfloat3.14, -0.5Precise values, scientific computing
Stringstr"hello", 'world'Text data
BooleanboolTrue, FalseConditional logic
Null valueNoneTypeNoneRepresents “no value”