Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Day 06 In Class Assignment

University of Missouri

✅ Put your name here.

✅ Put your group member names here.

Counting saguaros and plant covers, revisited

Landscape of saguaros with deep shadows across rolling hills

Credits: National Park Service

Learning goals for today’s assignment

  • Write and use functions in Python with varying types of input parameters, default parameters, and types of return values

  • Explore the purpose and utility of functions in writing Python code

  • Write and use more complex functions using Boolean logic, loops, and if/else statements

Assignment instructions

Work with your group to complete this assignment. Instructions for submitting this assignment are at the end of the Notebook. The assignment is due at the end of class.


Background: Ultimately we want to reproduce this table

Table with species of cover plants for saguaros in the census plots grouped into three classes.

Credits: Orum et al (2016)

Saguaro survival during a catastrophic freeze also depends on cover as well as age. Twenty-one species of plants serve as cover plants in our study plots. We have grouped them into three classes: C1) large trees (paloverde and mesquite), C2) small trees and large shrubs, and C3) small shrubs, grasses, and plants that provide minimal cover, or no cover plant at all.


1. The joys of real-life data

In the cell below, there is a fragment of the coverplants list you used in the last in-class when looking which cover plants were reported for which saguaros.

Remember: this data comes from an actual research lab. Notice that for some saguaros, they report multiple cover plants. And when this happens, there are several ways to record it. Sometimes different plants are separated by /, other times by , , and sometimes simply by ' and '. (And I’ve already massaged it a bit for you).

This is actually a pretty common occurence when different people capture the data (because surveying a whole National Park cannot be done by a single person!).

# sample data from the cover plants for seven saguaros
coverplants = [
    'Acacia (Vachellia) constricta',
    'Larrea tridentata',
    'Parkinsonia microphylla',
    'Parkinsonia microphylla',
    'Larrea tridentata/Acacia (Vachellia) constricta',
    'Opuntia fulgida and Isocoma tenuisecta',
    'Acacia (Vachellia) constricta, Opuntia versicolor, Ferocactus wislizeni'
]

✅  Question 1

Whenever you are working with multiple people to collect data, it is good to establish ground rules on how such collection will be done.

  • If you could go back in time and set ground rules for data collection, what would some of those rules be?

Put your answers here.


2. Fun-ception

Ultimately, you will first define two functions. You will use functio 1, to then define function 2. A function within a function as you saw in the pre-class. Fun-ception!

Pay attention to the required inputs and outputs for each function.

2.1: Function #1—Splitting a string, if applicable

Your function should do the following:

  • INPUT: a string

    • Check if the string contains separators: '/', ', ', or ' and '

    • Use the split function .split() to split the string if needed. pay attention to the blank spaces in the separators listed:

variable = 'cats&dogs`
print(variable.split('&'))
# This will print ['cats', 'dogs']

variable = 'cats'
print(variable.split('&'))
# This will print ['cats']
  • OUTPUT: a list, always

    • The list contains the separated items, if there was a separator present

    • Otherwise, the list contains the single input string.

output = 'cats'   # this is a string, which would be the WRONG output
output = ['cats'] # this is a list (which happens to contain a string)

2.2 Planning out your Function #1

✅  Task 2

In the cell below, write out your plan for your function in plain English (commonly referred to as pseudocode). Make sure you include:

  • function inputs

  • function outputs

  • basic code structure (will you have loops? if/else statements? variables? are things nested?)

Put your answers here.

2.3 Writing Function #1

✅  Task 3

In the cells below, you will write the first function following the indications and hints given.

# put your code here

2.4 Testing your Function

✅  Task 4

  • Loop through the coverplants list

  • Print the result of your function for each of the list items.

Expected output from coverplants:

['Acacia (Vachellia) constricta']
['Larrea tridentata']
['Parkinsonia microphylla']
['Parkinsonia microphylla']
['Larrea tridentata', 'Acacia (Vachellia) constricta']
['Opuntia fulgida', 'Isocoma tenuisecta']
['Acacia (Vachellia) constricta', 'Opuntia versicolor', 'Ferocactus wislizeni']

