What lcpy gen creates, what each file is for, and which one you own.
Every generated problem is the same six files. Learn the shape once and every
problem in the catalog feels like home.
lcpy gen -n 1
leetcode/two_sum/├── README.md # problem statement, difficulty, topics, tags├── solution.py # your code; the only file you edit├── test_solution.py # 10+ parametrized cases, ready to run├── helpers.py # run_/assert_ pair for readable test output├── playground.py # percent-format scratchpad notebook└── __init__.py
The problem statement: difficulty, topics, collection tags, a link to the
original LeetCode problem, the description, and worked examples. Everything
you need to solve without leaving the terminal.
Generated with a class skeleton, the method signature with type hints, and a
TODO where your implementation goes. Solved examples in this repo also
carry Time/Space complexity comments at the top of the method, the
house convention.
A parametrized pytest suite with 10+ cases per problem, edge cases included.
It runs red the moment you generate the problem and stays the contract: make
red go green, never edit the tests. See Testing.
Two functions per problem: run_<name> instantiates your solution class and
calls the method; assert_<name> compares result to expected, normalized
so order-insensitive answers compare cleanly. Failures print the inputs and
expected output instead of a raw object dump.
Every problem directory comes from a JSON template, so files arrive
byte-identical on every machine and CI verifies they regenerate exactly.
If something looks off, regenerate the problem with bake p-gen rather
than editing generated files by hand.
Last modified on August 21, 2026
{"docsConfig":{"theme":"mint","$schema":"https://www.mintlify.com/docs.json","name":"leetcode-py","description":"Modern Python LeetCode practice environment with automated problem generation, beautiful data structure visualizations, and comprehensive testing","colors":{"primary":"#3776AB","light":"#5A94C4","dark":"#387EB8"},"logo":{"light":"https://mintcdn.com/leetcode-py/aJKJ4BOUnXP-zM3G/img/brand/leetcode-py-lockup.svg?fit=max\u0026auto=format\u0026n=aJKJ4BOUnXP-zM3G\u0026q=85\u0026s=34c74a404ed256642a54345a92489c97","dark":"https://mintcdn.com/leetcode-py/aJKJ4BOUnXP-zM3G/img/brand/leetcode-py-lockup-dark.svg?fit=max\u0026auto=format\u0026n=aJKJ4BOUnXP-zM3G\u0026q=85\u0026s=263c5757fbf5e547de96291651e279e9"},"favicon":"https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/favicon.svg?fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=3b1dffe162e80798a504a810fcbeba45","background":{"color":{"light":"#F8F9FB","dark":"#0D1117"}},"navbar":{"links":[{"href":"https://github.com/wislertt/leetcode-py","label":"GitHub"}]},"footer":{"socials":{"github":"https://github.com/wislertt/leetcode-py"},"links":[{"header":"Resources","items":[{"label":"PyPI","href":"https://pypi.org/project/leetcode-py-sdk"},{"label":"Why leetcode-py","href":"/getting-started/why-leetcode-py"},{"label":"Made by Wisaroot Lertthaweedech","href":"https://wisl.dev"}]}]},"seo":{"metatags":{"canonical":"https://leetcode-py.wisl.dev","og:image":"https://leetcode-py.wisl.dev/img/brand/og-card-light.png","twitter:card":"summary_large_image"},"organization":{"url":"https://leetcode-py.wisl.dev","sameAs":["https://github.com/wislertt/leetcode-py","https://pypi.org/project/leetcode-py-sdk/","https://wisl.dev"]},"indexing":"all"},"styling":{"codeblocks":{"theme":{"light":"github-light","dark":"github-dark"}},"latex":true},"metadata":{"timestamp":true},"markdown":{"instructions":["leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform.","Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package.","Examples are backed by tests; copy them verbatim."]},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"leetcode-py","hasAudioNarration":false,"actualSubdomain":"leetcode-py","customDomains":["leetcode-py.wisl.dev"],"gitSource":{"type":"github","owner":"wislertt","repo":"leetcode-py","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{},"buildId":"6aeadd835fa1f5f231996c95","clientVersion":"0.0.4094","searchFilterCounts":[{"language":"default","tag":"Catalog","count":13},{"language":"default","tag":"Practice","count":5},{"language":"default","tag":"Troubleshooting","count":5},{"language":"default","tag":"Getting Started","count":3},{"language":"default","tag":"CLI","count":2},{"language":"default","tag":"Contributing","count":2},{"language":"default","tag":"Welcome","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"custom.css","content":".sd-catalog-table th:first-child,.sd-catalog-table td:first-child{min-width:0;width:3rem}html.dark .sd-hero-light{display:none}html:not(.dark) .sd-hero-dark{display:none}.sd-badges{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-start;margin:0 0 16px;padding:0}.sd-badges a,.sd-badges a:hover,.sd-badges a:visited{display:inline-flex;flex:0 0 auto;line-height:0;height:auto!important;max-height:24px;padding:0!important;margin:0!important;text-decoration:none!important;border-bottom:none!important;background:none!important;background-image:none!important}.sd-badges img{height:20px;width:auto;max-width:none;display:block;margin:0!important}.sd-preview{border:1px solid #387eb8;border-radius:10px}"}],"page":{"pagePath":"practice/problem-anatomy","slug":"/practice/problem-anatomy","pageMetadata":{"title":"Anatomy of a problem","description":"What lcpy gen creates, what each file is for, and which one you own.","href":"/practice/problem-anatomy"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"What lcpy gen creates, what each file is for, and which one you own.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,..._provideComponents(),...props.components},{CodeBlock,Heading,OptimizedImage}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Every generated problem is the same six files. Learn the shape once and every\nproblem in the catalog feels like home.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`lcpy`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` gen`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` -n`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` 1`})]}),`\n`]})})}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`leetcode/two_sum/`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`├── README.md # problem statement, difficulty, topics, tags`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`├── solution.py # your code; the only file you edit`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`├── test_solution.py # 10+ parametrized cases, ready to run`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`├── helpers.py # run_/assert_ pair for readable test output`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`├── playground.py # percent-format scratchpad notebook`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`└── __init__.py`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`readme-md`,children:`README.md`}),`\n`,_jsx(_components.p,{children:`The problem statement: difficulty, topics, collection tags, a link to the\noriginal LeetCode problem, the description, and worked examples. Everything\nyou need to solve without leaving the terminal.`}),`\n`,_jsx(OptimizedImage,{src:`https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/readme-example.png?fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=aea118af4404d48c697ecf51d7dc41d6`,alt:`Generated README for Two Sum`,\"data-og-width\":`957`,width:`957`,\"data-og-height\":`819`,height:`819`,\"data-path\":`images/readme-example.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/readme-example.png?w=280\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=0a0826922904578fe2b2c15fbc5a67ec 280w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/readme-example.png?w=560\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=ffdb0eef30a0fae4da2343cfcf166af2 560w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/readme-example.png?w=840\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=59ee69987be87eae3c278062c2e2d78f 840w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/readme-example.png?w=1100\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=a16df6d271d8a63abc5c2ad9bee1ad17 1100w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/readme-example.png?w=1650\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=24deaf570e4675747ee30707c1f69b74 1650w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/readme-example.png?w=2500\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=d527bbddbfed0785cc2dbee93e2dc649 2500w`}),`\n`,_jsx(Heading,{level:`2`,id:`solution-py-the-only-file-you-edit`,children:`solution.py: the only file you edit`}),`\n`,_jsxs(_components.p,{children:[`Generated with a class skeleton, the method signature with type hints, and a\n`,_jsx(_components.code,{children:`TODO`}),` where your implementation goes. Solved examples in this repo also\ncarry `,_jsx(_components.code,{children:`Time`}),`/`,_jsx(_components.code,{children:`Space`}),` complexity comments at the top of the method, the\nhouse convention.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`class`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Solution`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` # Time: O(n)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` # Space: O(n)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` def`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` two_sum`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(self, nums: list[`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`int`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`], target: `}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`int`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`) -> list[`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`int`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`]:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` ...`})}),`\n`]})})}),`\n`,_jsx(OptimizedImage,{src:`https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/solution-boilerplate.png?fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=a1cac7874c2ad7e96fff0ce22cef7d50`,alt:`Generated solution.py stub with TODO placeholder`,\"data-og-width\":`889`,width:`889`,\"data-og-height\":`207`,height:`207`,\"data-path\":`images/solution-boilerplate.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/solution-boilerplate.png?w=280\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=f90bda32267784005f474be5938fb757 280w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/solution-boilerplate.png?w=560\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=8cce717cc068ebf2ef759eb31cb3599a 560w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/solution-boilerplate.png?w=840\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=8951d8cbf0595aad1d357387453e69cc 840w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/solution-boilerplate.png?w=1100\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=779ae2c0e89e85c799353bfb2c3bdc0f 1100w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/solution-boilerplate.png?w=1650\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=242885aec4405fdec2a220b779ad2b12 1650w, https://mintcdn.com/leetcode-py/VCrzlUI648LnF7Pk/images/solution-boilerplate.png?w=2500\u0026fit=max\u0026auto=format\u0026n=VCrzlUI648LnF7Pk\u0026q=85\u0026s=6d74a55b4ae826029f1f6f1190a6cb9c 2500w`}),`\n`,_jsx(Heading,{level:`2`,id:`test_solution-py`,children:`test_solution.py`}),`\n`,_jsxs(_components.p,{children:[`A parametrized pytest suite with 10+ cases per problem, edge cases included.\nIt runs red the moment you generate the problem and stays the contract: make\nred go green, never edit the tests. See `,_jsx(_components.a,{href:`/practice/testing`,children:`Testing`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`helpers-py`,children:`helpers.py`}),`\n`,_jsxs(_components.p,{children:[`Two functions per problem: `,_jsx(_components.code,{children:`run_\u003cname>`}),` instantiates your solution class and\ncalls the method; `,_jsx(_components.code,{children:`assert_\u003cname>`}),` compares result to expected, normalized\nso order-insensitive answers compare cleanly. Failures print the inputs and\nexpected output instead of a raw object dump.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`def`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` run_two_sum`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(solution_class: `}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`type`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`, nums: list[`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`int`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`], target: `}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`int`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`):`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` implementation `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` solution_class()`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` return`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` implementation.two_sum(nums, target)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`def`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` assert_two_sum`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(result: list[`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`int`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`], expected: list[`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`int`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`]) -> `}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`bool`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` assert`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` sorted`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(result) `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`==`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` sorted`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(expected)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` return`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` True`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`playground-py`,children:`playground.py`}),`\n`,_jsxs(_components.p,{children:[`A scratchpad in jupytext percent format: plain Python in git, a notebook\nwhen you want one. See `,_jsx(_components.a,{href:`/practice/notebooks`,children:`Notebooks`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`generated-not-hand-rolled`,children:`Generated, not hand-rolled`}),`\n`,_jsxs(_components.p,{children:[`Every problem directory comes from a JSON template, so files arrive\nbyte-identical on every machine and CI verifies they regenerate exactly.\nIf something looks off, regenerate the problem with `,_jsx(_components.code,{children:`bake p-gen`}),` rather\nthan editing generated files by hand.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":{"theme":{"light":"github-light","dark":"github-dark"}},"config":{},"pageMetadata":{"title":"Anatomy of a problem","description":"What lcpy gen creates, what each file is for, and which one you own.","href":"/practice/problem-anatomy"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"README.md","slug":"readme-md","depth":2,"children":[]},{"title":"solution.py: the only file you edit","slug":"solution-py-the-only-file-you-edit","depth":2,"children":[]},{"title":"test_solution.py","slug":"test_solution-py","depth":2,"children":[]},{"title":"helpers.py","slug":"helpers-py","depth":2,"children":[]},{"title":"playground.py","slug":"playground-py","depth":2,"children":[]},{"title":"Generated, not hand-rolled","slug":"generated-not-hand-rolled","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"leetcode-py","siteName":"leetcode-py","title":"Anatomy of a problem - leetcode-py","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-08-21T15:43:40.722Z","gitLastModified":"2026-08-21T15:13:00.000Z","originalFileLocation":"practice/problem-anatomy.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"What lcpy gen creates, what each file is for, and which one you own.\">\u003cmeta data-mint-head name=\"application-name\" content=\"leetcode-py\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Anatomy of a problem - leetcode-py\">\u003cmeta data-mint-head property=\"og:description\" content=\"What lcpy gen creates, what each file is for, and which one you own.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"leetcode-py\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://leetcode-py.wisl.dev/practice/problem-anatomy\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://leetcode-py.wisl.dev/img/brand/og-card-light.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Anatomy of a problem - leetcode-py\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"What lcpy gen creates, what each file is for, and which one you own.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://leetcode-py.wisl.dev/img/brand/og-card-light.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/leetcode-py/MPF4VdYq1xxotsp3/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"leetcode-py\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#3776AB\">\u003clink data-mint-head rel=\"canonical\" href=\"https://leetcode-py.wisl.dev/practice/problem-anatomy\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/practice/problem-anatomy.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://leetcode-py.wisl.dev/#organization\",\"name\":\"leetcode-py\",\"url\":\"https://leetcode-py.wisl.dev\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/leetcode-py/aJKJ4BOUnXP-zM3G/img/brand/leetcode-py-lockup.svg?fit=max\u0026auto=format\u0026n=aJKJ4BOUnXP-zM3G\u0026q=85\u0026s=34c74a404ed256642a54345a92489c97\"},\"sameAs\":[\"https://github.com/wislertt/leetcode-py\",\"https://pypi.org/project/leetcode-py-sdk/\",\"https://wisl.dev\"]},{\"@type\":\"WebSite\",\"@id\":\"https://leetcode-py.wisl.dev#website\",\"name\":\"leetcode-py\",\"url\":\"https://leetcode-py.wisl.dev\",\"publisher\":{\"@id\":\"https://leetcode-py.wisl.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy#webpage\",\"url\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy\",\"name\":\"Anatomy of a problem\",\"description\":\"What lcpy gen creates, what each file is for, and which one you own.\",\"dateModified\":\"2026-08-21T15:13:00.000Z\",\"isPartOf\":{\"@id\":\"https://leetcode-py.wisl.dev#website\"},\"breadcrumb\":{\"@id\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"leetcode-py\",\"item\":\"https://leetcode-py.wisl.dev\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Anatomy of a problem\",\"item\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy#article\",\"headline\":\"Anatomy of a problem\",\"name\":\"Anatomy of a problem\",\"description\":\"What lcpy gen creates, what each file is for, and which one you own.\",\"url\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy\",\"mainEntityOfPage\":{\"@id\":\"https://leetcode-py.wisl.dev/practice/problem-anatomy#webpage\"},\"image\":\"https://leetcode-py.wisl.dev/img/brand/og-card-light.png\",\"dateModified\":\"2026-08-21T15:13:00.000Z\",\"publisher\":{\"@id\":\"https://leetcode-py.wisl.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://leetcode-py.wisl.dev#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"leetcode-py\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"leetcode-py","nav":{"global":null,"groups":[{"group":"Welcome","pages":[{"title":"LeetCode Practice Environments in Python","sidebarTitle":"leetcode-py","href":"/index"}]},{"group":"Getting Started","pages":[{"title":"Install the lcpy CLI via pip or uv","sidebarTitle":"Installation","href":"/getting-started/installation"},{"title":"lcpy Quickstart: First Problem in 5 Commands","sidebarTitle":"Quickstart","href":"/getting-started/quickstart"},{"title":"LeetCode Practice Environment vs a Bare Editor","sidebarTitle":"Why leetcode-py","description":"What a generated practice environment gives you that a bare editor does not.","href":"/getting-started/why-leetcode-py"}]},{"group":"Practice","pages":[{"title":"Anatomy of a problem","href":"/practice/problem-anatomy"},{"title":"Test LeetCode Solutions Locally with pytest","sidebarTitle":"Test locally","description":"Set up a local feedback loop for LeetCode problems: generate a problem, run its pytest suite, make red go green, and iterate on single cases.","href":"/practice/test-locally"},{"title":"LeetCode Python Test Cases with pytest","sidebarTitle":"Testing","href":"/practice/testing"},{"title":"Visualizations","href":"/practice/visualizations"},{"title":"Notebooks","href":"/practice/notebooks"}]},{"group":"CLI","pages":[{"title":"lcpy CLI: Generate and List Problems","sidebarTitle":"lcpy","href":"/cli/lcpy"},{"title":"Blind 75, Grind 75, NeetCode and Others","sidebarTitle":"Collections","href":"/cli/collections"}]},{"group":"Catalog","pages":[{"title":"LeetCode Problem Catalog: All Collections","sidebarTitle":"Catalog","href":"/catalog/index"},{"title":"All LeetCode Problems in Python with Tests","sidebarTitle":"All Problems","href":"/catalog/all"},{"title":"Easy LeetCode Problems in Python with Tests","sidebarTitle":"Easy","href":"/catalog/easy"},{"title":"Medium LeetCode Problems in Python with Tests","sidebarTitle":"Medium","href":"/catalog/medium"},{"title":"Hard LeetCode Problems in Python with Tests","sidebarTitle":"Hard","href":"/catalog/hard"},{"title":"Topics","href":"/catalog/topics"},{"title":"Grind 75 in Python with Tested Solutions","sidebarTitle":"Grind 75","href":"/catalog/grind-75"},{"title":"Grind Collection in Python: Tested Solutions","sidebarTitle":"Grind","href":"/catalog/grind"},{"title":"Blind 75 in Python with Tested Solutions","sidebarTitle":"Blind 75","href":"/catalog/blind-75"},{"title":"NeetCode 150 in Python with Tested Solutions","sidebarTitle":"NeetCode 150","href":"/catalog/neetcode-150"},{"title":"NeetCode 250 in Python with Tested Solutions","sidebarTitle":"NeetCode 250","href":"/catalog/neetcode-250"},{"title":"NeetCode All in Python with Tested Solutions","sidebarTitle":"NeetCode All","href":"/catalog/neetcode"},{"title":"AlgoMaster 75 in Python with Tested Solutions","sidebarTitle":"AlgoMaster 75","href":"/catalog/algo-master-75"}]},{"group":"Contributing","pages":[{"title":"Add a New LeetCode Problem End to End","sidebarTitle":"Problem creation","href":"/contributing/problem-creation"},{"title":"Contributor Reference: bakefile Tasks","sidebarTitle":"bakefile","href":"/contributing/bakefile"}]},{"group":"Troubleshooting","pages":[{"title":"lcpy Errors and Troubleshooting","sidebarTitle":"Troubleshooting","href":"/troubleshooting/index"},{"title":"lcpy gen Error: Problem Not Found","sidebarTitle":"Problem not found","href":"/troubleshooting/unknown-problem"},{"title":"lcpy gen Error: Problem Already Exists","sidebarTitle":"Already exists","href":"/troubleshooting/files-already-exist"},{"title":"Visualizations Show ASCII Instead of Diagrams","sidebarTitle":"ASCII diagrams","href":"/troubleshooting/graphviz-missing"},{"title":"Playground Notebook Cells Do Not Render","sidebarTitle":"Notebook cells","href":"/troubleshooting/notebook-cells"}]}]},"basePath":"","title":"Anatomy of a problem - leetcode-py","buildId":"dpl_42LwxxU1kGN114H4XzwGYXa9ZDah","deploymentId":"dpl_42LwxxU1kGN114H4XzwGYXa9ZDah","dynamics":["a74be98ba7"],"chunks":["zoom-image-lightbox-DkE6VzSN.js","lightbox-handle-r17bVUz3.js"]}