Teaching High School Students Software Engineering: Prerequisites

4 Jul 2024


(1) Joseph Latessa, Department of Computer Science Wayne State University, Detroit MI USA (jlatessa@wayne.edu);

(2) Aadi Huria, Senior, Salem High School Canton, MI USA (huria.aadi@gmail.com);

(3) Deepak Raju, Senior, Salem High School, Canton MI USA (Deepak.Raju294@outlook.com).

Abstract and Introduction

Related Work

Project Prerequisites

Project Implementation

Insight and Reflections

Conclusions, Acknowledgement and References


We will now take a closer look at each part of the project’s development. Throughout the summer, our meetings took place using Zoom at intervals of one or two meetings per week and each session lasted between one and two hours.

3.1 Tools and Installation

After introductions, a discussion about scheduling, and a discussion about what we planned to accomplish over the summer, we decided upon and installed our development tools to ensure a consistent development environment. This involved stepping through the WSL installation process and setting up Ubuntu user accounts. We then installed Windows Terminal as our command line application and Visual Studio Code as our preferred text editor. We then visited github.com to explore GitHub’s features and establish user accounts.

3.2 Linux Shell Familiarization

At our next meeting, we explored Windows Terminal and entered basic commands to navigate the directory structure. Basic commands such as ls, pwd, cd, mkdir, touch, mv, cp, and clear were discussed and demonstrated. We practiced creating directories, creating files, moving files, and displaying a directory’s contents. In addition to navigating the command line on one’s local machine, automation with GitHub Actions requires command line navigation on GitHub’s runners. A familiarity with the command line will therefore be needed later in the project.

3.3 Introducing Version Control

For the next few meetings, we focused on learning version control. To assist with this learning and because the students had previous experience writing Python, we implemented a simple calculator application in Python. The main function provided a menu for users to choose arithmetic operations and to input operands. Each operation such as addition, subtraction, and raising a number to a power was a separate function that received the requisite operands as parameters and returned the result. A skeleton of the Python code was provided, with unimplemented function stubs that all returned zero.

The students learned to create a new repository on GitHub and clone the new repository to a directory on their local machine. Git was introduced using terminal commands rather than through a GUI to provide further command line practice, which will be useful when executing commands on GitHub’s runners. Upon cloning the remote repository, we discussed the concepts of distributed versus centralized version control and discussed the pros and cons of each system. The students added the new calculator skeleton to the repository and pushed it to the remote. The Git commands clone, pull, status, log, add, commit, and push were introduced and applied.

Since two students were working on the project, one student implemented the addition function, and the other implemented the subtraction function. Each committed their local changes and pushed those changes to the remote. Each screen-shared while implementing the changes, and we noted how the second person to push needed to pull the changes already made to the remote before pushing one’s own. It was also noted that having made changes to different functions, the differences could be reconciled automatically without giving rise to a merge conflict.

We next discussed the concept of branching and the benefits of developing features on specific feature branches. We created separate branches for the implementation of the multiplication and power functions. One student implemented multiplication and the other implemented power. Continuing to practice staging and committing files, we committed our local feature branches and learned to establish remote tracking for new branches. git diff was also introduced to compare un-staged changes with the most recent local commit and to compare other commits using the relevant commit hash. We then applied git merge to locally merge our feature back into our local main branch. Since each student had changed different parts of the code, it was again noted that the merge was automatic and gave rise to no merge conflict.

Next, we specifically edited the code to create and demonstrate a merge conflict. Having both edited the same section of the code, the students learned to manually resolve merge conflicts.

Figure 1: Students editing the same division function to purposefully give rise to a merge conflict.

We concluded our introduction to version control with a look at pull requests and forks. In addition to merging branches locally, we discussed a typical workflow in which a developer without push access to the main branch would propose changes by submitting a pull request. We also looked at creating repository forks and saw how pull requests could be submitted across forks. The final calculator function, a square root function, was merged into the main branch through the submission and approval of a pull request.

To prepare for the next phase of our project, the students created their own forks of the JETSCAPE [1] and GOMC [2] application repositories as well as the JETSCAPE and GOMC website repositories. Most of the time spent writing these tests would pertain to the website repositories.

3.4 Introducing Continuous Integration

To introduce the concept of continuous integration, we created a simple Python script that uses the requests.get method to query a website and return a status code. The script can be run manually at the command line and accepts a URL as a command line argument. If the status code returned is 200, a success message is printed, and the program exits normally. If another code is returned or if there is no response from the server, the program terminates having raised an exception. We tested the program manually on popular websites like google.com and on URLs we knew to be invalid.

We then discussed the usefulness of having a test run automatically either on a set schedule or whenever there are changes to a specified branch. Since there are two students and two websites (JETSCAPE [1] and GOMC [2]), each student focused on a specific website and worked on their locally cloned fork. We committed the Python script that checks for reachability and discussed the YAML file steps required to generate the automation. We decided that the test should run on push operations and pull requests to the main branch and run once per day at a specific time. We discussed the job steps including running on ubuntu-latest, checking out the current repository using GitHub’s checkout action, and executing terminal commands on GitHub’s runners to install the requests library using pip. We discussed that this step would be performed every time the workflow executes because each job runs on a new instance of ubuntu-latest. We then added the job steps to navigate to the tests/ folder on the runner and to execute the python3 command calling the URL reachability script. The students committed, pushed to the remote forks, and checked the Actions tabs on GitHub to review the running tests and their respective logs.

Equipped with prior knowledge of the Python language and having now gained a familiarity with the command line, version control, and automating workflows with GitHub Actions, the students were ready to start researching and experimenting with writing and deploying the automated tests.

This paper is available on arxiv under CC BY-NC-ND 4.0 DEED license.