Lesson 2 of 16 · Level 1: Beginner
Python Variables, Data Types and Operators
- ⏱ 14 min read
- ❓ 4 review questions
- ✍️ Exercise with solution
In this lesson
- Create variables with clear, professional names.
- Use Python's basic types: int, float, str, bool and None.
- Convert between types and round numbers correctly.
- Calculate and compare with arithmetic, comparison and logical operators.
- Understand and fix the
TypeErrorandValueErroryou get when types don't mix.
Programs work with data: names, prices, dates, product lists. To store that data and reuse it, we use variables. In this lesson you'll learn how to create them, which basic data types Python has, and how to use operators to calculate and compare. By the end you'll write a small end-of-day sales report for a taco truck in Texas.
+ to exponents **What a variable is
A variable is a name that points to a value stored in memory. You create one with the = sign, which in programming means "assign," not "equals":
name = "Emma"
age = 29
price = 49.99
active = True
print(name)
print(age + 1)
Emma
30
Unlike languages such as Java or C#, Python doesn't make you declare the type; it figures it out from the value. A variable can also change its value while the program runs:
stock = 10
stock = stock - 3
print(stock) # 7
Read stock = stock - 3 from right to left: "take the current value of stock, subtract 3, and store the result back in stock." Python has no true constants, but by convention values that shouldn't change are written in capital letters: SALES_TAX = 0.0825. Anyone reading your code knows not to touch them.
Rules for naming variables
- Names can contain letters, numbers and underscores, but can't start with a number (
2nd_priceis invalid;price_2works). - They're case-sensitive:
ageandAgeare different variables. - They can't be reserved words such as
if,for,classorTrue. - The Python convention is snake_case: lowercase words joined by underscores (
total_price,due_date), not camelCase. - Choose names that explain the content:
total_salesbeatstsorx. You'll read your code far more often than you write it.
Python's basic data types
Integer · int
42, -7, 0
Decimal · float
3.14, 49.99
Text · str
"Hello", 'Denver'
Boolean · bool
True, False
Null · NoneType
None
You can check the type of any value with type():
print(type(29)) # <class 'int'>
print(type(49.99)) # <class 'float'>
print(type("29")) # <class 'str'>
Watch the last one: "29" in quotes is text, not a number, and you can't add 1 to it. That's also why ZIP codes like "02134" should be stored as strings: as an int, the leading zero of a Boston ZIP code would disappear.
1. What type is the value 3.5?
Numbers with a decimal point are floats, whole numbers are ints and anything in quotes is a str.
Converting between types
int("29") # 29 (text → integer)
float("49.99") # 49.99 (text → decimal)
str(29) # '29' (number → text)
int(9.99) # 9 (chops off the decimals, doesn't round)
round(9.99) # 10
round(243.56249, 2) # 243.56
Converting is essential whenever data comes from a user, a web form or a file, because it almost always arrives as text. You'll see this in the next lesson with input().
When conversion fails: TypeError and ValueError
These two errors show up as soon as you work with real data. The first one happens when you mix text and numbers:
quantity = "12" # arrived as text from a web form
total = quantity + 1
Traceback (most recent call last):
File "order.py", line 2, in <module>
total = quantity + 1
~~~~~~~~~^~~
TypeError: can only concatenate str (not "int") to str
Read it as: "I can only concatenate (join) text with text, not with an int." The fix is to convert first: int(quantity) + 1. The second error appears when the text doesn't look like a number. In the U.S. the usual culprits are dollar signs and thousands separators copied from a spreadsheet or a bank statement:
float("$49.99") # ValueError: could not convert string to float: '$49.99'
float("1,250.50") # ValueError: could not convert string to float: '1,250.50'
int("12.5") # ValueError: invalid literal for int() with base 10: '12.5'
ValueError means "the type is right (it's text), but its content can't be used." Python only understands plain digits with a dot for decimals. In the next lesson you'll clean strings with .replace("$", "") and .replace(",", ""). To turn "12.5" into an integer, convert it to float first: int(float("12.5")) gives 12.
2. What does "5" + "3" return?
They're both strings, so + joins them. To add them as numbers, convert first: int("5") + int("3") = 8.
Arithmetic operators
| Operator | Operation | Example | Result |
|---|---|---|---|
+ | Addition | 7 + 2 | 9 |
- | Subtraction | 7 - 2 | 5 |
* | Multiplication | 7 * 2 | 14 |
/ | Division (always returns a float) | 7 / 2 | 3.5 |
// | Floor division | 7 // 2 | 3 |
% | Remainder (modulo) | 7 % 2 | 1 |
** | Exponent | 7 ** 2 | 49 |
The % operator is more useful than it looks: n % 2 == 0 tells you whether a number is even, and minutes % 60 gives the leftover minutes after full hours. Python follows the usual order of operations (exponents, then multiplication and division, then addition and subtraction), so use parentheses whenever you want to be explicit: price * (1 - discount).
Shorthand assignment operators
total = 100
total += 20 # same as total = total + 20 → 120
total -= 5 # 115
total *= 2 # 230
3. What do 17 // 5 and 17 % 5 return?
// is floor division (5 fits into 17 three times) and % is the remainder (17 − 15 = 2).
Comparison and logical operators
Comparison operators compare values and return True or False. They're the foundation of the decisions you'll write in lesson 4:
age = 20
print(age >= 18) # True
print(age == 20) # True (== compares; = assigns)
print(age != 30) # True (not equal)
print(age > 18 and age < 65) # True
print(age < 18 or age > 65) # False
print(not True) # False
and is True only when both sides are True; or is True when at least one side is; not flips the value. Python even lets you chain comparisons the way you'd write them in math class: 18 <= age < 65.
x = 5 stores 5 in x. x == 5 asks whether x equals 5. Mixing them up inside an if causes a syntax error or a result you didn't expect.
4. A customer types their payment as "1,250.50". What happens when you run float("1,250.50")?
Python doesn't accept thousands separators inside a number. Remove the comma before converting. The type is fine (it's a string) but its content isn't, which is why it's a ValueError, not a TypeError.
Full example: a final price calculator
SALES_TAX = 0.0825
base_price = 250.0
discount = 0.10
discounted_price = base_price * (1 - discount)
tax = discounted_price * SALES_TAX
final_price = discounted_price + tax
print("Discounted price:", discounted_price)
print("Sales tax:", round(tax, 2))
print("Total due:", round(final_price, 2))
Discounted price: 225.0
Sales tax: 18.56
Total due: 243.56
Notice the order: in most states, sales tax applies to the price after a store discount, so the discount comes first. Also notice that print() accepts several values separated by commas and displays them with a space in between.
Real case: closing out a taco truck in San Antonio
Rosie runs a taco truck in San Antonio, Texas, and every night she does the math in a notebook. This program uses everything in the lesson: constants in capital letters, ints and floats, //, % and a comparison that returns a bool.
# End-of-day cash count for Rosie's Taco Truck (San Antonio, Texas)
TACO_PRICE = 3 # dollars
SODA_PRICE = 2
AGUA_FRESCA_PRICE = 4
TORTILLAS_PER_PACK = 30
tacos = 185
sodas = 45
aguas_frescas = 30
supply_cost = 320.0 # meat, tortillas, produce and propane
taco_sales = tacos * TACO_PRICE
drink_sales = sodas * SODA_PRICE + aguas_frescas * AGUA_FRESCA_PRICE
total_sales = taco_sales + drink_sales
profit = total_sales - supply_cost
margin = profit / total_sales * 100
tortillas = tacos * 2 # every taco is served on two tortillas
packs = tortillas // TORTILLAS_PER_PACK
loose = tortillas % TORTILLAS_PER_PACK
print("Total sales:", total_sales)
print("Profit:", profit)
print("Margin (%):", round(margin, 1))
print("Full packs:", packs, "| loose tortillas:", loose)
print("Did we beat the $750 goal?", total_sales >= 750)
Total sales: 765
Profit: 445.0
Margin (%): 58.2
Full packs: 12 | loose tortillas: 10
Did we beat the $750 goal? True
Three things to notice in the output:
- 765 is an int, but 445.0 is a float: subtracting a float (
supply_cost) turns the result into a float. Mixing ints and floats always gives a float. - // and % work as a team: 370 tortillas are 12 full packs plus 10 loose ones, so Rosie actually needs to buy 13 packs.
- The comparison returns a bool (
True). In lesson 4 you'll use values like this to make decisions, such as printing a congratulations message.
- Tacos (72.5%) $555185 tacos × $3 =
tacos * TACO_PRICE - Sodas (11.8%) $9045 sodas × $2
- Aguas frescas (15.7%) $12030 aguas frescas × $4
total_sales, times 100: the same formula the program uses for the margin.0.1 + 0.2 gives 0.30000000000000004 because of how decimals are stored in binary. To display money, use round(value, 2). If you ever build accounting or payment software where every cent counts, Python's built-in decimal module has a Decimal type that does exact decimal math.
Common mistakes with variables and types
Adding a number that arrived as text: "12" + 1.
Convert first: int("12") + 1. The clue is TypeError: can only concatenate str….
Writing a price with a comma: price = 49,99.
Use a dot: 49.99. With a comma, Python silently creates a tuple, (49, 99), and the bug shows up much later.
Using int() to round: int(9.99) gives 9.
int() truncates. To round, use round(9.99).
Naming a variable print, sum or list.
Those names are already Python tools. After print = 5, the next call fails with TypeError: 'int' object is not callable.
Cryptic names like x, ts or data2.
Self-explanatory names: total_sales, supply_cost.
Practice exercise
- Create variables for a person's monthly take-home pay ($3,800) and fixed expenses ($2,650).
- Calculate how much is left over each month and what percentage of take-home pay that is.
- Calculate how many months it takes to save $5,000 if they save everything left over. Try floor division and regular division: which answer makes more sense?
- Show whether the monthly savings are at least 20% of take-home pay (True/False).
See solution
take_home_pay = 3800
fixed_expenses = 2650
left_over = take_home_pay - fixed_expenses # 1150
percentage = left_over / take_home_pay * 100 # 30.26...
print("Left over:", left_over)
print("Percentage:", round(percentage, 1), "%")
print(5000 // left_over)
print(5000 / left_over)
print(left_over >= take_home_pay * 0.20)
Left over: 1150
Percentage: 30.3 %
4
4.3478260869565215
True
Floor division says 4, but after 4 months they'd have $4,600, which isn't enough: in practice they need 5 months. To "round up" you'll use math.ceil() later in the course. And yes, $1,150 is more than 20% of $3,800 ($760).
Summary
- Variables are created with
=, and their names use snake_case; constants go in CAPITALS by convention. - Basic types:
int,float,str,boolandNone; check them withtype(). - Convert with
int(),float()andstr(); round withround(), notint(). /divides with decimals,//floor-divides,%gives the remainder and==compares.TypeErrormeans types that can't be mixed;ValueErrormeans text that doesn't look like a number, such as "$49.99".
Next lesson: Python Strings, F-Strings and input(). You'll index and slice text, use string methods, format dollars with f-strings and ask the user for data.
Create your account in 30 seconds, mark your lessons and download your certificate at the end.