amarquis has asked for the
wisdom of the Perl Monks concerning the following question:

The situation: I've a sister over a decade my junior, 9th grade, who is looking for a science fair project. Neither the teacher's suggestions nor ideas she found via internet search excited her, so we were kicking ideas around. Based on her desires (something different / unique) and knowledge (beginner Perl programmer, just basic operations and ideas like variables, arithmatic, etc.) I suggested a computer science project.

So we popped online and looked at ideas, but the wall we are hitting is that neither of us is really sure what a good project is, in terms of scope. What is too much work, and what too little, for a beginner? Ideas so far that piqued her interest:

Something with board games and AI. Perfect play with a trivial game seems too modest a project, but even a small sub-problem of a more difficult game seems daunting. Regardless, ideas along this line seemed most exciting to her, out of the options we looked at.

Question number one to the monks: Do you think we're in the difficulty ballpark here, given limited Perl experience and the 9th grade level? The school doesn't really give guidelines as to how "big" the project should be, but based on looking around at the science fair last year I'd guess the median to be around 100ish student-hours. Well, the median of the not "slapped-together-last-night" projects.

Also, if you've other ideas, please share them. I think our best bet might be finding a difficulty appropriate board game / AI problem, but she seems open to anything interesting.

Update: Thank you to everyone who has provided perspective/ideas. Going to point my sister to this thread and see what she thinks.

I might suggest the old animal guessing game. The program has a list of questions with yes/no answers and a binary tree that leads to the animal that fits the answers to the questions. If the user thinks of an animal that it can't guess, it requests a question to distinguish it from it's best guess and updates its tree.

The solution for this one involves decision processing (if/else), looping and loop termination, at least one search algorithm (binary), decision trees, and other topics at the core of CS. Using a program to study the algorithm might be sufficient for part or all of a project of this size, depending on the skill and experience of your sister.

Something with board games and AI. Perfect play with a trivial game seems too modest a project

I disagree. For a 9th grade that's not so very easy. For example Tic-tac-toe has 0.3M possible game plays, so one could implement searching in the tree, and then using symmetry to reduce the the tress size. You have to know how to backtrack, build and traverse a tree. That might seem trivial to us, but isn't for somebody who has never done it before.

Another game that might be interesting and not too hard if done imperfectly is Connect Four, but I wouldn't inflect that on a 9th grade.

I think that's quite a nice one, because you can get a result rather quickly, but still can optimize quite much (for example you can use a dictionary, digraph and trigraph tables that you build from the dictionary etc, but you already get some intermediate results for longer encrypted texts by using very simple approaches).

The computer science club at my college used to (perhaps still does) host a programming contest for high school students. While the participants were under a more compressed time frame, the assumption that we made for the easiest program was if/then/else and a loop construct of some sort. More advanced problems included nested control structures, switch statements, text processing (think split and join), and other problems that are easily programmed multiple times a day by anyone who does a modest amount of programming.

Remember that this should stretch the capabilities of the student, not stress them to the point of breaking :)

Go is probably too complicated, and tic-tac-toe has some subtleties, but one thing that might be interesting and not too hard is to build a simple game, like nim, with *learning* capability. It's been a long while since I did this but I recall that it just involved making a tree structure to store possible moves, storing the results as a score, and then doing a tree traversal to see what gives you the highest or lowest "Score". Look up something called a "minmax" algorithm.
(although you'll find a bunch of people have done this particular one already)
The game of "mastermind" might also be a good balance of easy to program and interesting, although not so easy to do a tree for.
PS It's not perl but take a look at the Alice language from CMU. Makes it easy to do visuals to go with a game.

The encryption idea was my favorite, because based on how fast the base part of the project got done there is a lot of room to spend time making it smarter and faster.

Good points about tic-tac-toe, which was actually the game I had in my head while writing. My worry, I think, might be the difficulty convincing an older science teacher with limited domain knowledge that the problem is hard enough for a science fair project.

My sister mentioned the game of go, because she plays, but I don't think we could come up with an appropriate problem. Even small problems, like for example life and death of stones, are really hard. Limiting the game to a board small enough to be searched, you get into gross ruleset specific distinctions.

Depending on how your sister implements it, the project could teach basic game theory, recursion, a-b pruning, and other advanced (for high school, and somewhat for early college) topics. Show the teacher some of the classic literature, and how even something as "simple" as the Missionaries and cannibals problem can be mapped into the same problem space.

Perhaps the game is not the way to present it to the teacher, but the way the game is solved.

Good points about tic-tac-toe, which was actually the game I had in my head while writing. My worry, I think, might be the difficulty convincing an older science teacher with limited domain knowledge that the problem is hard enough for a science fair project.

I think that shouldn't be a blocker. People can be dealt with, if you know how ;-)

Some people are easily impressed by numbers. For example the game could have a small counter telling you that there are $n possible game plays left, and $n starts at 300k. That demonstrates that the program does really much work.

I assume that she has to write some kind of description, and if that nicely illustrates the search trees, that could convince other teachers.

Again others are impressed by everything that computers do, those should be the easiest to convince.

There are two problems in Go that I would think might be appropriate (assuming that 9th grade == somewhere around about age 14).

The first, and the easiest to demonstrate because it's quickest, would be figuring out whether a move results in a group that is entirely surrounded and can be removed from the board.

The second, which builds on that, would be to implement a board on which two people can play, with the computer removing prisoners during play as above, but also spotting and not allowing other illegal moves such as suicide or repetition. Don't worry about the ruleset distinctions - just pick one and go with it.

I'm probably biased by my high school experiences with science fairs, and getting knocked out in the regionals by someone who just wrote software to make a picture move around on a computer screen. (which by the posing of their problem, should've been categorized as 'biology').

