Refactor a messy function into clean, maintainable code
FreeA copy-paste ChatGPT prompt that refactors a messy function into clean, maintainable code without changing its behavior — it audits the code, rewrites it, explains each change, and suggests tests to prove nothing broke.
Turn one tangled function into clean, reviewer-ready code with its behavior provably intact.
This prompt
You are a staff software engineer known for turning tangled, hard-to-read code into clean code that reviewers approve on the first pass — without ever breaking behavior.
Refactor the {{language}} function below into clean, readable, maintainable code. You succeed when the refactored version returns the same outputs, side effects, and errors as the original for every input it handles, while being easier to read, test, and change.
Context:
- Language / runtime: {{language}}
- Project conventions to follow: {{conventions}}
- Hard constraints that must not change: {{constraints}}
- The function to refactor is between the markers:
<code>
{{messy_code}}
</code>
Work through these steps:
1. Restate the contract. In one or two sentences, describe what the function takes in, what it returns, its side effects, and how it handles errors and edge cases. This is the behavior you must preserve.
2. Audit. List the specific problems, pointing at the exact spot for each — for example: unclear names, duplicated logic, deep nesting, an over-long body doing several jobs at once, magic numbers or strings, dead code, or unhandled edge cases.
3. Refactor. Rewrite the function, making only changes that improve clarity or structure: use intention-revealing names, replace deep nesting with early returns and guard clauses, pull repeated logic into small well-named helpers, replace magic values with named constants, and delete dead code. Match the existing conventions and idioms instead of importing a new style.
4. Preserve behavior. Keep the same public signature and return contract unless a constraint allows otherwise. Do not add features, swap dependencies, or "improve" behavior beyond the refactor.
5. Flag, do not silently fix. If you find a real bug or genuinely ambiguous behavior, keep the current behavior in your rewrite and describe the issue separately so a human can decide.
Return your answer in these sections:
1. Contract — the one or two sentence behavior summary from step 1.
2. Refactored code — the full function plus any new helpers, in a single {{language}} code block, ready to paste in.
3. Changes made — a short bulleted list pairing each change with its reason.
4. Behavior and risks — confirm what stays identical, and list any bugs, ambiguities, or assumptions you had to make.
5. Suggested tests — 2 to 4 test cases, including edge cases, that would prove the behavior is unchanged.
Constraints:
- Preserve observable behavior exactly. When the original intent is unclear, state your assumption rather than guessing silently.
- Prefer the simplest structure that reads well; do not add abstraction, indirection, or error handling the task does not call for.
- Keep the existing language and dependencies; introduce a new library only if a constraint allows it.
- Refactor only the code provided; do not redesign the surrounding modules.
- If the function is already clean, say so and make only the small improvements that clearly help.6 fields still empty — the {{like_this}} slots fill in as you type.
See it in action
What this prompt produces with example details filled in:
**1. Contract**
Takes an array of order line items (each with `type`, `price`, `qty`), sums their line totals — applying a 10% discount to `book` items with quantity over 5, and a 5% surcharge to `food` items — then subtracts a flat $10 when the subtotal is over $100. Returns a number.
**2. Refactored code**
```javascript
const BOOK_BULK_QTY = 5;
const BOOK_BULK_DISCOUNT = 0.9; // 10% off
const FOOD_SURCHARGE = 1.05; // 5% surcharge
const LARGE_ORDER_THRESHOLD = 100;
const LARGE_ORDER_REBATE = 10; // flat $ off
function lineTotal({ type, price, qty }) {
const base = price * qty;
if (type === "book" && qty > BOOK_BULK_QTY) return base * BOOK_BULK_DISCOUNT;
if (type === "food") return base * FOOD_SURCHARGE;
return base;
}
function orderTotal(items) {
const subtotal = items.reduce((sum, item) => sum + lineTotal(item), 0);
return subtotal > LARGE_ORDER_THRESHOLD
? subtotal - LARGE_ORDER_REBATE
: subtotal;
}
```
**3. Changes made**
- Renamed `calc` -> `orderTotal` and `o` -> `items` so the names say what they hold (allowed: internal helper, per constraints).
- Extracted `lineTotal()` so each item's pricing rule lives in one place and the summing loop reads in a single line.
- Replaced the magic numbers (`0.9`, `1.05`, `5`, `100`, `10`) with named constants that state the business rule.
- Swapped the manual `for` loop for `reduce`, and the trailing `if` reassignment for a ternary — one expression each, no mutation.
**4. Behavior and risks**
- Identical: same discount, surcharge, and rebate math and thresholds; empty array still returns `0`; return type is still a number.
- Assumption: `type` is always a string and `price`/`qty` are always numbers, as in the input — so switching `==` to `===` changes nothing here. If those fields can be other types, `===` is a (desirable) behavior change; confirm before shipping.
- Possible bug, left as-is: a book with `qty` exactly 5 gets no bulk discount (the rule is `> 5`, not `>= 5`). Preserved on purpose — confirm the intended threshold.
**5. Suggested tests**
- `orderTotal([])` -> `0` (empty input).
- `orderTotal([{ type: "book", price: 10, qty: 6 }])` -> `54` (10% off; subtotal under 100, no rebate).
- `orderTotal([{ type: "book", price: 10, qty: 6 }, { type: "book", price: 10, qty: 6 }])` -> `98` (subtotal 108 over 100, $10 rebate applied once).
- `orderTotal([{ type: "food", price: 20, qty: 1 }])` -> `21` (5% surcharge).Tips
- Paste the whole function plus any small helpers it calls, so the model can lock in the exact contract it must preserve.
- Fill the constraints slot with anything that must stay put — the public signature, a framework version, or "no new dependencies" — to stop over-eager rewrites.
- If you already have tests, paste them too and ask the model to keep them green.
- Refactor one function at a time; for a large file, run the prompt per unit rather than dumping the whole module.
Built by Web Innoventix
Want the work done, not just prompted? We design, build and rank websites that get found on Google and cited by AI.
Get a free quoteMore prompts
Browse all →Build a React component from a description
Turn a plain-English description into a production-ready, accessible React + Tailwind component with a usage example.
Senior code review that catches real bugs
Paste a snippet or PR diff and get a senior-engineer review: real issues ranked by severity, each with the exact input that breaks it and a concrete fix — not a wall of style nitpicks.
Debug an error by root cause, not guesswork
Paste an error and its context to get a traced root-cause diagnosis, a fix that addresses the real cause, and a concrete way to verify the bug is gone.
Write thorough unit tests for a function or component
A fill-in prompt that turns any function or component into a runnable unit test suite covering happy paths, edge cases, boundaries, and error handling in your chosen framework.
Build a regex from a plain-English description (with test cases)
A fill-in-the-blank ChatGPT prompt that turns a plain-English rule into a working regex for your exact language — with a line-by-line breakdown and a pass/fail table of positive and negative test cases.
Write a clear, conventional git commit message from a diff
A fill-in prompt that turns any git diff into a clean, convention-compliant commit message with a tight subject line and a what-and-why body a reviewer can trust.