Important: Notice that each of the printed outputs is a list. Also notice that there are no unnecessary blank spaces at the beginning/end of the strings within these resulting lists.

# put your test code here

2.5 Writing Function #2—a list of unique values

Now that you have a working first function, you will write the second function following the indications and hints given.

  • INPUT: a list of string values

    • Create a list that can be used to keep track of the unique values. This will be your bag of unique values.

    • Loop over the list of all strings

    • For each of these strings, get another list with the split values. Use Function 1 to do this.

    • Now loop through this new list (a nested loop)

    • Use if/else statements to determine if each of the items is already in your bag of uniques.

    • Add unique values to your list as you find them

  • OUTPUT: the list of unique values

Hint: Remember that you can use in to check if a value is inside a list. You can also check if something not in a list using not in.

✅  Task 5

Code the function #2

If you’re feeling stuck, here’s some pseudocode to get started!

# define a function that takes in a list
    # declare an empty bag list
    # loop over all the input list items
        # save the result of the first function applied to the item
        # loop over the values of this new list
            # if the value is not in the bag, add it

    # return the bag list

2.6 Testing your Function

✅  Task 6

  • Run your second function with coverplants as its input

  • Store the resulting output list in another variable

  • Print this result and its length. Does it match your expectations?

Expected result:

['Acacia (Vachellia) constricta', 'Ferocactus wislizeni', 'Isocoma tenuisecta', 'Larrea tridentata', 'Opuntia fulgida', 'Opuntia versicolor', 'Parkinsonia microphylla']

Hint: Python has an in-built sorted function. sorted(my_list) returns a list with the same items as my_list but in ascending order. A sorted function is easier to evaluate it by eye.

# test

3. Testing on the Full Data Set

Just like in the last In-Class, we load the full dataset. Make sure that the census_saguaro_cover_classes.csv file is in the same directory as this Notebook.

# Just run this cell

import pandas as pd
df = pd.read_csv('census_saguaro_cover_classes.csv', index_col=0)
coverplants, coverclass = [ df[key].tolist() for key in ['NURSE PLANT', 'COVER CLASS']]
print(coverplants[:5])
print(coverclass[:5])
['Acacia (Vachellia) constricta', 'Parkinsonia microphylla', 'Parkinsonia microphylla', 'Parkinsonia microphylla', 'Ephedra sp.']
['C2', 'C1', 'C1', 'C1', 'C2']

✅  Task 7

Now copy/paste your code from (2.6), now with the full data set

  • How many different cover plant species were found in the saguaro surveys?

# Your code here

✅  Question 8

How do you know that your code is working correctly? Did your function work the first time? If so, what did you do that made it work well? If not, what changes did you need to make?

Put your answers here.


4. Refining the unique lists

You should have printed a list of 32 different cover plant species. But that list includes all cover plants found for all saguaros. As we saw in previous Notebooks, it is important to keep cover classes separate for better analysis.

✅  Task 9

For cover class C1, generate a new list c1_plants: the cover plant species but only when looking at C1 class saguaros

  • Declare an empty c1_plants list

  • Loop through the coverplantslist

  • If the saguaro is class C1, append the plant to the new list

Hint: Remember that coverclass is the list with the class for each saguaro and that the indices of coverplants and coverclass match.

# Your code

✅  Task 10

  • Compute the list of unique cover plant species that are observed when looking at C1 class saguaros.

  • Store and then print this list

Do you think you can simply copy/paste your Task 7 or do you think you need to edit your functions?

# Your code

✅  Question 11

  • Is your list of unique plant species the same as the one listed in Table 1 from Orum et al (2016)?

  • If not, what species is extra? (Any guess of why we have an extra plant?)

Put your answers here.


5. Putting it all together: Considering Other species

In the last In-Class, we were able to count the number of times a certain plant species appeared in the coverplants list. But we were limited to only look whichever species we declared beforehand. Now we have a way to know all the unique species we have registered and we can count everything now.

5.1 Counting the number of times thing show up in a list

Copy/paste your times_in_list function from last In-Class in the cell below. If you don’t have it at hand, a version of it is already below (but it is better if you use your own written code because you are already familiar with it). If you remember, this code includes partial matches. We actually want two counts: exact and partial matches.

