Project: Custom Indian Business Utility Package (indialib)0%

Project: Custom Indian Business Utility Package (indialib)

Intermediate16 min readUpdated: 2026-09-12
Study Materials

Project: Custom Indian Business Utility Package (indialib)

Welcome to the Chapter 3 Capstone Project! Over the preceding lessons, you mastered module creation, search hierarchies, __name__ == '__main__', package structures, and standard library tools.

Now, you will synthesize all these disciplines by engineering a reusable, production-ready Python package named indialib. This package solves everyday computational challenges for Indian digital enterprises:

  1. 1
    Indian Currency Formatter (currency.py): Converts numbers to traditional South Asian comma-separated formats (Thousands, Lakhs, Crores: ₹12,34,567.89).
  2. 2
    Identity & Tax Validator (validators.py): Validates 10-character Indian PAN cards, 12-digit Aadhaar numbers, and 15-character GSTIN tax identifiers.
  3. 3
    Data Masking & Security (security.py): Masks sensitive customer credentials for compliance (XXXX-XXXX-5678).
  4. 4
    Package Facade (__init__.py): Curates clean public exports and governs access via __all__.

Real-World Analogy: Building a Reusable Zoho/Tally Business SDK

Imagine building a shared internal toolkit for a financial technology startup in Bengaluru:

Visual Architecture Blueprint
+-------------------------------------------------------------------------+
|                    INDIALIB BUSINESS SDK ARCHITECTURE                   |
+-------------------------------------------------------------------------+
|                                                                         |
|   Consumer Application (billing_service.py)                             |
|          │                                                              |
|          ▼                                                              |
|   Package Facade: indialib/__init__.py                                  |
|   ├── Exposes: format_inr, validate_pan, mask_aadhaar                    |
|   └── Enforces __all__ boundary & version stamping                      |
|          │                                                              |
|          ├──────────────────────┼──────────────────────┐                |
|          ▼                      ▼                      ▼                |
|   [ currency.py ]        [ validators.py ]      [ security.py ]         |
|   Lakhs/Crores Engine    PAN & GSTIN Regex      Aadhaar Data Masker     |
|                                                                         |
+-------------------------------------------------------------------------+

Any engineering team within your company can install or import indialib and immediately format financial ledgers or sanitize customer KYC inputs with zero code duplication.


Indian Numbering System Formatting Rule

Unlike the Western numbering system (groups of 3 digits: 1,000,000), the Indian numbering system groups the last 3 digits together, and every subsequent group by 2 digits:

Output
Number: 1 2 3 4 5 6 7 8
Western: 12,345,678 (12 Million, 345 Thousand, 678)
Indian: 1,23,45,678 (1 Crore, 23 Lakh, 45 Thousand, 678)

Complete Production-Grade Implementation

Here is the modular, fully runnable codebase for the indialib package:

Visual Architecture & Process Flow

How data and code flow step-by-step

Flowchart
Step 1
def format_inr
amount: float, symbol: str = "₹"
Step 2
str:

Expected Output

Output
=== Running indialib Business SDK Verification (v1.2.0) ===
 
--- Indian Currency Formatting (Lakhs & Crores) ---
Raw: 450.00 ➔ Formatted: ₹450.00
Raw: 1,500.00 ➔ Formatted: ₹1,500.00
Raw: 95,000.00 ➔ Formatted: ₹95,000.00
Raw: 1,234,567.89 ➔ Formatted: ₹12,34,567.89
Raw: 50,000,000.00 ➔ Formatted: ₹5,00,00,000.00
 
--- Identity & Tax Format Validation ---
PAN 'ABCDE1234F ': VALID ✅
PAN 'abcde1234f ': VALID ✅
PAN '12345ABCDE ': INVALID ❌
PAN 'TOOLONG12345F ': INVALID ❌
GST '27AAPFU0939F1ZV ': VALID ✅
GST '07AAAAA0000A1Z5 ': VALID ✅
GST 'INVALID_GST_SAMPLE': INVALID ❌
 
--- Compliance Aadhaar Data Masking ---
Raw Aadhaar : 9876 5432 1098
Masked Output : XXXX-XXXX-1098
Audit Ref ID : KYC-3B8A9F1C

Best Practices & Comparison: Do's and Don'ts

PracticeBad ImplementationGold-Standard Implementation
Number FormattingUsing Western thousands commas for Indian rupeesCustom grouping for thousands, lakhs, and crores
Security MaskingStoring plain raw Aadhaar numbersStore masked Aadhaar XXXX-XXXX-1234 for UIDAI compliance
Random IDsUsing random.randint() for financial referencesUse secrets.token_hex() for tamper-proof reference tokens
Package ExportsLeaving __all__ empty in __init__.pyExplicitly define __all__ to govern public API surface
Input SanitizationAssuming user won't pass spaces in PAN or AadhaarClean whitespace and normalize case with .strip().upper()

