This task is part of project07 which is due at 23:00 EDT on 2025-10-28.
You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.
You can download the starter code for this task using this link.
You can submit this task using this link.
Put all of your work for this task into the file
quadrats.py
(you will create this file from scratch)
This task will give you practice using nested for loops and indexing on 2D grids. It is ecology-themed, but no understanding of ecology should be required to complete it. The functions here are not necessarily actually used in real ecology, but have been chosen to give you practice with certain important programming concepts.
In ecology, a "quadrat" is a square or rectangular frame used to count things like species abundance or distribution by placing it over an area and then counting organisms within each square of the grid.
SonoranDesertNPS from Tucson, Arizona, CC BY 2.0, via Wikimedia Commons
We can represent counts of a particular species in a quadrat in Python using a list of lists: the outer list holds multiple "row" lists, and each "row" list holds a series of numbers: the count of that species within each cell in that row. For a 5x5 quadrat like the one pictured above, this might look like:
data = [
[1, 0, 0, 2, 0],
[2, 1, 0, 0, 0],
[1, 1, 0, 3, 0],
[0, 1, 1, 2, 1],
[0, 0, 0, 2, 1]
]
Here we have a list of 5 sub-lists, with 5 numbers in each sub-list. We've arranged the code into a square pattern but it could also have been written as:
data = [[1, 0, 0, 2, 0], [2, 1, 0, 0, 0], [1, 1, 0, 3, 0], [0, 1, 1, 2, 1], [0, 0, 0, 2, 1]]
Your job in this task is to write a number of Python functions for processing data of this form. You can assume in all cases that there will be at least 1 row with 1 value in it, and that all values will be non-negative integers. You can also assume that each row within a given example will have the same number of entries, that is, you can assume that the grid is rectangular (but not necessarily square).
Although in some cases these problems could be solved without using a nested loop, the point of this task is to practice using nested loops, so you must use a nested loop in each function you write.
As usual each function must include a docstring.
There are 6 functions to write:
totalCountThe totalCount function simply
returns the total sum of each cell count
in the entire grid, given a data
list-of-lists as described above. These totalCount
examples show how it should work.
Note that normally it would be possible to do this using a single loop
and the sum function, but in order to practice writing nested loops,
you are not allowed to use sum in this
function and you must use a
nested loop.
inhabitedCellsThe inhabitedCells function
returns the total number of cells in which the count is above
0. These inhabitedCells
snippets give some examples.
highestCountThe highestCount function must
return the highest single entry from the
grid. These highestCount
snippets give examples.
Note that normally it would be possible to do this using a single loop
and the max function, but in order to practice writing nested loops,
you are not allowed to use max in this
function and you must use a
nested loop.
highestThreeThe highestThree function works
like highestCount except that it returns a list containing 3 elements,
which are the 3 highest (or tied-for-highest) counts in the
grid. These highestThree
snippets provide examples.
Note that even if the grid has fewer than 3 cells, there should always be 3 elements in the list returned, with zeroes added to achieve that.
squaresCountSpecies that are more fragmented can be more vulnerable than those that are distributed more evenly. One measure of fragmentation is how many 2x2 squares in the grid include at least one member of the target species in all 4 of their cells. For example, these two grids both have 17 total organisms, but in the first grid there is only one 2x2 square that's got at least 1 organism in every cell and in the second there are five such squares (counting overlaps):
fragmented = [
[3, 0, 2, 4],
[2, 1, 2, 3],
[0, 1, 0, 1],
]
consolidated = [
[2, 1, 2, 4],
[2, 1, 1, 3],
[0, 1, 1, 1],
]
The squaresCount function returns
the number of 2x2 squares in which all 4 elements are
non-zero, including overlapping squares in
the count. For example, on a 3x3 grid, there are four 2x2 squares to
check. These squaresCount snippets show how it
works.
Hint: In general, for a grid of height X and width Y, there are (X - 1) times (Y - 1) total 2x2 squares.
Note that for this function, you will need to use an index loop and
so you are required to use the range function (or enumerate as an
alternative).
isolatedCountAnother way of looking at fragmentation is the number of isolated cells: cells where at least one organism is counted, but where none of the four orthogonally adjacent cells have any. Counting the number of isolated cells helps assess how fragmented the distribution is. For example, both of these grids have a total population of 11, but the first grid has two isolated cells, while the second grid here has none:
isolated = [
[1, 0, 3],
[0, 2, 0],
[1, 1, 3]
]
joined = [
[1, 0, 2],
[1, 1, 1],
[0, 2, 3]
]
Note that we don't check how many individuals are in an isolated cell, just that the counts are zero in all four neighbors.
The isolatedCount function must
return the count of isolated cells in a
grid. These isolatedCount
snippets give examples of how it should work.
Notes:
range function (or enumerate as an
alternative).totalCount Examples
Examples of how totalCount works.
In []:Out[]:totalCount([[1, 3], [0, 5]])In []:9Out[]:totalCount([[0, 2, 0], [0, 1, 2], [1, 1, 1]])In []:8Out[]:totalCount([[0, 5, 3, 3], [2, 3, 4, 6], [6, 4, 2, 1], [3, 0, 4, 2]])In []:48Out[]:totalCount( [[0, 1, 1, 0], [2, 0, 0, 4], [0, 0, 2, 0], [2, 0, 0, 0], [0, 1, 2, 0]] )15
inhabitedCells Examples
Examples of how inhabitedCells works.
In []:Out[]:inhabitedCells([[1, 3], [0, 5]])In []:3Out[]:inhabitedCells([[0, 2, 0], [0, 1, 2], [1, 1, 1]])In []:6Out[]:inhabitedCells([[0, 5, 3, 3], [2, 3, 4, 6], [6, 4, 2, 1], [3, 0, 4, 2]])In []:14Out[]:inhabitedCells( [[0, 1, 1, 0], [2, 0, 0, 4], [0, 0, 2, 0], [2, 0, 0, 0], [0, 1, 2, 0]] )8
highestCount Examples
Examples of how highestCount works.
In []:Out[]:highestCount([[1, 3], [0, 5]])In []:5Out[]:highestCount([[0, 2, 0], [0, 1, 2], [1, 1, 1]])In []:2Out[]:highestCount([[0, 5, 3, 3], [2, 3, 4, 6], [6, 4, 2, 1], [3, 0, 4, 2]])In []:6Out[]:highestCount( [[0, 1, 1, 0], [2, 0, 0, 4], [0, 0, 2, 0], [2, 0, 0, 0], [0, 1, 2, 0]] )4
highestThree Examples
Examples of how highestThree works. Note that if there are fewer than 3 total values, zeroes are added to make the result always have length 3
In []:Out[]:highestThree([[1, 3], [0, 5]])In []:[5, 3, 1]Out[]:highestThree([[3, 0, 2, 4], [2, 1, 2, 3], [0, 1, 0, 1]])In []:[4, 3, 3]Out[]:highestThree( [ [1, 1, 0, 0, 0, 0, 4, 1, 3, 3, 5], [0, 0, 0, 1, 0, 2, 0, 3, 2, 3, 3], [3, 2, 3, 3, 0, 3, 3, 0, 1, 4, 2], [4, 3, 3, 2, 3, 3, 0, 2, 0, 5, 4], [3, 4, 4, 1, 0, 1, 2, 0, 3, 4, 7], [2, 0, 3, 2, 1, 1, 0, 0, 3, 6, 8], [0, 0, 2, 0, 1, 1, 2, 3, 3, 5, 6], [0, 0, 0, 0, 0, 2, 1, 1, 3, 4, 5], [0, 3, 0, 1, 0, 0, 1, 2, 3, 0, 0], [1, 2, 0, 0, 0, 2, 3, 0, 0, 0, 0], [1, 0, 2, 0, 1, 0, 2, 1, 0, 0, 12], ] )In []:[12, 8, 7]Out[]:highestThree([[0, 0, 0], [0, 0, 0], [0, 0, 0]])In []:[0, 0, 0]Out[]:highestThree([[1], [1]])In []:[1, 1, 0]Out[]:highestThree([[1]])[1, 0, 0]
squaresCount Examples
Examples of how squaresCount works. Note how overlapping squares are counted separately.
In []:Out[]:squaresCount([[1, 3], [0, 5]])In []:0Out[]:squaresCount([[0, 2, 0], [0, 1, 2], [1, 1, 1]])In []:1Out[]:squaresCount([[0, 5, 3, 3], [2, 3, 4, 6], [6, 4, 2, 1], [3, 0, 4, 2]])In []:6Out[]:squaresCount( [[0, 1, 1, 0], [2, 0, 0, 4], [0, 0, 2, 0], [2, 0, 0, 0], [0, 1, 2, 0]] )0
isolatedCount Examples
Examples of how isolatedCount works. Note how it counts cells on the edge as isolated as long as their neighbors in the grid are zeroes.
In []:Out[]:isolatedCount([[1, 3], [0, 5]])In []:0Out[]:isolatedCount([[3, 0, 2, 4], [2, 1, 2, 3], [0, 1, 0, 1]])In []:0Out[]:isolatedCount( [ [1, 1, 0, 0, 0, 0, 4, 1, 3, 3, 5], [0, 0, 0, 1, 0, 2, 0, 3, 2, 3, 3], [3, 2, 3, 3, 0, 3, 3, 0, 1, 4, 2], [4, 3, 3, 2, 3, 3, 0, 2, 0, 5, 4], [3, 4, 4, 1, 0, 1, 2, 0, 3, 4, 7], [2, 0, 3, 2, 1, 1, 0, 0, 3, 6, 8], [0, 0, 2, 0, 1, 1, 2, 3, 3, 5, 6], [0, 0, 0, 0, 0, 2, 1, 1, 3, 4, 5], [0, 3, 0, 1, 0, 0, 1, 2, 3, 0, 0], [1, 2, 0, 0, 0, 2, 3, 0, 0, 0, 0], [1, 0, 2, 0, 1, 0, 2, 1, 0, 0, 12], ] )In []:5Out[]:isolatedCount([[1, 0, 3], [0, 2, 0], [1, 1, 3]])In []:2Out[]:isolatedCount([[1, 0, 2], [1, 1, 1], [0, 2, 3]])In []:0Out[]:isolatedCount([[0, 0, 0], [0, 0, 0], [0, 0, 0]])In []:0Out[]:isolatedCount([[1]])In []:1Out[]:isolatedCount([[0, 5, 0], [5, 0, 5], [0, 5, 0]])4
totalCount must return the correct result
totalCount function is run must match the solution result.inhabitedCells must return the correct result
inhabitedCells function is run must match the solution result.highestCount must return the correct result
highestCount function is run must match the solution result.highestThree must return the correct result
highestThree function is run must match the solution result.squaresCount must return the correct result
squaresCount function is run must match the solution result.isolatedCount must return the correct result
isolatedCount function is run must match the solution result.totalCount with 1 parameter
def to define totalCount with 1 parametertotalCount with 1 parameter, use any kind of loop in at least one place.totalCount with 1 parameter, use any kind of loop in at least one place.sum
totalCount with 1 parameter, do not call sum.inhabitedCells with 1 parameter
def to define inhabitedCells with 1 parameterinhabitedCells with 1 parameter, use any kind of loop in at least one place.inhabitedCells with 1 parameter, use any kind of loop in at least one place.highestCount with 1 parameter
def to define highestCount with 1 parameterhighestCount with 1 parameter, use any kind of loop in at least one place.highestCount with 1 parameter, use any kind of loop in at least one place.max
highestCount with 1 parameter, do not call max.highestThree with 1 parameter
def to define highestThree with 1 parameterhighestThree with 1 parameter, use any kind of loop in at least one place.highestThree with 1 parameter, use any kind of loop in at least one place.squaresCount with 1 parameter
def to define squaresCount with 1 parametersquaresCount with 1 parameter, use any kind of loop in at least one place.squaresCount with 1 parameter, use any kind of loop in at least one place.range
squaresCount with 1 parameter, call range or enumerate in at least one place.isolatedCount with 1 parameter
def to define isolatedCount with 1 parameterisolatedCount with 1 parameter, use any kind of loop in at least one place.isolatedCount with 1 parameter, use any kind of loop in at least one place.range
isolatedCount with 1 parameter, call range or enumerate in at least one place.= or by defining a parameter for a function) you must also later use that variable as part of another expression. If you need to create a variable that you won't use, it must have the name _, but you should only do this if absolutely necessary.totalCount must return the correct result
totalCount function is run must match the solution result.inhabitedCells must return the correct result
inhabitedCells function is run must match the solution result.highestCount must return the correct result
highestCount function is run must match the solution result.highestThree must return the correct result
highestThree function is run must match the solution result.squaresCount must return the correct result
squaresCount function is run must match the solution result.isolatedCount must return the correct result
isolatedCount function is run must match the solution result.highestCount with 1 parameter
def to define highestCount with 1 parameterhighestCount with 1 parameter, use any kind of loop in exactly 2 places.highestThree with 1 parameter
def to define highestThree with 1 parameterhighestThree with 1 parameter, use any kind of loop in exactly 2 places.squaresCount with 1 parameter
def to define squaresCount with 1 parametersquaresCount with 1 parameter, use any kind of loop in exactly 2 places.isolatedCount with 1 parameter
def to define isolatedCount with 1 parameterisolatedCount with 1 parameter, use any kind of loop in exactly 2 places.