All 57 lessons
Lesson 4 of 57 · Getting Started
Numbers and Operators in Python
By Skillancy Editorial Team
Run the code in the free Python Compiler or on your own computer. Lessons that read files use the FreshBasket practice data: download the dataset (ZIP).
Analytics is mostly arithmetic done at scale: totals, averages, percentages, growth rates, discounts and taxes. Python handles all of it, and once you understand a handful of operators and one famous quirk about decimals, you can express almost any business calculation in a single readable line.
This lesson covers the numeric operators, the order in which Python evaluates them, the difference between true division and floor division, rounding, and why 0.1 + 0.2 does not give exactly 0.3. Every example uses FreshBasket pricing and delivery numbers so the calculations feel like real work.
The arithmetic operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | Addition | 7 + 3 | 10 |
- | Subtraction | 7 - 3 | 4 |
* | Multiplication | 7 * 3 | 21 |
/ | True division (always a float) | 7 / 2 | 3.5 |
// | Floor division (whole part) | 7 // 2 | 3 |
% | Modulo (remainder) | 7 % 2 | 1 |
** | Power (exponent) | 7 ** 2 | 49 |
Two of these deserve special attention. Division with / always returns a float, even when the answer is whole: 10 / 5 is 2.0. Floor division // throws away the fractional part and keeps the whole number of times one value fits in another, and % gives what is left over. Together they answer questions such as "how many full boxes, and how many items are left over?".
Precedence: who goes first?
Python follows the same order as school maths, often remembered as BODMAS or PEMDAS: brackets first, then powers, then multiplication, division, floor division and modulo (left to right), and finally addition and subtraction. So 2 + 3 * 4 is 14, not 20. When in doubt, add brackets. They cost nothing and make your intent obvious to the next reader.
Worked examples
Example 1: GST on a basket
Question: A customer's basket is ₹864 before tax. With 5% GST and a ₹25 delivery fee, what is the total?
basket = 864
gst = basket * 5 / 100
total = basket + gst + 25
print(gst, total)Output
43.2 932.2How it works: basket * 5 / 100 multiplies first, then divides (left to right), giving the tax amount. We add tax and the delivery fee to the basket. Because / was involved, the results are floats.
Reading the result: GST is ₹43.2 and the customer pays ₹932.2. Notice that gst is a float even though 864 and 5 are integers: / always produces a float.
Example 2: Percentage discounts and percentage change
Question: Yesterday's revenue was ₹1,85,000 and today's is ₹2,12,750. What is the percentage growth? Then apply a 15% coupon to a ₹649 basket.
yesterday = 185000
today = 212750
growth_pct = (today - yesterday) / yesterday * 100
print(round(growth_pct, 2))
coupon_basket = 649 * (1 - 15 / 100)
print(round(coupon_basket, 2))Output
15.0
551.65How it works: Percentage change is always (new minus old) divided by old, times 100. The brackets force the subtraction to happen before the division. For the coupon, 1 - 15/100 gives 0.85, the fraction the customer still pays.
Reading the result: Revenue grew by 15.0%, and the discounted basket is ₹551.65. Writing 1 - discount is a neat way to avoid subtracting a discount amount in a second step.
Example 3: Floor division and remainder
Question: A rider can carry 8 orders at a time. For 61 orders waiting at a dark store, how many full trips are needed and how many orders are left for a final partial trip?
orders_waiting = 61
capacity = 8
full_trips = orders_waiting // capacity
leftover = orders_waiting % capacity
print(full_trips, leftover)
print(divmod(orders_waiting, capacity))Output
7 5
(7, 5)How it works: // counts how many times 8 fits into 61 and % returns what remains. The built-in divmod(a, b) returns both in one call, as a pair.
Reading the result: There are 7 full trips with 5 orders left over, so the store needs 8 trips in total. The identity full_trips * capacity + leftover == orders_waiting always holds, which is a good sanity check.
Example 4: Converting minutes to hours and minutes
Question: A rider worked 487 minutes today. Display that as hours and minutes.
worked = 487
hours, minutes = divmod(worked, 60)
print(f"{hours}h {minutes}m")Output
8h 7mHow it works: Dividing minutes by 60 with divmod gives whole hours and the remaining minutes. The pair is unpacked straight into two variables, a technique you saw in the variables lesson.
Reading the result: 487 minutes is 8 hours and 7 minutes. The same trick converts seconds to minutes, days to weeks, or paise to rupees.
Example 5: Rounding up, down and to the nearest
Question: Each delivery box holds 12 items. A customer orders 50 items. How many boxes are needed? Compare it with ordinary rounding.
import math
items = 50
per_box = 12
print(items / per_box)
print(round(items / per_box))
print(math.floor(items / per_box))
print(math.ceil(items / per_box))Output
4.166666666666667
4
4
5How it works: / gives 4.1667 (rounded). round() goes to the nearest whole number, math.floor() always rounds down and math.ceil() always rounds up. When you need a whole number of containers you must round up, because a fifth, partly filled box still has to exist.
Reading the result: The right answer is 5 boxes, and ordinary rounding would have given 4, leaving two items without a box. Choosing the right rounding direction is a business decision, not just a maths one.
Example 6: Python's banker's rounding and decimal places
Question: How does round() treat halves, and how do I keep two decimal places?
print(round(2.5), round(3.5), round(4.5))
print(round(7.456, 2), round(7.454, 2))
print(round(1234.5678, -2))Output
2 4 4
7.46 7.45
1200.0How it works: For exact halves, Python's round() goes to the nearest even number (called banker's rounding), so 2.5 becomes 2 and 3.5 becomes 4. This reduces bias when you round many numbers. The second argument is the number of decimal places, and a negative number rounds to tens, hundreds and so on.
Reading the result: The first line prints 2 4 4, the second 7.46 7.45, and the third rounds to the nearest hundred, giving 1200.0. If your business needs "round half up" (as most invoices do), use the decimal module, shown in the next example.
Example 7: The famous 0.1 + 0.2 problem
Question: Why does Python say 0.1 + 0.2 is not 0.3?
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(round(0.1 + 0.2, 2) == 0.3)Output
0.30000000000000004
False
TrueHow it works: Computers store decimals in binary, and numbers such as 0.1 cannot be written exactly in binary, just as 1/3 cannot be written exactly in decimal. Each float is a very close approximation, and tiny errors can appear after arithmetic. This is true in every mainstream programming language. Excel uses the same binary format, but it rounds what it displays, which hides the effect most of the time.
Reading the result: The sum prints as 0.30000000000000004, so the equality test is False. The practical rules are: never compare floats with == (round first, or use math.isclose), and display results with round() or an f-string. For exact money arithmetic, use whole paise as integers or Python's Decimal:
from decimal import Decimal, ROUND_HALF_UP
price = Decimal("19.995")
print(price.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))
print(Decimal("0.1") + Decimal("0.2"))Output
20.00
0.3Decimal stores numbers as written, so 0.1 + 0.2 is exactly 0.3, and quantize rounds half up the way an invoice would. For analysis on large datasets, ordinary floats are fine; pandas uses them throughout.
Example 8: Powers, compound growth and useful built-ins
Question: If FreshBasket grows orders by 8% every month, how many daily orders will a store have after 6 months starting from 150? Also find the cheapest and costliest of four item prices.
start_orders = 150
monthly_growth = 0.08
after_6 = start_orders * (1 + monthly_growth) ** 6
print(round(after_6))
prices = [49, 245, 118, 62]
print(min(prices), max(prices), sum(prices), abs(-37))Output
238
49 245 474 37How it works: Compound growth multiplies by (1 + rate) once per period, which is (1 + rate) ** periods. The power operator ** binds tighter than multiplication, so the growth factor is calculated first. min, max and sum work on lists (covered soon), and abs returns the absolute value, removing the minus sign.
Reading the result: Starting at 150 orders a day, six months of 8% growth gives about 238 orders a day. The cheapest item costs ₹49, the dearest ₹245, and the four together cost ₹474.
Example 9: Readable large numbers
Question: How do I write big numbers without miscounting zeros?
annual_revenue = 12_50_00_000
crore = 1_00_00_000
print(annual_revenue / crore)
print(1.5e3, 2e-2)
print(f"{annual_revenue:,}")Output
12.5
1500.0 0.02
125,000,000How it works: Underscores inside number literals are ignored by Python and exist only to help human eyes. You can group them in thousands, or in the Indian lakh and crore style as above. Scientific notation 1.5e3 means 1.5 × 10³. In output, the , format adds Western thousand separators.
Reading the result: The annual revenue is 12.5 crore rupees. The scientific values print as 1500.0 and 0.02. Python's f-string , format does not group by lakhs, so for Indian-style grouping you need a small custom function, which we build in the functions lesson.
Common mistakes
1. Expecting / to return an integer. 10 / 2 is 5.0. Use // for a whole-number result.
2. Forgetting precedence. 100 - 20 / 2 is 90.0, not 40.0. Add brackets: (100 - 20) / 2.
3. Dividing by zero. This crashes the program, and in analytics it happens when a denominator is empty.
conversion_rate = 120 / 0Output
Traceback (most recent call last):
File "example.py", line 1, in <module>
conversion_rate = 120 / 0
~~~~^~~
ZeroDivisionError: division by zero4. Comparing floats with ==. Use round() or math.isclose(a, b) instead.
5. Using ^ for powers. In Python ^ means bitwise XOR, not exponent. Write 2 ** 3 for 8.
Practice questions
Practice 1 (Easy): Bill with discount
A basket of ₹1,240 gets a 10% discount, then 5% GST is added on the discounted amount. What is the final amount, rounded to two decimals?
Show solution
basket = 1240
after_discount = basket * (1 - 0.10)
final = after_discount * (1 + 0.05)
print(round(final, 2))Output
1171.8GST applies after the discount, so we first reduce the basket and then multiply by 1.05. The answer is ₹1171.8.
Practice 2 (Medium): Packing trays
FreshBasket packs eggs in trays of 30. A store receives 1,000 eggs. How many full trays can it make, how many loose eggs remain, and how many trays are needed if every egg must be in a tray?
Show solution
import math
eggs = 1000
full_trays, loose = divmod(eggs, 30)
trays_needed = math.ceil(eggs / 30)
print(full_trays, loose, trays_needed)Output
33 10 34divmod returns 33 full trays and 10 loose eggs, so one extra tray is required, making 34 in total.
Practice 3 (Hard): Break-even growth
A store makes 200 orders a day and wants to reach 500. At 6% monthly growth, how many whole months will it take? Use a calculation, not a loop (hint: try math.log).
Show solution
import math
months = math.log(500 / 200) / math.log(1.06)
print(round(months, 2), math.ceil(months))Output
15.73 16We solve 200 × 1.06ⁿ = 500 for n. Taking logarithms gives n = log(500/200) / log(1.06), about 15.73 months, and since we need whole months we round up to 16.
Key takeaways
/always returns a float,//returns the whole part,%returns the remainder, and**is the power operator.- Python follows BODMAS; use brackets when you want to be explicit.
- Percentage change is
(new - old) / old * 100; a discount of d% multiplies the price by1 - d/100. - Use
math.ceilwhen you need enough containers,math.floorfor complete units, androundfor the nearest, remembering that Python rounds halves to the nearest even number. - Floats are approximate: round for display, never compare with
==, and useDecimalfor exact money. divmod(a, b)gives quotient and remainder together, and underscores such as12_50_00_000make big numbers readable.
Frequently asked questions
Why does 7 / 2 give 3.5 but 7 // 2 give 3?
/ is true division and always returns a float. // is floor division: it divides and then rounds down to the nearest whole number. With negative numbers, floor division rounds toward minus infinity, so -7 // 2 is -4.
What is the difference between % and a percentage?
% is the modulo operator and returns a remainder. To calculate a percentage you multiply by the rate divided by 100. Python has no percent operator.
How big can an integer be in Python?
There is effectively no limit; Python integers grow as needed, limited only by memory. Floats, however, have a fixed range and about 15 to 16 digits of precision.
Should I use float or Decimal for money?
For small calculations that need exact rounding, such as invoices, use Decimal or whole paise stored as integers. For analysing large datasets, floats are standard and faster. Round only when you display or report a value.
Why does round(2.675, 2) give 2.67?
Because 2.675 cannot be represented exactly in binary, the stored value is slightly below 2.675, so it rounds down. This is the same floating-point effect described above.
Is there a built-in function for average?
Not in the core language, but sum(values) / len(values) works, and the statistics module has mean(). In pandas you will simply call .mean() on a column.
Keep learning Python
One email a week with Python and analytics guides, new practice questions and cohort dates. No spam, unsubscribe anytime.
Ready to practise? Try the Python interview questions