Demos

CodeSkulptor

These are some exceptional programs made by our students.

Bunny's Big AdventureJenna NetlandRiceFall 2012
Rice RacerSteve KnockCourseraFall 2012
Star WarsSteve KnockCourseraFall 2012
Elemental Tower DefenceScott ReynoldsCourseraFall 2012
Psychedelic 1D Cellular AutomataScott ReynoldsCourseraFall 2012
Tile FloodSergey EfimovCourseraSpring 2013
Game of LifeJonathon NixonCourseraSpring 2013
Py*bertJeff BottsCourseraSpring 2013
DDR cloneEmily WachtelCourseraSpring 2013
The DescentJiaqi LiuRiceFall 2013
Analog ClockKostya ShkryobCourseraFall 2013
Rubik's CubeKaren Ward & Dennis della CorteCourseraFall 2013
Galaxy InvadersIgor PetetskihCourseraFall 2013
PangEnder KasimCourseraFall 2013
Sine Wave TextJason ButwellCourseraSpring 2014
Card AnimationSimon NicholsonCourseraSpring 2014
HexVladimir CvetkovicCourseraSpring 2014
Lunar LanderJohn ZavadilCourseraSpring 2014

The following demos illustrate some of the features of CodeSkulptor, emphasizing the interactive aspects provided by its SimpleGUI module.

Draggable map magnifierUses mouse control.
Craps dice gameUses simple control elements. Prints output to console.
Sprite sheet animation
Tetris prototypeUse left & right arrows to move sideways, up & down arrows to rotate.
Simple music playerUses buttons and sounds. Note: The sample .ogg sounds are not supported in Safari.
Doodle Jump prototypeUse arrows to move.

CodeSkulptor provides the SimpleGUI module for interactive programs. However, SimpleGUI is available only inside CodeSkulptor. Pygame is a commonly-used (but significantly more complex) module for interactive programs in Python. The following resources describe how to port programs from SimpleGUI to Pygame.


From SimpleGUI to Pygame — Kevin Byiers, Coursera, Fall 2012

From SimpleGUI to Pygame (videos) — Julie Stoltz and Andrew Sadavoy, Spring 2013

CodeSkulptor provides the SimpleGUI module for interactive programs. However, SimpleGUI is available only inside CodeSkulptor. tkinter is a commonly-used (but significantly more complex) module for interactive programs in Python. The following resources describe how to port programs from SimpleGUI to tkinter.

Examples of converting SimpleGUI code into tkinter, Bill, Fall 2012 & Spring 2013

Here are some examples of converting code from using SimpleGUI to Python's default GUI, tkinter. I'm not a programmer so don't expect any coding wizardry, but I think these examples will help people looking for a different GUI they can use outside this class. To use these you'll need to go to the CodeSkulptor link and copy the code into a new window in IDLE or another Python environment. I suggest naming them like I did, but that's up to you. These were coded in Python 3.2.3. Python 3 uses the module name tkinter, whereas Python 2 uses the module name Tkinter. Thus, you'll need to edit the module name to run in Python 2. In later examples, I'll show you how to write your code to run in both versions without an edit.

Remember that while the example programs are provided as CodeSkulptor links, they will not run in CodeSkulptor since they use tkinter, not SimpleGUI.

sg_tick_tkinter.pyConverts Scott Rixner's SimpleGUI tick function to use tkinter.Details
sg_tick_tkinter_add_tb.pyIntroduces two new tkinter widgets: Frame and Text.Details
sg_calculator_tkinter.pyDemonstrates tkinter widgets Frame, Button, Label, Entry, Text and Scrollbar by converting Joe Warren's calculator example to tkinter.Details
sg_calculator_tkinter_error_check.pyAdds Python error checking for divide-by-zero and for non-numerical input. Student project: Extend the error-checking messages.Details
sg_calculator_tkinter_fonts.pyAdds font support for Buttons and shows Scrollbar layout error.Details
sg_calculator_tkinter_fonts_layout.pyUses multiple frames to fix the scrollbar problem.Details
sg_welcome.pyConverts the Codeskulptor “Welcome!” home page to tkinter. Introduces the Canvas widget and writing text to the canvas.Details
import_example.pyExplains import library vs. import library as x vs. from library import * and shows a sample error.Details
z_flag_norway_sudan.pyDraws line and polygon shapes to make flags on two Canvas widgets. Runs in both Python 2 and Python 3 without edits.Details
z_flag_maldives.pyAdds more shapes on the Canvas. Introduces drawing arcs, ovals, and circles andetting a closer color match.Details
tk_radiobutton_example.pyIntroduces the Radiobutton widget, shown in two modes. This is a very important widget for many forms.Details
tk_graphical_rpsls.pyConverts “Rock-Paper-Scissors-Lizard-Spock” (RPSLS) project to tkinter, with basic graphics. Includes a Scott Rixner mode.Details
tk_gtn.pyGraphical version of “Guess the Number” project. Much better layout of Canvas and Frame (Figured THAT out, finally.)Details
tk_scale_0.pyPer a request from a student, I made a demo of the Scale widget. You can use this in “Guess the Number” to avoid input errors, plus learn another cool graphical interface.Details
tk_list_selection_example_0.pyDemonstrates capturing mouse clicks, per a student request.Details

