AlgoMaster Logo
AlgoMasterRefactor Expense Importermedium

Refactor Expense Importer

medium

An expense importer receives compact lines such as travel:120. The legacy implementation treats parsing, business validation, and bookkeeping as one operation. It handles a few happy paths, but it accepts unknown categories and expenses above the company limit because the import rules have no clear owner.

Refactor the starter code while preserving the public ExpenseImporter API:

  • ExpenseImporter() creates an importer with an empty ledger.
  • boolean importLine(String line) imports one expense and returns whether it was accepted.
  • A line must contain exactly one colon and have the form "<category>:<amount>", where the amount is a base-10 integer.
  • The allowed categories are "travel", "meals", and "supplies".
  • An amount must be between 1 and 5000 inclusive.
  • int acceptedCount() returns the number of expenses in the ledger.
  • int rejectedCount() returns how many import attempts were malformed or violated the policy.
  • int total() returns the sum of all accepted expenses.
  • int categoryTotal(String category) returns the accepted total for that category, or 0 when none exists.

Parsing answers “can this text become an expense?” Policy validation answers “does the company allow this expense?” Storage happens only after both answers are yes.

Example 1:

Input:

Output:

Explanation: Both lines are well formed and satisfy the expense policy, so they reach the ledger.

Example 2:

Input:

Output:

Explanation: The first line parses, but its category is not allowed. The second has a valid category but an invalid amount. Neither belongs in the ledger.

Constraints:
  • 0 <= line.length <= 60
  • 0 <= category.length <= 30
  • At most 100 calls will be made across all methods.

Starter Code

The starter keeps every concern in one class. It also implements only part of the company policy, so refactoring includes restoring the missing rules.

How the design is graded

needs 7/10 to pass
  • Separated concerns

    Full marks when parsing, policy validation, and accepted-expense storage live in separate types coordinated by ExpenseImporter. Lose points heavily when one method owns the file syntax, business rules, and ledger updates.

  • Safe import flow

    Full marks when malformed and policy-rejected lines increment the rejected count exactly once and never reach the ledger. Lose points when partially parsed data is stored or rejected data affects totals.

  • Single ownership

    Full marks when the policy is the only place that knows allowed categories and amount limits, while the ledger alone owns accepted totals. Lose points for duplicated rules or separate counters that can drift from ledger contents.

Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.

Hints

Loading...
CallReturns
new ExpenseImporter()null
importLine("travel:120")true
importLine("meals:30")true
acceptedCount()2
rejectedCount()0
total()150
categoryTotal("travel")120

Both lines are well formed and satisfy the expense policy, so they reach the ledger.

Run checks these cases. Submit also runs a larger hidden set.