You’ve decided to visit the Metropolitan Museum of Art with some friends and notice an interesting painting on the wall:
One of your friends wonders out loud how probable it would to hit a colored section of the painting if they were to close their eyes and throw a dart at random at the canvas. You tell your friend that this is a very bad idea, but because you are in an Introduction to Computer Programming class you know that you can use your newly acquired Python skills to solve this problem!
For this program you will be writing some code that will simulate the throwing of a random dart at this modern art painting. To do this you can repeatedly generate a random coordinate within the painting area and test to see which shape (if any) the dart falls into. Note that the playing field is 800 units wide and 500 units high, so you will be generating random coordinates within this range as part of your simulation.
When you are finished you should calculate the % chance of a dart hitting a particular shape. Refer to the schematic below for the exact measurements of the painting. Hint: Start off by simulating just one dart toss and use the coordinate plane to determine if the dart has fallen into one of the colored regions. Start off with the red rectangle since it will be the simplest shape to work with — how can you write a statement to determine if a point falls within a rectangle? From there, expand this logic and apply it to the other shapes. Hint: you may need the distance formula again to determine if a point falls within a circular region! Once you are confident that you have designed an effective algorithm you can scale up and place your code inside a loop.
Here’s a a few sample runnings of the program with user input highlighted:
Number of throws: -5000
Invalid, try again!
Number of throws: 10000
Total time elapsed: 0.01 seconds
Red: 961 (9.61%)
Blue: 425 (4.25%)
Grey: 59 (0.59%)
Black: 772 (7.72%)
Yellow: 96 (0.96%)
Green: 1,012 (10.12%)
Misses: 6,675 (66.75%)Number of throws: 1000000
Total time elapsed: 0.87 seconds
Red: 93,387 (9.34%)
Blue: 43,550 (4.35%)
Grey: 6,309 (0.63%)
Black: 78,583 (7.86%)
Yellow: 10,902 (1.09%)
Green: 99,948 (9.99%)
Misses: 667,321 (66.73%)Number of throws: 5000000
Total time elapsed: 4.35 seconds
Red: 468,863 (9.38%)
Blue: 218,584 (4.37%)
Grey: 31,383 (0.63%)
Black: 393,151 (7.86%)
Yellow: 54,378 (1.09%)
Green: 498,781 (9.98%)
Misses: 3,334,860 (66.70%)Input assumptions:
Number of throws: a value of data type ‘integer’ within the range -2147483648 to 2147483647
You can always assume the user will enter an integer when prompted, but you will need to validate it so that it falls within the desired range (1 or larger)
Start off by generating a single random point within the bounds of the painting (an x value between 0 and 800 and a y value between 0 and 500). The coordinate system shown here is one that is standard in the world of computer graphics — notice that the origin point is at the top left side of the screen, and that the y axis only contains positive values.
You can generate a random floating point number within a given range by using the random.uniform() function. This function takes two arguments – a low boundary and a high boundary – and generates a floating point number within this range (edges inclusive)
Next, write a series of tests to see if the number you just picked falls within one of the shapes shown. If so, you should update an accumulator to go count this as a “hit” to that particular region.
The distance formula may be helpful in determining if a point falls within a circle (hint: if the distance from a point to the center of a circle is less than the radius of that circle then the point can be considered inside of that circle.
Once this works for a single point you will need to design a loop to iterate a large number of times and repeat this process. We sometimes call this a ‘Monte Carlo’ simulation, which is designed to approximate a solution to a problem through the use of random numbers.
Because of this you will see different numbers when you run your program. The percentages that get generates should roughly match the percentages shown here. They will not be exactly the same unless your program generates the exact same random numbers as mine, and you generate those values in the same order as my program. It’s not required to get exactly the same answer for this program as long as your values are close to the sample outputs.
The more “throws” you compute the closer you will get to the actual solution.
You can ask Python to generate the current time by calling the time.time() function. You will need to import the time module in order to call this function. This function returns the current time based on your computer’s internal clock as a single floating point number. Every time you call this number it will get bigger, indicating the current time as measured in ‘seconds’ since the Unix Epoch. Hint: to compute the total execution time of your program you may need to capture the time before you begin your simulation and after your simulation finishes.
Your “execution time” value will be different than the ones given here in the sample output. This is due to the fact that every computer will run at a slightly different rate based on processor speed, available memory, etc. – this is fine and you will not lose credit for having different time values in your output.
You will need to format your output to match the sample output above (i.e. all of your values should line up). In my sample output I’m formatting the number of throws to 15 characters.