Project: Custom Indian Business Utility Package (indialib)
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:
- 1Indian Currency Formatter (
currency.py): Converts numbers to traditional South Asian comma-separated formats (Thousands, Lakhs, Crores:₹12,34,567.89). - 2Identity & Tax Validator (
validators.py): Validates 10-character Indian PAN cards, 12-digit Aadhaar numbers, and 15-character GSTIN tax identifiers. - 3Data Masking & Security (
security.py): Masks sensitive customer credentials for compliance (XXXX-XXXX-5678). - 4Package 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:
+-------------------------------------------------------------------------+ | 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:
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
Expected Output
Best Practices & Comparison: Do's and Don'ts
| Practice | Bad Implementation | Gold-Standard Implementation |
|---|---|---|
| Number Formatting | Using Western thousands commas for Indian rupees | Custom grouping for thousands, lakhs, and crores |
| Security Masking | Storing plain raw Aadhaar numbers | Store masked Aadhaar XXXX-XXXX-1234 for UIDAI compliance |
| Random IDs | Using random.randint() for financial references | Use secrets.token_hex() for tamper-proof reference tokens |
| Package Exports | Leaving __all__ empty in __init__.py | Explicitly define __all__ to govern public API surface |
| Input Sanitization | Assuming user won't pass spaces in PAN or Aadhaar | Clean 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__.pyaggregates 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:
- 1Create 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}$.
- 1Create a function
normalize_mobile(mobile_str):
- Strips spaces, hyphens, and leading
+91or0. - Returns a clean 10-digit mobile number if valid, or
Noneif invalid.
Starter Code
Complete Solution
Visual Architecture & Process Flow
How data and code flow step-by-step
Expected Output
Working with Context Managers (with statement)
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Popular Python Modules Overview | Working with Context Managers (with statement) |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.