Skip to content

Commit b2c0c80

Browse files
author
Philip Guo
committed
added a bunch of files
1 parent 5335a79 commit b2c0c80

File tree

147 files changed

+23884
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+23884
-0
lines changed

README

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
Online Python Tutor
2+
Copyright (C) 2010 Philip J. Guo ([email protected])
3+
https://github.com/pgbovine/OnlinePythonTutor/
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
======
19+
Introduction:
20+
21+
The Online Python Tutor is a web application where you can type Python
22+
scripts directly in your web browser, execute those scripts, and
23+
single-step FORWARDS AND BACKWARDS through execution in order to view
24+
the state of run-time data.
25+
26+
Using this application, teachers and students can write small Python
27+
code snippets together and see what happens to the data structures when
28+
the code gets executed.
29+
30+
---
31+
32+
Try it out live at: http://people.csail.mit.edu/pgbovine/python/
33+
34+
---
35+
Original vision (from January 2010):
36+
37+
I want to create a web-based interactive learning platform for students
38+
to explore programming. I envision an HTML UI where a student can enter
39+
in code and then single-step through it and see how the data structures
40+
change during execution.
41+
42+
I realized that for the small programs that students write, it might be
43+
possible to simply LOG all execution (and data structures) and then we
44+
can simply play it back with single-step forwards and also BACKWARDS
45+
46+
After all, we don't need students to be able to interactive probe and
47+
make changes in the middle of execution, which is the only value-added
48+
of a REAL debugger.
49+
50+
What kinds of things do we want to log?
51+
52+
On the execution of each line, log:
53+
- the line number just executed
54+
- all data created by the program
55+
56+
Also log calls and returns of a student's function
57+
(NOT library functions)
58+
59+
We can use the Python JSON module to encode data structures in JSON and
60+
send it to the client's web browser
61+
62+
The PDB debugger (Lib/pdb.py) is written in pure Python:
63+
http://docs.python.org/library/pdb.html
64+
- the bdb debugger framework is the C module that pdb calls
65+
http://docs.python.org/library/bdb.html
66+
67+
---
68+
69+
Informal system architecture overview --- sent in an email on 2010-09-05
70+
71+
'''
72+
i'll give you a bit of background on the architecture of the system:
73+
74+
1.) The front-end is HTML/javascript (using the jQuery library) ... it's
75+
responsible for the input text box, submitting the Python code (as
76+
plaintext) to the backend, receiving an execution trace from the
77+
backend, and then rendering that trace as data structure visualizations.
78+
all the front-end code is already publicly available in these 5 files:
79+
80+
http://people.csail.mit.edu/pgbovine/python/index.html
81+
http://people.csail.mit.edu/pgbovine/python/jquery-1.3.2.min.js
82+
http://people.csail.mit.edu/pgbovine/python/jquery.textarea.js
83+
http://people.csail.mit.edu/pgbovine/python/edu-python.js
84+
http://people.csail.mit.edu/pgbovine/python/edu-python.css
85+
86+
87+
2.) The back-end is a server-side app that takes Python script source
88+
code as input, executes the entire script (up to 100 executed lines, to
89+
prevent infinite loops), and collects a full trace of all variable
90+
values after each line is executed. It then sends that trace to the
91+
front-end in an encoded JSON format. The front-end then parses that
92+
trace, which is how it's able to single-step forwards AND backwards
93+
through execution.
94+
95+
The back-end currently runs on my server, and I think the most
96+
convenient thing to do right now is to simply invoke it as a web
97+
service. This is the URL:
98+
99+
http://people.csail.mit.edu/pgbovine/python/cgi-bin/web_exec.py
100+
101+
and it expects only ONE following parameter to be passed in via POST.
102+
that parameter is called 'user_script', and it's a string that contains
103+
the text of the script to be executed. so the interface is pretty
104+
simple ;)
105+
'''
106+

