Home » Teaching » CSCI 40500: Software Engineering (FA ’25)

Recent News

Subscribe

Archives

Categories

Tags

Meta

Attribution-NonCommercial-ShareAlike 4.0 International

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International license.

CSCI 40500: Software Engineering (FA ’25)

Assignments

Observer Pattern

Implement the Observer Pattern in an Object-Oriented programming language of your choice. Create both abstract and concrete classes as shown in the pattern description and UML class hierarchy diagram for the pattern. While the abstract classes can be conceivably used in professional projects, the concrete class can be very simple. For example, you may create a concrete subject for only a single scalar integer. Also note that while some programming languages may include abstract classes for the pattern, write your own so that you can learn the pattern.

Next, write at least two test classes, preferably using a testing framework, one for subjects and one for observers. Note that a given system can have multiple subjects, but for this assignment, one subject is sufficient. However, in order to make the assignment interesting, you must have at least two observers for the subject. The tests should exercise the methods outlined in the pattern.

Your submission should be a complete, runnable program. In your README.md file, write how to compile (if necessary) and run your program, and include any instructions for installing dependencies and run-time requirements. You may provide a Docker image if you like, but the image must be accompanied by your source code. The entire assignment must be runnable on our (Ubuntu-based) lab machines. The assignment must compile (if applicable) and run without error to receive credit. Assignments that either do not compile (if applicable) or run will receive a grade of zero.

Finally, create a GitHub Action or other CI that runs your tests on commits to the main branch. Note that the action must fail if the test fails. Accept the assignment on our GitHub Classroom, and ensure that all code is pushed by the due date. Also ensure that you have selected the correct EMPLID associated with your GitHub username in our “classroom.”

Project Deliverables

Product Vision

Develop your group’s product vision for the semester-long project. Use the vision template and example. For information sources for developing a product vision, see Table 1.2.

Ultimately, the vision you come up with now may not reflect what you eventually decide your project to be. In other words, your vision may change during the course of the project’s development. Indeed, that is exactly the motivation behind agile methods. Thus, at the point, you only need to have an initial idea of what the project should be.

Clearly label your group’s product vision in your project’s README.md file in your Git repository created by GitHub Classroom. Then, push your changes up to GitHub. Use markdown to write it. For example, your README.md file may look as follows:

# Project 10

## Product Vision

Your product vision here.

Finally, submit the permalink of your project’s README.md file by the deadline on Bb (do not put it in the comment text box, instead, create a submission). You must submit the permalink (the URL is insufficient). An example permalink is https://github.com/CSCI-40500-Fall-2025/project-7/blob/8ca0d62fa8d2b2ded2c13f336659e5f8e5f3a94b/README.md (note that a permalink includes the SHA1 hash).

Proof-of-concept Prototype

Once your project vision has been documented, it’s now time to make your first project prototype. Per Ch. 1 of our textbook, the prototype at this stage will most likely be very bare (skeletal), may not use the technology that your final product will use, and maybe eventually thrown away. In other words, this is a proof-of-concept prototype; use it to assess the feasibility of your product and elicit the features that you will want it to have. You can use this prototype to build your product backlog (Ch. 2). This first prototype can be very simple, e.g., only showing pop-up messages of the functionality that will eventually be present.

While it is acceptable to use firebase and other kinds of “app” generators for the prototype, such technologies should be avoided for the final project deliverable. You need to write code to apply the lessons from the course.

Push your code to your GitHub Classroom repository on the master (main) branch. In your README.md file, explain how to use the prototype. Then, create a release of your product in GitHub (instructions here). In Brightspace, enter the URL of the release by the deadline. If your project is deployable, e.g., web app, mobile app, deploy your prototype. Your group may be asked to present their prototypes in class.

Product Backlog

Use your proof-of-concept prototypes to create a product backlog for your software product. It should be similar to the example given in Table 2.6:

  1. Create a project in your repository as shown in the tutorial.
  2. On the Kanban board, create columns corresponding to the states in Table 2.7.
  3. Create PBIs as “notes” in the (first) “ready for consideration” column. You may want to ask potential users to use your prototypes in order to elicit feedback. Such users can be, for example, family members or other members of your household, or other classmates.
  4. Refine the PBIs and transition them to appropriate states (columns) from Table 2.7. Do this by performing the activities detailed on slide 26. Higher priority items should go towards the top of the board.
  5. Create issues out of each PBI in the (last) “ready for implementation” column using the issues feature of your GitHub Classroom repository. The note should have an option to convert them to GitHub issues.
  6. For each issue, label (using the issue labels) it as either a feature, user request, development activity, engineering improvement, etc.
  7. Estimate the time to do each issue by adding a label (e.g., 1h, 1d, 1/2d).
  8. Submit the URL of your project on Brightspace.

