Python Foundation for Data Engineers

Chapter 2 — Variables & Data Types

Lesson 2.1 — Variables: Storing the Numbers and Names You'll Work With

Picture this. You're building a small script to check yesterday's sales file. Before you touch the actual data, you need somewhere to keep track of things as you go — how many rows you've read, what today's date is, which source system the file came from.

That's exactly what a variable is: a named place to keep a piece of information, so you can use it later without retyping it.

Let's write one.

python
row_count = 4500

Read that like a sentence: "row count equals four thousand five hundred." On the left is the name we're choosing — row_count. On the right is the value we're storing — 4500. The equals sign isn't asking a question, like "is this equal to that?" It's an instruction: "store this value, under this name."

Once it's stored, you can use it anywhere:

python
row_count = 4500 print(row_count) print("Rows loaded:", row_count)

Naming matters more than people expect when they're starting out. row_count tells the next person reading your code exactly what it holds. A name like x tells them nothing. In data engineering, you're rarely the only person who'll ever read your code — a teammate, or future-you six months from now, will thank you for a clear name.

A few small rules Python enforces: variable names can't start with a number, can't contain spaces, and are case-sensitive — row_count and Row_Count are two different variables entirely, which trips up a lot of beginners. The convention in Python, one you'll see everywhere, is lowercase words separated by underscores — source_system, file_date, total_revenue.

Try It Yourself: In a new file, variables.py, create three variables: source_system (a name like "CRM"), file_date (today's date as text), and row_count (any whole number). Print all three, each on its own line, with a short label like "Source:" before the value.


Lesson 2.2 — Numbers, Text & True/False: The Four Types You'll Use Constantly

Not all data looks the same, and Python treats different kinds of data differently. Understanding this now will save you real confusion later, so let's slow down here.

Think about a single row from a sales file: a product name, a price, a quantity, and whether the order was refunded. Four values, four different types.

python
product_name = "Wireless Mouse" # str — text price = 24.99 # float — a decimal number quantity = 3 # int — a whole number is_refunded = False # bool — true or false

str stands for string — any text, always wrapped in quotes. Product names, source system names, email addresses, even a date written as text — all strings.

int is a whole number, no decimal point. Row counts, quantities, ages, IDs.

float is a number with a decimal point. Prices, percentages, measurements — anything where fractions matter.

bool is one of exactly two values: True or False. Capital T, capital F — that capitalization matters to Python. You'll use booleans constantly for flags: is this row valid, is this file processed, is this record a duplicate.

You can always check what type something is using the built-in type() function:

python
print(type(price))

This will print <class 'float'>. When you're debugging a confusing pipeline problem later in this course, type() will be one of your best friends — a huge number of data bugs come down to a value being the wrong type without anyone noticing.

Try It Yourself: Create four variables representing one row from an orders file: order_id (int), customer_name (str), order_total (float), and is_priority (bool). Print each variable's value, and right next to it, print its type using type().


Lesson 2.3 — Converting Between Types: Why a "Number" in a File Isn't Always a Number

Here's something that catches almost every beginner off guard, and it's worth a lesson of its own because it causes real bugs in real pipelines.

When you read a file — a CSV especially — every single value comes into Python as text, a string, even if it looks like a number to your eyes.

Let's prove it:

python
row_count = "4500" print(row_count + 1)

Run that, and Python throws an error: TypeError: can only concatenate str (not "int") to str. Python is telling you, quite literally: you're trying to add a number to a piece of text, and it doesn't know how to do that. It won't guess what you meant — it stops and tells you.

This is exactly what happens when you read a value out of a CSV file. It looks like 4500. It behaves like "4500" — text — until you tell Python otherwise.

The fix is converting the type, on purpose:

python
row_count = "4500" row_count = int(row_count) print(row_count + 1)

Now it prints 4501, because int() converted the text "4500" into an actual whole number.

The same idea works in reverse, and you'll need this constantly for writing readable output:

python
total = 4500 message = "Total rows: " + str(total) print(message)

Here, str() converts the number into text so it can be joined with another piece of text. Without it, Python would throw the same kind of error, just in reverse.

The habit to build here: whenever a value is coming from a file, an API, or user input, assume it's text until you've deliberately converted it. That one habit alone will save you from a whole category of bugs later in this course, when we start reading real CSV files.

Try It Yourself: Create a variable price_text = "19.99". Convert it to a float using float(), store it in a new variable price, and print price + 5 to prove it's now a real number you can do math with. Then try the same thing without converting first, and read the error message it gives you.


Lesson 2.4 — Hands-On: Build a Tiny Data Profiler

Time to put Chapter 2 together into something that actually resembles real work.

Imagine your manager hands you a single messy row from a vendor's file, and asks: "Before we load a thousand of these, can you check what we're dealing with?" That's genuinely a real, common first task for a junior data engineer — profiling a sample of data before trusting it.

Here's your row, exactly as it might arrive from a file — notice everything is text, even the number:

python
raw_row = { "order_id": "10432", "customer_name": "Priya Shah", "order_total": "149.50", "is_priority": "True" }

Don't worry about the curly braces yet — we'll cover this properly in the next chapter. For now, just know each piece is accessed like this: raw_row["order_id"] gives you "10432".

Your task:

  1. Pull out each of the four values into its own variable.
  2. Convert order_id to an int.
  3. Convert order_total to a float.
  4. Print each value along with its type, using type(), so you can see exactly what you're working with — before and after converting.

Here's the shape to get you started — fill in the gaps yourself:

python
order_id = raw_row["order_id"] print("Before conversion:", order_id, type(order_id)) order_id = int(order_id) print("After conversion:", order_id, type(order_id)) # Now do the same for order_total

Notice you're not just writing code — you're checking your own work as you go, printing before and after so you can see the type actually change. That habit of checking, not assuming, is the exact seed that grows into proper testing, which we'll build on together at the end of this week.

Try It Yourself: Finish the profiler for all four fields. Then add one more line at the end: a single print statement that summarizes the row in a clean sentence, something like: "Order 10432 from Priya Shah: $149.50, priority: True" — built using the converted variables, not the raw text ones.