Web Final Practicum: Gardening Simulator Spring 2024


Overview

In this practicum, we are building a full-stack React application to track plants growing in a garden.

Setup

  1. Create a repository on our Gitlab called gardening-abc123 where abc123 is your username. Make it a private repository
  2. Add your instructor as a Reporter to the project.
  3. Clone your (empty) repository locally.
  4. Go to our starter code base here: https://kgcoe-git.rit.edu/axmvse/gardening-starter-2024
  5. Download the code in zip using the “Download” button, right next to the “Clone” button.
  6. Extract the code into your repository. Your code should be laid out just like how our skeleton code is, i.e. server and client are in the root of the repository. Please make sure your folder structure is correct.
  7. Create your db.yml file as you have in past projects. This one is in server/db/db.yml
  8. In the client directory, do npm install to set up your node_modules directory
  9. Make sure you install the following dependencies in Python: pip install flask flask_restful flask_cors psycopg2.
  10. To start the server, run python server/server.py from the root of repository.
  11. To start the client, run npm start from the client directory of the repository.

UI Intended Functionality

To summarize, here’s a behavior specification of the UI:

  • Assume that the entire garden was planted on Day 0.
  • When the day changes, all of the plants update their progress until they have germinated.
  • The arrow buttons should modify the day by +/-1 and +/-5
  • If a plot is fertilized πŸ’©, the number of days to germinate is reduced by 3
  • If a plot is irrigated πŸ’§, the number of days to germinate is reduced by 5
  • If you click on an individual plant, you can change its species (i.e. 🌺🌼🌹 and 🌡 after Task 7). This also recalculates the germination status.

Final

These should be all independent tasks, but we recommend going in order.

  • Task 1. Day button wrong. The double-arrow (β—‚β—‚) button decrements the day by 1, not 5. Fix this according to how it’s supposed to behave.

  • Task 2. Path Plot wrong. The path plot should extend to the entire length of the grid. See screenshot below.

  • Task 3. Center align the plants. The plant icons are aligned to the left. Make them center-aligned like in the screenshot below.

  • Task 4. Fertilized Ignored The “fertilized” attribute doesn’t work as expected. It should shorten the germination time by 3 days, but instead it has no effect. You can tell that Raised Beds 1 and 3 grow at the same rate, but Bed 1 should finish earlier than Bed 3.

  • Task 5. Reset Button. Add a button near the arrow buttons called 0 that resets the day to zero.

  • Task 6. Change Plot Attributes Feature. Add the ability to click on the upper-left corner of each plot and change irrigated and fertilized attributes. Each of these should be toggleable individually, but the specific HTML form elements and is up to you. All of the information should update after making this change. We recommend finishing Task 3 before this.

  • Task 7. Species Info from Database. Currently, the default species info about each plant comes from a hard-coded set of data in Plant.js. Change the system so that it makes an appropriate REST call to the /gardening/species endpoint when the Sync button is pressed. In case of failure, the system should still default to the hardcoded info. The database has a cactus 🌡 whereas the hardcoded defaults do not.

  • Tasks 8+… to be revealed at Final Exam. These will be at least one new client-based feature and one new full-stack feature, and possibly more.

  • Task 8. Full stack change. Replace the contents of your database schema in server/db/gardening.sql with the new schema below. This schema is much more detailed, separating out genus and species, as well as day counts for the different stages of germination. Rewrite the SQL call in your database layer to query using the proper techniques we covered: single query, no subqueries, proper join, proper aggregation, and secure from injection. A few more details:

    • The order does not need to match our output.
    • Update the GET /gardening/species API endpoint to resemble the test case sketch below.
    • The precise formatting of your query (i.e. combinations of arrays and dictionaries) is up to you, but the information from our test case sketch should match, especially the new total_days number (which differs from our takehome version).
    • The scientific_name is a concatenation of genus and species with a space in between.
    • We have replaced the emoji in the SQL statements with strings like ROSE_EMOJI. This comes from Unicode standards not agreeing with each other, and everyone’s character set defaults being slightly different. Let’s work around this problem by having the client know about our four emojis and makes the translation in presentation, rather than storing emoji strings directly in the database.
  • Task 9. Summary Component. Add a new component to the client that shows a summary of how many of each species is fully sprouted.

    • You will need to “lift state up” to accomplish this, which we will be looking for in your implementation.
    • Visually, the component will need to stretch the to the same width as the plot map.
    • Placement within the DOM is up to you, but we do expect a new React component for this feature.
    • The layout should use ul and li, display: flex, have a black border like the other components, and should space the items like the screenshot below. Use 0.5em padding and margin: 0 for the li items.
    • A screenshot of what this should look like is below.

