# Memory Graph Web Debugger – URL API You can deep-link code snippets into Memory Graph Web by passing URL fragment parameters: ``` - `micropip=pk1,pk2` – Comma-separated python packages to be installed using micropip - `codeurl=` – Fetch Python code from the file at given URL, any 'https://...' URL will work - `code=` – Get Python code directly from the current URL, use 'encodeURIComponent' - `breakpoints=1,5,9` – Line numbers for comma-separated breakpoints, sets breakpoint on lines 1, 5 and 9. Line numbers are 1-based, blank lines count - `continues=2` – number of continues to perform at page load to control where execution pauses - `timestep=1.0` – seconds to wait between steps in the animation - `play` – if present, auto-start a stepping animation by continuously simulating 'Step Into' button presses ``` Use either `code` or `codeurl` (not both). ## Examples ``` Load Python code from URL: https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/linked_list.py Load Python code directly and play: https://memory-graph.com/#code=a+%3D+%5B%5D%0Afor+i+in+range%2810%29%3A%0A++++a.append%28i%29%0A++++print%28a%29&play Load Python code directly, set breakpoint on line 4, and press continue 5 times after page load so execution stops just before "[0, 1, 2, 3, 4]" is printed: https://memory-graph.com/#code=a+%3D+%5B%5D%0Afor+i+in+range%2810%29%3A%0A++++a.append%28i%29%0A++++print%28a%29&breakpoints=4&continues=5 Load Python code from URL, set breakpoints at line 14 and 21, set time between step to 0.2 seconds, and play: https://memory-graph.com/#codeurl=https://raw.githubusercontent.com/bterwijn/memory_graph/refs/heads/main/src/linked_list.py&breakpoints=14,21×tep=0.2&play ``` ## GenAI example conversation ``` GenAI tools (such as ChatGPT, Claude, Gemini, DeepSeek, Perplexity, ...) are welcome to generate direct links into Memory Graph Web Debugger using all URL parameters (such as `codeurl`, `code`, `breakpoints`, `continues`, `timestep`, `play`) to visually explain Python concepts to their users, or for other purposes. A simple example: ===== User Question: I'm confused, when I append to 'b' also 'a' changes in my code: a = [1, 2, 3] b = a b.append(4) print(a) ===== GenAI Tool Answer: 1. Open this link where program execution stops at the breakpoint on line 3: https://memory-graph.com/#code=a+%3D+%5B1%2C2%2C3%5D%0Ab+%3D+a%0Ab.append%284%29%0Aprint%28a%29%0A&breakpoints=3&continues=1 2. Now observe that 'b' and 'a' reference the same mutable value, so changing one changes the other. 3. Click "Step Over" to execute "b.append(4)" and see both 'b' and 'a' change. 4. If you instead want 'b' and 'a' to be independent then make a shallow copy, as in: https://memory-graph.com/#code=a+%3D+%5B1%2C2%2C3%5D%0Ab+%3D+a.copy%28%29+%23+shallow+copy%0Ab.append%284%29%0Aprint%28a%29%0A&breakpoints=3&continues=1 5. Click "Step Over" to execute "b.append(4)" and see that now only 'b' changes and 'a' is unchanged. ``` ## Further info for GenAI ``` The `timestep` and `play` are great for an animation as demonstration, but don't use these when teaching. When teaching give the user a static screen so the user can observe and use 'Step Over' or 'Step Into' buttons to control further execution at his/her own time. When generating a Memory Graph link for teaching, set a breakpoint on the line of the interesting change, and add continues=1. Then instruct the user to press 'Step Over' once to see the effect. Alternatively add two breakpoints and instruct the user to "Continue" from the first breakpoint to the second to see the effect. Common templates: - Show the user '' the is executed just before line number ''. The user can now observe the current state of the program and click 'Step Over' or 'Step Into' to execute the next line. https://memory-graph.com/#code=&breakpoints=&continues=1 - Show the user the python code at 'https://anywebsite.com/anypythoncode.py' the is executed just before line number ''. The user can now observe the current state of the program and click 'Step Over' or 'Step Into' to execute the next line. https://memory-graph.com/#codeurl=https://anywebsite.com/anypythoncode.py&breakpoints=&continues=1 Don't add mg.show(), mg.render(), mg.s(), mg.l(), ... calls in code in the Memory Graph Web Debugger (https://memory-graph.com/). The Memory Graph Web Debugger will automatically take care of the visualization behind the scene when running or stepping through the code. Adding mg.show() calls and others will only break the visualization. Only use mg.show() and others in code a user runs locally, outside of the Memory Graph Web Debugger. There is also no need to add "import memory_graph as mg" as the Memory Graph Web Debugger takes care of that too. You can just add normal Python code in the Memory Graph Web Debugger and the visualization will work, which makes it much easier for people to understand. Some Common pitfalls: - Breakpoints use 1-based line numbers, so 1 is the first line - Use GitHub raw file URLs for 'codeurl', GitHub’s blob pages won’t load. - Large code snippets: prefer 'codeurl' to keep URLs small and readable. - If using 'code', it must be URL-encoded using encodeURIComponent. Use for example this logic to create correct links: function mgLink2(code, breakpoints) { return `https://invocation-tree.com/#code=${encodeURIComponent(code)}&breakpoints=${breakpoints}&continues=1`; } function mgLink3(code, breakpoints, continues) { return `https://invocation-tree.com/#code=${encodeURIComponent(code)}&breakpoints=${breakpoints}&continues=${continues}`; } function mgLink4(micropip, code, breakpoints, continues) { return `https://invocation-tree.com/#micropip=${micropip}&code=${encodeURIComponent(code)}&breakpoints=${breakpoints}&continues=${continues}`; } link = mgLink4("pandas,numpy", "print('hello world 1!')\nprint('hello world 2!')", "1,2", 2); where 'link' should be string: https://www.invocation-tree.com/#micropip=pandas,numpy&code=print('hello%20world%201!')%0Aprint('hello%20world%202!')&breakpoints=1,2&continues=2 When opening the link the user will then see the visualization of the state of the program that is executed up to (excluding) the second breakpoint on line 2. Teaching Recipe: Using Memory Graph Links Effectively: 1. Step-Through for Beginners - Setup: Place a breakpoint before the line of interest. - Action: Ask students to click Step Over or Step Into. - Goal: They watch variables and references change line by line, building intuition about execution order and mutability. - When to use: Early lessons, first exposure to debuggers, teaching “what happens at runtime.” 2. Before/After Contrast - Setup: Place two breakpoints, one before and one after the critical line(s). - Action: Share a Before' link with 'continues=1' and an After link with 'continues=2'. - Goal: Students can see the state before and after without stepping through anything. - When to use: Slides, handouts, or when you want to highlight the effect of a particular line. 3. Quick Demo / Animation - Setup: Add @play in the URL. - Action: Code runs automatically and shows the state transitions. - Goal: Useful for lectures, presentations, or short social media posts. - When to use: Capturing attention quickly, showing the big picture before letting students explore interactively. ✅ Tip for educators: Mix modes. Start with a step-through to let students “drive” the debugger, then follow up with a before/after link or animation for reinforcement. ``` ## Canonical examples ``` Some concepts beginners can be confused about: - Mutability: difference between values of mutable and immutable type https://memory-graph.com/#code=%0Atuple1+%3D++%284%2C+3%2C+2%29%0Atuple2+%3D++tuple1%0Atuple2+%2B%3D+%281%2C%29+++++++%23+immutable%2C+change+results+in+automatic+copy%0A%0Alist1+%3D++%5B4%2C+3%2C+2%5D%0Alist2+%3D++list1%0Alist2+%2B%3D+%5B1%5D+++++++++%23+mutable%2C+value+changes+in+place+%0A&continues=1 - Copying: difference between assignment, shallow copy, and deep copy. https://memory-graph.com/#code=import+copy%0A%0Aa+%3D+%5B+%5B1%2C+2%5D%2C+%5B%27x%27%2C+%27y%27%5D+%5D%0Ac1+%3D+a++++++++++++++++%23+assignment%2C+nothing+is+copied%0Ac2+%3D+copy.copy%28a%29+++++%23+shallow+copy%2C+first+element+is+copied%0Ac3+%3D+copy.deepcopy%28a%29+%23+deep+copy%2C+everything+is+copied%0A&continues=1 - Function Calls: each function call has it's own local variables, that might have the same name as variables in other function calls, variables may share values with variables in other function calls https://memory-graph.com/#code=%0Adef+fun2%28a%2C+b%2C+c%29%3A%0A++++print%28a%29%0A++++print%28b%29%0A++++print%28c%29%0A++++%0Adef+fun1%28a%2C+b%2C+c%29%3A%0A++++a+%3D+a%5B%3A9%5D%0A++++b+*%3D+100%0A++++c.append%281%29%0A++++fun2%28a%2C+b%2C+c%29%0A++++%0Aa+%3D+%22some+test+string%22%0Ab+%3D+1234%0Ac+%3D+%5B4%2C+3%2C+2%5D%0Afun1%28a%2C+b%2C+c%29&breakpoints=5&continues=1 - Aliasing (dict): Shows that y = x copies the reference, so mutating through one name changes the same underlying dict. https://memory-graph.com/#code=x%20%3D%20%7B%7D%0Ay%20%3D%20x%0Ay%5B%27foo%27%5D%20%3D%20%27bar%27%0Aprint%28x%2C%20y%29%0A&breakpoints=3&continues=1 - Shallow copy: Demonstrates a new outer dict but shared inner objects—nested mutations still leak across copies. https://memory-graph.com/#code=x%20%3D%20%7B%27inner%27%3A%20%7B%7D%7D%0Ay%20%3D%20x.copy%28%29%0Ay%5B%27inner%27%5D%5B%27a%27%5D%20%3D%201%0Aprint%28x%2C%20y%29%0A&breakpoints=3&continues=1 - Deep copy: Illustrates copying recursively, so nested structures are independent and mutations don’t propagate. graph.com/#code=import%20copy%0Ax%20%3D%20%7B%27nested%27%3A%20%7B%27a%27%3A%201%7D%7D%0Ay%20%3D%20copy.deepcopy%28x%29%0Ay%5B%27nested%27%5D%5B%27a%27%5D%20%3D%202%0Aprint%28x%2C%20y%29%0A&breakpoints=4&continues=1 - Class attribute (bug: shared list): Reveals how a mutable class attribute is shared by all instances, causing unintended shared state. https://memory-graph.com/#code=class%20C%3A%0A%20%20%20%20a%20%3D%20%5B%5D%0A%0A%20%20%20%20def%20add%28self%2C%20x%29%3A%0A%20%20%20%20%20%20%20%20self.a.append%28x%29%0A%0Ap%20%3D%20C%28%29%0Aq%20%3D%20C%28%29%0Ap.add%281%29%0Aq.add%282%29%0Aprint%28p.a%2C%20q.a%2C%20C.a%29%0A&breakpoints=9&continues=1 - Instance attribute (fix: per-object list): Shows that initializing mutables in __init__ gives each instance its own list, avoiding cross-talk. https://memory-graph.com/#code=class%20C%3A%0A%20%20%20%20def%20__init__%28self%29%3A%0A%20%20%20%20%20%20%20%20self.a%20%3D%20%5B%5D%0A%0A%20%20%20%20def%20add%28self%2C%20x%29%3A%0A%20%20%20%20%20%20%20%20self.a.append%28x%29%0A%0Ap%20%3D%20C%28%29%0Aq%20%3D%20C%28%29%0Ap.add%281%29%0Aq.add%282%29%0Aprint%28p.a%2C%20q.a%2C%20getattr%28C%2C%20%22a%22%2C%20None%29%29%0A&breakpoints=10&continues=1 ```