Learn
🤖 AI Hub 📰 News 📖 Dictionary 🧰 Resources
Grow
💼 Jobs 🚀 Community 🏆 Challenges
Explore by Stage
🌑 Zero 📚 Learn 🔧 Practice 🏗 Build 🚀 Launch 💰 Earn
Account
Login Sign Up
🏗️HTML 🎨CSS ⚡JavaScript 🐙Git & GitHub ⚛️React Soon 📘TypeScript Soon 🐍Python 🗄️Database & SQL Soon 🌐Web Development Soon ☁️Cloud & DevOps Soon 🤖AI & ML Soon 📄Resume Prep Soon 🎤Interview Prep Soon 💼Freelancing Soon 🚀SaaS & Side Projects Soon 🤖Automation Soon
Beginner 🕑 8 min read 👁 2 views 📅 Oct 22, 2026

Numbers and Math: Bills, Discounts and Percentages

Learn Python arithmetic, floor division, remainders, powers, rounding and the math module, then build a restaurant bill splitter with a discount, GST and fair shares.

Five Friends and One Bill

It is Sneha’s birthday, and five friends go out for dinner at a restaurant in Pune. The food is great. Then the bill arrives: a subtotal of Rs. 1,990, a 10% birthday discount, and 5% GST added on top. Who pays how much? One friend says Rs. 376, another says Rs. 380, and somebody forgets the GST completely.

Calculations like this happen everywhere: shop bills, mobile recharges, exam percentages, EMI amounts and salary slips. Computers are excellent at them, as long as you tell them exactly what to do. In this lesson you will learn how Python does arithmetic, how it decides the order of a calculation, how to round numbers, and how to avoid a few surprises with decimals. At the end, you will build a bill splitter for the birthday dinner.

The Basic Operators

An operator is a symbol that does something with values. Python uses these for arithmetic:

OperatorMeaningExampleResult
+Add450 + 320770
-Subtract1000 - 770230
*Multiply3 * 180540
/Divide900 / 5180.0
//Floor division (whole part only)135 // 602
%Remainder (called modulus)135 % 6015
**Power2 ** 38
print(450 + 320)    # 770
print(1000 - 770)   # 230
print(3 * 180)      # 540
print(900 / 5)      # 180.0  (/ always gives a float)
print(1000 / 3)     # 333.3333333333333

print(type(900 / 5))    # <class 'float'>
print(type(3 * 180))    # <class 'int'>

Python has two number types. An int is a whole number, like 540. A float has a decimal point, like 180.0. The / operator always gives a float, even when the answer is a whole number. That is why 900 / 5 shows 180.0.

// and %: Whole Parts and Remainders

Remember division in primary school? 135 divided by 60 is “2, remainder 15”. Python gives you both parts with two operators:

  • // (floor division) gives the whole part: 135 // 60 is 2.
  • % (modulus) gives the remainder: 135 % 60 is 15.

They are perfect for turning minutes into hours and minutes, or for packing things into boxes:

# How long did the dinner take?
minutes = 135
hours = minutes // 60          # whole hours
left_over = minutes % 60       # minutes that remain
print(hours, "hours and", left_over, "minutes")   # 2 hours and 15 minutes

