From aa1a026f8ef4ddc585a0e822359b10a62c4a73b7 Mon Sep 17 00:00:00 2001 From: Robert Chisholm Date: Sat, 26 Apr 2025 08:51:18 +0100 Subject: [PATCH 1/4] Add steps argument to Predator Prey exercise code Argument is mandatory, and requires a positive integer, previously defaulted to 250 Closes #83 --- episodes/files/pred-prey/predprey.py | 12 +++++++++--- episodes/profiling-functions.md | 5 ++--- episodes/profiling-lines.md | 5 +++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/episodes/files/pred-prey/predprey.py b/episodes/files/pred-prey/predprey.py index 2f2ea1de..94f35d3d 100644 --- a/episodes/files/pred-prey/predprey.py +++ b/episodes/files/pred-prey/predprey.py @@ -415,8 +415,14 @@ def run(self, random_seed=12): # plot graph of results self._plot() +# Argument parsing +if len(sys.argv) != 2: + print("Script expects 1 positive integer argument (number of steps), %u found."%(len(sys.argv) - 1)) + sys.exit() +steps = int(sys.argv[1]) +if steps < 1: + print("Script expects 1 positive integer argument (number of steps), %s converts < 1."%(sys.argv[1])) + sys.exit() - - -model = Model() +model = Model(steps=steps) model.run() \ No newline at end of file diff --git a/episodes/profiling-functions.md b/episodes/profiling-functions.md index 3bdb227b..88ead1f4 100644 --- a/episodes/profiling-functions.md +++ b/episodes/profiling-functions.md @@ -437,12 +437,11 @@ Download and profile the Python p > > The three agents; predators, prey and grass exist in a two dimensional grid. Predators eat prey, prey eat grass. The size of each population changes over time. Depending on the parameters of the model, the populations may oscillate, grow or collapse due to the availability of their food source. -The program can be executed via `python predprey.py`. +The program can be executed via `python predprey.py `. +The value of `steps` for a full run is 250, however a full run may not be necessary to find the bottlenecks. -It takes no arguments, but contains various environment properties which can be modified to change the model's behaviour. When the model finishes it outputs a graph of the three populations `predprey_out.png`. - :::::::::::::::::::::::: solution It should be clear from the profile that the method `Grass::eaten()` (from `predprey.py:278`) occupies the majority of the runtime. diff --git a/episodes/profiling-lines.md b/episodes/profiling-lines.md index 2efaaf63..e00dd7e4 100644 --- a/episodes/profiling-lines.md +++ b/episodes/profiling-lines.md @@ -461,9 +461,10 @@ from line_profiler import profile def eaten(self, prey_list): ``` -`line_profiler` can then be executed via `python -m kernprof -lvr predprey.py`. +`line_profiler` can then be executed via `python -m kernprof -lvr predprey.py `. -This will take much longer to run due to `line_profiler`, you may wish to reduce the number of steps. In this instance it may change the profiling output slightly, as the number of `Prey` and their member variables evaluated by this method both change as the model progresses, but the overall pattern is likely to remain similar. +This will take much longer to run due to `line_profiler`, you may wish profile less steps than you did in the function-level profiling exercise (250 was suggested for a full run). +In this instance it may change the profiling output slightly, as the number of `Prey` and their member variables evaluated by this method both change as the model progresses, but the overall pattern is likely to remain similar. ```python # line ~420 From ebb40a93433e0cdf0b8403f6a7900bd924145ba6 Mon Sep 17 00:00:00 2001 From: Robert Chisholm Date: Sat, 10 May 2025 20:16:51 +0100 Subject: [PATCH 2/4] Update episodes/profiling-lines.md Co-authored-by: Jost Migenda --- episodes/profiling-lines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/episodes/profiling-lines.md b/episodes/profiling-lines.md index e00dd7e4..a8142545 100644 --- a/episodes/profiling-lines.md +++ b/episodes/profiling-lines.md @@ -463,7 +463,7 @@ from line_profiler import profile `line_profiler` can then be executed via `python -m kernprof -lvr predprey.py `. -This will take much longer to run due to `line_profiler`, you may wish profile less steps than you did in the function-level profiling exercise (250 was suggested for a full run). +Since this will take much longer to run due to `line_profiler`, you may wish to profile fewer `steps` than you did in the function-level profiling exercise (250 was suggested for a full run). In this instance it may change the profiling output slightly, as the number of `Prey` and their member variables evaluated by this method both change as the model progresses, but the overall pattern is likely to remain similar. ```python From 43a9668ead2ab559812fc71ce6c32ef4a980e046 Mon Sep 17 00:00:00 2001 From: Robert Chisholm Date: Sat, 10 May 2025 20:19:06 +0100 Subject: [PATCH 3/4] Update episodes/files/pred-prey/predprey.py Co-authored-by: Jost Migenda --- episodes/files/pred-prey/predprey.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/episodes/files/pred-prey/predprey.py b/episodes/files/pred-prey/predprey.py index 94f35d3d..f69603bc 100644 --- a/episodes/files/pred-prey/predprey.py +++ b/episodes/files/pred-prey/predprey.py @@ -418,11 +418,11 @@ def run(self, random_seed=12): # Argument parsing if len(sys.argv) != 2: print("Script expects 1 positive integer argument (number of steps), %u found."%(len(sys.argv) - 1)) - sys.exit() + sys.exit(1) steps = int(sys.argv[1]) if steps < 1: print("Script expects 1 positive integer argument (number of steps), %s converts < 1."%(sys.argv[1])) - sys.exit() + sys.exit(1) model = Model(steps=steps) model.run() \ No newline at end of file From 967111da308cdd1ebc75befe2b04bb7e8e043496 Mon Sep 17 00:00:00 2001 From: Robert Chisholm Date: Sat, 10 May 2025 20:21:16 +0100 Subject: [PATCH 4/4] Jost review suggestions --- episodes/files/pred-prey/predprey.py | 1 + episodes/profiling-lines.md | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/episodes/files/pred-prey/predprey.py b/episodes/files/pred-prey/predprey.py index f69603bc..bf927b0a 100644 --- a/episodes/files/pred-prey/predprey.py +++ b/episodes/files/pred-prey/predprey.py @@ -1,3 +1,4 @@ +import sys import math import numpy as np import matplotlib.pyplot as plt diff --git a/episodes/profiling-lines.md b/episodes/profiling-lines.md index a8142545..df7b31bc 100644 --- a/episodes/profiling-lines.md +++ b/episodes/profiling-lines.md @@ -466,11 +466,6 @@ from line_profiler import profile Since this will take much longer to run due to `line_profiler`, you may wish to profile fewer `steps` than you did in the function-level profiling exercise (250 was suggested for a full run). In this instance it may change the profiling output slightly, as the number of `Prey` and their member variables evaluated by this method both change as the model progresses, but the overall pattern is likely to remain similar. -```python -# line ~420 -model = Model(50) # 50 steps (originally defaulted to 250) -``` - Alternatively, you can kill the profiling process (e.g. `ctrl + c`) after a minute and the currently collected partial profiling information will be output. This will produce output similar to that below.