... but I'm of the opinion that a good science fair project uses the scientific method, and isn't just the 'can I build something?' type project. By that definition, consider what the question is that you're trying to answer, and what your hypothesis and null hypothesis might be:

Can a computer beat a teenage human player in (some game?)

Will (x strategy) beat (y strategy) in (some game?)

Can a computer distinguish between four authors (of some genre/time period/etc) using text analysis?

...

And don't forget that you'll need to consider not just the time to write the program, but to conduct the experiment as well ... hopefully, at least 30 times per group, which might make my first phrasing of the game idea problematic.

For any of the AI projects, this can be "does the AI beat a random player"? Mostly, I think this wouldn't be too interesting (a checkers player with any brain ought to beat a random player every time), but I think tic-tac-toe might have an interesting result (the random player may win by chance once in a while).

If you want to get the "wow" factor from a science project.... use a gui of some sort. Of course I recommend Tk or Gtk2. ;-) How about something cool like simulating an instrument on a satellite and logging the data on a strip chart recorder on earth? See Tk Realtime data aquisition Maybe monitor solar wind? You could connect right to the spacecraft data-servers like solar data server Have the data recorder and maybe make a 2-d visualization of the magnetosphere at the current moment, that could be done with animated gifs.

One that is more real-life, and could lead to a career, is setup a linear research project (optimizations done with matrices and linear equations) to find the optimal manufacturing/ordering/warehousing setup for something cool like emergency food distribution. Factors like proximity of warehouses to likely disaster areas, local costs, road availability, expiration dates, etc. You could setup a map, and determine where the warehouses should be built and what capacity at each location. But that is getting more like work, and not a fun project.

I was thinking about how she'd visualize whatever she ended up doing, and as cool as having a gui would be it would probably be a lot for her to learn. Maybe I'll install Apache with her and then and let her go to town with a web interface if she needs interaction. She already has strong skills with html/css, so that seems like a natural fit.

I strongly advise using a gui such as Tk. Sure there is some learning to do, but the amount of code involved is likely to be much less and more directly pertinent to providing the UI than anything CGI based. There is a larger disconnect between code and effect in CGI than using a gui like Tk which makes the creation of the code and debugging it harder.

Heh, maybe there's your science project right there - test the assertion that a Tk based gui is easier to develop than a CGI based one. Metrics in terms of time spent, lines of code, perceived difficulty, ease of maintenance, ...

If you want to get the "wow" factor from a science project.... use a gui of some sort. Of course I recommend Tk or Gtk2. ;-) How about something cool like simulating an instrument on a satellite and logging the data on a strip chart recorder on earth? See Tk Realtime data aquisition Maybe monitor solar wind? You could connect right to the spacecraft data-servers like solar data server Have the data recorder and maybe make a 2-d visualization of the magnetosphere at the current moment, that could be done with animated gifs.

You can get most of that data in closer to real time from CDAWeb, and it'll generate plots, too. (I'm not a fan of their interface, though ... you can also get their data via a web service or see VSPO for other sources. I know of other solar weather plotting software ... but much of it's not in Perl (IDL, Java, etc) or is tied up with legal questions about distribution.

One that is more real-life, and could lead to a career ...

I'm just going to assume that you're just saying that heliophysics data won't lead to a career as they normally have physics phds write the code ... who have no formal programming education. (and they tend to write data systems that only answer their own questions, without considering data reuse ... but I'll probably complain about that more at the fall AGU)