TODO

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
A disorganized collection of TODOs, bug reports, and suggestions from friends
2+
---
3+
4+
Ideas for programming tutorials
5+
- Could do a track on more advanced Python concepts for people who are
6+
already pretty comfortable with programming ... an intro to Python
7+
for programmers
8+
9+
10+
Don't display boilerplate code when classes are being initialized
11+
12+
13+
Rob Miller's suggestions for handling aliasing:
14+
15+
'''
16+
Incidentally, for the aliasing example, it might help if you strive to
17+
have one object be the "official" one, in a sense, and make the aliases
18+
to it look different. For example, the x list would be displayed
19+
normally, but the y list might be displayed faded out (with a little
20+
note that says "this is the same object as x above"). Mousing over the
21+
x list or y list might highlight its aliases.
22+
23+
That would reinforce the fact that there's only one object in memory.
24+
We usually do that on the blackboard -- draw only one object, and have
25+
arrows from x and y pointing to that single object.
26+
'''
27+
28+
29+
Hubert's suggestions for permalinks:
30+
'''
31+
Hubert: 1) It would be cool to have the ability to link directly to an
32+
execution point, so that when I send you a link, you could see the code
33+
I'd written and the point in execution that I want to discuss.
34+
35+
me: good suggestion. that also requires me to save your code in
36+
something other than a regular POST variable, which i'm not doing right
37+
now. then i could send links of the following form:
38+
39+
http://python.pgrind.com/code_id=20#4 (for line 4 of code snippet 20)
40+
41+
Hubert: yup, yeah the problem lies in storing the code, which brings in
42+
a whole can of worms. but suppose you did, consider a RESTful approach
43+
(which I am drilling into deeply, hence it's on my mind):
44+
45+
http://python.pgrind.com/pg/code/20#4
46+
47+
...quite easy to do and manage in a framework like Django.
48+
'''
49+
50+
51+
Cory: 'Might be nice to be able to automatically jump to particular step
52+
# rather than just inc/decrement and jump to ends, particular if the
53+
number of steps executed is significant.'
54+
55+
56+
Maybe integrate in this snazzy code EditArea, if it doesn't look too ugly:
57+
(ugh kinda cheesy tho)
58+
http://www.cdolivet.com/index.php?page=editArea&sess=3a3d89b7ef37aa5f74d6d4682aeda876
59+
60+
61+
Deployment on Google App Engine for scalability
62+
http://code.google.com/appengine/docs/python/runtime.html
63+
- the main issue is whether their restricted Python will allow us to
64+
run 'import bdb' and other necessary modules
65+
- could try to get Sal Khan to pay for my hosting if I host it
66+
alongside Khan Academy
67+
- could store analytics and user data in Google's db
68+
69+
70+
Related work:
71+
- PyWhip: http://pywhip.appspot.com/
72+
- also powered by Google App Engine
73+
- Crunchy: http://code.google.com/p/crunchy/
74+
75+
76+
From Hubert, regarding rendering linked structures vs. using
77+
containment:
78+
'''
79+
i totally agree with the sentiment that if you're not ever going to use it (for
80+
any binding of "it"), don't add the complexity. i sympathize with the laziness
81+
argument, that it's easy to do HTML tables than arrowheads, but if you change
82+
your mind, consider using HTML5's canvas -- many browsers support it.
83+
regarding the aliasing, from an epistemological standpoint, do you foresee that
84+
you'll have to cover the difference between passing by reference vs by value?
85+
this was a rather big stumbling block for me when learning Python, having come
86+
from C where the different passing styles are syntactically explicit. i
87+
recognize that the current visualizations don't depict argument passing, so it
88+
may be moot. but one cheap trick you can explore is to "color" identical
89+
objects with the same color, so that if a data structure appears in multiple
90+
places, it is colored differently, if they are indeed different objects.
91+
'''
92+
93+
---
94+
2010-09-05
95+
96+
From an email from Peter Wentworth ([email protected])
97+
98+
'''
99+
I'd like to see the heap explicitly represented, so that mutable
100+
structures like lists are created in the heap rather than "in the stack
101+
frame". Passing a list as an argument then becomes "pass the
102+
reference".
103+
104+
I appreciate that you do have the id tags to indicate which are the
105+
aliases, but I think the instructional value would be even more
106+
compelling to see some pointers referencing the same underlying object.
107+
'''
108+
109+
---
110+
From Hacker News feedback:
111+
112+
- support for raw_input() sounds like something reasonable to include,
113+
though, since it could simply pop up a text box and ask the user to
114+
input a string e.g., javascript:alert("hello, " + prompt("what is your
115+
name?"))
116+
117+
---
118+
2010-09-29
119+
120+
Chas Leichner ([email protected]) emailed me to show me his related
121+
project:
122+
123+
http://www.youtube.com/watch?v=ZiS4MZF5eDQ
124+
http://code.google.com/p/idlecarpentry/
125+
126+
He had an interesting idea of annotating lines of code with special
127+
comments, and those comments would display when those lines were being
128+
executed. That way, you can have sorta like 'literate programming
129+
tutorials' that intermix code and comments. I could think about
130+
implementing something similar within my Online Python Tutor.
131+
132+
e.g.,
133+
134+
#> declare a variable
135+
x = 5
136+
137+
#> an if statement tests a condition
138+
if x < 5:
139+
y = x + 5
140+
else:
141+
y = x - 5
142+
143+
the appropriate annotations would display when you stepped through the
144+
line of code immediately below each annotation.
145+
146+
---
147+
2011-01-16
148+
149+
Bug report from Peter Wentworth
150+
151+
'''
152+
I also have what I think is a bug report: your front-end javascript treats variables with the value None as if they are undefined. (They are reflected in the trace that we get from the server.)
153+
154+
X = 123
155+
z = 'hello'
156+
x = None
157+
y = 123
158+
159+
del y
160+
print(x)
161+
print(type(x))
162+
163+
---
164+
I changed your script - around line 293 of edu-python.js, you have a condition checking for undefined (search for the comment containing “which is OKAY!”). I just eliminated the check, and can’t figure out which cases I might have broken it for!
165+
'''
166+
167+
---
168+
2011-05-23
169+
170+
Bug report from Peter Wentworth
171+
172+
'''
173+
Hi Philip
174+
175+
I hope you are keeping well!
176+
177+
Scripts fail in the visualizer when the user has a variable called “length”, because somehow the front-end jquery is doing something wrong. It happens both when used as a local or as a global variable. See my image of what is happening on your site. (Tried in both Firefox and Internet Explorer).
178+
179+
It looks like a jquery bug (I haven’t tried moving to a newer version – I’m using 1.3.2 that I got from your version).
180+
181+
The iterators + lambda functions appear to be misbehaving when varname has the value “length”.
182+
So I’ve had to rip out the iterators and gone for vanilla javascript loops, which has solved it for me.
183+
184+
I’ve done changes similar to this in 4 places in function updateOutput in file edu_python.js
185+
186+
187+
// $.each(curTrace[i].globals, function(varname, val) {
188+
// // eliminate duplicates (act as an ordered set)
189+
// if ($.inArray(varname, orderedGlobals) == -1) {
190+
// orderedGlobals.push(varname);
191+
// curGlobalFields[varname] = undefined; // 'unset it'
192+
// }
193+
// });
194+
195+
for (varname in curTrace[i].globals) {
196+
// eliminate duplicates (act as an ordered set)
197+
if ($.inArray(varname, orderedGlobals) == -1) {
198+
orderedGlobals.push(varname);
199+
curGlobalFields[varname] = undefined; // 'unset it'
200+
}
201+
}
202+
203+
Regards
204+
205+
Peter
206+
'''
207+

cgi-bin/.htaccess

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Options +ExecCGI
2+
AddHandler cgi-script .py

cgi-bin/create_db.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Setup sqlite database for optional query logging
2+
3+
from db_common import *
4+
import os
5+
6+
# the 'post_date' field is stored as an int representing GMT time since
7+
# the UNIX epoch; to convert to localtime in sqlite, use:
8+
# SELECT datetime(1092941466, 'unixepoch', 'localtime');
9+
10+
def create_db():
11+
assert not os.path.exists(DB_FILE)
12+
(con, cur) = db_connect()
13+
cur.execute('''CREATE TABLE query_log
14+
(id INTEGER PRIMARY KEY,
15+
post_date TEXT,
16+
ip_addr TEXT,
17+
user_agent TEXT,
18+
input_script TEXT,
19+
had_error INTEGER)''')
20+
con.commit()
21+
cur.close()
22+
23+
if __name__ == "__main__":
24+
create_db()
25+
print 'Created', DB_FILE
26+

cgi-bin/db_common.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Setup sqlite database for optional query logging
2+
3+
import sqlite3
4+
5+
DB_FILE = 'edu-python-log.sqlite3'
6+
7+
def db_connect():
8+
con = sqlite3.connect(DB_FILE)
9+
cur = con.cursor()
10+
return (con, cur)
11+

0 commit comments

Comments
 (0)