| Introduction |
This programming assignment is designed to ensure that you know how to write
scripts that combine the standard control structures in Python: blocks,
ifs, for loops, while loops, break, and
try/except statements.
You will also continue gaining experience with the more basic Python features:
assignment and import statements and expressions (that use arithmetic,
relational, logical, and textual operators -including lots of
logical/bool expressions).
Finally, you will practice writing, testing, and debugging scripts using
iterative enhancement: a divide-and-conquer technique for building
and testing scripts a bit at a time.
Please follow the instructions below for each script: finish each enhancement before continuing to the next one (including printing whatever messages it displays in the console, copied exactly). Import whatever modules/functions you think appropriate, using whatever form of import you think appropriate (try to use both forms appropriately). Use short (but not overly short) well-chosen names. For indefinite loops, please write while True: loops with if/break statements in their blocks; when you are finished, you may transform the while test if the result is simpler. You will create each modules in a new project folder, and submit each module separately in Checkmate. Only one student should submit all parts of the the assignment, but both student's names should appear in the comments at the top of each submitted .py file. It should look something like # Romeo Montague, Lab 1 # Juliet Capulet, Lab 1 # We certify that we worked cooperatively on this programming # assignment, according to the rules for pair programmingPlease turn in each script as you finish it, so that I can accurately assess the progress of the class as a whole during this assignment. Print this document and carefully read it, marking any parts that contain important detailed information that you find (for review before you turn in the files). Reread the section on Time Management from Programming Assignment 0 before starting this assignment. Finally, for your information, I am listing below the number of lines in my solution scripts. These scripts are formated in the standard way. I am counting only lines with code; but I am not counting blank lines nor lines that are comments. My darts script is 10 lines (although with blank lines and comments it is 19 lines); my compressmodule script is 19 lines (although with blank lines and comments it was 26 lines); my montyhall script is 34 lines (although with blank lines and comments it is 42 lines); Your scripts might be smaller, and they might be larger; but if your script starts exceeding 2-3 times the size of mine, you might want to rethink your approach (or come get some help). Speaking of lines, I found it useful to put \ on one line to continue it on the next line (so the line wouldn't be too long). |
| Calculating π with Randomly Thrown Darts |
Write a script that performs the following tasks.
To simulate throwing darts, we will call the uniform method imported from the random module. Its header is random.uniform(min : float, max : float) -> float: When called, it returns random float between the values of min and max inclusive (e.g., in the range [min,max]) such that each value is equally likely (that is what uniform means; their are other distributions like normal that the random module can produce). From the picture above, the x and y coordinates we compute for each dart should be between -1 and +1. Use a bool expression to determine whether or not the coordinates of the dart are inside or outside the circle that is inscribed in the square (remember some geometry: it is inside if the distance from the origin to the dart's coordinate is less than or equal to the radius, which is 1). Design, code, test, and debug this script using iterative-enhancement, as 6 mini-scripts. Test each script to ensure that it is correct before proceeding to the next enhancement; simplify your code as much as possible before proceeding. This is the same methodology that we will use for larger scripts; so, it is a good idea to practice this technique here, where the script is small, even if you can write the entire script all at once. Later, we will discuss this technique in greater depth.
Enter number of darts to throw: 4
Dart thrown
x = -0.381578344458126 / y = 0.9986559633141296
Outside Circle
Inside count = 0
Dart thrown
x = 0.6230088145199804 / y = -0.6090162025597516
Inside Circle
Inside count = 1
Dart thrown
x = -0.6099645490335772 / y = 0.40343888285810103
Inside Circle
Inside count = 2
Dart thrown
x = 0.02227869342945632 / y = -0.6092767196745654
Inside Circle
Inside count = 3
pi is approximately = 3.0
Here is an example of my script running (which took about 3 seconds).
Of course because we are using random numbers, your answer may be different.
Hand in ONLY THE FINAL ENHANCEMENT of the script: the one meeting the complete specifications, with no intermediate output produced. Test it by throwing 10; 100; 1,000; 10,000; 100,000, 1 million, and 10 million darts (try a few billion, if you have a fast computer or have a lot of time on your hands). Also, try the same number of darts more than once and observe that the computed value changes, because the darts are thrown randomly each time. Typically, the more darts thrown, the better the answer approximates the true value of π (pi): 3.141592653589793.... |
| Compressing a Python Module |
Write a script that performs the following tasks.
import prompt
in_file_name = prompt.for_string('Enter file name')
in_file = open(in_file_name)
out_file_name = 'out-'+in_file_name
out_file = open(out_file_name,'w')
line_no = 0
for l in in_file:
line_no += 1
ls = l.rstrip()
print(line_no, ls)) # print to console
print(line_no, ls, file=out_file) # print to file
When you run this code the first time, you might have to refresh the project to see the newly create file appear in the PDev Package Explorer window. Design, code, test, and debug this script using iterative-enhancement, as 5 mini-scripts. Test each script to ensure that it is correct before proceeding to the next enhancement; simplify your code as much as possible before proceeding. This is the same methodology that we will use for larger scripts; so, it is a good idea to practice this technique here, where the script is small. Soon, we will discuss this technique in greater depth.
Enter file name: crops
Cannot find file: crops.py
Enter file name: craps
Compressed file contents written in file: compressed-craps.py
The actual contents of compressed-craps.py is as follows.
Compare it to the crapslpy contents.
It is interesting that we can use some programs as data to other programs.
from goody import irange
from dice import Dice
from stopwatch import Stopwatch
import prompt
import predicate
win_count = 0
lose_count = 0
dice = Dice([6,6])
game_timer = Stopwatch()
games_to_play = prompt.for_int('Enter
game_timer.start()
for game in irange(1, games_to_play):
first_roll = dice.roll().pip_sum()
if first_roll == 7 or first_roll == 11:
win_count += 1
elif first_roll == 2 or first_roll == 3 or first_roll == 12:
lose_count += 1
else:
point = first_roll
while(True):
roll = dice.roll().pip_sum()
if roll == point:
win_count += 1
break
elif roll == 7:
lose_count+= 1
break
game_timer.stop();
print(' Raw Wins/Lose =', '{:,}'.format(win_count), '/', '{:,}'.format(lose_count))
print(' % Wins/Lose =', 100.0*win_count/(win_count+lose_count), '/', 100.0*lose_count/(win_count+lose_count))
print()
print(' Dice Thrown =', '{:,}'.format(dice.rolls()))
print(' Avg Dice/game =', dice.rolls()/games_to_play)
print()
print(' Elapsed Time =' , game_timer.read(), 'seconds')
Hand in ONLY THE FINAL ENHANCEMENT of the script: the one meeting the complete
specifications, with no intermediate output produced.
|
| Monty Hall Let's Make a Deal |
In the 1970s, a popular TV game show was "Let's Make A Deal", whose host was
Monty Hall.
A typical contestant would be shown three doors: behind one door was a
valuable prize; behind the other two doors were "goats" (worthless prizes).
The contestant would first pick a door.
Then, Monty would often show them a goat prize behind one of the other doors;
no matter what door the contestant picked, there was always one other door
with a goat prize behind it for Monty to show them, and Monty knows what is
behind every door.
Next, Monty would often ask the contestant whether or not he/she wanted to
keep the door they originally chose, or switch to the other door (the one
not shown by Monty).
Is there an advantage to staying with your door? Is there an advantage to switching doors? Are both options equally good (in terms of how likely the contestant will win the valuable prize)? You could watch many shows and keep statistics on what strategy the contestant used and whether he/she won or lost with that strategy. Or, we can write a script that can simulate very many shows, to determine if there is a best strategy, and what it is. Although such a computer simulation will tell you which strategy is best, it won't tell you why that strategy is best, but knowing which might help you figure out why. You may also want to use your reasoning powers to deduce the correct answer before running your script, but this problem is notoriously difficult to solve correctly. Marilyn vos Savant (she writes the column, "Ask Marilyn", in Parade Magazine; she supposedly has the highest IQ of anyone in the US) discussed this problem in her column in the early 1990s and it generated a huge volumne of mail, many from PhDs in mathematics who (incorrectly) disagreed with her analysis. If you do a web search, you'll find lots written about the Monty Hall problem. But before you do, try to come up with your own solution to this problem. In fact, it appears in the following clip from the movie 21; the student supplies the answer but does not justify the solution. The previouis descrioption is a simplification of the real game show. You can watch various episodes of Let's Make a Deal on You Tube. What is interesting here is that different people can each effectively argue that their solution is correct (because the problem is subtle, and many wrong solutions sound right). Once someone has formulated a solution, it is difficult to convince them that they are wrong. Yet, we can write a simple computer program to determine which, if any, strategy is best: even given such evidence, people have a hard time "giving up" on an incorrect solution. So, you will write a script that prompts the user for the strategy to use (switch to the remaining door or stay with the door you chose originally), the number of games to play (accept only numbers greater than 0), and whether to print a detailed trace of the script; then it simulates playing that many games, keeping track of how often playing the chosen strategy wins. The script prints the statistics it collects (the number of times the player won and lost) at the end: from these numbers, you can deduce which strategy is best (if there really is a significant difference). To simulate choosing doors, we will use the randint function in the random module. Its header is random.randint(min : int, max : int) -> int: When called, it returns random int between the values of min and max inclusive (e.g., in the range [min,max]) such that each value is equally likely. Before playing, a random door is chosen as the "good prize" door,and a random door is chosen as the "contestant's door", and then Monty chooses the door to expose: it can't be either the good prize or chosen door. When you need to choose a random door, call this function and bind the results to the appropriate name (e.g., prize_door, chosen_door, exposed_door) for use in subsequent statements in the script. Design, code, test, and debug this script using iterative-enhancement, as 6 mini-scripts. Test each script to ensure that it is correct before proceeding to the next enhancement; simplify your code as much as possible before proceeding. This is the same methodology that we will use for larger scripts; so, it is a good idea to practice this technique here, where the script is small. Soon, we will discuss this technique in greater depth.
Switch when asked?: True
Trace game?: True
Enter number of games to play: 4
Game Played
Prize behind door 1 / Contestant chooses door 2
trying to expose door 3
Monty exposes door 3
Player won; has won 1 times
Game Played
Prize behind door 3 / Contestant chooses door 1
trying to expose door 3
trying to expose door 2
Monty exposes door 2
Player won; has won 2 times
Game Played
Prize behind door 2 / Contestant chooses door 3
trying to expose door 3
trying to expose door 3
trying to expose door 3
trying to expose door 2
trying to expose door 3
trying to expose door 1
Monty exposes door 1
Player won; has won 3 times
Game Played
Prize behind door 1 / Contestant chooses door 1
trying to expose door 2
Monty exposes door 2
Player lost; has won 3 times
4 games played
3 games won
1 games lost
Here is an example of my script running (which took about 15 seconds).
Of course because we are using random numbers, your answer may be different.
Hand in ONLY THIS FINAL ENHANCEMENT of the script: the one meeting the complete specifications and printing just six lines of output, including the three prompts. Test it by playing 10; 100; 1,000; 10,000; 100,000, and 1 million games. Also, try the same number of games more than once and observe that the computed values change, because the doors are chosen randomly each time. Typically, the more games played, the more accurate the answer is. |