A coding model can turn a kata into deliberate practice, but only if you keep ownership of the difficult decisions. This routine uses a small Python exercise: return the first character that appears exactly once in a string. You will define the rules, write tests, request limited hints, and finish with an unaided rerun.
1. Write the first-unique-character contract
Before opening a model conversation, write down the function’s behavior. Accept a string and return its first non-repeating character, preserving input order. Return None when no character qualifies. Treat uppercase and lowercase as different characters, and count spaces like any other character.
Keep the scope narrow: assume valid string input and use ordinary Python string iteration. Skip normalization, streaming input, and user-interface work. These boundaries prevent the model from turning a small exercise into a framework.
2. Give the model a coaching boundary
Start a fresh conversation so earlier solutions cannot leak into the exercise. Paste your contract and ask the model to act as a coach rather than an implementer.
Starter prompt: “I am practicing a Python kata that returns the first non-repeating character. Here is my contract. Do not write implementation code or reveal an algorithm yet. Ask one clarifying question if needed, then wait for my tests. Give hints only when I request them.”
If you want to use your existing coding tool, SwiftRelay works with Claude Code, Codex, Gemini CLI, and OpenAI-compatible SDKs. Sign up for SwiftRelay to try this routine with its small new-account gift credit. For an OpenAI-compatible SDK, use https://api.fastapirelay.com/v1 as the base URL; Claude Code and Gemini CLI take the bare host, https://api.fastapirelay.com. Claude Sonnet 5.5 is one model you can use for the coaching conversation.
3. Build tests before requesting hints
Write your own tests first, using pytest if that is already part of your setup. Include these cases, but decide the expected outputs yourself before checking them:
- An empty string returns None.
- A single character returns that character.
- The string “aabb” returns None.
- The string “swiss” returns “w”.
- The string “Aa” returns “A”.
- A space followed by “a” returns the space.
Then ask: “Review these tests against my contract. Identify missing behavior without supplying implementation code.” Add a test only when you can explain the behavior it protects. Avoid collecting cases merely because the model suggested them.
4. Make an independent attempt, then request one hint
Implement a solution without asking for a complete answer. A straightforward approach is acceptable, even if it repeats work. Run the tests and inspect failures yourself before sharing anything with the model.
If you get stuck, send the smallest relevant function, the failing input, and the expected and actual results. Ask: “Give me one conceptual hint about this failure. Do not rewrite the function.” Apply that hint yourself, then rerun the tests. Request another hint only after making a concrete attempt.
5. Review correctness before improving complexity
Once the tests pass, ask for a review focused on the contract: “Find a counterexample to this implementation, or explain why it preserves input order and handles repeated characters correctly.” Treat any proposed counterexample as a claim to verify locally.
Next, examine repeated scanning. If your solution counts occurrences separately for every character, consider counting frequencies once and then scanning the original string. Explain the time and space costs in your own words before requesting feedback. Do not accept an optimization you cannot trace manually.
6. Refactor without expanding the exercise
Improve names, remove unnecessary branches, and keep the function easy to read. Run the unchanged tests after each meaningful edit. Ask the model to flag misleading names or redundant logic, not to produce a polished replacement.
Keep a short practice log: your initial mistake, the hint that helped, and the reason the final algorithm works. This records learning rather than merely preserving a successful answer.
7. Close the chat and rerun the kata
In a later session, start from an empty file with the same contract and no transcript. Recreate the tests and implementation unaided. Compare your reasoning with the practice log afterward.
If you still need the same hint, repeat that part of the exercise. The finish line is not accepted model output; it is a solution you can rebuild, explain, and test independently.