Using Pystep to understand basic Python

One surprising fact about interactive programming in Python is that moderately sophisticated interactive programs can be constructed using only a very small subset of Python. Before tackling interactive programming, we will focus on learning a small, but useful, subset of Python 2. With Pystep, our approach to learning Python will be to break this subset of Python into five levels, each introducing some new basic functionality of Python.

To support this learning process, we have created a tutorial program called

Pystep — https://py2.codeskulptor.org/#demos-pystep.py.

Pystep supports the five language levels shown below that correspond to increasingly larger subsets of Python. For each language level, Pystep contains multiple examples that illustrate the structure and behavior of the particular language features associated with that level. You will continue to use CodeSkulptor for the development and testing of your Python code. We suggest that you start by reviewing the short summary of the basic features of Pystep and then experiment with the examples below.

Each of these five levels of Python correspond to a half-week of material. In particular, the first 2.5 weeks of An Introduction to Interactive Programming in Python focuses on the following features of Python.

Summary of Pystep features

Selecting the language level and example

Users can select the language level and various examples from that level using the two buttons in the control area on the upper right-hand side. The name of the example is echoed in the message pane above the main coding pane in the middle of the frame. Pystep supports two methods for exploring the structure and behavior of basic Python programs at a particular language level.

Visualizing the structure of the example

Learning to write valid Python programs requires us to understand the structure of Python programs. In particular, Python programs consist of a collection of components such as statements and expressions. To visualize the structure of these components, users can navigate the example programs using the arrow keys. Using the up or down arrow keys selects the preceding or following line, respectively, of the Python program. Using the left or right arrow key selects various components that comprise a particular line of Python code. The selection pane in the lower right-hand portion of the frame contains information about the current selection and other kinds of Python statements or expressions that could be used in place of the current selection.

Evaluating the example program

Pystep includes three buttons on the left-hand side control area that enable the user to evaluate the example Python program in a controlled manner. The “Step” button takes the current Python programs and reduces it to simpler Python program that produces an equivalent result. Although modern implementations of Python (such as CodeSkulptor) do not evaluate programs in this manner due to efficiency considerations, this idea of repeatedly reducing a program to a simpler program has the advantage that it makes understanding the behavior of simple Python programs much easier for novice programmers. The “Unstep” button allows the previous “Step” to be undone, while the third button allows reloading of the current example.

Level 0 — Expressions (Week 0a)

Example: hello_world

In Python, a program consists of a sequence of statements. When executing a program, Python executes each statement in the program one after the other (sequentially). Executing different kinds of Python statement causes Python to perform different actions. For language level zero, we only consider one kind of Python statement, the print statement. To begin, load the first example at language level zero, hello_world, into Pystep.

print "Hello world" 

For level zero, most of our example programs will consist of a single print statement. At this point, we suggest that you experiment with the left and right arrow keys for a moment. Note that when the entire statement is selected (the entire line is red), the selection pane shows that the selected component is a statement whose particular instance is print. Now, pressing the right arrow key selects the expression "Hello world". The selection pane notes that this expression is a “string_value” with a particular instance of "Hello world".

To evaluate this Python statement, next press the “Step” button in the left-hand control area. When evaluating a print statement, Python repeatedly reduces the expression associated with the print to a increasingly simple equivalent expressions until no further simplification is possible. At this point, the expression is a value. In this example, "Hello world" is already a value so pressing the "Step" button causes Python to execute the print statement and print the value "Hello world" in the console of the underlying CodeSkulptor window, just as executing this Python program in CodeSkulptor would. In this example, "Hello world" is a particular type of value known as string. We will return to strings later.

