|
6 | 6 | <title>Python Code Editor - Practice Questions</title> |
7 | 7 | <link rel="stylesheet" href="css/style.css"> |
8 | 8 | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
9 | | - <!-- PyScript for running Python in browser --> |
10 | | - <link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css"> |
11 | | - <script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script> |
| 9 | + <!-- Skulpt for fast Python execution in browser --> |
| 10 | + <script src="https://cdn.jsdelivr.net/npm/skulpt@1.2.0/dist/skulpt.min.js" defer></script> |
| 11 | + <script src="https://cdn.jsdelivr.net/npm/skulpt@1.2.0/dist/skulpt-stdlib.js" defer></script> |
12 | 12 | </head> |
13 | 13 | <body> |
14 | 14 | <nav class="navbar"> |
@@ -124,53 +124,60 @@ <h3><i class="fas fa-terminal"></i> Output</h3> |
124 | 124 | </div> |
125 | 125 | </div> |
126 | 126 |
|
127 | | - <!-- PyScript code execution --> |
128 | | - <script type="py" config='{"packages": []}' id="python-runner" style="display: none;"> |
129 | | -from js import document, console |
130 | | -import sys |
131 | | -from io import StringIO |
132 | | -import traceback |
133 | | - |
134 | | -def run_user_code(): |
135 | | - output_div = document.getElementById("output") |
136 | | - loading_div = document.getElementById("loading") |
137 | | - |
138 | | - # Get code from editor |
139 | | - code = document.getElementById("code-editor").value |
140 | | - |
141 | | - # Show loading |
142 | | - loading_div.style.display = "block" |
143 | | - output_div.innerHTML = "" |
144 | | - |
145 | | - # Capture stdout |
146 | | - old_stdout = sys.stdout |
147 | | - sys.stdout = StringIO() |
148 | | - |
149 | | - try: |
150 | | - # Execute the code |
151 | | - exec(code, {}) |
| 127 | + <!-- Skulpt Python execution helper --> |
| 128 | + <script> |
| 129 | + // Skulpt output handler |
| 130 | + function outf(text) { |
| 131 | + const output = document.getElementById('output'); |
| 132 | + const existingPre = output.querySelector('pre.output-success'); |
| 133 | + if (existingPre) { |
| 134 | + existingPre.textContent += text; |
| 135 | + } else { |
| 136 | + output.innerHTML = '<pre class="output-success">' + text + '</pre>'; |
| 137 | + } |
| 138 | + } |
152 | 139 |
|
153 | | - # Get output |
154 | | - output = sys.stdout.getvalue() |
| 140 | + function builtinRead(x) { |
| 141 | + if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined) |
| 142 | + throw "File not found: '" + x + "'"; |
| 143 | + return Sk.builtinFiles["files"][x]; |
| 144 | + } |
155 | 145 |
|
156 | | - # Display output |
157 | | - if output: |
158 | | - output_div.innerHTML = f'<pre class="output-success">{output}</pre>' |
159 | | - else: |
160 | | - output_div.innerHTML = '<div class="output-info">Code executed successfully (no output)</div>' |
| 146 | + // Run Python code using Skulpt |
| 147 | + window.runPythonCode = function(code) { |
| 148 | + const output = document.getElementById('output'); |
| 149 | + const loading = document.getElementById('loading'); |
161 | 150 |
|
162 | | - except Exception as e: |
163 | | - # Display error with traceback |
164 | | - error_msg = traceback.format_exc() |
165 | | - output_div.innerHTML = f'<pre class="output-error"><strong>Error:</strong>\n{error_msg}</pre>' |
166 | | - |
167 | | - finally: |
168 | | - # Restore stdout |
169 | | - sys.stdout = old_stdout |
170 | | - loading_div.style.display = "none" |
171 | | - |
172 | | -# Make function available globally |
173 | | -window.run_user_code = run_user_code |
| 151 | + // Show loading |
| 152 | + loading.style.display = 'block'; |
| 153 | + output.innerHTML = ''; |
| 154 | + |
| 155 | + // Configure Skulpt |
| 156 | + Sk.configure({ |
| 157 | + output: outf, |
| 158 | + read: builtinRead, |
| 159 | + __future__: Sk.python3 |
| 160 | + }); |
| 161 | + |
| 162 | + // Run the code |
| 163 | + Sk.misceval.asyncToPromise(function() { |
| 164 | + return Sk.importMainWithBody("<stdin>", false, code, true); |
| 165 | + }).then( |
| 166 | + function(mod) { |
| 167 | + // Success |
| 168 | + loading.style.display = 'none'; |
| 169 | + const outputContent = output.querySelector('pre'); |
| 170 | + if (!outputContent || !outputContent.textContent.trim()) { |
| 171 | + output.innerHTML = '<div class="output-info">Code executed successfully (no output)</div>'; |
| 172 | + } |
| 173 | + }, |
| 174 | + function(err) { |
| 175 | + // Error |
| 176 | + loading.style.display = 'none'; |
| 177 | + output.innerHTML = '<pre class="output-error"><strong>Error:</strong>\n' + err.toString() + '</pre>'; |
| 178 | + } |
| 179 | + ); |
| 180 | + }; |
174 | 181 | </script> |
175 | 182 |
|
176 | 183 | <script src="js/progress.js"></script> |
|
0 commit comments