Python for CA Professionals
A Complete Beginner's Guide
Welcome! You've spent years mastering financial statements, auditing standards, and tax laws.
Now it's time to add one more powerful tool to your arsenal: Python.
"Python is the Excel of the future — except it can do in 3 lines what Excel takes 30 clicks to do."
Who is this notebook for?
- CA graduates and finance professionals
- Absolute beginners — zero coding experience required
- Anyone who wants to automate repetitive financial tasks
What will you learn?
By the end of this notebook, you will be able to: - Write your first Python programs - Work with numbers, text, and data — just like in Excel but far more powerful - Build a simple tax calculator and financial report generator - Automate repetitive calculations
How to use this notebook
- Each grey box below is a code cell — it contains Python code you can run
- Click on a code cell and press Shift + Enter to run it
- Markdown cells (like this one) contain explanations — just read them
- Try changing the numbers in code cells and re-run them — experimentation is the best teacher!
⏱️ Estimated time: 3–4 hours (you can go at your own pace)
📋 Table of Contents
| # | Topic | What you'll learn |
|---|---|---|
| 1 | What is Python? | Why Python matters for finance |
| 2 | Your First Program | print(), comments |
| 3 | Variables | Storing values, naming rules |
| 4 | Data Types | Numbers, text, True/False |
| 5 | Python as a Calculator | Arithmetic, tax & interest calculations |
| 6 | Making Decisions | if / elif / else, tax brackets |
| 7 | Working with Text | Strings, formatting financial reports |
| 8 | Lists | Collections of data, expense lists |
| 9 | Dictionaries | Key-value data, ledger records |
| 10 | Loops | Automating repetitive work |
| 11 | Functions | Reusable code, tax calculator |
| 12 | Practice Exercises | Test your skills |
Section 1: What is Python?
Think of Python as a very smart assistant
Imagine you have a new junior staff member who: - Does exactly what you tell them, every single time - Works 24/7 without complaining - Can process thousands of transactions in seconds - Never makes arithmetic mistakes
That's Python.
Why do CA professionals use Python?
| Task | Without Python | With Python |
|---|---|---|
| Calculate VAT on 500 invoices | 30 minutes in Excel | 2 seconds |
| Classify expenses into categories | Manual, error-prone | Automatic |
| Generate financial reports | Hours of formatting | Minutes |
| Detect anomalies in transactions | Sampling only | 100% coverage |
| Reconcile bank statements | Tedious VLOOKUP | One command |
Python in the real world (Finance)
- Big 4 firms use Python for data analytics and audit automation
- Banks use Python for risk modelling and fraud detection
- Tax authorities (like IRD) use Python to analyse return data
- Stock exchanges use Python for real-time data processing
💡 Key insight: Python does not replace your CA knowledge. It multiplies it.
Section 2: Your First Python Program
The print() function
The most basic thing Python can do is display a message on screen.
We use the print() function for this.
Syntax: print('your message here')
Think of print() as Python's way of speaking to you.
Whatever you put inside the brackets (in quotes) will be displayed.
Let's run our first program:
print('Hello, World!')
Hello, World!
Congratulations! 🎉 You just wrote your first Python program!
Now let's try something more relevant to our work:
print('Welcome to Python for Finance!')
print('This notebook will help CA professionals automate their work.')
print('Let us get started!')
Welcome to Python for Finance!
This notebook will help CA professionals automate their work.
Let us get started!
Comments — Notes to yourself
In your audit working papers, you write notes explaining your work.
In Python, we do the same using comments.
A comment starts with # (hash symbol). Python completely ignores anything after # on that line.
Comments are for humans to read — they help explain what the code is doing.
# This is a comment — Python ignores this line
print('Fiscal Year 2081-82 BS (Mid-July 2024 to Mid-July 2025)') # You can also add comments at the end of a line
# The line below prints the company name
print('Sunrise Trading Pvt. Ltd.')
# Always write comments to explain WHY you wrote the code, not just WHAT it does
Fiscal Year 2081-82 BS (Mid-July 2024 to Mid-July 2025)
Sunrise Trading Pvt. Ltd.
✏️ Mini Exercise 1
In the cell below, write a Python program that prints: 1. Your name 2. Your firm name (or any name) 3. Today's date
Add a comment before each print statement explaining what it does.
# Write your code here
Section 3: Variables — Storing Information
What is a variable?
In accounting, you have ledger accounts — each account holds a value (like Cash Account = NPR 50,000).
In Python, a variable is the same concept — it's a named container that holds a value.
cash_balance = 50000
↑ ↑
account name account value
The = sign means "store this value in this variable" (it does NOT mean "equal to" the way it does in maths).
Once you create a variable, you can use it anywhere in your code.
# Creating variables — storing financial data
revenue = 1500000 # Total revenue: NPR 15,00,000
expenses = 980000 # Total expenses: NPR 9,80,000
tax_rate = 0.30 # Tax rate: 30%
company_name = 'Sunrise Trading Pvt. Ltd.'
# Now we can USE these variables
print(company_name)
print(revenue)
print(expenses)
print(tax_rate)
Sunrise Trading Pvt. Ltd.
1500000
980000
0.3
# Variables can be used in calculations — just like cell references in Excel
profit = revenue - expenses
print('Profit before tax:', profit)
tax_payable = profit * tax_rate
print('Tax payable:', tax_payable)
profit_after_tax = profit - tax_payable
print('Profit after tax:', profit_after_tax)
Profit before tax: 520000
Tax payable: 156000.0
Profit after tax: 364000.0
Rules for naming variables
Just like account names follow conventions in accounting, variable names follow rules in Python:
| Rule | Example |
|---|---|
| Use letters, numbers, underscores only | tax_rate, profit2024 |
| Must start with a letter or underscore | revenue ✅ 1revenue ❌ |
| No spaces — use underscore instead | net_profit ✅ net profit ❌ |
| Case-sensitive | Revenue and revenue are different variables |
| Use descriptive names | tax_payable ✅ t ❌ |
Convention: Use lowercase with underscores (this is called snake_case — very common in Python)
# Good variable names — descriptive and clear
gross_salary = 1200000
standard_deduction = 50000
hra_exemption = 180000
taxable_income = gross_salary - standard_deduction - hra_exemption
print('Taxable Income:', taxable_income)
# Variables can be updated (reassigned)
gross_salary = 1500000 # Got a raise!
print('Updated salary:', gross_salary)
Taxable Income: 970000
Updated salary: 1500000
✏️ Mini Exercise 2
Create variables for the following Balance Sheet items and print them: - Share Capital: NPR 5,00,000 - Reserves & Surplus: NPR 2,50,000 - Long-term Debt: NPR 3,00,000 - Calculate and print: Total Equity + Debt
# Write your code here
Section 4: Data Types — Types of Information
Every piece of data has a type
In accounting, data comes in different forms: - Amounts — NPR 50,000 (numbers) - Client names — "Reliance Industries" (text) - Audit status — Yes/No (True/False)
Python has corresponding data types for each of these:
| Python Type | What it stores | Example |
|---|---|---|
int |
Whole numbers | 1000, -500, 0 |
float |
Decimal numbers | 18.5, 0.30, 99.99 |
str |
Text (string) | 'Revenue', 'ABC Ltd' |
bool |
True or False | True, False |
You can check the type of any value using the type() function.
# int — whole numbers (no decimal point)
number_of_invoices = 250
number_of_employees = 48
financial_year = 2025
print('Number of invoices:', number_of_invoices)
print('Type:', type(number_of_invoices)) # Shows the data type
Number of invoices: 250
Type: <class 'int'>
# float — numbers with a decimal point
vat_rate = 13.0 # 13% Nepal VAT rate
income_tax_rate = 25.0 # Nepal corporate income tax rate
interest_rate = 8.5 # 8.5% interest rate
invoice_amount = 47500.75
print('VAT Rate:', vat_rate)
print('Type:', type(vat_rate))
print('Invoice Amount:', invoice_amount)
VAT Rate: 13.0
Type: <class 'float'>
Invoice Amount: 47500.75
# str (string) — text data
# Strings are ALWAYS enclosed in quotes (single '' or double "")
client_name = 'Himalayan Tech Solutions Pvt. Ltd.'
audit_period = 'Shrawan 2081 to Ashadh 2082 BS'
pan_number = '123456789' # Nepal PAN (9 digits) # Even numbers stored as text when not used for calculation
print('Client:', client_name)
print('Audit Period:', audit_period)
print('PAN:', pan_number)
print('Type:', type(client_name))
Client: Himalayan Tech Solutions Pvt. Ltd.
Audit Period: Shrawan 2081 to Ashadh 2082 BS
PAN: 123456789
Type: <class 'str'>
# bool — Boolean (True or False only)
# Very useful for status checks and decisions
is_audit_complete = True
is_tax_paid = False
is_listed_company = True
print('Audit complete?', is_audit_complete)
print('Tax paid?', is_tax_paid)
print('Listed company?', is_listed_company)
print('Type:', type(is_audit_complete))
Audit complete? True
Tax paid? False
Listed company? True
Type: <class 'bool'>
# Real-world example: A client record with mixed data types
client_name = 'Ncell Pvt. Ltd.' # str
client_id = 10045 # int
revenue_crores = 146767.0 # float (Revenue in crores)
is_fortune500 = True # bool
print('--- Client Profile ---')
print('Name:', client_name)
print('ID:', client_id)
print('Revenue (NPR Crores):', revenue_crores)
print('Fortune 500 Company?', is_fortune500)
--- Client Profile ---
Name: Ncell Pvt. Ltd.
ID: 10045
Revenue (NPR Crores): 146767.0
Fortune 500 Company? True
⚠️ Important: Numbers in quotes are NOT numbers!
This is a very common beginner mistake. Watch carefully:
# This is a NUMBER (int)
amount1 = 50000
print(type(amount1)) # <class 'int'>
# This is TEXT (str) — the quotes make it text!
amount2 = '50000'
print(type(amount2)) # <class 'str'>
# What happens when you try to add them?
print(amount1 + amount1) # 100000 — correct! (number + number)
print(amount2 + amount2) # '5000050000' — joins text! (text + text)
# Lesson: Always store amounts as numbers (int or float), not as strings
<class 'int'>
<class 'str'>
100000
5000050000
Section 5: Python as Your Financial Calculator
Arithmetic Operators
Python handles all standard arithmetic — and then some:
| Operator | Operation | Example | Result |
|---|---|---|---|
+ |
Addition | 100 + 50 |
150 |
- |
Subtraction | 100 - 30 |
70 |
* |
Multiplication | 100 * 2 |
200 |
/ |
Division | 100 / 4 |
25.0 |
// |
Floor Division (quotient only) | 100 // 3 |
33 |
% |
Modulo (remainder only) | 100 % 3 |
1 |
** |
Exponent (power) | 2 ** 10 |
1024 |
Order of operations is the same as in mathematics (BODMAS/PEMDAS).
# Basic arithmetic
revenue = 2500000
cost_of_goods = 1600000
operating_expenses = 350000
gross_profit = revenue - cost_of_goods
print('Gross Profit:', gross_profit)
net_profit = gross_profit - operating_expenses
print('Net Profit:', net_profit)
gross_margin = (gross_profit / revenue) * 100
print('Gross Profit Margin:', gross_margin, '%')
Gross Profit: 900000
Net Profit: 550000
Gross Profit Margin: 36.0 %
# VAT Calculation (Nepal — single tax, no CGST/SGST split)
invoice_base_amount = 85000 # Base amount before VAT (NPR)
vat_rate = 13.0 # 13% VAT (Nepal standard rate per IRD)
vat_amount = invoice_base_amount * (vat_rate / 100)
invoice_total = invoice_base_amount + vat_amount
print('--- VAT Invoice Summary (Nepal) ---')
print('Base Amount: NPR ', f'{invoice_base_amount:,}')
print('VAT @ 13%: NPR ', f'{vat_amount:,}')
print('Invoice Total: NPR ', f'{invoice_total:,}')
print()
print('Note: Nepal uses a single VAT rate (no CGST/SGST split like India)')
print('VAT Registration required for turnover > NPR 50 Lakhs per year (IRD)')
--- VAT Invoice Summary (Nepal) ---
Base Amount: NPR 85,000
VAT @ 13%: NPR 11,050.0
Invoice Total: NPR 96,050.0
Note: Nepal uses a single VAT rate (no CGST/SGST split like India)
VAT Registration required for turnover > NPR 50 Lakhs per year (IRD)
# Compound Interest Calculation
# Formula: A = P * (1 + r/n)^(n*t)
principal = 500000 # NPR 5,00,000 initial investment
annual_rate = 0.12 # 12% per annum
n = 4 # Compounded quarterly (4 times a year)
years = 3 # Investment period
# ** is the power operator in Python (same as ^ in Excel/maths)
amount = principal * (1 + annual_rate / n) ** (n * years)
interest_earned = amount - principal
print('--- Fixed Deposit Summary ---')
print('Principal: NPR ', principal)
print('Rate: ', annual_rate * 100, '% per annum')
print('Period: ', years, 'years')
print('Maturity Amount: NPR ', round(amount, 2))
print('Interest Earned: NPR ', round(interest_earned, 2))
--- Fixed Deposit Summary ---
Principal: NPR 500000
Rate: 12.0 % per annum
Period: 3 years
Maturity Amount: NPR 712880.44
Interest Earned: NPR 212880.44
# EMI Calculation
# Formula: EMI = [P * r * (1+r)^n] / [(1+r)^n - 1]
loan_amount = 2000000 # NPR 20,00,000 home loan
annual_rate = 8.5 # 8.5% per annum
loan_years = 20 # 20 years
monthly_rate = (annual_rate / 100) / 12 # Convert to monthly rate
n_months = loan_years * 12 # Total number of months
emi = (loan_amount * monthly_rate * (1 + monthly_rate) ** n_months) / ((1 + monthly_rate) ** n_months - 1)
total_payment = emi * n_months
total_interest = total_payment - loan_amount
print('--- Home Loan EMI Calculator ---')
print('Loan Amount: NPR ', loan_amount)
print('Interest Rate: ', annual_rate, '% per annum')
print('Loan Tenure: ', loan_years, 'years')
print('Monthly EMI: NPR ', round(emi, 2))
print('Total Payment: NPR ', round(total_payment, 2))
print('Total Interest: NPR ', round(total_interest, 2))
--- Home Loan EMI Calculator ---
Loan Amount: NPR 2000000
Interest Rate: 8.5 % per annum
Loan Tenure: 20 years
Monthly EMI: NPR 17356.46
Total Payment: NPR 4165551.52
Total Interest: NPR 2165551.52
✏️ Mini Exercise 3
A client has the following P&L data: - Net Sales: NPR 45,00,000 - Cost of Goods Sold: NPR 28,00,000 - Administrative Expenses: NPR 4,50,000 - Selling Expenses: NPR 2,20,000 - Tax Rate: 25%
Calculate and print: 1. Gross Profit 2. Net Profit Before Tax 3. Tax Amount 4. Net Profit After Tax 5. Net Profit Margin (%)
# Write your P&L calculator here
Section 6: Making Decisions — if / elif / else
Python can think!
In your work, you constantly make decisions based on conditions: - "If income exceeds NPR 10 lakh, apply the higher tax slab" - "If debt-to-equity ratio is above 2, flag as high risk" - "If the account balance is negative, send an alert"
Python does this using if / elif / else statements.
Structure:
if condition:
# do this if condition is True
elif another_condition:
# do this if the above is False but this is True
else:
# do this if ALL above conditions are False
⚠️ Indentation is critical in Python! The code inside if/elif/else must be indented (4 spaces or 1 Tab). This is how Python knows which code belongs to which block.
# Simple if/else — Checking if a company is profitable
net_profit = 250000
if net_profit > 0:
print('Company is PROFITABLE')
print('Profit amount: NPR ', net_profit)
else:
print('Company is at a LOSS')
print('Loss amount: NPR ', abs(net_profit)) # abs() gives absolute (positive) value
# Try changing net_profit to a negative number and re-run!
Company is PROFITABLE
Profit amount: NPR 250000
# Comparison operators — used to create conditions
# > greater than
# < less than
# >= greater than or equal to
# <= less than or equal to
# == equal to (note: TWO equal signs!)
# != not equal to
revenue = 5000000
threshold = 4000000
print(revenue > threshold) # True
print(revenue < threshold) # False
print(revenue == threshold) # False (not equal)
print(revenue != threshold) # True (they are different)
True
False
False
True
# Nepal Income Tax Slab Calculator (FY 2081-82 BS)
# Source: Inland Revenue Department (IRD), Nepal
taxable_income = 850000 # Change this to test different amounts (in NPR)
# Nepal individual income tax slabs (FY 2081-82)
# Slab 1: Up to NPR 5,00,000 → 1%
# Slab 2: NPR 5,00,001 to 7,00,000 → 10%
# Slab 3: NPR 7,00,001 to 20,00,000 → 20%
# Slab 4: Above NPR 20,00,000 → 30%
print('Taxable Income: NPR ', f'{taxable_income:,}')
print('-' * 45)
if taxable_income <= 500000:
tax = taxable_income * 0.01
slab = '1% slab (up to NPR 5 Lakh)'
elif taxable_income <= 700000:
tax = (500000 * 0.01) + (taxable_income - 500000) * 0.10
slab = '10% slab (NPR 5L to NPR 7L)'
elif taxable_income <= 2000000:
tax = (500000 * 0.01) + (200000 * 0.10) + (taxable_income - 700000) * 0.20
slab = '20% slab (NPR 7L to NPR 20L)'
else:
tax = (500000 * 0.01) + (200000 * 0.10) + (1300000 * 0.20) + (taxable_income - 2000000) * 0.30
slab = '30% slab (above NPR 20L)'
print('Applicable Slab:', slab)
print('Income Tax: NPR ', f'{round(tax, 2):,}')
print('Net Income: NPR ', f'{round(taxable_income - tax, 2):,}')
print()
print('Note: No cess/surcharge in Nepal. SSF contribution is separate.')
Taxable Income: NPR 850,000
---------------------------------------------
Applicable Slab: 20% slab (NPR 7L to NPR 20L)
Income Tax: NPR 55,000.0
Net Income: NPR 795,000.0
Note: No cess/surcharge in Nepal. SSF contribution is separate.
# Loan Eligibility Check — using 'and' / 'or' for multiple conditions
age = 35
annual_income = 720000 # NPR 7.2 lakhs
credit_score = 720
existing_emi = 8000 # Monthly existing EMI
# Monthly income
monthly_income = annual_income / 12
# EMI should not exceed 40% of monthly income (FOIR rule)
max_emi = monthly_income * 0.40
print('--- Loan Eligibility Assessment ---')
print('Monthly Income: NPR ', round(monthly_income, 2))
print('Max Allowable EMI (40%): NPR ', round(max_emi, 2))
print()
if age >= 21 and age <= 60 and credit_score >= 700 and existing_emi < max_emi:
print('Result: ELIGIBLE for loan ✓')
elif credit_score < 700:
print('Result: NOT ELIGIBLE — Low credit score')
elif existing_emi >= max_emi:
print('Result: NOT ELIGIBLE — Existing EMI too high')
else:
print('Result: NOT ELIGIBLE — Age criteria not met')
--- Loan Eligibility Assessment ---
Monthly Income: NPR 60000.0
Max Allowable EMI (40%): NPR 24000.0
Result: ELIGIBLE for loan ✓
✏️ Mini Exercise 4
Write a program that checks a company's Debt-to-Equity ratio and classifies it: - D/E < 1.0 → "Low Risk — Financially healthy" - D/E between 1.0 and 2.0 → "Moderate Risk — Monitor closely" - D/E > 2.0 → "High Risk — Caution advised"
Test it with: Total Debt = NPR 45,00,000, Total Equity = NPR 30,00,000
# Write your D/E ratio checker here
total_debt = 4500000
total_equity = 3000000
# Calculate D/E ratio
# Add your if/elif/else here
Section 7: Working with Text — Strings
Strings are everywhere in finance
Client names, invoice descriptions, report headings, audit observations — all of these are text (strings) in Python.
A string is any text enclosed in single '...' or double "..." quotes.
You can do many useful things with strings: - Combine them (concatenation) - Convert case (upper, lower) - Check if something is in the string - Format them with variables (f-strings) ← the most useful one!
# String basics
company = 'CloudNepal Pvt. Ltd.'
city = 'Kathmandu'
# String length — how many characters?
print('Company name length:', len(company))
# Convert case
print(company.upper()) # WIPRO LIMITED
print(company.lower()) # wipro limited
# Combine strings (concatenation) using +
full_description = company + ', ' + city
print(full_description)
Company name length: 20
CLOUDNEPAL PVT. LTD.
cloudnepal pvt. ltd.
CloudNepal Pvt. Ltd., Kathmandu
# f-strings — The best way to create formatted text
# Put 'f' before the opening quote, then use {} to insert variable values
client_name = 'Unilever Nepal Ltd.'
audit_year = 2025
fee = 850000
audit_status = 'In Progress'
# Without f-string (old way — clunky)
message_old = 'Client: ' + client_name + ', Year: ' + str(audit_year)
print(message_old)
# With f-string (modern way — clean and readable)
message = f'Client: {client_name}, Year: {audit_year}'
print(message)
# You can even do calculations inside {}
print(f'Audit Fee: NPR {fee:,}') # {:,} adds comma formatting
print(f'Status: {audit_status}')
print(f'Fee in Lakhs: NPR {fee/100000:.2f}L') # :.2f means 2 decimal places
Client: Unilever Nepal Ltd., Year: 2025
Client: Unilever Nepal Ltd., Year: 2025
Audit Fee: NPR 850,000
Status: In Progress
Fee in Lakhs: NPR 8.50L
# Creating a formatted financial report header using f-strings
company_name = 'Bottlers Nepal Ltd.'
report_type = 'Statement of Profit and Loss'
period = 'Year ended 16th July 2025 (Ashadh 2082 BS)'
currency = 'NPR (NPR in Lakhs)'
# Using the * operator to repeat characters — useful for formatting
separator = '=' * 55
print(separator)
print(f' {company_name}')
print(f' {report_type}')
print(f' {period}')
print(f' All figures in: {currency}')
print(separator)
=======================================================
Bottlers Nepal Ltd.
Statement of Profit and Loss
Year ended 16th July 2025 (Ashadh 2082 BS)
All figures in: NPR (NPR in Lakhs)
=======================================================
# Useful string methods for data cleaning (very common in practice!)
# Often, data imported from Excel/CSV has extra spaces or inconsistent case
messy_client_name = ' infosys limited ' # Extra spaces
print('Before cleaning:', messy_client_name)
# .strip() removes leading and trailing spaces
clean_name = messy_client_name.strip()
print('After strip():', clean_name)
# .title() makes first letter of each word uppercase
formatted_name = clean_name.title()
print('After title():', formatted_name)
# .replace() — find and replace text
description = 'Sales Receipts - Cash - 2024'
updated = description.replace('Cash', 'Online')
print('Updated:', updated)
# Check if a string contains something
print('Contains 2024?', '2024' in description) # True
print('Contains 2025?', '2025' in description) # False
Before cleaning: infosys limited
After strip(): infosys limited
After title(): Infosys Limited
Updated: Sales Receipts - Online - 2024
Contains 2024? True
Contains 2025? False
Section 8: Lists — Collections of Data
From single values to collections
So far, we've stored one value in each variable:
revenue = 2500000
But what if you have multiple invoices, multiple clients, or 12 months of data?
That's where Lists come in. A list stores multiple values in a specific order.
Think of a list like a column in Excel — it holds many values, one below the other.
Syntax: my_list = [value1, value2, value3, ...]
# Creating lists
monthly_revenue = [120000, 135000, 98000, 145000, 162000, 178000,
155000, 142000, 168000, 191000, 203000, 215000]
expense_categories = ['Salaries', 'Rent', 'Utilities', 'Marketing', 'Depreciation']
clients = ['NTC', 'Ncell', 'Fusemachines', 'InfoDevelopers', 'Deerwalk Services Pvt. Ltd.']
print('Monthly Revenue:', monthly_revenue)
print('Expense Categories:', expense_categories)
print('Clients:', clients)
print()
print('Number of months of data:', len(monthly_revenue)) # len() gives length
print('Number of clients:', len(clients))
Monthly Revenue: [120000, 135000, 98000, 145000, 162000, 178000, 155000, 142000, 168000, 191000, 203000, 215000]
Expense Categories: ['Salaries', 'Rent', 'Utilities', 'Marketing', 'Depreciation']
Clients: ['NTC', 'Ncell', 'Fusemachines', 'InfoDevelopers', 'Deerwalk Services Pvt. Ltd.']
Number of months of data: 12
Number of clients: 5
# Accessing items in a list — indexing
# IMPORTANT: Python counts from 0, not 1!
# Index: 0 1 2 3 4
clients = ['NTC', 'Ncell', 'Fusemachines', 'InfoDevelopers', 'Deerwalk Services Pvt. Ltd.']
print('First client:', clients[0]) # TCS
print('Second client:', clients[1]) # Ncell
print('Last client:', clients[-1]) # -1 always gives the last item!
print('Second last:', clients[-2])
# Slicing — getting a range of items [start:end] (end is NOT included)
print('First three clients:', clients[0:3]) # Ncell, NTC, Fusemachines
print('Last two clients:', clients[-2:])
First client: NTC
Second client: Ncell
Last client: Deerwalk Services Pvt. Ltd.
Second last: InfoDevelopers
First three clients: ['NTC', 'Ncell', 'Fusemachines']
Last two clients: ['InfoDevelopers', 'Deerwalk Services Pvt. Ltd.']
# Useful list operations for financial data
monthly_revenue = [120000, 135000, 98000, 145000, 162000, 178000,
155000, 142000, 168000, 191000, 203000, 215000]
print('--- Revenue Analysis ---')
print('Total Annual Revenue: NPR ', sum(monthly_revenue)) # sum() adds all values
print('Highest Month: NPR ', max(monthly_revenue)) # max() finds highest
print('Lowest Month: NPR ', min(monthly_revenue)) # min() finds lowest
print('Average Monthly: NPR ', sum(monthly_revenue) / len(monthly_revenue))
print()
# Adding items to a list
clients = ['NTC', 'Ncell', 'Fusemachines']
clients.append('Accenture') # Add to the end
print('Updated clients:', clients)
# Sorting
invoices = [45000, 12000, 78000, 34000, 91000, 23000]
invoices.sort() # Sort in ascending order
print('Sorted invoices:', invoices)
invoices.sort(reverse=True) # Sort in descending order
print('Descending order:', invoices)
--- Revenue Analysis ---
Total Annual Revenue: NPR 1912000
Highest Month: NPR 215000
Lowest Month: NPR 98000
Average Monthly: NPR 159333.33333333334
Updated clients: ['NTC', 'Ncell', 'Fusemachines', 'Accenture']
Sorted invoices: [12000, 23000, 34000, 45000, 78000, 91000]
Descending order: [91000, 78000, 45000, 34000, 23000, 12000]
Section 9: Dictionaries — Organized Data Records
From lists to labelled data
A List stores values by position (index 0, 1, 2...).
But sometimes you want to label your data — like a ledger entry where each piece of information has a name.
A Dictionary stores data as key-value pairs — just like a real dictionary where each word (key) has a meaning (value).
Think of it like a mini spreadsheet row:
Column name → Value
'name' → 'NTC'
'revenue' → 2200000
'sector' → 'IT'
Syntax: my_dict = {'key1': value1, 'key2': value2}
# A dictionary — like a client record
client = {
'name': 'Nepal Telecom (NTC)',
'pan': '123456789', # Nepal PAN — 9-digit numeric (IRD registration)
'sector': 'Information Technology',
'annual_revenue': 220000000000, # NPR 2.2 lakh crores
'employees': 614000,
'is_listed': True
}
# Accessing values using the key (like looking up a column name)
print('Client Name:', client['name'])
print('PAN:', client['pan'])
print('Sector:', client['sector'])
print('Listed?', client['is_listed'])
Client Name: Nepal Telecom (NTC)
PAN: 123456789
Sector: Information Technology
Listed? True
# Adding, updating, and removing from a dictionary
invoice = {
'invoice_no': 'INV-2025-001',
'client': 'ABC Pvt Ltd',
'date': '15-Apr-2025',
'amount': 250000,
'vat_rate': 18
}
# Add a new key-value pair
invoice['vat_amount'] = invoice['amount'] * invoice['vat_rate'] / 100
invoice['total'] = invoice['amount'] + invoice['vat_amount']
# Update an existing value
invoice['status'] = 'Paid'
# Print all key-value pairs
print('--- Invoice Details ---')
for key, value in invoice.items():
print(f'{key:15}: {value}')
--- Invoice Details ---
invoice_no : INV-2025-001
client : ABC Pvt Ltd
date : 15-Apr-2025
amount : 250000
vat_rate : 18
vat_amount : 45000.0
total : 295000.0
status : Paid
# List of dictionaries — like a table in Excel
# Each dictionary is one row, the keys are column names
transactions = [
{'date': '01-Apr-2025', 'description': 'Sales Revenue', 'debit': 0, 'credit': 500000},
{'date': '03-Apr-2025', 'description': 'Office Rent', 'debit': 45000, 'credit': 0},
{'date': '05-Apr-2025', 'description': 'Sales Revenue', 'debit': 0, 'credit': 320000},
{'date': '10-Apr-2025', 'description': 'Salaries Paid', 'debit': 180000, 'credit': 0},
{'date': '15-Apr-2025', 'description': 'Utility Bill', 'debit': 12000, 'credit': 0},
]
print('--- Transaction Ledger ---')
print(f'{"Date":<15} {"Description":<20} {"Debit":>12} {"Credit":>12}')
print('-' * 62)
for txn in transactions:
debit_str = f"NPR {txn['debit']:>10,}" if txn['debit'] > 0 else ''
credit_str = f"NPR {txn['credit']:>10,}" if txn['credit'] > 0 else ''
print(f"{txn['date']:<15} {txn['description']:<20} {debit_str:>12} {credit_str:>12}")
--- Transaction Ledger ---
Date Description Debit Credit
--------------------------------------------------------------
01-Apr-2025 Sales Revenue NPR 500,000
03-Apr-2025 Office Rent NPR 45,000
05-Apr-2025 Sales Revenue NPR 320,000
10-Apr-2025 Salaries Paid NPR 180,000
15-Apr-2025 Utility Bill NPR 12,000
Section 10: Loops — Automating Repetitive Work
Stop repeating yourself!
Imagine you need to calculate GST on 100 invoices.
Writing 100 separate print() statements is clearly not the answer.
Loops let you repeat an action multiple times automatically.
The for loop
Use for when you want to go through a collection (list, etc.) one item at a time.
for item in collection:
# do something with item
Think of it as: "For each invoice in my invoice list, calculate the GST"
# Simple for loop — going through a list
clients = ['NTC', 'Ncell', 'Fusemachines', 'InfoDevelopers', 'Deerwalk Services Pvt. Ltd.']
print('--- Client List ---')
for client in clients:
print('Client:', client)
--- Client List ---
Client: NTC
Client: Ncell
Client: Fusemachines
Client: InfoDevelopers
Client: Deerwalk Services Pvt. Ltd.
# Batch GST calculation on multiple invoices
invoice_amounts = [85000, 42000, 125000, 67500, 98000, 33000]
vat_rate = 13.0
total_gst_collected = 0 # We'll accumulate GST here
print(f"{'Invoice Amount':>17} | {'GST (13%)':>12} | {'Total Amount':>14}")
print('-' * 50)
for amount in invoice_amounts:
gst = amount * vat_rate / 100
total = amount + gst
total_gst_collected += gst # Same as: total_gst_collected = total_gst_collected + gst
print(f'NPR {amount:>15,} | NPR {gst:>11,.2f} | NPR {total:>12,.2f}')
print('-' * 50)
print(f'Total GST Liability: NPR {total_gst_collected:,.2f}')
Invoice Amount | GST (13%) | Total Amount
--------------------------------------------------
NPR 85,000 | NPR 11,050.00 | NPR 96,050.00
NPR 42,000 | NPR 5,460.00 | NPR 47,460.00
NPR 125,000 | NPR 16,250.00 | NPR 141,250.00
NPR 67,500 | NPR 8,775.00 | NPR 76,275.00
NPR 98,000 | NPR 12,740.00 | NPR 110,740.00
NPR 33,000 | NPR 4,290.00 | NPR 37,290.00
--------------------------------------------------
Total GST Liability: NPR 58,565.00
# range() — loop a specific number of times
# Useful when you don't have a list but know how many times to repeat
print('Quarterly Revenue Projections (10% growth each year):')
base_revenue = 1000000 # NPR 10 lakhs starting revenue
growth_rate = 0.10
for year in range(1, 6): # range(1, 6) gives: 1, 2, 3, 4, 5
projected = base_revenue * (1 + growth_rate) ** year
print(f'Year {year}: NPR {projected:>12,.2f}')
Quarterly Revenue Projections (10% growth each year):
Year 1: NPR 1,100,000.00
Year 2: NPR 1,210,000.00
Year 3: NPR 1,331,000.00
Year 4: NPR 1,464,100.00
Year 5: NPR 1,610,510.00
# while loop — keeps going as long as a condition is True
# Use when you don't know HOW MANY times to repeat
# How many years to double your investment at 8% per annum? (Rule of 72)
investment = 100000 # Starting amount
target = 200000 # Double the investment
rate = 0.08 # 8% annual return
year = 0
print('Investment Growth at 8% p.a.:')
while investment < target:
investment = investment * (1 + rate) # Grow by 8%
year += 1 # Count the year
print(f'Year {year}: NPR {investment:>12,.2f}')
print(f'\nYour investment doubled in {year} years!')
print(f'(Rule of 72 predicts: {round(72/8)} years)')
Investment Growth at 8% p.a.:
Year 1: NPR 108,000.00
Year 2: NPR 116,640.00
Year 3: NPR 125,971.20
Year 4: NPR 136,048.90
Year 5: NPR 146,932.81
Year 6: NPR 158,687.43
Year 7: NPR 171,382.43
Year 8: NPR 185,093.02
Year 9: NPR 199,900.46
Year 10: NPR 215,892.50
Your investment doubled in 10 years!
(Rule of 72 predicts: 9 years)
✏️ Mini Exercise 5
You have a list of 6 employees with their annual salaries:
salaries = [480000, 720000, 960000, 1200000, 1440000, 2400000]
Using a for loop, calculate and print for each employee:
1. Professional Tax (PT): NPR 200/month if salary ≤ NPR 10L, else NPR 2,500/year (Maharashtra slab — simplified)
2. Provident Fund (EPF @ 10% (employee) of salary (capped at salary of NPR 1,80,000)
3. Net take-home salary
Hint: PF is calculated on salary capped at NPR 1,80,000
salaries = [480000, 720000, 960000, 1200000, 1440000, 2400000]
# Write your loop here
Section 11: Functions — Write Once, Use Many Times
What is a function?
Think about the VLOOKUP formula in Excel. You write the formula once, give it inputs, and it returns an output. You don't need to re-write the logic each time.
A function in Python works exactly the same way: - You define it once (write the logic) - You call it many times with different inputs - It returns the result
def function_name(input1, input2):
# Do something with the inputs
result = input1 + input2
return result # Send the answer back
This eliminates repetition and makes your code reliable — fix a bug in one place, it's fixed everywhere.
# Defining a simple function
def calculate_gst(base_amount, rate=18):
"""
Calculates GST on a given amount.
base_amount: The pre-GST invoice amount
rate: GST rate in % (default is 13%)
Returns: (vat_amount, total_amount)
"""
vat_amount = base_amount * rate / 100
total_amount = base_amount + vat_amount
return vat_amount, total_amount
# Calling the function — use it like Excel's VLOOKUP
gst, total = calculate_gst(85000) # Uses default 13%
print(f'GST: NPR {gst:,} | Total: NPR {total:,}')
gst, total = calculate_gst(50000, 5) # 5% GST
print(f'GST: NPR {gst:,} | Total: NPR {total:,}')
gst, total = calculate_gst(200000, 28) # 28% GST
print(f'GST: NPR {gst:,} | Total: NPR {total:,}')
GST: NPR 15,300.0 | Total: NPR 100,300.0
GST: NPR 2,500.0 | Total: NPR 52,500.0
GST: NPR 56,000.0 | Total: NPR 256,000.0
# Nepal Income Tax Calculator (FY 2081-82 BS)
# IRD-compliant individual income tax rates
def calculate_nepal_income_tax(taxable_income, status='individual'):
"""
Calculate Nepal income tax per IRD slabs (FY 2081-82 BS).
status: 'individual' (single) or 'couple' (additional NPR 1L exemption)
"""
extra_exemption = 100000 if status == 'couple' else 0
adjusted = max(taxable_income - extra_exemption, 0)
# Nepal progressive slab
if adjusted <= 500000:
tax = adjusted * 0.01
elif adjusted <= 700000:
tax = 5000 + (adjusted - 500000) * 0.10
elif adjusted <= 2000000:
tax = 5000 + 20000 + (adjusted - 700000) * 0.20
else:
tax = 5000 + 20000 + 260000 + (adjusted - 2000000) * 0.30
# Karmachari Sanchaya Kosh (EPF) is separate — not income tax
return round(tax, 2)
# Test the function
income = 1200000
tax_individual = calculate_nepal_income_tax(income, 'individual')
tax_couple = calculate_nepal_income_tax(income, 'couple')
print(f'Taxable Income: NPR {income:,}')
print()
print(f"{'Particulars':<28} {'Individual':>12} {'Couple':>12}")
print('-' * 55)
print(f"{'Income Tax':<28} NPR {tax_individual:>9,} NPR {tax_couple:>9,}")
print(f"{'Effective Rate':<28} {tax_individual/income*100:>11.2f}% {tax_couple/income*100:>10.2f}%")
print(f"{'Net Take-home':<28} NPR {income-tax_individual:>9,} NPR {income-tax_couple:>9,}")
print()
print(f'Couple gets NPR {tax_individual - tax_couple:,} tax saving (NPR 1L extra exemption at 20% bracket)')
print()
print('Source: Inland Revenue Department (IRD), Nepal — FY 2081-82 BS')
Taxable Income: NPR 1,200,000
Particulars Individual Couple
-------------------------------------------------------
Income Tax NPR 125,000.0 NPR 105,000.0
Effective Rate 10.42% 8.75%
Net Take-home NPR 1,075,000.0 NPR 1,095,000.0
Couple gets NPR 20,000.0 tax saving (NPR 1L extra exemption at 20% bracket)
Source: Inland Revenue Department (IRD), Nepal — FY 2081-82 BS
# Financial Ratios Calculator — all ratios in one place
def financial_ratios(revenue, gross_profit, net_profit, current_assets,
current_liabilities, total_debt, total_equity):
"""Calculate key financial ratios and return a summary."""
gross_margin = (gross_profit / revenue) * 100
net_margin = (net_profit / revenue) * 100
current_ratio = current_assets / current_liabilities
de_ratio = total_debt / total_equity
roe = (net_profit / total_equity) * 100
print('--- Financial Ratios Analysis ---')
print(f'Gross Profit Margin : {gross_margin:.2f}%')
print(f'Net Profit Margin : {net_margin:.2f}%')
print(f'Current Ratio : {current_ratio:.2f}x')
print(f'Debt-to-Equity : {de_ratio:.2f}x')
print(f'Return on Equity : {roe:.2f}%')
# Quick health check
print()
print('Quick Assessment:')
print(' Liquidity:', 'Good ✓' if current_ratio >= 1.5 else 'Monitor ⚠')
print(' Leverage :', 'Safe ✓' if de_ratio <= 2.0 else 'High Risk ✗')
print(' Profit :', 'Good ✓' if net_margin >= 10 else 'Low ⚠')
# Call the function with sample data
financial_ratios(
revenue = 5000000,
gross_profit = 1800000,
net_profit = 620000,
current_assets = 2200000,
current_liabilities= 1100000,
total_debt = 1800000,
total_equity = 2500000
)
--- Financial Ratios Analysis ---
Gross Profit Margin : 36.00%
Net Profit Margin : 12.40%
Current Ratio : 2.00x
Debt-to-Equity : 0.72x
Return on Equity : 24.80%
Quick Assessment:
Liquidity: Good ✓
Leverage : Safe ✓
Profit : Good ✓
✏️ Mini Exercise 6
Write a function called depreciation_schedule that:
- Takes: asset_name, cost, salvage_value, useful_life (in years) as inputs
- Calculates annual depreciation using the Straight Line Method (SLM)
- Prints a year-wise schedule showing: Year, Depreciation, Accumulated Depreciation, Book Value
Test with: Computer equipment, Cost = NPR 1,50,000, Salvage = NPR 10,000, Useful Life = 5 years
# Write your depreciation_schedule function here
# Call your function
# depreciation_schedule('Computer Equipment', 150000, 10000, 5)
Section 12: Putting It All Together
Let's combine everything we've learned to build a mini financial report generator.
# Mini Financial Report Generator
# Uses: variables, data types, lists, dicts, loops, functions, f-strings, conditionals
def generate_pl_report(company_info, pl_data):
"""Generates a simple Profit & Loss statement."""
separator = '=' * 55
thin_line = '-' * 55
# Header
print(separator)
print(f" {company_info['name']}")
print(f" Statement of Profit & Loss")
print(f" For the year ended {company_info['year_end']}")
print(f" (All amounts in NPR )")
print(separator)
# Revenue section
total_revenue = sum(pl_data['revenue'].values())
print(f"\n {'I. REVENUE':}")
for item, amount in pl_data['revenue'].items():
print(f" {item:<35} {amount:>12,}")
print(thin_line)
print(f" {'Total Revenue':<35} {total_revenue:>12,}")
# Expenses section
total_expenses = sum(pl_data['expenses'].values())
print(f"\n {'II. EXPENEPSES'}")
for item, amount in pl_data['expenses'].items():
print(f" {item:<35} {amount:>12,}")
print(thin_line)
print(f" {'Total Expenses':<35} {total_expenses:>12,}")
# Profit calculations
pbt = total_revenue - total_expenses
tax = pbt * company_info['tax_rate'] if pbt > 0 else 0
pat = pbt - tax
print(f"\n{separator}")
print(f" {'Profit Before Tax':<38} {pbt:>12,}")
print(f" {'Tax @ {:.0f}%'.format(company_info['tax_rate']*100):<38} {round(tax):>12,}")
print(separator)
print(f" {'PROFIT AFTER TAX':<38} {round(pat):>12,}")
print(separator)
# Ratios
print(f"\n Key Ratios:")
print(f" Net Profit Margin : {pat/total_revenue*100:.2f}%")
print(f" Tax Efficiency : {pat/pbt*100:.2f}%" if pbt > 0 else '')
status = 'Profitable ✓' if pat > 0 else 'Loss Making ✗'
print(f" Financial Status : {status}")
# ---- Data ----
company_info = {
'name': 'Sunrise Manufacturing Pvt. Ltd.',
'year_end': '16th July 2025 (Ashadh 2082 BS)',
'tax_rate': 0.25
}
pl_data = {
'revenue': {
'Revenue from Operations': 8500000,
'Other Income': 125000,
},
'expenses': {
'Cost of Materials': 4200000,
'Employee Benefits': 1250000,
'Finance Costs': 185000,
'Depreciation': 320000,
'Other Expenses': 480000,
}
}
generate_pl_report(company_info, pl_data)
=======================================================
Sunrise Manufacturing Pvt. Ltd.
Statement of Profit & Loss
For the year ended 16th July 2025 (Ashadh 2082 BS)
(All amounts in NPR )
=======================================================
I. REVENUE
Revenue from Operations 8,500,000
Other Income 125,000
-------------------------------------------------------
Total Revenue 8,625,000
II. EXPENEPSES
Cost of Materials 4,200,000
Employee Benefits 1,250,000
Finance Costs 185,000
Depreciation 320,000
Other Expenses 480,000
-------------------------------------------------------
Total Expenses 6,435,000
=======================================================
Profit Before Tax 2,190,000
Tax @ 25% 547,500
=======================================================
PROFIT AFTER TAX 1,642,500
=======================================================
Key Ratios:
Net Profit Margin : 19.04%
Tax Efficiency : 75.00%
Financial Status : Profitable ✓
Section 13: Practice Exercises
Now it's your turn! These exercises will test everything you've learned.
🏋️ Exercise 1 — Working Capital Analysis
A company has the following current assets and liabilities:
Current Assets: Cash NPR 85,000 | Debtors NPR 3,20,000 | Inventory NPR 4,75,000 | Prepaid Expenses NPR 25,000
Current Liabilities: Creditors NPR 2,80,000 | Short-term Loans NPR 1,50,000 | Accrued Expenses NPR 45,000
Write a program using lists or dictionaries to: 1. Calculate Total Current Assets 2. Calculate Total Current Liabilities 3. Calculate Working Capital (CA - CL) 4. Calculate Current Ratio (CA / CL) 5. Calculate Quick Ratio ((CA - Inventory) / CL) 6. Print a formatted summary with assessment (ratios below 1 = warning)
# Exercise 1 — Working Capital Analysis
# Tip: Use a dictionary for assets and liabilities, then loop through them
🏋️ Exercise 2 — Ageing Analysis of Debtors
You have the following list of outstanding invoices with their ages (days overdue):
invoices = [
{'client': 'Alpha Ltd', 'amount': 125000, 'days': 25},
{'client': 'Beta Corp', 'amount': 85000, 'days': 65},
{'client': 'Gamma Inc', 'amount': 210000, 'days': 45},
{'client': 'Delta Pvt', 'amount': 55000, 'days': 95},
{'client': 'Epsilon Ltd', 'amount': 175000, 'days': 15},
{'client': 'Zeta Co', 'amount': 92000, 'days': 130},
]
Using a for loop, classify each invoice into:
- 0–30 days → "Current"
- 31–60 days → "1–2 Months"
- 61–90 days → "2–3 Months"
- 90+ days → "Overdue >3 Months" (flag as high risk)
Print the ageing report and the total outstanding amount in each bucket.
# Exercise 2 — Debtors Ageing Analysis
invoices = [
{'client': 'Alpha Ltd', 'amount': 125000, 'days': 25},
{'client': 'Beta Corp', 'amount': 85000, 'days': 65},
{'client': 'Gamma Inc', 'amount': 210000, 'days': 45},
{'client': 'Delta Pvt', 'amount': 55000, 'days': 95},
{'client': 'Epsilon Ltd', 'amount': 175000, 'days': 15},
{'client': 'Zeta Co', 'amount': 92000, 'days': 130},
]
# Write your ageing analysis here
🏋️ Exercise 3 — Housing Allowance Exemption Calculator
Professional/Education Deduction (under old regime) is the minimum of three amounts: 1. Actual Housing Allowance received from employer 2. 50% of Basic Salary (metro city) or 40% (outside Kathmandu Valley) 3. Actual Rent Paid minus 10% of Basic Salary
Write a function called calculate_hra_exemption that takes:
- basic_salary (annual)
- hra_received (annual)
- rent_paid (annual)
- is_metro (True/False)
And returns the Professional/Education Deduction amount.
Test with: - Basic Salary: NPR 6,00,000 | Housing Allowance Received: NPR 2,40,000 | Rent Paid: NPR 2,16,000 | Metro: Yes - Basic Salary: NPR 4,80,000 | Housing Allowance Received: NPR 1,44,000 | Rent Paid: NPR 1,80,000 | Metro: No
# Exercise 3 — Housing Allowance Exemption Calculator
# Tip: Use the min() function to find the minimum of three values
💡 Solutions
Try the exercises on your own first! Run the cells below only after you've attempted them.
# SOLUTION — Exercise 1: Working Capital Analysis
current_assets = {
'Cash': 85000,
'Debtors': 320000,
'Inventory': 475000,
'Prepaid Expenses': 25000,
}
current_liabilities = {
'Creditors': 280000,
'Short-term Loans': 150000,
'Accrued Expenses': 45000,
}
total_ca = sum(current_assets.values())
total_cl = sum(current_liabilities.values())
working_capital = total_ca - total_cl
current_ratio = total_ca / total_cl
quick_ratio = (total_ca - current_assets['Inventory']) / total_cl
print('=== Working Capital Analysis ===')
print('\nCurrent Assets:')
for item, amt in current_assets.items():
print(f' {item:<25} NPR {amt:>10,}')
print(f' {"Total Current Assets":<25} NPR {total_ca:>10,}')
print('\nCurrent Liabilities:')
for item, amt in current_liabilities.items():
print(f' {item:<25} NPR {amt:>10,}')
print(f' {"Total Current Liab.":<25} NPR {total_cl:>10,}')
print(f'\nWorking Capital: NPR {working_capital:,}')
print(f'Current Ratio: {current_ratio:.2f}x', '✓' if current_ratio >= 1.5 else '⚠ Below ideal')
print(f'Quick Ratio: {quick_ratio:.2f}x', '✓' if quick_ratio >= 1.0 else '⚠ Below ideal')
=== Working Capital Analysis ===
Current Assets:
Cash NPR 85,000
Debtors NPR 320,000
Inventory NPR 475,000
Prepaid Expenses NPR 25,000
Total Current Assets NPR 905,000
Current Liabilities:
Creditors NPR 280,000
Short-term Loans NPR 150,000
Accrued Expenses NPR 45,000
Total Current Liab. NPR 475,000
Working Capital: NPR 430,000
Current Ratio: 1.91x ✓
Quick Ratio: 0.91x ⚠ Below ideal
# SOLUTION — Exercise 2: Debtors Ageing Analysis
invoices = [
{'client': 'Alpha Ltd', 'amount': 125000, 'days': 25},
{'client': 'Beta Corp', 'amount': 85000, 'days': 65},
{'client': 'Gamma Inc', 'amount': 210000, 'days': 45},
{'client': 'Delta Pvt', 'amount': 55000, 'days': 95},
{'client': 'Epsilon Ltd', 'amount': 175000, 'days': 15},
{'client': 'Zeta Co', 'amount': 92000, 'days': 130},
]
buckets = {
'Current (0-30 days)': 0,
'1-2 Months (31-60 days)': 0,
'2-3 Months (61-90 days)': 0,
'Overdue >3 Months (91+ days)': 0
}
print(f"{'Client':<15} {'Amount':>12} {'Days':>6} {'Category':<30}")
print('-' * 68)
for inv in invoices:
if inv['days'] <= 30:
category = 'Current (0-30 days)'
flag = ''
elif inv['days'] <= 60:
category = '1-2 Months (31-60 days)'
flag = ''
elif inv['days'] <= 90:
category = '2-3 Months (61-90 days)'
flag = '⚠'
else:
category = 'Overdue >3 Months (91+ days)'
flag = '🔴 HIGH RISK'
buckets[category] += inv['amount']
print(f"{inv['client']:<15} NPR {inv['amount']:>11,} {inv['days']:>5}d {category} {flag}")
print('\n=== Ageing Summary ===')
total = 0
for category, amount in buckets.items():
print(f'{category:<35} NPR {amount:>10,}')
total += amount
print(f'{"TOTAL OUTSTANDING":<35} NPR {total:>10,}')
Client Amount Days Category
--------------------------------------------------------------------
Alpha Ltd NPR 125,000 25d Current (0-30 days)
Beta Corp NPR 85,000 65d 2-3 Months (61-90 days) ⚠
Gamma Inc NPR 210,000 45d 1-2 Months (31-60 days)
Delta Pvt NPR 55,000 95d Overdue >3 Months (91+ days) 🔴 HIGH RISK
Epsilon Ltd NPR 175,000 15d Current (0-30 days)
Zeta Co NPR 92,000 130d Overdue >3 Months (91+ days) 🔴 HIGH RISK
=== Ageing Summary ===
Current (0-30 days) NPR 300,000
1-2 Months (31-60 days) NPR 210,000
2-3 Months (61-90 days) NPR 85,000
Overdue >3 Months (91+ days) NPR 147,000
TOTAL OUTSTANDING NPR 742,000
# SOLUTION — Exercise 3: Housing Allowance Exemption Calculator
def calculate_hra_exemption(basic_salary, hra_received, rent_paid, is_metro):
"""Calculate Professional/Education Deduction under Income Tax (Nepal Income Tax)."""
# Method 1: Actual Housing Allowance received
limit1 = hra_received
# Method 2: 50% of Basic (metro) or 40% (outside Kathmandu Valley)
limit2 = basic_salary * 0.50 if is_metro else basic_salary * 0.40
# Method 3: Rent paid minus 10% of Basic
limit3 = max(0, rent_paid - basic_salary * 0.10) # Cannot be negative
# Exemption = minimum of all three
exemption = min(limit1, limit2, limit3)
city_type = 'Metro' if is_metro else 'Non-Metro'
print(f'--- Housing Allowance Exemption Calculation ({city_type}) ---')
print(f'Basic Salary: NPR {basic_salary:>10,}')
print(f'Housing Allowance Received: NPR {hra_received:>10,}')
print(f'Rent Paid: NPR {rent_paid:>10,}')
print()
print(f'Limit 1 (Actual Housing Allowance): NPR {limit1:>10,}')
print(f'Limit 2 (% of Basic): NPR {limit2:>10,}')
print(f'Limit 3 (Rent - 10%B): NPR {limit3:>10,}')
print(f'Housing Allowance Exemption (min): NPR {exemption:>10,}')
print(f'Housing Allowance Taxable: NPR {hra_received - exemption:>10,}')
print()
return exemption
# Test Case 1
calculate_hra_exemption(600000, 240000, 216000, True)
# Test Case 2
calculate_hra_exemption(480000, 144000, 180000, False)
--- Housing Allowance Exemption Calculation (Metro) ---
Basic Salary: NPR 600,000
Housing Allowance Received: NPR 240,000
Rent Paid: NPR 216,000
Limit 1 (Actual Housing Allowance): NPR 240,000
Limit 2 (% of Basic): NPR 300,000.0
Limit 3 (Rent - 10%B): NPR 156,000.0
Housing Allowance Exemption (min): NPR 156,000.0
Housing Allowance Taxable: NPR 84,000.0
--- Housing Allowance Exemption Calculation (Non-Metro) ---
Basic Salary: NPR 480,000
Housing Allowance Received: NPR 144,000
Rent Paid: NPR 180,000
Limit 1 (Actual Housing Allowance): NPR 144,000
Limit 2 (% of Basic): NPR 192,000.0
Limit 3 (Rent - 10%B): NPR 132,000.0
Housing Allowance Exemption (min): NPR 132,000.0
Housing Allowance Taxable: NPR 12,000.0
132000.0
🎉 Congratulations!
You have completed the Python for CA Professionals introductory notebook.
What you've learned today
| Concept | What you can do now |
|---|---|
print() & comments |
Display output, document your code |
| Variables | Store and reuse financial data |
| Data Types | Work with numbers, text, and True/False |
| Arithmetic | Build calculators (GST, EMI, compound interest) |
if/elif/else |
Automate decisions (tax slabs, risk classification) |
| Strings & f-strings | Generate formatted financial reports |
| Lists | Manage collections of invoices, clients, transactions |
| Dictionaries | Create structured records like ledger entries |
| Loops | Process hundreds of transactions automatically |
| Functions | Build reusable tools (tax calculator, ratios) |
What's Next?
You're ready for the next module:
- pandas — Work with Excel files, large datasets, and financial data
- matplotlib / seaborn — Create charts and visualisations
- openpyxl — Read and write Excel files with Python
- NumPy — Advanced financial mathematics
- Automation — Schedule and automate reports
Remember: Every expert was once a beginner.
The best way to learn Python is to experiment — change the numbers, break things, fix them.
Your CA training has already given you the analytical mindset. Python is just the tool.
Python for CA Professionals — Module 1: Python Basics