Example: print_numbers

As part of this level, we will focus on understanding the most common kind of expressions in Python, arithmetic values or numbers, and the arithmetic expressions built from numbers. In Python, there are two types of numbers, int — corresponding to integers, and float — corresponding to real numbers. The second example print_nunbers has expressions of both types.

print 42
print 3.14

Stepping through this example prints out the numbers 4 and 3.14 in the console.

Examples: print_exp1, print_exp2

As in a calculator, we can construct more interesting arithmetic expressions in Python using arithmetic operators. Pystep includes several examples that illustrate the basic strategy for creating arithmetic expressions in Python. A arithmetic expression is either a number or a binary arithmetic operator applied to two arithmetic sub-expressions. We suggest that you use the left and right arrow keys to select the various arithmetic expressions (and sub-expressions) in these examples and note some of the possible operators in basic Python. These basic arithmetic operations include plus +, minus -, times *, division /, power **, integer division // and remainder %. The minus operator - can also be unary (i.e., take one argument), but we'll just represent that operation in binary form as multiplication by -1 for now. The functions int and float convert other kinds of data (such as strings) into ints and floats.

Python computes the value of arithmetic expression by repeatedly reducing the expression to a simpler expression until the expression is number. Python selects an arithmetic operator whose associated arithmetic expressions are numbers and then applies the operator to the numbers to compute the numerical value of the expression. When choosing between several options for which expression to evaluate, Python typically choose the leftmost unevaluated expression. We suggest that you experiment with “Step” and “Unstep” on these examples to better understand this process of evaluation for arithmetic examples.

Examples: my_name_is, convert_to_numbers, my_number_is, print_winner

To conclude, we return to examples with strings. The string "hello_world" is a value since Python cannot simplify this expression further. However, we can also construct string expressions using string operations in manners similar to that for arithmetic expressions. For example, string concatenation + takes two strings and joins them to form a single string. The example my_name_is illustrates this concept. The operator str converts other types of data such a number into a string in the example convert_to_numbers. The example my_number_is combines this concept with string concatenation to do some simple string processing. The final example print_winner uses multiple print statements to generate several lines of output to the console.

Level 1 — Variables and assignments (Week 0b)

Example: my_name_is_variable

Using only print statements, we can't form interesting computations. In Python, the assignment statement allows us to attach the value of an expression to a variable for later use in subsequent expressions. This statement will expand the range of possible Python programs to a much more interesting set of programs. To begin, consider the example my_name_is_variable at language level one.

# An assignment statement using a string
name = "Joe"
print "My name is", name

You can use the left and right arrows key to explore the structure of the assignment statement. Executing the assignment statement via “Step” causes the variable name to take on the value "Joe". Pystep visualizes this definition in the variable pane where the variable namecode> is shown as having the value "Joe" of type string. Now, when an expression using a variable is encountered during subsequent evaluation, Python looks up the value of the variable and substitutes that value in place of the variable. The expression is then evaluated as usual. In the example, the instance of name in the print statement is replaced by its value "Joe" during one step of evaluation.

Examples: fahrenheit_to_celsius, circle_area, triangle_area

More generally, the right-hand side of an assignment statement can be an expression. Python evaluates the assignment statement by first evaluating its associated right-hand-side expression and then storing its value in the variable on the left-hand side. The third line in the next example fahrenheit_to_celsius illustrates this case when the right-hand side of an assignment statement contains a complex expression. Note that Pystep repeatedly reduces this expression to a simpler equivalent expression before assigning the resulting value to the variable celsius. The remaining examples include multiple variables and multiple assignments used to specify more complicated computations.

As a note, Python variable names consist of alphanumeric character and the underscore "_" character. Variable names must begin with an alphanumeric character. Also, observe that, for statements, the selection pane now has three instances, print, comment and assignment. Technically, comments are not statements in Python. (During stepping, Pystepem> ignores comments.) However, we have included them here for convenience to better illustrate the structure of a Python program.

Level 2 — Functions (Week 1a)

Example: double

In several of the previous examples such as fahrenheit_to_celsius, we constructed a chunk of Python code that performed some useful computation that we might wish to carry out multiple times. Instead of copying the code, the standard solution in modern computing is to define a function that carries out the action of the code. For the fahrenheit_to_celsius example, this function would take fahrenheit as input and then compute and return the corresponding Celsius temperature. Here is a simple example of a function double defined via a function definition statement of the form