Prototype Extension

Once you have developed your initial list of feature ideas as part of the product backlog deliverable, extend your existing prototypes to demonstrate these features. The software prototype aims to test and clarify product ideas and demonstrate your product to management, funders, and potential customers. Once you have completed the next prototype version, create another release and submit the URL of the next release by the deadline as you did in the proof-of-concept prototype deliverable.

Once again, use the new prototype version to refine your product backlog, adding new details to features or even dumping (closing) features (that “won’t be fixed”). Transition the features through to appropriate states (columns) from Table 2.7 on your Kanban board that you created as part of the product backlog deliverable. You don’t have to submit the board for this deliverable. Instead, it should be something you use throughout your software product development.

Layered Software Architecture

This exercise will facilitate, amongst your team, the design and discussion of your software product architecture. This deliverable should be done before starting to code the final product.1 Your team should agree on priorities and understand the trade-offs you are making in these architectural decisions.

  1. Using Figure 4.4 and Table 4.4, decide on the most important qualities for your software.
  2. Using Figure 4.10 as an example, figure out how many layers to include in your system.
  3. Start to populate these layers, as done in Figure 4.11. Through the layered architecture, this diagram will show how the architectural components will be distributed and communicate with each other.
    1. Involve your whole team and try out various decompositions to help understand their advantages and disadvantages.
    2. By trial-and-error, stop when you have what seems to be a workable decomposition architecture.
  4. Using Table 4.8 as a guide, research and make decisions about the technologies you will use in your product.

The steps outlined above should lead to a description of your product architecture that sets out the fundamental structure of your software and serves as a reference for its implementation. As such, put all of this information (important qualities, architecture, technologies chosen) in the README.md file for your project (note that this includes an architecture diagram). Next, submit the permalink to your project’s README.md file on GitHub Classrooms to Brightspace.

Defensive Programming

Add “defensive” programming to your project by adding input validation similar to what we have seen done with regular expressions in Chapter 8. Some examples include checking the format of phone numbers, usernames (you can come up with a scheme similar to that in the slides), mailing addresses, email addresses, password complexity, and password history (not using a previously used password as a new password).

Add a wiki page to your repository named “Defensive Programming Examples” that lists (using permalinks) and describes the code you have written in your project to make your project more resilient to user input errors. Note that you may not need explicit code to implement such a feature; many libraries and frameworks include reusable code for input validation. Submit the URL of your wiki page in Brightspace by the published deadline.

Adding an Automated Unit Test Suite (CI)

Instructions

  1. Using a testing framework (e.g., unittestpytest, MochaJest, JUnit) of your choice, add at least two unit test classes to your project similar to what is done on slides 25 and 2728. Each test class must have at least five unit tests (e.g., methods starting with test_). This must be done using a testing framework.
  2. Create a test harness similar to that in slide 29 if applicable for your testing framework. Some frameworks do not require this step.
  3. Set up continuous integration for your project that invokes your test suite each time there is a new commit to your project in your GitHub repository. You may use services such as Travis CIGitHub ActionsJenkins, circleci and AWS CodePipeline.
  4. Add a badge to your README.md file that indicates the testing status of your project.

Submission

Create a project wiki page named “Testing.” On that wiki page, include the  following information:

  1. Permalinks to the code of the two test classes that you created in GitHub. If you created more than two classes, use a single URL representing the entire test suite code (e.g., package, module) in GitHub (example).
  2. Permalink to the code of your test harness (runner) in GitHub (if applicable).
  3. URL of a recent test run of your project (example).
  4. Permalink to the section of your README.md file representing your test badge (example).

Submit the URL of your wiki page.

Notes

You may wish to run your tests via a build system appropriate for the language for which your system is written (some build systems, e.g., Buck, are language agnostic). Example build systems include GradleMavenMakenpm, and Grunt). Many of these systems support multiple languages. Here is an example of a Maven configuration for running unit tests.

Adding Continuous Delivery and Deployment (CD)

Add continuous delivery and deployment (CD) to your product such that, on each commit to your repository, your software product is automatically built and deployed. Depending on the type of software product you are creating, there are a few different ways to achieve this.