... and as my boss just saw me looking at NASA websites and asking what I was doing, he suggested taking a look at the Stanford Solar Center, as they've had students turn some of their project ideas into winning science fair projects.

I had no idea what age a "9th grader" translated to, so I googled and found "14 to 15". These are based on the assumption that is correct. And that your sister is like the majority of the kids around here and can type SMS messges with one hand, whilst conducting a conversation with another phone in the other hand :)

A "txt msg" to text translator.

Take a text in the "Wat R U Doing L8R"; produce "What are you doing later."

A text to "txt msg" translator.

Vice versa above.

An SMS message entry algorithm with predictive completion.

Using the numeric keypad, the typical mapping and a dictionary.

One of these might just be familiar, topical and relevant enough to inspire her attention.

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.

"Science is about questioning the status quo. Questioning authority".

In the absence of evidence, opinion is indistinguishable from prejudice.

I'm going to suggest making it not Perl. Instead make it JavaScript. The languages are similar enough that she should be able to transfer her expertise over, but being able to use a browser for your interactive GUI is more likely to excite a teacher. She'll just have to get used to using Firefox and getting her debugging information in the error console. (You can find that in the Tools menu.)

A reasonable project might be to write a web page that will put up an $n*$m grid of squares that are black or white. If you click on one, it will flip the color of that square and the one to the north, south, east and west. Also have a button that says "Find Solution". Then once found it will say how many moves are left, will ask you if you wish to see it, and then can proceed to step you through that solution.

If you wish to tackle that project you may wish to peek at 5x5 Puzzle. If she can learn how to use closure-based callbacks in JavaScript and can port that code, she'll have the solution part of that project. If she can understand how to programatically tie closures to event handlers in JavaScript, then she should be able to create that GUI interface. Of course working out the details should take her a lot of work. And she'll learn a lot in doing it.

Now what the heck are closures? Well closures are just functions that keep a reference to the environment that it was created in. If you want to twist your brain, try to figure out how Re (tilly) 1 (perl): What Happened...(perils of porting from c) works. If you figure it out, then you probably understand closures.

Now I've given you lots of examples of closures in Perl. To do one in JavaScript is similar. Here is a code example:

Now translating that Perl into JavaScript will cause you to encounter one very, very confusing piece of behavior. In Perl the following creates an array of closures over different variables:

for (@some_array) {
# Declaring this in the loop creates a new variable per
# instance of the loop.
my $x = $_;
push @closures, sub {
# Do something using x. I'll just return it.
return $x;
};
}
# We now have one closure per array element.

Unfortunately in JavaScript all variables are scoped to the nearest function call. So a literal translation does something very different:

for (var i = 0; i < some_array.length; i++) {
// Declaring this in the loop creates a one variable for
// all instances of the loop.
var x = some_array[i];
closures.push(function () {
// Do something using x. I'll just return it.
return x;
});
}
// All closures now point at the last element.

How annoying. You need to arrange to have a function call. The ugly, gross, but effective syntactic trick to do the right thing looks like this:

for (var i = 0; i < some_array.length; i++) {
// This declares and immediately calls a function, and x
// is scoped to that function call.
(function (x) {
closures.push(function () {
// Do something using x. I'll just return it.
return x;
});
)(some_array[i]); // And here is where we bind the value.
}
// We now have one closure per array element.

Unfortunately in JavaScript all variables are scoped to the nearest function call. So a literal translation does something very different:

for (var i = 0; i < some_array.length; i++) {
// Declaring this in the loop creates a one variable for
// all instances of the loop.
var x = some_array[i];
closures.push(function () {
// Do something using x. I'll just return it.
return x;
});
}
// All closures now point at the last element.

One of the joys of using the Mozilla Javascript environment exclusively is that that some of these issues have been dealt with. Javascript 1.7 introduced the let keyword that deals with this scoping issue.

for (var i = 0; i < some_array.length; i++) {
// Declaring this in the loop creates a one variable for
// all instances of the loop.
let x = some_array[i];
closures.push(function () {
// Do something using x. I'll just return it.
return x;
});
} // now works as expected

A bit off topic maybe, but potential for big fun.... how about training an Alice bot with facts about her school? It's been awhile since I've played with it but there once was an Alice engine written in Perl.

amarquis,
I won the Maine State Science Fair in the "Talks And Demonstrations" category. That category is the longer and more thorough category where there are subject matter experts judging you. I am not telling you this to boast, but rather to lead credence to what advice I have.

If your sister is interested in winning and doing well she needs to realize it may be in direct conflict of doing an exciting project that she has fun with. At its core, a science fair is about testing a hypothesis using the scientific method and ensuring the results are statistically valid. Display and presentation will go a long way at the local level, but if she advances - everyone she will be competing against will have a whiz-bang show to put on. At that level, it will boil down to fundamentals.

She should decide early on if she wants the software portion of the project to be the experiment itself, or if it is going to be a tool in facilitating and validating the experiment. Let me explain. Conway's Game Of Life is an example where the program itself could be the experiment. It is possible to start with a few basic set of rules that evolves into a dynamic system. On the other hand, you could do like I did and use the program to perform statistical validation on the results of a psychological hypothesis (it was 1993).

The hypothesis could be that it is possible to write a tic-tac-toe computer player that is impossible to beat (ties are possible) using only N rules. It could be that she uses a program to test some advanced game theory (I have Scientific American magazines with lots of great ideas). No matter what, at the local level it will be more about show than substance and at the advanced levels it will be all about substance and how scientific the results and process are.

The last post had me thinking about this. I think the science should be the king here, a lot of people would look at the project and think - she's coded a game up, what questions is she really asking - regardless of how complex the game theory is. Is there any way that she could set up a psych profile spreadsheet that could be used by the computer to predict whether the player would use a high risk or low risk strategy (burned in from experience) in some kind of game of chance. I can't think of an appropriate game right now.
Either that or she can do a bioinformatics project for us.
See you later

Just another idea... There is a nice article
The Mathematics of Sudoku1) (PDF) by Tom Davis which explains common strategies that can be translated easily into algorithms. But apart from very easy Sudokus, these strategies bring you only to a certain point where e.g. backtracking is required (nice to visualise).
The grid structure of the game allows for straight forward visualisation.