For example, a saguaro with 'Acacia (Vachellia) constricta' cover is exactly covered by a whitethorn acacia. But a 'Larrea tridentata/Acacia (Vachellia) constricta' cover is just partial whitehorn acacia (because it is shared with creosote bush).

✅  Task 12

  • Rename and edit the function you just copy/pasted to return two counts instead: exact and partial matches found in the list

  • Hint 1: Look at the code from Part 1 from Day 05 In-Class

  • Hint 2: Remember that a function can return anything. You can make a list with the two counting values and return this list instead of a single number.

# Copy/paste your previously written function and delete the present code
# Only use the present code if you don't have your in-class immediately accessible

def times_in_list(name, my_list):
    counter = 0
    for item in my_list:
        if name in item:
            counter += 1
    return counter

✅  Task 13

Finally, test your newest function

  • Loop through the list of unique C1 cover plant species from Task 10

  • Print each species name along its number of exact and partial matches (as found across the full list of C1 species from Task 9)

Look back at Question 11. Do you have a better guess on why your Task10 list is different from the one in Table 1?

5.2 [Time-permitting] Excluding partial-only results

So far we have focused mostly on the C1 class saguaros. We can write a loop to go through all the classes and print all the results at once.

✅  Task 14

  • Write a loop that goes through Tasks 09 - 13 for classes C1 through C3

  • Keep a counter for all the plant species that have at least one exact match

    • We want to exclude species that only appear partially

Hint: It is useful to define a list with the classes names and use it for the outermost loop.

Important: You cannot use class as a variable name. But any other variation, like classes, a-ok.

# Here's some pseudocode to help you
# You should have most of the code already
# It is just a matter of copy/paste and some minor editing

classes = ['C1', 'C2', 'C3']
counter = 1
# loop through the list of classes
    # print class name
    # get a `c_plants` list as in task 9
    # get a `unique_plants` list as in task 10
    # loop through `unique_plants` as in task 13
         # get the exact and partial matches when looking in the `c_plants` list as in task 13
         # if the number of exact matches is positive
              # print the counter, plant name, the exact, and the exact + partial number of matches
              # add one to the counter
    # print('----') # this will separate class results for better visualization

We now have the counts for all the cover plants when only looking at saguaros of a specific cover class. This is why the count results are slightly different from the last in-class. We can compute the number of Other species as in Table 1.

For instance, for C2, after we exclude Acacia (Vachellia) constricta (whitethorn acacia), Larrea tridentata (creosote bush), Acacia (Senegalia) greggii (catclaw acacia), and Ephedra sp. (Mormon tea), we are left with only 13 exact counts.

Namely, Celtis pallida (7), Lycium sp. (4), and Ziziphus obtusifolia (2). (desert hackberry, wolfberry, and lotebush, respectively).

✅  Question 15

  • Can you do the same calculations for C3? Does the other count match with Table 1?

Put your answers here.

✅  Question 16

Orum et al (2016) reads in its Mortality subsection (emphasis mine):

Saguaro survival during a catastrophic freeze also depends on cover as well as age. Twenty-one species of plants serve as cover plants in our study plots*. We have grouped them into three classes: C1) large trees (paloverde and mesquite), C2) small trees and large shrubs, and C3) small shrubs, grasses, and plants that provide minimal cover, or no cover plant at all (Table 1).

  • Do you actually find 21 different, unique plant species? Remember to exclude those species that have no exact matches.

  • Remember that the list of unique items include non-species names like “open”, “unknown” or generic terms like “composite”, “shrub”.

Put your answers here.


Congratulations, you’re done!

Submit this assignment by uploading it to the course Canvas web page. Go to the “In-class assignments” folder, find the appropriate submission link, and upload it there.

See you next class!

© Copyright 2026, Division of Plant Science & Technology—University of Missouri

References
  1. Orum, T. V., Ferguson, N., & Mihail, J. D. (2016). Saguaro (Carnegiea gigantea) Mortality and Population Regeneration in the Cactus Forest of Saguaro National Park: Seventy-Five Years and Counting. PLOS ONE, 11(8), e0160899. 10.1371/journal.pone.0160899