A Python-based rule evaluation system for determining the validity of fund load attempts under velocity and regulatory constraints. When a batch of transactions is received, each attempting to load funds into a customer’s account, the system must evaluate whether each one meets the required constraints. These constraints determine which transactions are permitted to proceed. This program replicates that decision-making process: assigning an acceptance status to each load attempt, and producing an output file that guides which transactions should be executed. This program processes fund load attempts and determines whether each should be accepted or declined based on the following business rules:
- Daily Limit: A customer may load a maximum of $5000 per day
- Weekly Limit: A customer may load a maximum of $20000 per week
- Daily Load Count: A customer may perform at most 3 load attempts per day
- Prime ID: If a customer's ID is a prime number, they may:
- Perform only 1 load attempt per day
- Load a maximum of $9999 per day
- Monday Penalty: Loads performed on a Monday are counted at double their value for all limit evaluations (e.g.
$4000counts as$8000toward limits)
- The input is parsed by
services.parserline-by-line frominput.txt, and each line (considered a load attempt) is converted into aLoadAttemptobject (defined inmodels.load_attempt) with standardized fields (amount, timestamp, etc.). services.evaluatorthen processes the list ofLoadAttemptobjects in chronological order (by the"time"field in input) to ensure logical evaluation (i.e. constraint application) order, regardless of theLoadAttemptline order in the input file.- Each load attempt is evaluated (in
services.evaluator) against the constraints defined under Velocity Limits and Special Sanctions. - Accepted (
"accepted":true) load attempts are tracked using aCustomerFundobject (defined inmodels.customer_fund), which maintains per-day and per-week histories for each customer. - After constraint evaluation (
services.evaluator), eachLoadAttemptis updated with anaccepted: true/falseflag to reflect the decision. services.writerserializes the updatedLoadAttemptobjects tooutput.txt(in the same directory asmain.py), one JSON object per line (JSON Lines format), matching the required output schema.
The program is fully modular, with separate folders for models, services, utilities, and tests. All core logic is covered by targeted unit tests and can be run manually for verification.
- Week starts on Monday (ISO 8601)
- All currency values are in USD
- All
"id"fields in the input file are unique "id"in the input refers to the load attempt IDidin the Extra Credit - Special Sanctions of the restrictions refers only tocustomer_id"customer_id"in the input file is used to apply sanctions and velocity limits- For Prime ID sanctions,
customer_idis treated as an integer - Each fund load is either fully accepted (
"accepted":true) or fully declined ("accepted":false). Partial acceptance is not allowed - Load amounts are formatted as strings and may include currency symbols or prefixes (e.g.,
"$"or"USD"), but do not contain commas
Make sure you are using Python 3.9 or later.
- Install dependencies:
pip install python-dateutil- Place your
input.txtin the same directory asmain.py. - Then run the program:
python main.py- The program will generate
output.txt(will be created in the same directory asmain.py) with results in JSON Lines format.
The program outputs one JSON object per line in output.txt:
{"id":"15337","customer_id":"999","accepted":false}Each object includes:
"id": the load attempt ID (string)"customer_id": the ID of the customer attempting the load (string)"accepted": whether the attempt passed all constraints (true) or not (false)
Unit tests are included for all key components. Each test file can be run independently using python.
To run a specific test file:
python tests/test_<feature>.pyWhere <feature> is one of:
time_utilsprime_utilsparserevaluator
| File | Description |
|---|---|
main.py |
Entrypoint script that runs the full pipeline with process logs |
config.py |
Contains global configuration values (limits) |
requirements.txt |
Python dependency list |
input.txt |
Input data file (use file to generate output.txt) |
output.txt |
Output results file (generated by running main.py) |
fund-load-restriction-check/
├── main.py # Entrypoint script
├── config.py # Velocity/sanction limits
├── requirements.txt # Dependencies
├── input.txt # Sample input data
├── README.md # Explains solution and any assumptions
|
├── models/ # Data class module
│ ├── load_attempt.py # LoadAttempt dataclass and helpers
│ ├── customer_fund.py # Tracks accepted attempts per customer
│ └── __init__.py
│
├── services/ # Business & Processing logic module
│ ├── parser.py # Parses input file into LoadAttempt objects
│ ├── evaluator.py # Applies business rules and constraints
│ ├── writer.py # Serializes result to output file
│ └── __init__.py
│
├── utils/ # Helper module
│ ├── time_utils.py # Monday/week key/date logic
│ ├── prime_utils.py # Prime number checking
│ └── __init__.py
|
├── tests/ # Unit tests (run manually)
│ ├── test_time_utils.py
│ ├── test_prime_utils.py
│ ├── test_parser.py
│ ├── test_evaluator.py
│ └── __init__.py- This submission does not include generated
__pycache__folders - The output is written in JSON Lines format for scalability and clarity
- All constraints (daily limits, weekly limits, prime restrictions, etc.) are enforced only against only prior attempts that were accepted (
accepted: true) - Certain print statements for debugging and evaluation tracing remain commented out in
evaluator.pyandcustomer_fund.py. These can be uncommented for additional visibility during review or testing.