Tic-tac-toe or Nim or another simple game, but rather than writing a program that plays it perfectly, write a program that learns from experience and let two programs "play" against another, to build up their databases of good and bad moves. How many games does it take before you cannot beat it anymore?

CountZero

A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Another "Board Game"ish problem that you might consider is
Pentominos.
The challenge is to write a piece of software that can, for example, list all the solutions for the 6x10 board. When it comes to displaying the results either a simple printout, a graphical display or, better still, an actual physical set can be quite effective.

The solution exercises a variety of CS concepts and yet even a brute force approach can quickly yield a few usable results.

The rules and a picture of the board are given here:
http://www.centralconnector.com/GAMES/mancala.html

If you are not familiar with the game, try it before you pooh-pooh it as too simple. The programming logic should be fairly straight forward, but still challenging and the player needs to play a clever strategy. It is more complex and unique than tic tac toe.

Advantages as a Science fair project – it can be designed and developed in stages, any of the stages would be acceptable as a project for the fair submission.

Possible steps:
1)board lay out can be in non graphic mode, using digits to represent the number of stones in each bowl. With dashes or * as separators.
2) programming can be done as a series of variables, or as an array to calculate the move results handled in either for, or while loops.
3) user input can be designated as a text entry designating the bowl whose stones should be distributed.
4) the gui representation can be added later if time permits.

Good luck to your sister in the project!

And I bet you could point her to a super place to get perl advice!

Update - here is some crude code - it uses arrays and simple control statements to create a text mancala board, allows a user to enter a bin number and then distributes the stones. Please note there are much more elegant ways to handle the situation, but I tried to keep the code concepts fairly basic so a new user could get a feel for it wihout being overwhelmed. I assume you will be helping/coaching your sister.

I would strongly suggest you and your sister play the game in the real world, to get a feel for where the code should go.

this code was developed in the following order:
1) create 2 arrays, display the board.
2) accept user input, and edit check it.
3) distribute stones code
#### don't panic this code is not complex, just repetitive

Nuff said, I hope this code may help as an idea generator.