def double(x):
    return 2 * x

The indented statement in this example is the body of the function. (In general, the body of a Python function is a sequence of indented statements.) The return statement instructs Python that 2 * x is the value returned by the function double. Given this definition, we can call the function double later in the program via an expression of the form double(2). The example "double" illustrates this process.

# A function that doubles a number
def double(x):
    return 2 * x
print double(1 + 1)

The process by which Python evaluates a function call is fairly straightforward, but has multiple steps. We will use Pystep to illustrate this process visually. In particular, let's step through the program above. The first step of execution defines the function double. Note that the variable pane now has a definition for double of type <funct>. The next step evaluates the right-hand side of the print statement, double(1 + 1). To evaluate the expression double(1 + 1), Python first evaluates its argument 1 + 1 and reduces the expression to double(2).

Next, Python evaluates the function call double(2). This evaluation is by far the most complex process that we have studied up to now. To make this process more transparent, we will explain this process as a transformation into an equivalent Python program involving the body of the function and some extra assignement statements. It is important to note that, in reality, Python does not evaluate a function in this manner. Instead, the following explanation is designed to provide a simple equivlaent mental model for the novice seeking to understand function evaluation.

To visualize the first step of evaluation of the function call double(2), Pystep applies the following transformations to the program:

  • Replace the function call double(2) by a new variable double₀,
  • Prepend the body of double to the top of the current program,
  • Create an assignment of the parameter x to the corresponding value 2 from the function call,
  • Prepend this assignment to the top of the current program,
  • Replace the return 2 * x statement by a pair of statements, double₀ = 2 * x and return double₀.

The resulting program has the following form:

x₁ = 2
double₀ = 2 * x₁
return double₀
print double₀

You should use “Step” and “Unstep” to move back and forth between the program before the body of double is inserted and after the body of is inserted. Walk through the items above to make sure that you understand the transformation entailed in this single step.

Before proceeding with the evaluation of this program, we note that the subscripted variables introduced into the program are new variables created to store values generated and used in evaluating double. The subscript indicates the call level associated with the variable (the number of function calls pending when the variable was created). Observe that the variable x₁ is local to the definition of double since x₁ is used purely inside the definition of double. double₀ is a temporary variable that stores the value returned by function evaluation for later use at the function call location. This temporary variable has subscript zero to indicate that it exists outside the body of the function call. (Note that double₀ is an artifact of our visualization of function evaluation. In actual Python function evaluation, the return value is directly substituted for the function call.)

At this point, evaluation of the program via stepping proceeds as usual. Observe that Pystep has inserted a blue line to separate the code add to the front of the program in response to the function call from the remainder of the code. When Pystep executes a return statement, this statement alerts Python that evaluation of the function is completed and Python then deletes all code up to the blue line. At this point, the variable double₀ contains the value returned by the function call and the print statement then prints 4 in the console.

Examples: fahrenheit_to_kelvin, triangle_area_function

Functions in Python may call other functions leading to a sequence of pending function calls as illustrated during the evaluation of the fahrenheit_to_kelvin example. In that example, we have defined two functions: one function f2c that converts temperatures from degrees Fahrenheit to degrees Celsius and a second function f2k that converts from degrees Fahrenheit to Kelvin with the help of f2c. Note that functions may also have more than one parameter such as illustrated in the triangle_area_function example.

Example: print_name

Besides returning a value, Python functions may also have side effects like printing out a message. In the example, print_name, we provide a function that take the string name and prints the string expression "My name is " + name to the console. In this example, the call to the function print_name is both an expression and a statement. Since function calls need not return a value, we use the return statement without a return expression to return from the function call. In this case, Python returns the special value None by default to indicate that no value was returned.

Level 3 — Logic and conditionals (Week 1b)

Example: True_False

The programs that we are capable of constructing in our subset of Python are still fairly uninteresting. In particular, the sequence of statements executed by Python does not depend on the actual values used in the computation. In language level three, we will extend the types of data that we consider to include a new binary data type called Booleans. (The corresponding type in Python is bool.) The two Boolean values are True and False. We begin by noting that Python programs can print and assign Boolean values in the same manner as numbers and strings. For example,

print True, False

prints out the Boolean values True and False as expected.

Examples: boolean_expressions, is_positive

Boolean values can combined using the three Boolean operators and, or and not. The example boolean_expressions contains several examples of Boolean expressions. Boolean values can also be created by comparing other types of data. In particular, we will often compare numbers using relational comparisons such as ==, !=, < and >. These operators take two numbers and return a Boolean value. (Relation comparisons also work on strings.) The example is_positive defines a simple function that returns True if an input number is positive and False otherwise.

Example: absolute_value

The main use of Boolean values is to control the sequence in which Python executes statements. For now, we will focus on three related types of conditional statements: if statements, else statements and elif statements. A sequence of these statements forms a compound statement consisting of an if statement followed by zero or more elif statements followed by an optional else statement. In Python, if statements have the form

if condition:
    body

Note that body of the if statement corresponds to a sequence of indented Python statements (similar to the body of a function definition). You may use the left and right arrow keys to explore the structure of the if statement. To execute an if statement, Python first evaluates the Boolean expression that forms the condition. If the condition evaluates to True, Python executes the body of the if statement. If the condition evaluates to False, the body is ignored. An else statement has the form:

else:
    body

else statements (when needed) always follow either an if statement (or an elif statement). The body of the else statement also consists of a sequence of indented Python statements. The body of the else statement is executed its preceding if statement's condition evaluates to False. The example absolute_value illustrates the use of an if and else statement. Note that Pystep first evaluates the condition for the if statements and then replaces the if and else statements by the appropriate body.

Examples: sign, military_time

In many situations, we wish to select among more than two choices. For this situation, we suggest using one or more elif statements in conjunction with if and else statements. An elif statement has the form:

elif condition:
    body

elif statements always follow either an if statements or another elif statement. If the conditions for the preceding sequence of if/elif statements all evaluate to False, the condition for the elif is evaluated. If the condition evaluates to True, the body of the statement is executed. Otherwise, any following elif and else statements are then executed. The example sign uses an if-elif-else sequence to return -1 when an input number is negative, 0 when the number is zero and 1 when the number is positive. The example military_time illustrates the use of a longer chain of conditionals to convert military time to twelve-hour time.

Example: factorial

The final factorial example demonstrates that the combination of functions and conditionals is surprisingly powerful. The factorial function in this example calls itself conditionally based on the value of its input. This idea of a function calling itself is known as recursion. While we won't leverage the power of recursion in this course, recursion is a critical tool in many more advanced computer applications.

Level 4 — Local and global variables (Week 2a)

Example: circle_area_function

For language level four, we will broaden the capabilities of Python slightly and consider the kinds of variables that we can use in creating programs. At level one, assignments to variables outside functions generated global variables whose values can be referenced anywhere inside the program, even inside the body of a function. In the example circle_area_function, the variable PI references the global version of the variable. (Note the absence of a subscript in Pystep.) Global variables can be referenced before, during and after a functional call.

Example: cylinder_volume

At language level two, we observed that the parameters of the function have the property that they are local to the body of the function and can only be accessed/updated inside the function body. In many case, we would like to create other variables that are local to the function to temporarily hold value that are useful in the function. In Python, assignment to a variable inside a Python function creates a local version of the variable. In the example cylinder_volume, we observe that the assignment to area creates a new variable with subscript one to indicate that this variable is local to the function. Observe that, as we step through this example, once evaluation of the function is completed, the local definition disappears.

Example: fahrenheit_to_kelvin2

One obvious question at this point is: What happens if we try to assign to an existing global variable inside the body of a function? In Python, this assignment creates a new local copy of the variable even if a global version of the variable already exists. In the example fahrenheit_to_kelvin2, assignment to the variable c inside the function f2k creates a new local copy of c inside f2k. (Note that this local version has subscript one). The global version of c persists through evaluation of the call to f2k and is referenced later in the final print.

Example: player_is_ready

However, in some cases, we would like to modify the value of a global variable inside a Python function. Since, by default, an assignment creates a local variable in a function, placing a global statement in that function instructs Python to treat any assignments to the specified variable(s) in the function as assignments to the global version of the variable. In the example player_is_ready, assignment to the variable message inside the function ready does not create a new local variable due to the global statement inside the function. We will make use of global variables inside functions substantially in this class since, early in the class, our primary mechanism for communicating information between the various event handlers controlling interactive program will be global variables. Later in the class, we will introduce object-oriented methods for reducing our reliance on global variables.

The CodeSkulptor documentation was built by John Greiner.