If your product consists a package that customers install (e.g., Android app) or a library or framework that customers use as a dependency in another software, you may consider using SNAPSHOT builds for this purpose. Such builds represent the latest version of the software, which may not be fully tested nor stable. However, they will be “bleeding-edge;” containing all of the latest features, enhancements, and bug fixes. A version number could be, for example, v4.2.1-SNAPSHOT. The “SNAPSHOT” part typically gets replaced with a timestamp that corresponds to the time the product was built (this is all typically done automatically by a build system). Then, when your ready to release the a proper version of your product, you simply remove the SNAPSHOT designator from the version, e.g. v4.2.1. Either way, they are both delivered and deployed automatically and when commits occur to the mainline branch of the repository. As an example, have a look at the release page of one of our research libraries.

If your product is a web service, a cloud service, or a web-based app, you may want to consider two different “areas” of deployment, i.e., a staging area where new features can be tested and a production area where the product is used by real customers. For simplicity, for this assignment, you can use just one “area,” where both your team and real customers will access the service or app. Either way, when commits reach the mainline branch2 of your project’s repository, the system should automatically build and deploy your product. Within minutes, you should be able to test a live, deployed version of your product corresponding to the latest commit pushed to your mainline branch. As an example, consider one of our research projects. It’s a web app that deploys via Heroku upon each commit to the main branch (have a look at the deployments).

There are many ways to achieve this, but, which ever way you choose, we require the following tasks, which must happen automatically:

  1. A working “deployments” section of your GitHub repository. Commits to your default (mainline) branch should trigger the deployment process, and there must be a “deployment” entry on your GitHub page corresponding to the deployment.
  2. The deployment should only happen if your test pass.
  3. If you are developing a web app or cloud service, a live URL of the deployment.

Have a look at this continuous deployment guide for more information. While you can use the same tools for CD as you do for CI, there are other options. You may also want to look into tools mentioned in the book, e.g., Puppet, Chef.

Submission

Create a project wiki page named “Deployment.” On that wiki page, include the  following information:

  1. A link to your deployments area as described above.
  2. A permalink to your deployment, which also must be stored in your repository, showing that:
    • The deployment is triggered by commits to your default branch.
    • The deployment commences only if the CI passes.
  3. A live URL of your deployment. If your product is a package downloaded and installed, this should be a link to the download page (e.g., a GitHub release with your package attached; the release must be created automatically).

Submit the URL of your wiki page.

Adding Event Logging and Monitoring

Instructions

  1. Using a logging framework (e.g., Log4Jlogging, winstonspdlog, Django Logging), add event logging to your project. You must use a logging framework; do not simply use “print” statements.
  2. Once you have the dependency on the logging framework setup (if necessary; some languages include built-in ones), add at least five logging statements of at least four granularities. For example, you may have five “fatal” log statements, ten “warning” log statements, twenty “info,” and five “fine” logging statements. The granularity names vary between languages and frameworks, but you should be able to find analogous log levels. Be sure to choose a framework that has at least four levels of logging granularity.
  3. Set your software product to log at the lowest level, e.g., “fine,” for continuous integration (CI) and not for production. In “real-life,” you may not normally do this because CI logs can get too long, but, for this deliverable, we want to be able to see all of the logs. It also helps to have a lower level of granularity in CI so that you can more easily diagnose test failures. Also note that logging should not just be exercised by the unit tests.
  4. Setup a log monitoring system for your product as shown on Figure 10.17. There are several options here, e.g., Amazon CloudWatch, Azure Monitor Logs, Splunk, Sumo Logic. The choice may depend on the kind of product you are building, a cloud hosting service that you are (possibly) using, and academic licensing. There are also open-source options, e.g., LogAI, Logstash. You may need to host these yourself, which should be relatively easy if your product is a web app; you can simply host the log analysis tool alongside your app (ensure that you have proper credentials to access logs as publicly exposed logs may pose security risks). If not, you can self-host a standalone logging console or ask me for department resources to do so.
  5. The log ingestion must happen in real-time; once a log is emitted from your product, it should appear in the logging console. You should omit the CI logs, however, from the console ingestion.

Submission