# Packing 50 laddoos into boxes of 12
laddoos = 50
box_size = 12
print("Full boxes:", laddoos // box_size)          # Full boxes: 4
print("Laddoos left over:", laddoos % box_size)    # Laddoos left over: 2

The % sign here has nothing to do with percentages. In Python it always means remainder. A common use: number % 2 is 0 for even numbers and 1 for odd numbers.

** for Powers

Two stars mean “to the power of”. 2 ** 3 means 2 × 2 × 2. Powers are useful for areas, for growth such as interest, and for big round numbers.

print(2 ** 3)       # 8      (2 x 2 x 2)
print(12 ** 2)      # 144    (the area of a 12 by 12 floor in square feet)
print(10 ** 5)      # 100000 (one lakh)

# Savings of Rs. 10000 that grow by 10% for 2 years
print(10000 * 1.1 ** 2)   # 12100.000000000002 (see "float surprises" below)

Order of Operations

When a line has several operators, Python follows the same order you learned in school maths (often remembered as BODMAS):

  1. Brackets ( ) first
  2. Then powers **
  3. Then *, /, // and %, from left to right
  4. Then + and -, from left to right
print(100 + 50 * 2)        # 200  (* first, then +)
print((100 + 50) * 2)      # 300  (brackets first)

# 10% discount on a Rs. 800 bill
bill = 800
print(bill - bill * 10 / 100)      # 720.0
print((bill - bill) * 10 / 100)    # 0.0  (wrong brackets, wrong answer)

When you are not sure, add brackets. They make the order clear to Python and to anyone reading your code.

Handy Built-in Functions: round, abs, min, max

Python has some number tools ready to use, with no setup:

  • round(x) rounds to the nearest whole number. round(x, 2) keeps 2 decimal places, which is what you want for rupees and paise.
  • abs(x) gives the absolute value: the number without its minus sign. Useful for “how far apart are these two amounts?”
  • min(...) and max(...) give the smallest and biggest of several values.
share = 376.1125

print(round(share))       # 376      (nearest whole number)
print(round(share, 2))    # 376.11   (2 decimal places)
print(round(2.5))         # 2  (exactly halfway goes to the even number)
print(round(3.5))         # 4

print(abs(-150))          # 150  (distance from zero, never negative)

print(min(240, 310, 275)) # 240  (smallest)
print(max(240, 310, 275)) # 310  (biggest)
A rounding surprise: when a number is exactly halfway, like 2.5, round() picks the nearest even number, so round(2.5) is 2 and round(3.5) is 4. This is called banker’s rounding. It keeps totals fair when you round many numbers.

The math Module: sqrt, ceil and floor

A module is a toolbox of extra functions that comes with Python. You open it with import at the top of your program, then use its tools with a dot: math.sqrt().

import math

print(math.sqrt(144))     # 12.0   (square root)
print(math.ceil(376.11))  # 377    (always rounds UP)
print(math.floor(376.99)) # 376    (always rounds DOWN)
print(math.pi)            # 3.141592653589793

math.ceil() is the friend of bill splitting. If each share is Rs. 376.11, rounding up to Rs. 377 makes sure the restaurant is never paid less than the bill. math.floor() does the opposite and always rounds down.

Float Surprises and Money Tips

Run this and look at the first line carefully:

print(0.1 + 0.2)               # 0.30000000000000004
print(0.1 + 0.2 == 0.3)        # False

# Fix 1: round the result before you show or compare it
print(round(0.1 + 0.2, 2))     # 0.3

# Fix 2: count money in paise (whole numbers), convert at the end
tea_paise = 1050               # Rs. 10.50
samosa_paise = 1525            # Rs. 15.25
total_paise = tea_paise + samosa_paise
print(total_paise)             # 2575
print(total_paise / 100)       # 25.75

This is not a mistake in your code. Computers store numbers in binary (only 0s and 1s), and some simple decimals like 0.1 cannot be stored exactly, just as 1 ÷ 3 cannot be written exactly as a decimal (0.3333...). The tiny error appears when you add them. Almost every programming language does the same.

For money, follow these habits:

  • Round at the end. Do the full calculation, then use round(amount, 2) when you show the result.
  • Count in paise for exact sums. Rs. 10.50 becomes 1050. Whole numbers are always exact.
  • Do not compare floats with ==. Round both sides first.

Python also has a decimal module for exact decimal money calculations, which you may meet later in bigger projects.

Real-Life Example: The Birthday Bill Splitter

Here is the full calculation for Sneha’s birthday dinner. The rates are stored as constants, the discount comes before GST, and each share is rounded up. The small extra amount is left as a tip.

import math

# Birthday dinner for 5 friends at a restaurant in Pune
paneer_tikka = 2 * 260     # 2 plates at Rs. 260
veg_biryani = 3 * 220      # 3 plates at Rs. 220
butter_naan = 8 * 45       # 8 naan at Rs. 45
lassi = 5 * 90             # 5 glasses at Rs. 90

FRIENDS = 5
DISCOUNT_PERCENT = 10      # birthday offer
GST_PERCENT = 5            # tax added by this restaurant

subtotal = paneer_tikka + veg_biryani + butter_naan + lassi
discount = subtotal * DISCOUNT_PERCENT / 100
after_discount = subtotal - discount
gst = after_discount * GST_PERCENT / 100
total = after_discount + gst

exact_share = total / FRIENDS
each_pays = math.ceil(exact_share)       # round UP to whole rupees
collected = each_pays * FRIENDS
tip = collected - total

print("Subtotal:   Rs.", subtotal)
print("Discount:   Rs.", round(discount, 2))
print("GST (5%):   Rs.", round(gst, 2))
print("Total:      Rs.", round(total, 2))
print("Exact share: Rs.", round(exact_share, 2))
print("Each pays:  Rs.", each_pays)
print("Extra left as a tip: Rs.", round(tip, 2))

The output is:

Subtotal:   Rs. 1990
Discount:   Rs. 199.0
GST (5%):   Rs. 89.55
Total:      Rs. 1880.55
Exact share: Rs. 376.11
Each pays:  Rs. 377
Extra left as a tip: Rs. 4.45

Try these changes:

  1. Change FRIENDS to 4. How much does each person pay now, and how big is the tip?
  2. Change the discount to 15%. Notice that the GST also becomes smaller, because it is worked out after the discount.
  3. Use max() to print the most expensive line of the order (paneer tikka, biryani, naan or lassi).

Common Mistakes

  • Writing a percentage with the % sign. In Python % means remainder, so 18% on its own is an error:
bill = 1000
gst = bill * 18%   # ERROR: SyntaxError

Write the percentage as a division by 100 instead:

bill = 1000
gst = bill * 18 / 100
print(gst)   # 180.0
  • Using x or ^. Multiply with *, not x. For powers use **. The ^ sign means something else in Python, so 2 ^ 3 gives 1, not 8.
  • Expecting / to give a whole number. 10 / 2 is 5.0. Use // if you really want only the whole part.
  • Forgetting brackets. 800 + 200 * 5 / 100 adds GST only to the 200. Write (800 + 200) * 5 / 100 for GST on the full Rs. 1,000.
  • Rounding too early. If you round every small step, the errors add up. Keep full values while you calculate and round only the final answers.

Practice Task: The Canteen Order

Four friends order food in the college canteen after their exam. Complete the starter code so that it:

  • Adds up the subtotal of the dosas, the coffees and the momo plate
  • Adds 5% GST and prints the total rounded to 2 decimal places
  • Prints each friend’s share, rounded up with math.ceil()
  • Uses // and % to share 30 momos equally and print how many are left over
import math

# Canteen order for 4 friends after the exam
masala_dosa = 4 * 70
cold_coffee = 4 * 60
momos = 30            # pieces of momos in the order
momo_price = 150      # for the whole plate of 30
FRIENDS = 4

# TODO 1: Work out the subtotal (dosa + coffee + momo plate)

# TODO 2: Add 5% GST and print the total, rounded to 2 decimals

# TODO 3: Each friend's share, rounded UP to whole rupees with math.ceil

# TODO 4: How many momos does each friend get, and how many are left over?
Show one possible answer (try it yourself first!)
import math

masala_dosa = 4 * 70
cold_coffee = 4 * 60
momos = 30
momo_price = 150
FRIENDS = 4

subtotal = masala_dosa + cold_coffee + momo_price
gst = subtotal * 5 / 100
total = subtotal + gst
print("Total: Rs.", round(total, 2))          # Total: Rs. 703.5

each_pays = math.ceil(total / FRIENDS)
print("Each pays: Rs.", each_pays)            # Each pays: Rs. 176

print("Momos each:", momos // FRIENDS)        # Momos each: 7
print("Momos left over:", momos % FRIENDS)    # Momos left over: 2

Key Takeaways

  • Python uses +, -, * and / for arithmetic, and / always gives a float.
  • // gives the whole part and % gives the remainder: great for hours and minutes or packing boxes.
  • ** is the power operator. Brackets come first, then powers, then * / // %, then + -.
  • round(), abs(), min() and max() are built in. math.sqrt(), math.ceil() and math.floor() need import math.
  • Decimals like 0.1 are not stored exactly. Round money only at the end, or count in paise.

❓ Frequently Asked Questions

In Python 3, the / operator always returns a float. Use 10 // 2 if you want the whole number 5.
round() goes to the nearest value, up or down. math.ceil() always goes up to the next whole number, which is safer when you split a bill.
Multiply by the percentage and divide by 100. For example, 18% GST on 1000 is 1000 * 18 / 100, which gives 180.0.
No. It comes from how computers store decimal numbers in binary, and most languages behave the same way. Round the result with round(value, 2) when you display it.
Yes. Python integers can be as large as your computer's memory allows, so even 2 ** 100 is calculated exactly.
Was this lesson helpful?

🎯 Finished this lesson?

🔗 Related Tutorials
🤖 Got a Doubt? Ask AI
Get instant answers in Hindi or English
🤖
Z2T Bot
Online
Ask me anything about this tutorial — I'm here! 👋