#!/usr/bin/perl
# this program creates a text based maa board with text input
#########################################
########### DON'T PANIC
#########################################
# bins for each player (should be 7 - 6 bins + 1 mancala)
@p1 = (4,4,4,4,4,4,0);
@p2 = (4,4,4,4,4,4,0);
while ($in ne "Q"){
# send the routine to draw the board the number of stones in each bin
&draw_board($p1[0],$p1[1],$p1[2],$p1[3],$p1[4],$p1[5],$p1[6],
$p2[0],$p2[1],$p2[2],$p2[3],$p2[4],$p2[5],$p2[6]);
# ask for input
print "enter bin to distribute or Q to exit:";
# get keyboard input
$in = <>;
# remove the carriage return from the entry
chomp $in;
# edit check the input
# return to top of loop if Q is entered
next if ($in eq "Q");
# display error message if a non digit or bin number is out of range
# then erturn to the top of the loop
if ($in =~ /\D/ || $in < 1 || $in > 12){
print " bin can only be 1 through 12 or Q\n\n";
next;
}
# we have a valid entry, so distribute stones
&distribute_stones($in);
}
sub distribute_stones{
# set variable $bin to the user input bin t be distribuetd
$bin = $_[0];
# set the variable $stones_2_distribute equal to the number of stones
# in the array for player 1 or player 2 represented by the bin number
# the user entered. Then set that array entry to 0. (because all of
# the stones in that bin have been picked up to be distributed)
#
# remember - perl arrays are indexed from 0 - or simply stated, the
# first entry used in a per array is number 0.
# this code is for the player 1 array (@p1)
if ($bin == 1){
$stones_2_dist = $p1[0];
$p1[0] = 0;
}
if ($bin == 2){
$stones_2_dist = $p1[1];
$p1[1] = 0;
}
if ($bin == 3){
$stones_2_dist = $p1[2];
$p1[2] = 0;
}
if ($bin == 4){
$stones_2_dist = $p1[3];
$p1[3] = 0;
}
if ($bin == 5){
$stones_2_dist = $p1[4];
$p1[4] = 0;
}
if ($bin == 6){
$stones_2_dist = $p1[5];
$p1[5] = 0;
}
# this code is for player 2 array (@p2)
if ($bin == 7){
$stones_2_dist = $p2[0];
$p2[0] = 0;
}
if ($bin == 8){
$stones_2_dist = $p2[1];
$p2[1] = 0;
}
if ($bin == 9){
$stones_2_dist = $p2[2];
$p2[2] = 0;
}
if ($bin == 10){
$stones_2_dist = $p2[3];
$p2[3] = 0;
}
if ($bin == 11){
$stones_2_dist = $p2[4];
$p2[4] = 0;
}
if ($bin == 12){
$stones_2_dist = $p2[5];
$p2[5] = 0;
}
# variable $bin_switch will help us determine where
# to start distributing stones, then will be set to 0
# so the remaining stones can be distributed in order
#
$bin_switch = $bin;
while ($stones_2_dist > 0){
# please see coding notes below
# this piece of code will only be accessed when stone distribution
# comes around the corner - it will never be the first bin a
# stone is distributed to
if ($bin_switch < 1){
$p1[0]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 2){
# add 1 to player 1 array first entry
# the folloing line is shorthand for $p1[0] = $p1[0] + 1
$p1[1]++;
$stones_2_dist--; # subtract one from our pile of stones to dis+tribute
$bin_switch = 0; # set the bin switch to zero so remainder of st+ones can be distribnuted
}
# this line will cause control to return to the top of the
# loop, if there are no more stones to distribute, where
# the while statement will terminate the loop
next if ($stones_2_dist < 1);
if ($bin_switch < 3){
$p1[2]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 4){
$p1[3]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 5){
$p1[4]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 6){
$p1[5]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
#determine if a stone should be dropped in player 1's
#mancala (bins 1-6 belong to player 1)
if ($bin > 0 && $bin <7){
$p1[6]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
## begin player 2 array
# this piece of code will only be accessed when stone distribution
# comes around the corner - it will never be the first bin a
# stone is distributed to
if ($bin_switch < 7){
$p2[0]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 8){
$p2[1]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 9){
$p2[2]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 10){
$p2[3]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 11){
$p2[4]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
if ($bin_switch < 12){
$p2[5]++;
$stones_2_dist--;
$bin_switch = 0;
}
next if ($stones_2_dist < 1);
#determine if a stone should be dropped in player 2's
#mancala (bins 7-12 belong to player 2)
if ($bin > 6 && $bin <13){
$p2[6]++;
$stones_2_dist--;
$bin_switch = 0;
}
# the following line is not technically required
# but will save trouble if you ever need to add
# some code between this line and the end of the loop
next if ($stones_2_dist < 1);
}
}
sub draw_board{
# display the board
print "\n\n\n";
printf " Bin=| %3d | %3d | %3d | %3d | %3d | %3d | \n\n" ,12,11,+10,9,8,7;
printf "-------------------------------------------------\n";
printf " %3d | %3d | %3d | %3d | %3d | %3d | %3d | \n" ,$_[13],$+_[12], $_[11],$_[10],$_[9],$_[8],$_[7];
printf " |-----+-----+-----+-----+-----+-----| \n";
printf " | %3d | %3d | %3d | %3d | %3d | %3d | %3d\n" ,$_[0], +$_[1],$_[2],$_[3],$_[4],$_[5],$_[6];
printf "-------------------------------------------------\n";
printf "\n Bin=| %3d | %3d | %3d | %3d | %3d | %3d | \n\n" ,1,2,+3,4,5,6;
}