Skip to content

Commit f11c530

Browse files
author
Philip Guo
committed
more simplification of lessons.html and associated files
1 parent f4656fd commit f11c530

4 files changed

Lines changed: 51 additions & 160 deletions

File tree

v3/app.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ handlers:
1818
- url: /example-code
1919
static_dir: example-code
2020

21+
- url: /lessons
22+
static_dir: lessons
23+
2124
- url: /.*
2225
script: pythontutor.app
2326

v3/js/opt-lessons.js

Lines changed: 38 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -31,173 +31,61 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3131

3232
var backend_script = 'exec'; // URL of backend script, which must eventually call pg_logger.py
3333

34-
var appMode = 'edit'; // 'edit' or 'visualize'
35-
36-
3734
var myVisualizer = null; // singleton ExecutionVisualizer instance
3835

39-
function enterEditMode() {
40-
$.bbq.pushState({ mode: 'edit' }, 2 /* completely override other hash strings to keep URL clean */);
41-
}
42-
43-
44-
var pyInputCodeMirror; // CodeMirror object that contains the input text
45-
46-
function setCodeMirrorVal(dat) {
47-
pyInputCodeMirror.setValue(dat.rtrim() /* kill trailing spaces */);
48-
}
49-
50-
51-
$(document).ready(function() {
52-
53-
pyInputCodeMirror = CodeMirror(document.getElementById('codeInputPane'), {
54-
mode: 'python',
55-
lineNumbers: true,
56-
tabSize: 2,
57-
// convert tab into two spaces:
58-
extraKeys: {Tab: function(cm) {cm.replaceSelection(" ", "end");}}
59-
});
60-
61-
pyInputCodeMirror.setSize(null, '450px');
62-
63-
64-
65-
// be friendly to the browser's forward and back buttons
66-
// thanks to http://benalman.com/projects/jquery-bbq-plugin/
67-
$(window).bind("hashchange", function(e) {
68-
appMode = $.bbq.getState('mode'); // assign this to the GLOBAL appMode
69-
70-
// default mode is 'edit'
71-
if (appMode == undefined) {
72-
appMode = 'edit';
73-
}
74-
75-
// if there's no myVisualizer, then default to edit mode since there's
76-
// nothing to visualize:
77-
if (!myVisualizer) {
78-
appMode = 'edit';
79-
$.bbq.pushState({ mode: 'edit' }, 2 /* completely override other hash strings to keep URL clean */);
80-
}
81-
82-
83-
if (appMode == 'edit') {
84-
$("#pyInputPane").show();
85-
$("#pyOutputPane").hide();
86-
}
87-
else if (appMode == 'visualize') {
88-
$("#pyInputPane").hide();
89-
$("#pyOutputPane").show();
90-
91-
$('#executeBtn').html("Visualize execution");
92-
$('#executeBtn').attr('disabled', false);
93-
94-
95-
// do this AFTER making #pyOutputPane visible, or else
96-
// jsPlumb connectors won't render properly
97-
myVisualizer.updateOutput();
98-
99-
// grab focus so that keyboard events work
100-
myVisualizer.grabKeyboardFocus();
101-
102-
// customize edit button click functionality AFTER rendering (TODO: awkward!)
103-
$('#pyOutputPane #editBtn').click(function() {
104-
enterEditMode();
105-
});
106-
107-
}
108-
else {
109-
assert(false);
110-
}
111-
});
112-
113-
// From: http://benalman.com/projects/jquery-bbq-plugin/
114-
// Since the event is only triggered when the hash changes, we need
115-
// to trigger the event now, to handle the hash the page may have
116-
// loaded with.
117-
$(window).trigger( "hashchange" );
118-
119-
120-
$("#executeBtn").attr('disabled', false);
121-
$("#executeBtn").click(function() {
122-
$('#executeBtn').html("Please wait ... processing your code");
123-
$('#executeBtn').attr('disabled', true);
124-
$("#pyOutputPane").hide();
125-
126-
127-
$.get(backend_script,
128-
{user_script : pyInputCodeMirror.getValue(),
129-
cumulative_mode: $('#cumulativeMode').prop('checked')},
130-
function(dataFromBackend) {
131-
var trace = dataFromBackend.trace;
132-
133-
// don't enter visualize mode if there are killer errors:
134-
if (!trace ||
135-
(trace.length == 0) ||
136-
(trace[trace.length - 1].event == 'uncaught_exception')) {
137-
138-
if (trace.length == 1) {
139-
var errorLineNo = trace[0].line - 1; /* CodeMirror lines are zero-indexed */
140-
if (errorLineNo !== undefined) {
141-
// highlight the faulting line in pyInputCodeMirror
142-
pyInputCodeMirror.focus();
143-
pyInputCodeMirror.setCursor(errorLineNo, 0);
144-
pyInputCodeMirror.setLineClass(errorLineNo, null, 'errorLine');
145-
146-
pyInputCodeMirror.setOption('onChange', function() {
147-
pyInputCodeMirror.setLineClass(errorLineNo, null, null); // reset line back to normal
148-
pyInputCodeMirror.setOption('onChange', null); // cancel
149-
});
150-
}
151-
152-
alert(trace[0].exception_msg);
153-
}
154-
else {
155-
alert("Whoa, unknown error! Reload to try again, or report a bug to philip@pgbovine.net\n\n(Click the 'Generate URL' button to include a unique URL in your email bug report.)");
156-
}
157-
158-
$('#executeBtn').html("Visualize execution");
159-
$('#executeBtn').attr('disabled', false);
36+
function parseLessonFile(dat) {
37+
var toks = dat.split('======');
38+
var lessonScript = toks[0].rtrim();
39+
var metadataJSON = $.parseJSON(toks[1]);
40+
console.log(lessonScript);
41+
console.log(metadataJSON);
42+
43+
$.get(backend_script,
44+
{user_script : lessonScript},
45+
function(dataFromBackend) {
46+
var trace = dataFromBackend.trace;
47+
48+
// don't enter visualize mode if there are killer errors:
49+
if (!trace ||
50+
(trace.length == 0) ||
51+
(trace[trace.length - 1].event == 'uncaught_exception')) {
52+
53+
if (trace.length == 1) {
54+
alert(trace[0].exception_msg);
16055
}
16156
else {
162-
myVisualizer = new ExecutionVisualizer('pyOutputPane',
163-
dataFromBackend,
164-
{embeddedMode: true});
165-
166-
$.bbq.pushState({ mode: 'visualize' }, 2 /* completely override other hash strings to keep URL clean */);
57+
alert("Whoa, unknown error! Reload to try again, or report a bug to philip@pgbovine.net\n\n(Click the 'Generate URL' button to include a unique URL in your email bug report.)");
16758
}
168-
},
169-
"json");
170-
});
59+
}
60+
else {
61+
myVisualizer = new ExecutionVisualizer('pyOutputPane',
62+
dataFromBackend,
63+
{embeddedMode: true});
64+
65+
myVisualizer.updateOutput();
66+
67+
// grab focus so that keyboard events work
68+
myVisualizer.grabKeyboardFocus();
69+
}
70+
},
71+
"json");
72+
}
73+
74+
$(document).ready(function() {
17175

76+
$.get("lessons/aliasing.txt", parseLessonFile);
17277

17378
// log a generic AJAX error handler
17479
$(document).ajaxError(function() {
17580
alert("Server error (possibly due to memory/resource overload).");
176-
177-
$('#executeBtn').html("Visualize execution");
178-
$('#executeBtn').attr('disabled', false);
17981
});
18082

18183

18284
// redraw connector arrows on window resize
18385
$(window).resize(function() {
184-
if (appMode == 'visualize') {
86+
if (myVisualizer) {
18587
myVisualizer.redrawConnectors();
18688
}
18789
});
18890

189-
$('#genUrlBtn').bind('click', function() {
190-
var urlStr = $.param.fragment(window.location.href,
191-
{code: pyInputCodeMirror.getValue(),
192-
curInstr: (appMode == 'visualize') ? myVisualizer.curInstr : 0,
193-
mode: appMode,
194-
cumulative_mode: $('#cumulativeMode').prop('checked')
195-
},
196-
2);
197-
$('#urlOutput').val(urlStr);
198-
});
199-
200-
201-
$.get("example-code/aliasing.txt", setCodeMirrorVal);
20291
});
203-

v3/lesson.html

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,6 @@
6767

6868
</div>
6969

70-
<div id="pyInputPane">
71-
72-
<div id="codeInputPane"></div> <!-- populate with a CodeMirror instance -->
73-
74-
<p>
75-
<button id="executeBtn" class="bigBtn" type="button">Visualize execution</button>
76-
</p>
77-
78-
</div>
79-
8070
<div id="pyOutputPane">
8171
</div>
8272

v3/lessons/aliasing.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
x = [1, 2, 3, 4, 5]
2+
y = x
3+
z = [1, 2, 3, 4, 5]
4+
x.append(6)
5+
======
6+
{
7+
"1": "execution point one",
8+
"2": "execution point two",
9+
"4": "execution point four"
10+
}

0 commit comments

Comments
 (0)