Create a project wiki page named “Logging.” On that wiki page, include the  following information:

  1. A description of your project’s logging strategy.
  2. A description of the logging framework of your choice.
  3. A description of the logging console of your choice.
  4. Permalinks to a recent CI run that shows your logs at the lowest granularity level, e.g., “fine.”
    • Do not make these too far in the past. Many platforms will rotate (delete) logs from runs. Please ensure that the permalink is to a recent run.
  5. Four permalinks to logging statements in your code, each having different granularity levels.
  6. URL of your logging console.
    • You may need to provide credential information to access it. If so, please do so in Brightspace only. Do not add them to your wiki page or use a password you use elsewhere.
    • Do not use 2FA if possible.
    • Ensure that your logs are emitted close to the due date (as in #4 above). Again, many platforms may rotate the logs frequently. To make it more likely for us to access your console with the logs you desire, please make them appear closer to the due date.

Submit the URL of your wiki page, along with any credential information (e.g., username, password) to access your live logging analysis console.

Adding Machine Learning (ML)

Add a Machine Learning (ML) component to your software product. You can either create your own model or query a third-party one. Create a project wiki page named “Machine Learning.” On that wiki page, include the  following information:

  1. A description of your project’s learning component. How does it work? How does it enhance users’ experience?
  2. A description of how you integrated the component into your existing application.
  3. Any challenges you faced.
  4. A self-assessment on how well it performs.
  5. Plans to enhance the component.

Submit the URL of your wiki page.

Enhancing Machine Learning (ML)

Enhance the Machine Learning (ML) component of your software product that you added in the previous deliverable. You may choose one of the following. If you have something else in mind, please ask the instructor first:

  1. We discussed that foundation models typically only generate artifacts (e.g., text, graphics) based on the software product. Enhance your project to take action on behalf of the user based on the output of your ML component. For example, if your product allows users to write reviews of courses they have taken, perhaps you may use your ML component to generate a good title for the review based on the review contents. Then, set the title based on this result, which should then be reflected in your database.
  2. The previous deliverable asked you for a “self” assessment on how well your ML component performs. Instead, create a quantifiable assessment that is completely automated.The assessment must work on the deployed software product and use data from the “production” environment.
  3. Collect live data from production and use it to enhance your ML component in some way, e.g.., retrain it offline, using online (streaming) learning. The collection must be automated (perhaps using logging from the previous deliverable). You may also wish to retrain and redeploy the models automatically (checkout MLOps). If you are using a foundation model, you may want to think about (automatically) enhancing your prompts over time using live data.
  4. If you are using foundation models, integrate RAG to incorporate alternative or current data sources.
  5. Integrate agents to enhance your ML component(s). The agents should work together to solve complex problems (you must have at least two). See this article for more information. Here is an example using LangChain4j.

Create a project wiki page named “Enhanced Machine Learning.” On that wiki page, include the  following information:

  1. The number of the task you did above (if you have a different idea, please let the instructor know beforehand).
  2. A description of your project’s enhanced learning component. How does it work? How does it enhance users’ experience?
  3. A description of how the enhancement differs from the previous deliverasble.
  4. A description of how you integrated the component into your existing application. Were there any new challenges?

Submit the URL of your wiki page.


  1. Note that a prototype aims to help you understand more about the product you plan to develop. Thus, it would be best if you implemented prototypes as quickly as possible. ↩︎
  2. What’s perhaps more interesting is to have a deployment from not only the mainline branches but also branches involved in pull requests. That way, pull request reviews can try out the proposed changes. ↩︎

Examinations

Midterm Examination

  • The exam will be 60 minutes in length. The exam will be held in the first part of the class. Following a brief break, we will continue the class, where I will most likely introduce a new deliverable, which you may work on with your group.
  • The exam covers material including software products, agile software development, software architecture, reliable programming (including design patterns), and the beginning parts of testing.
  • The exam will assess your understanding of the concepts put forth by the course materials up to this point in the course. You should have a good understanding of how to apply the concepts discussed.
  • A good way to study for the exam is to practice the questions at the end of the chapters. You can meet with your classmates to discuss the answers or at office hours. Another good way to study is to review your project deliverables and any practices from the course that you’ve applied to your project.
  • For any open-ended questions, keep your responses brief and to-the-point. Rambling and excessively long answers will be penalized.

Final Examination

  • December 17, 11:30 am – 1:30 pm in Hunter North C002.
  • The exam will be 60 minutes in length.
    • We may start with live demos in the first hour.
      • Presentations must not go over eight minutes to accommodate as many groups as possible.
    • Can leave when you are done with the exam.
  • The exam covers material up until the last class but not material before the midterm (non-accumulative).
    • The exam will cover material including testing, DevOps, code management, Constraint Programming (basics/high-level), Machine Learning, and Machine Learning systems.
    • Please focus on topics for which we had homework assignments or project deliverables..
  • The exam will assess your understanding of the concepts put forth by the course materials from the midterm and up to the end of the course.
    • You should have a good understanding of how to apply the concepts discussed.
  • A good way to study for the exam is to practice the questions at the end of the chapters.
    • You can meet with your classmates to discuss the answers or at office hours.
    • Another good way to study is to review your project deliverables and any practices from the course that you’ve applied to your project.
  • For any open-ended questions, keep your responses brief and to-the-point.
    • Rambling and excessively long answers will be penalized.

Resources