Quick Revision Summary Cheat Sheet

  • Lakhs & Crores Rule: Rightmost 3 digits group first, then all subsequent numbers group in pairs of 2.
  • PAN Format: ^[A-Z]{5}[0-9]{4}[A-Z]{1}$ (exactly 10 uppercase characters).
  • Aadhaar Masking: Keep only the last 4 digits visible for regulatory compliance.
  • Package Architecture: Submodules handle distinct logic (currency.py, validators.py); __init__.py aggregates them into an intuitive facade.
  • Version Tracking: Always define __version__ = "X.Y.Z" at the package root for dependency tracking.

Multiple Choice Questions

1. In the Indian numbering system, how is the number 1234567.89 correctly formatted?

A. ₹1,234,567.89 B. ₹12,34,567.89 C. ₹123,456,7.89 D. ₹1.234.567,89 Answer: B Explanation: Under the Indian numbering system, the last three digits are grouped together (567), and all preceding digits are grouped in pairs of two (12 and 34), producing ₹12,34,567.89 (12 Lakhs, 34 Thousand, 567).


2. What is the standard structure of a valid 10-character Indian PAN number?

A. 4 letters, 5 numbers, 1 letter B. 5 uppercase letters, 4 digits, 1 uppercase letter C. 10 numeric digits D. 3 letters, 6 numbers, 1 letter Answer: B Explanation: An Indian PAN card consists of 5 alphabetic characters, followed by 4 numeric characters, ending with 1 alphabetic character (e.g. ABCDE1234F).


3. Why is data masking (e.g. XXXX-XXXX-1098) applied to Aadhaar numbers in software systems?

A. To make the database file size smaller B. To comply with Indian data protection laws and UIDAI regulations that prohibit storing or displaying unmasked Aadhaar numbers C. Because Python cannot print 12-digit integers D. To convert Aadhaar numbers into cryptocurrency Answer: B Explanation: Indian privacy regulations mandate that public-facing and non-banking storage systems must mask the first 8 digits of Aadhaar numbers to prevent identity theft.


4. What is the role of secrets.token_hex(4).upper() in generating transaction references?

A. It calculates the square root of the transaction amount B. It generates a cryptographically random, unpredictable 8-character hexadecimal string suitable for transaction audit trails C. It sorts the database D. It connects to the bank's WiFi network Answer: B Explanation: secrets.token_hex(4) produces 4 random bytes represented as an 8-character hexadecimal string using the OS's secure random number generator, making it unpredictable and unique.


5. Why should a package's __init__.py explicitly define an __all__ list?

A. To prevent Python from compiling bytecode B. To define the exact public interface of the package and protect internal helper functions from being exposed during wildcard imports C. Because Python refuses to run without __all__ D. To make the package compatible only with Windows Answer: B Explanation: __all__ establishes an explicit boundary between public APIs and private internal implementation details, preventing accidental exposure when users run from indialib import *.


Practice Challenge

Scenario: Indian Bank IFSC Code Validator & Normalizer

Add an IFSC (Indian Financial System Code) validator to the indialib package:

  1. 1
    Create a function validate_ifsc(ifsc_code):
  • Must consist of exactly 11 characters.
  • The first 4 characters must be uppercase letters (Bank Code).
  • The 5th character must be strictly the number 0 (reserved for future use).
  • The last 6 characters can be letters or numbers (Branch Code).
  • Standard regex: ^[A-Z]{4}0[A-Z0-9]{6}$.
  1. 1
    Create a function normalize_mobile(mobile_str):
  • Strips spaces, hyphens, and leading +91 or 0.
  • Returns a clean 10-digit mobile number if valid, or None if invalid.

Starter Code

Python
import re
 
def validate_ifsc(ifsc_code):
pass
 
def normalize_mobile(mobile_str):
pass

Complete Solution

Visual Architecture & Process Flow

How data and code flow step-by-step

Flowchart
Step 1
def validate_ifsc
ifsc_code: str
Step 2
bool:

Expected Output

Output
=== IFSC Code Validation ===
IFSC 'SBIN0001010 ': VALID ✅
IFSC 'HDFC0000452 ': VALID ✅
IFSC 'PUNB0123456 ': VALID ✅
IFSC 'INVALID123 ': INVALID ❌
IFSC 'SBIN1001010 ': INVALID ❌
 
=== Indian Mobile Normalization ===
Raw: +91 98765-43210 ➔ Normalized: 9876543210
Raw: 09811223344 ➔ Normalized: 9811223344
Raw: 9444556677 ➔ Normalized: 9444556677
Raw: 1234567890 ➔ Normalized: [INVALID]
Raw: +91 8877665544 ➔ Normalized: 8877665544
Next Lesson

Working with Context Managers (with statement)

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext