The following demos illustrate some of the features of CodeSkulptor, emphasizing the interactive aspects provided by its SimpleGUI module.
These are some exceptional programs made by our students.
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.
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.
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.py
— Converts Scott Rixner's SimpleGUI tick
function to use tkinter.
More details
sg_tick_tkinter_add_tb.py
— Introduces two new tkinter widgets:
Frame
and Text
.
More details
sg_calculator_tkinter.py
— Demonstrates tkinter widgets Frame
,
Button
, Label
, Entry
,
Text
and Scrollbar
by converting
Joe Warren's calculator example to tkinter.
More details
sg_calculator_tkinter_error_check.py
— Adds Python error checking
for divide-by-zero and for non-numerical input.
Student project: Extend the error-checking
messages.
More details
sg_calculator_tkinter_fonts.py
— Adds font support for Button
s
and shows Scrollbar
layout error.
More details
sg_calculator_tkinter_fonts_layout.py
— Uses multiple frames to fix the scrollbar problem.
More details
sg_welcome.py
— Converts the Codeskulptor “Welcome!”
home page to tkinter. Introduces the Canvas
widget and writing text to the canvas.
More details
import_example.py
— Explains import library
vs.
import library as x
vs.
from library import *
and shows a sample error.
More details
z_flag_norway_sudan.py
— Draws line and polygon shapes to make flags on two
Canvas
widgets.
Runs in both Python 2 and Python 3 without edits.
More details
z_flag_maldives.py
— Adds more shapes on the Canvas
.
Introduces drawing arcs, ovals, and circles and
getting a closer color match.
More details
tk_radiobutton_example.py
— Introduces the Radiobutton
widget, shown
in two modes. This is a very important widget for many forms.
More details
tk_graphical_rpsls.py
— Converts “Rock-Paper-Scissors-Lizard-Spock”
(RPSLS) project to tkinter, with basic graphics.
Includes a Scott Rixner mode.
More details
tk_gtn.py
— Graphical version of “Guess the Number”
project. Much better layout of Canvas
and
Frame
(Figured THAT out, finally.)
More details
tk_scale_0.py
— Per 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.
More details
tk_list_selection_example_0.py
— Demonstrates capturing mouse clicks, per a student request.
More details
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. Our approach to learning Python will be to break this subset of Python into five levels with each level containing some new basic functionality of Python.
To support this learning process, we have created a tutorial program called
Pystep — http://www.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.
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.
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.
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.
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.
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.
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.
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.
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
name
code> 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.
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.
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:
double(2)
by a new variable double0
,
double
to the top
of the current program,
x
to the corresponding value 2
from the function call,
return 2 * x
statement
by a pair of statements,
double0 = 2 * x
and
return double0
.
The resulting program has the following form:
x1 = 2 double0 = 2 * x1 return double0 print double0
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 x1
is local to the definition of
double
since x1
is used purely inside the definition of double
.
double0
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 double0
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 double0
contains the value returned by the function call and the
print
statement then prints
4
in the console.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.