{"id":7312,"date":"2025-03-06T10:28:47","date_gmt":"2025-03-06T10:28:47","guid":{"rendered":"https:\/\/algocademy.com\/blog\/why-you-understand-code-but-cant-write-it-from-scratch\/"},"modified":"2026-10-15T10:34:49","modified_gmt":"2026-10-15T10:34:49","slug":"why-you-understand-code-but-cant-write-it-from-scratch","status":"publish","type":"post","link":"https:\/\/algocademy.com\/blog\/why-you-understand-code-but-cant-write-it-from-scratch\/","title":{"rendered":"Why You Understand Code but Can&#8217;t Write It From Scratch"},"content":{"rendered":"<p>You can follow a solution line by line, yet an empty editor gets you nowhere. That is normal, and it does not mean you are bad at programming. Reading code and writing code are different skills. Reading checks whether what you see makes sense; writing makes you produce every piece yourself, in the right order, from memory. The fix is to practice producing code, in small steps, with a plan.<\/p>\n<h2>What is actually going on<\/h2>\n<h3>Recognition is easier than recall<\/h3>\n<p>When you read code, every line is in front of you as a cue. You only have to judge &#8220;does this look right?&#8221; When you write, nothing is in front of you. You have to retrieve the syntax, the method names and the shape of the solution. Psychologists have long found that recognizing something is easier than recalling it, which is why a multiple-choice test feels easier than a short-answer test on the same material.<\/p>\n<p>That is also why a tutorial can feel like learning while you are watching and then vanish when you close it. If you want a name for the trap, it is the one described in <a href=\"https:\/\/algocademy.com\/blog\/why-youre-stuck-in-tutorial-hell-even-after-completing-10-courses\/\">tutorial hell<\/a>: lots of recognition, little retrieval.<\/p>\n<h3>Fluent reading feels like understanding<\/h3>\n<p>A finished solution is smooth. Each step follows from the last, and you nod along. What you do not see are the dead ends the author dropped, the decisions they made, and the reason each line is there. So you may understand <em>what<\/em> the code does without knowing <em>why it was built that way<\/em> or how to arrive at it. Writing exposes that gap immediately.<\/p>\n<h3>Writing means holding many things at once<\/h3>\n<p>Working memory is small; common estimates put it at around four chunks of information at a time. When you write a function from nothing you are juggling the problem, your plan, the language syntax, variable names and edge cases together. A beginner has to think about each of these individually, so the load is high. An experienced programmer has chunked the common pieces (a loop over an array, a dictionary lookup, a two-pointer scan) into single units, which leaves room for the actual problem. This is the main thing practice buys you.<\/p>\n<h3>You are missing the patterns, not the intelligence<\/h3>\n<p>Much of &#8220;writing from scratch&#8221; is recognizing which familiar pattern the problem is an instance of, then adapting it. If you have seen a few dozen problems solved with a hash map, a sliding window or binary search, you start from a template. If you have seen the solutions but never produced them, the templates are not available to you when you need them.<\/p>\n<h2>A routine that closes the gap<\/h2>\n<h3>1. Retrieve before you look<\/h3>\n<p>After studying a solution, close it and write it again from memory. Do not worry about getting it perfect. Then compare, and note exactly what you missed (a base case, an off-by-one, a method name). Repeat the same problem a day later, then a few days later. Spacing the repetitions makes the retrieval harder, and that difficulty is what makes it stick.<\/p>\n<p>The key rule: struggle for a few minutes before you look. If you look at the answer the moment you are stuck, you are back to recognition.<\/p>\n<h3>2. Plan in plain language first<\/h3>\n<p>Do not start with syntax. Write the steps as comments or pseudocode, then fill in code under each. This separates &#8220;what should happen&#8221; from &#8220;how do I spell it&#8221;, so you carry one load at a time. The post on <a href=\"https:\/\/algocademy.com\/blog\/the-secret-to-writing-code-from-scratch-start-by-writing-pseudocode\/\">writing code from scratch by starting with pseudocode<\/a> goes into this in more detail, and if you freeze at the very first line, <a href=\"https:\/\/algocademy.com\/blog\/why-you-cant-start-coding-breaking-the-blank-page-barrier\/\">breaking the blank page barrier<\/a> has tactics for that.<\/p>\n<h3>3. Build in small, working steps<\/h3>\n<p>Get the smallest version running, then extend it. Run the code after every few lines. If you write 40 lines and then run them, you will have several bugs tangled together and nothing to tell you which line caused which. Small steps keep the load low and give you feedback early.<\/p>\n<h3>4. Write the tests first, or at least the examples<\/h3>\n<p>Write three or four inputs with expected outputs before the code: a typical case, an empty input, a single element, and the boundaries. Examples also tell you whether you understood the problem, which is often the actual blocker.<\/p>\n<h3>5. Change solutions you have seen<\/h3>\n<p>A good bridge between reading and writing is modification. Take working code and change the requirement. Make it return the last match instead of the first. Make it work on strings. Make it handle duplicates. Each change forces you to understand why the original lines are there.<\/p>\n<h2>Worked example: binary search, written in stages<\/h2>\n<p>Say you have read a binary search and can follow it. Here is how to move from that to producing a variant yourself. The task: given a sorted list, return the index of the <em>first<\/em> occurrence of a target, or -1 if absent.<\/p>\n<p><strong>Step 1: examples.<\/strong><\/p>\n<pre><code class=\"language-text\">[]               target 3  -> -1\n[3]              target 3  -> 0\n[3]              target 4  -> -1\n[1, 2, 2, 2, 5]  target 2  -> 1\n[1, 2, 3, 4, 5]  target 5  -> 4\n[1, 2, 3, 4, 5]  target 0  -> -1\n[1, 2, 3, 4, 5]  target 6  -> -1\n<\/code><\/pre>\n<p><strong>Step 2: plan in words.<\/strong><\/p>\n<ol>\n<li>Keep a range of positions that could still hold the answer.<\/li>\n<li>Look at the middle. If the middle value is smaller than the target, the answer is to the right; otherwise it could be the middle itself or to the left, so keep the middle and discard everything to its right.<\/li>\n<li>When the range has one candidate left, check whether it equals the target.<\/li>\n<\/ol>\n<p>The point of the &#8220;otherwise&#8221; rule is that you do not stop when you find the target; you keep narrowing left, which is what finds the <em>first<\/em> one.<\/p>\n<p><strong>Step 3: code, one comment at a time.<\/strong><\/p>\n<pre><code class=\"language-python\">def first_index(nums, target):\n    \"\"\"Index of the first occurrence of target in sorted nums, or -1.\"\"\"\n    lo, hi = 0, len(nums)          # search in [lo, hi)\n    while lo &lt; hi:\n        mid = (lo + hi) \/\/ 2\n        if nums[mid] &lt; target:\n            lo = mid + 1\n        else:\n            hi = mid\n    if lo &lt; len(nums) and nums[lo] == target:\n        return lo\n    return -1\n<\/code><\/pre>\n<p><strong>Step 4: run the examples.<\/strong> All seven examples were run; each returned the expected value, for instance <code>[1, 2, 2, 2, 5]<\/code> with target 2 gives 1 and the empty list gives -1.<\/p>\n<p><strong>Step 5: the memory test.<\/strong> The next day, close this page and write it again from the examples and your three-line plan. If you get stuck, note where: usually it is the half-open range <code>[lo, hi)<\/code> and whether to write <code>hi = mid<\/code> or <code>hi = mid - 1<\/code>. That exact spot is what to practice. The AlgoCademy <a href=\"https:\/\/algocademy.com\/link\/?lang=py&amp;problem=lower-bound&amp;solution=1\">lower bound<\/a> lesson is this same problem, and <a href=\"https:\/\/algocademy.com\/link\/?lang=py&amp;problem=binary-search&amp;solution=1\">binary search<\/a> is the base version if you want to start there.<\/p>\n<h2>Mistakes that keep the gap open<\/h2>\n<ul>\n<li><strong>Re-reading instead of retrieving.<\/strong> Re-reading feels productive and mostly builds familiarity. Writing from memory builds ability.<\/li>\n<li><strong>Looking at the solution too soon.<\/strong> Give yourself a fixed struggle time, such as 20 minutes, before looking, and then read only the first hint rather than the entire solution.<\/li>\n<li><strong>Copying code you do not own.<\/strong> Typing out a solution you have not tried to produce yourself is still recognition.<\/li>\n<li><strong>Doing too many different problems.<\/strong> A pattern needs a handful of repetitions across variations. Three binary search variants beat thirty problems you never revisit.<\/li>\n<li><strong>Waiting until you feel ready.<\/strong> The feeling of readiness comes after the writing, not before.<\/li>\n<li><strong>Treating lookups as failure.<\/strong> Professionals check documentation constantly. What you want to be able to produce unaided is the structure of the solution; exact method names can be looked up.<\/li>\n<\/ul>\n<h2>How long it takes<\/h2>\n<p>There is no honest universal number. What changes with practice is that more of the common pieces become automatic, so you stop spending attention on them. You will notice it in small ways: you stop looking up how to loop over a dictionary, then you stop needing a plan for simple problems, then you start recognizing the pattern from the problem statement. A realistic target for a week is one or two problems you can solve, from nothing, twice in a row on different days.<\/p>\n<p>If you want step-by-step practice where you write the code yourself and get checked immediately, AlgoCademy&#8217;s <a href=\"https:\/\/app.algocademy.com\/\">interactive lessons<\/a> are built that way, and the approach above works with any source of problems.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Why reading code feels easy and writing it feels impossible, and a practical routine to close the gap: retrieval practice, plan first, build in small steps.<\/p>\n","protected":false},"author":1,"featured_media":7311,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23],"tags":[],"class_list":["post-7312","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-problem-solving"],"_links":{"self":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts\/7312"}],"collection":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/comments?post=7312"}],"version-history":[{"count":1,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts\/7312\/revisions"}],"predecessor-version":[{"id":8694,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts\/7312\/revisions\/8694"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/media\/7311"}],"wp:attachment":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/media?parent=7312"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/categories?post=7312"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/tags?post=7312"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}