# The Account Manager

> Deposits, withdrawals, and the risk of going negative.

Canonical URL: <https://datadriven.io/problems/the_account_manager>

Domain: Python · Difficulty: easy · Seniority: L4

## Problem

Implement bank_account_simulator(initial_balance, ops) that applies a list of ops to a BankAccount starting at initial_balance. Ops are ['deposit', amt], ['withdraw', amt], or ['balance']. Withdraw raises ValueError if amt > balance. Return the final balance after all ops; if any withdraw would overdraw, return the string 'ValueError' instead.

## Worked solution and explanation

### Why this problem exists in real interviews

Implementing a class with state validation tests **OOP fundamentals**: constructors, instance methods, property access, and raising exceptions on invalid operations. It is a basic class design check.

---

### Break down the requirements

#### Step 1: Constructor sets the initial balance

Store the balance as an instance attribute.

#### Step 2: Deposit adds to the balance

Simple addition. Deposits are always positive.

#### Step 3: Withdraw subtracts with validation

Raise ValueError if the withdrawal exceeds the current balance.

#### Step 4: Balance property for read access

Expose the balance as a property or attribute.

---

### The solution

**Stateful class with validation on withdrawal**

```python
class BankAccount:
    def __init__(self, initial_balance):
        self._balance = initial_balance
    @property
    def balance(self):
        return self._balance
    def deposit(self, amount):
        self._balance += amount
    def withdraw(self, amount):
        if amount > self._balance:
            raise ValueError('Insufficient funds')
        self._balance -= amount
```

> **Time and Space Complexity**
>
> **Time:** O(1) for all operations.
> 
> **Space:** O(1) per instance.

> **Interviewers Watch For**
>
> Using a property with `@property` decorator to expose balance as read-only. Candidates who use a public attribute are technically correct but miss the encapsulation signal.

> **Common Pitfall**
>
> Forgetting to raise ValueError on overdraft. Returning False or silently ignoring the withdrawal are incorrect behaviors.

---

## Common follow-up questions

- How would you add transaction history? _(Tests maintaining a list of (type, amount, timestamp) tuples.)_
- How would you make this thread-safe? _(Tests using threading.Lock to guard balance modifications.)_
- What if deposits and withdrawals should be atomic? _(Tests the concept of database-style transactions with commit/rollback semantics.)_

## Related

- [All practice problems](https://datadriven.io/problems)
- [Mock interview mode](https://datadriven.io/interview/the_account_manager)
- [Python Interview Questions](https://datadriven.io/python-interview-questions)
- [Data Engineering Interview Prep Guide](https://datadriven.io/data-engineer-interview-prep)
- [Daily Challenge](https://datadriven.io/daily)

---

Source: DataDriven (https://datadriven.io). 100% free data engineering interview prep. Live code execution against Postgres 16, Python 3.11, and Spark sandboxes. No paywall, no premium tier, no signup gate.