Lab 12: Bear-Fish Simulation

Purpose: to practice basic class design and implementation, practice with 2D data structures, and write code to track simulations.

In this lab, you’ll work with basic class design and implementation to modify a predator-prey simulation.

Step 1: Setup

To get started with this lab exercise do the following things.

  1. Download the starter code.

  2. Extract the ZIP file to a folder named bear_fish (or similar) in your class OneDrive (or similar).

  3. Read the README.txt file. This is a common way of describing a program that spans over several files.

  4. Run the bearfishsimulation.py file and see that it works.

Step 1.5: Add some documentation

The code has very little documentation. Find two methods that could use some documentation and try to add some. Ask the professor or lab assistant for help if you can’t figure out what something is doing.

Step 2: Report bear and fish counts

Notice that the simulation reports 0 bears and 0 fish constantly. That’s because the counting functionality hasn’t been implemented.

Check that the printout is correct now.

Alternative approaches

We could have also used a few other approaches to count the bears and fish:

  1. By looping through the thing_list
  2. By keeping count whenever add_thing or del_thing gets called.

But we chose to loop through the grid to practice working with 2D data structures.

Step 3: Log the bear and fish counts

Make a list of dictionaries, like:

[
    {'step': 0, 'num_bears': 10, 'num_fish': 10},
    {'step': 1, 'num_bears': 10, 'num_fish': 10},
    {'step': 2, 'num_bears': 10, 'num_fish': 9},
    ...
]

We’ve already initialized an empty log list that you can append to.

Step 4: Save the logs to a JSON file

We could simply make a plot at this point using the log data we have. But there’s two big limitations to this:

  1. If we want to change something about how the plot looks, we’d have to re-run the entire simulation, which takes a while.
  2. If we want to look at typical behavior across many runs of the simulation, it would really take a lot of time to run all those, so we better have a way to save our work.

To address both issues, let’s save the results of the simulation in a file. We could use a CSV file, but that’s limited in some ways. A more general file format is JSON; it can basically store any kind of data structure. Let’s practice making and storing some data.

Step 5: Make a plotting script

Make a new script, called plot_results.py. Load the trial data from trial_1.json:

with open('trial_1.json') as f:
    trial_data = json.load(f)

# TODO: get the log out of the trial data
# (this is a single assignment statement.)

# Make a dataframe of the results
trial_dataframe = pd.DataFrame(log)

Now plot the bear and fish counts over time. I’d suggest a line plot.

You can use whatever framework (plain Python or Streamlit) and plotting toolkit you’d like (I’d suggest Plotly, but matplotlib is fine too). The key thing is that this is a separate script.

Note: if you use plotly, you can pass a list of column names for y.

Step 6: Fix the simulation

Once you have all this working, try changing the size of the world to be 25x25. Then, try changing the number of steps the world simulates to be 5000 or 10000.

What I see is that all the fish always die out, but the bears live on – even after the fish are gone. Why is this? Let’s try to fix it:

You might want to add print statements to see every time a bear is born and when a bear dies (and why).

Optional Extensions

Submit your lab

Create a new ZIP file with your completed project code and upload it to Moodle.

If you don’t know how to do make a ZIP file, here are a few references: https://www.wikihow.com/Make-a-Zip-File, https://www.digitaltrends.com/computing/how-to-zip-a-file-in-windows-10/