Python Project
This is a pair assignment worth 150
points.
100 points for the project. 50 points for the presentation.
The program
should begin with a comment including your names,
a brief description of what the program does and information on any
help you received on
the project. If it
is entirely your own
work, say so. If
anyone helped either of you,
identify them by name and describe how they helped.
Also identify how you helped others.
One partner should submit the file or files for your
project.
If you have multiple project files, combine them into a zip file.
Note
special
requirements
due to this being a possibly large and open-ended project:
Include a README.txt file that explains how to run your program in
detail, with all the steps to get going, in order. In
particular
with multiple files, what IS the main program? You do not
need to
repeat explicit prompts in your program. In general make sure
you
turn in
every
file you need
to run your program. For instance you have a graphics program
and
use graphics.py, turn in graphics.py. If you have a web
project,
make sure you turn in the localCGIServer.py program and all your
templates.... An exception is if you need special packages installed
(like Python 2.6 + PyGame). In such a case be
sure to mention it in the instructions, including download URL's. In
this case with special package download instructions, please talk with
me about arranging to
demo your project in Adobe Connect.
In addition,
everyone should separately
submit a personal log. Note this is a little
more elaborate than previous logs. Include the following:
- Roughly how long you worked for the project (including
class time)
- Briefly, how it went for you, for instance what was the
hardest part to get ...
- Who your partner was if you had one, or "No partner"
- If you had a partner, give an indication of how things went
with your partner. Was working together a good
thing? If
you worked remotely with a partner, how did that go?
This is an open ended assignment. You can do a graphics
program,
a dynamic web program, or some other Python program.
Some
very different (and
increasingly
more difficult) possibilities are mentioned below.
If you
would
like to do something else, read the section on Alternatives at the end
.
Some things are feasible and others are not. You
may not have enough experience to know the difference. Also
it is important to find a way to break the project into a sequence of
steps where you can check yourself before adding too much.
Particularly if you suggest a unique project, discuss this
all with me before you make your written submission of a plan!
Look on the schedule for all the dates that incremental work is due:
- Plan
for a
project: If you are going to do a canned topic from below,
this
can be one line.
If you are making up your own thing, please give me enough detail to
get an idea of it and to try to figure out how feasible it is.
- Outline
of steps to be
completed and target dates
- descriptions of steps that can be
completed and checked
individually
- dates for the steps to be completed: The
final project is
not an assignment to start the evening it is due!
- Display major
steps completed -
me meeting with you and seeing
- Final project
due
Project Ideas
Hangman
There are so many Python Hangman games out there, that
you may only select this option if you do something substantively
different in your program. This may be something different in the
graphics, in the options, in the feedback, etc. Please check with
me!! You do NOT want to submit a project that I find online, even
with minor modifications! You will get a zero if that happens!
That being said, there is scope for a lot of creativity using the
Hangman game.
Code the classic hangman game, where the computer
selects a word randomly from a list, and the player guesses letters,
with a limit for the number of wrong letter guesses, displayed
somehow. Correct guesses need to be indicated
positionally.
For instance for the secret word "program", if the player has correctly
guessed nothing, display underscores for all 7 letters:
_ _ _ _ _ _ _
Later if the user has correctly selected
r,
you should display something like
_ r _ _ r _ _
and then if
g
is selected,
_ r _ g r _ _
.... This display is the trickiest part of a basic version.
The basic version needs neither the web nor graphics, so you can do it
on any kind of computer.
Elaborations
after
you get a
basic text version working:
- display bad past choices or remaining choices
- multiple games with score kept,
- choice of easier and harder versions with words of
different
difficuly levels,
- text graphics or regular graphics just for a hangman image,
or
- (lots of extra credit) a totally graphics based version,
where
the alphabet is shown in
little boxes on the graphics screen and the used just clicks on the
next letter chosen.....
- (alos lots of extra credit) fancier version on the web,
possibly
with Hangman images. The web
verson could involve typing a letter choice or clicking a radio button
for the right letter....
A Graphics Game: Find the Hole
The program should use Zelle's graphics. Use a random number
generator to select a
point and a perhaps radius around that point. These determine the
target 'hole' and
are not revealed to the player. The user is then
permitted
to click around on the screen to “find the
hole”. You
should show each point the user tries immediately after the
click. Once the user
selects
a point that is within the chosen radius of the mystery point, the
circle should
appear.
There should be a message announcing how many steps it took.
Clicking to find the hole should stop after the hole is
found.
Tthe easiest way to do this is with
while loop
to drive the
repeated search for the hidden circle. The loop should stop
when
the hidden circle is located.
Hint:
If the distance
between
the hidden center and the latest mouse click is less than the radius of
your mystery circle, then the circle is "found". The
bounce2.py
example program has a function getShift to
calculate the difference (dx, yd) in the coordinates of
two points. You can either directly use or modify
getShift
to
calculate the distance from the Pythagorean Theorem: (dx*dx
+
dy*dy)**.5
Here are some enhancements to the hole finding game:
- You can make it more interesting by putting a limit on the
number
of tries the user can have. You could think about what would
be
reasonable – does it depend on the radius? On the number of
possible point? You still
need a while loop, but the condition is more complicated, with two
different reasons to be break out of the loop.
- Add extra graphical items like a display of the count of
the current number of tries.
- You might offer different levels of difficulty for playing
the game – fewer tries, a smaller circle, etc. Do NOT copy
sections of code to make the different levels! Use functions
and
parameters.
- You can always make it more visually appealing.
- You can permit the user to decide the number of games to
play and then display the best score.
- Program reading enhancement: encapsulate logical
unified
ideas in functions with parameter passing, particularly where the same
idea is used in different places with different data.
A grade of 80% (32) will be given for a program that correctly
satisfies the minimum requirements. Better grades will be
given
to projects that implement one or more enhancements and a nice user
interface. I suggest you write a little bit of the program at
a time, and test it after each small feature is added.
Web Mad Lib
Have several files with mad lib format strings in them. Chose
one at random. (See bullet 3 below.)
Dynamically
generate and
display a web form with all cues and with input fields for the user to
fill in. Process
the form and show the resulting mad lib. Go on to a further
random madlib....
Here is a progresson of programs going from limited credit to large
amounts of extra credit:
- Have a single predetermined madlib file and
explicitly
embed the key questions for that madlib in a form. This means
the user can start from the web form page. Important detail
for
later generalization: For each cue in the form, make the
visible
label include the cue in a standard pattern, and make the
field
name attribute be the cue. In the CGI script, put the cues
and
their responses into a dictionary, for use with the madlib format
string.
There
are two levels of embedding data into strings here: 1)
embedding
the madlib choices in the mad lib. 2) Embedding the mad lib
inside a web page. Make sure you see the difference and get
both
parts.
- Generalize to allow any mad lib format string, as
in madlib2.py. Initially you can choose a specific
mad lib
file, but as in madlib2.py, the idea is to not have any of the Python
code or web page templates have the cues hard coded into them.
Instead, as in madlib2.py, use my getKey function to extract
the
list of cues from the madlib, and process all the cues in for-loops.
There are two places you need to do this. Both
require a
serious understanding of madlib2.py, the CGI process, and for-loops:
- Extracting
data from the form:
This is actually the second place in the order of execution
of
the full program, but if you made the field names match the cues in the
first part, you can write and test this part next. To know
what
data to extract from the form, extract
the list of keys from the
madlib format file, and then read the values for those
keys from the
form
input. In madlib2.py, the user was queried and then dictionary entries
were made. In this case you still want to make the same sort
of
dictionary entries, but the data comes from the form, rather than
keyboard input. (Actually this step is not needed if the
user gives values for all keys, because the form object created by the
cgi module actually behaves like a dictionary already, but the format
operation fails if values are not given in the dictionary explicitly
for
each key. It is important to create a dictionary that has
some
entry for each key used in the madlib.)
- Getting
the cues into the inital form:
For the more general version, the form cannot be a fixed
page; it
must be generated dynamically to include all the proper cues for the
particular madlib file chosen. You must generate the page
from a
CGI script. Look at the source code of the html for
the
form in step 1(if you followed my suggestions), and see the pattern in
the sections that present a
single text field per key. Each such part can be created by
embedding a cue into a format string based on the html source code for
one entry. You can copy one entry out of the source
for the
form for part 1. You can loop
through all the cues and create a list of all the entries with the
proper cues. You can combine a
list of strings as you did in the joinAll.py exercise, or you can look
at the optional section on the string method join.
For both
part a and part b you need to have many of the same utility functions.
You can have two scripts with much duplicated code,
or both
parts can be in one CGI script if you
provide information to distinguish the two situations. An
obvious choice is to have a hidden variable put in the form that states
the madlib file name. If the cgi program starts without a key
associated with such a file name, then the initial form still needs to
be created (code of part b), and it needs to include a hidden variable
like madlibFile with the value of the madlib file name. If
the
script runs when the hidden variable is there, then you have
data from a form and can display the madlib with substitutions (code
from part a).
- Select the mad lib format
file at random in the
inital cgi program (part b above). If you have a list
aList of madlib filenames, then you can
import the random module and use random.shuffle(aList) to mutate the
list into a random order. Then aList.pop() returns the last
element,
which will be random, because of the shuffle.
- After
the user sees a
completed madlib let the user click to go on to a mad lib form
for
a different random
madlib. When
the user has done all the madlibs, you could tell the user
that there are no more madlibs available. A good way to
accomplish this is to make another hidden variable be the remaining
list of madlib file names, saved after they were shuffled and the
latest
file was popped out. Since the variables
must be strings, you need some of the string methods that we skipped in
Chapter 2, like split and join, or find with slicing. You
could
also set
things up to only have one hidden variable if it includes all the
remaining madlib file names and
the one you are working on at the moment.
Elaborated Pizza Web Program
Elaborate the pizza order web site in Tutorial section 4.3.5 so the
prices and the toppings are stored in a file or two files, and the
values are read in from the file(s) rather than being literal values in
the program. The manager's page should show a form at the top
of
the page listing the prices in text fields and a comma
separated
list of toppings in a text field. Allow the manager to edit
the data and press a
submit button to record the changes, so the the price and toppings file
or files are updated for subsequent custormer orders. You
can
choose the file format. (Discuss it with me.) The
manager form should still show the
already coded list of past orders. If the manager form is
submitted,
the
simplest thing forthe program to do is to go back to the customer order
form, showing
the new data.
Read the section below on further file methods.
This is quite an elaborate program. Only take it on
if you are looking for a
major challenge, because there is no obvious simpler version for
full
credit. Be sure to discuss with me the format of
your data
files and the overall flow of the code.
Alternatives ....
Are these too lame or canned or not your style? Suggest
something
different to
me!
You can start by discussing it orally with me, but before
final
approval, make a written specification for yourself and me, about as
specific as what is given for the problems above. The
specification is due as stated in the schedule. I am more
likely to accept a proposal if it includes a new use of a while-loop or
for-loop. Just a a long fixed sequence of steps, even with if
statements, is
not
likely
to
be accepted.
Here are some comments about particular situations that might be of use:
Further file reading operations
Thus
far you were only given the method to read a whole file at a time.
You
may also read a single line at a time with the file method readline().
A line
includes
its final
newline, but you can use the string method strip() to strip off all the
white space from both ends, including the newline. Example:
infile =
open('datafile.txt')
line =
infile.readline()
print('line 1 is
with whitespace removed from the ends:
', line.strip())
line =
infile.readline()
print('line 2 is
with whitespace removed from the ends:
', line.strip())
(You can also remove the final newline using the slice notation from
the optional sections of Chapter 2: line[:-1].)
If you are converting a line with the text of a single number
to a float
with the float constructor, the newline does not matter, since white
space is automatically stripped in the conversion. If
datafile has a
first line like 5.25, then the following code would read it and convert
it to a float:
infile =
open('datafile.txt')
line =
infile.readline()
val = float(line)
Fancy cgi programs with multiple calls to cgi scripts:
In a console Python application you might have something like:
s
= input("Enter ....')
# process s
print(....)
# something
using s
t = input("Enter
....')
# process with BOTH
s ans t
print
(....) # something
based on both s and t...
In a web based situation it is more complicated, because the server
does not automatically remember the data from an earlier server
call. Yo would need something more like this:
#Start
with cgi script that works at multiple stages of the input/output
sequence:
#....
s =
form.getFirst('s', '')
t =
form.getFirst('t', '')
# know where you are
by how many
of your variables have been defined
if s ==
'':
# ... print
initial form looking for s value
# for use in the next case....
elif t
== '':
# ... produce
page USING the value of s
# and also including a form REQUESTING
t,
# AND include
in the form a hidden variable 's'
# set to
the current value of
Python variable s
# (using
template substitution),
# for use in the
next case, with the
new t....
else:
# ...
generate page using s and t
This shows how to use a couple of pages in sequence. More
elif's
and more hidden variables needed for you to go further.....