Code Snippets

New schema and test data for Tasks 8 and 9:

DROP TABLE IF EXISTS stages CASCADE;
DROP TABLE IF EXISTS species CASCADE;
DROP TABLE IF EXISTS genus CASCADE;

CREATE TABLE genus(
    id          SERIAL PRIMARY KEY NOT NULL,
    genus_name  TEXT NOT NULL DEFAULT '(genus unspecified)'
);

CREATE TABLE species (
    id               SERIAL PRIMARY KEY NOT NULL,
    genus_id         INTEGER NOT NULL,
    species_name     TEXT NOT NULL DEFAULT '(species unspecified)',
    common_name      TEXT NOT NULL DEFAULT '(no name specified)',
    emoji            TEXT NOT NULL DEFAULT '?'
);

CREATE TABLE stages (
    id               SERIAL PRIMARY KEY NOT NULL,
    species_id       INTEGER NOT NULL,
    stage_name       TEXT NOT NULL DEFAULT '(no stage name specified)',
    days             INTEGER NOT NULL DEFAULT 0
);

INSERT INTO genus(id, genus_name)
VALUES           (1, 'Hibiscus'),
                 (2, 'Helianthus'),
                 (3, 'Rosa'),
                 (4, 'Ferocactus');

INSERT INTO species(id, genus_id, species_name, common_name, emoji)
VALUES (1, 1, 'acetosella', 'Red Hibiscus', 'HIBISCUS_EMOJI'),
	   (2, 2, 'Helianthus', 'Sunflower',  'SUNFLOWER_EMOJI'),
	   (3, 3, 'cinnamomea', 'Rose', 'ROSE_EMOJI'),
       (4, 4, 'glaucescens', 'Cactus', 'CACTUS_EMOJI');

INSERT INTO stages(species_id, stage_name, days)
VALUES  (1, 'imbition', 1),    -- Red Hibiscus
        (1, 'respiration', 3), -- Red Hibiscus
        (1, 'germination', 5), -- Red Hibiscus
        (1, 'sprouting', 8),   -- Red Hibiscus
        (2, 'imbition', 2),    -- Sunflower
        (2, 'respiration', 4), -- Sunflower
        (2, 'germination', 6), -- Sunflower
        (2, 'sprouting', 10),  -- Sunflower
        (3, 'imbition', 5),    -- Rose
        (3, 'respiration', 4), -- Rose
        (3, 'germination', 3), -- Rose
        (3, 'sprouting', 1),   -- Rose
        (4, 'imbition', 1),    -- Cactus
        (4, 'respiration', 4), -- Cactus
        (4, 'germination', 11), -- Cactus
        (4, 'sprouting', 10);  -- Cactus


Expected endpoint output

species_id species_name genus_name scientific_name total_days common_name emoji
1 acetosella Hibiscus Hibiscus acetosella 17 Hibiscus HIBISCUS_EMOJI
2 Helianthus Helianthus Helianthus Helianthus 22 Sunflower SUNFLOWER_EMOJI
3 cinnamomea Rosa Rosa cinnamomea 13 Rose ROSE_EMOJI
4 glaucescens Ferocactus Ferocactus glaucescens 26 Cactus CACTUS_EMOJI

Expected Screenshots

After Task 2,3, and 5:

../gardening-tasks235.png

After Task 9, on a default load, on Day 20:

../gardening-task9.png

Submission

This is due at the end of the Final exam, May 6 6:45pm. Commit to your master branch by the due date/ time. Please tag your submission with final so we grade the right version.

Fixups. If you didn’t finish, you can finish your work after the final to show how close you were. Tag it again with revised and notify Professor Meneely. Grading will start the day after the final, so that evening is when you can fix it up.

For the CI, we will be cloning and grading locally. There is no need to get things working on the CI/CD system. We also do not have any automated tests for this final. You are welcome to use it, but are not required.

Grading Rubric

There are a total of 200 points.

  • (20pts) Submission directions followed
  • (20pts) Maintainability and code style across all tasks
  • (10pts) Task 1
  • (10pts) Task 2
  • (10pts) Task 3
  • (10pts) Task 4
  • (20pts) Task 5
  • (20pts) Task 6
  • (30pts) Task 7
  • (30pts) Task 8
  • (20pts) Task 9