In most courses you never have to work on an assignment again once you submit it. Most project courses are different:
Assignments are cumulative, i.e., each one builds on the ones before it.
Projects may roll forward from one term to the next, so the end of one team's involvement isn't necessarily the end of the project.
These courses are meant to simulate real life, where delivery of a particular version is just another step in the product lifecycle.
This chapter describes some things you might be asked to do when wrapping up. Even if they aren't required, doing them is good practice for working in the real world.
At a minimum, your finished project should have:
A home page with an elevator pitch and a few paragraphs or bullet lists to help newcomers orient themselves.
An architectural overview, including a block diagram of the major components and a walkthrough of how it behaves. (I prefer the use-case maps introduced in Chapter 12 for this.)
An installation guide.
An up-to-date set of issues. If the work has been done, the issue should be closed; if not, it should describe the state of the bug (or enhancement, or question) well enough for someone to know where to start work.
Another possible deliverable is a package that other people can download and install (Chapter 12). It isn't an either/or choice: every good package has a home page, installation instructions, and so on.
It's OK to have bugs in your code when you finish your project—after all, almost all products do. This isn't because developers are lazy or careless; instead, it's a matter of economics. If you're near the end of the development cycle, it may be riskier to fix a minor bug (and introduce new bugs in doing so) than to document its existence and provide a workaround.
Depending on the structure of your course, you may be asked to figure out how much you would charge for the software you have produced. The answer is out of scope for this book, but [Davidson2009] is a good short introduction to the topic.
You may also be asked to do some marketing, which is the process of figuring out how to tell the people you're trying to help how you can help them. This doesn't mean spamming people with discount coupons; instead, it means explaining the problem that the product will solve in ways that will reach the intended users. I have seen more startups fail because of poor marketing than because of poor programming; it is also out of scope for this book, but [Jackson2017] is a good introduction.
If your project is like most, you're going to submit your work several times over the course of the term. That means it's important for you to keep track of exactly what version you're working on at any time, where it came from, and where it's going.
The usual way to do this is with version numbers. Most projects these days use semantic versioning; when you see a number like "220.127.116.117" attached to a piece of software, it generally means:
major version 6
minor version 2
The major version number is only incremented when significant changes are made. In practice, "significant" means "changes that make it impossible for older versions to read the new version's data or configuration files". In practice, major version numbers are often under the control of the marketing department—if a competitor releases a new major version, we'd pretty much have to as well.
Minor version numbers are what most people think of as releases. If you've added a few new features, changed part of the GUI, etc., you increment the minor version number so that your customers can talk intelligently about which version they have.
Patches don't have their own installers. If, for example, you need to change one HTML form, or one DLL, you will often just mail that out to customers, along with instructions about where to put it, rather than creating a new installer. You should still give it a number, though, and make an entry in your release log.
The build number is incremented every time you create a new version of the product for QA to test. Build numbers are never reset, i.e. you don't go from 18.104.22.1681 to 22.214.171.124, but from 126.96.36.1991 to 188.8.131.522, and so on. Build numbers are what developers care about: they're often only matched up with version numbers after the fact (i.e. you create build #1017, QA says, "It looks good," so you say, "All right, this'll be 6.1.0," and voila, you have 184.108.40.2067.)
Finally, groups will sometimes identify pre-releases as "beta 1", "beta 2", and so on, as in "6.2 beta 2". Again, this label is usually attached to a particular build after the fact—you wait until QA (or whoever) says that build #1017 is good enough to send out to customers, then tag it in version control.
A four-part numbering scheme is more than you need for an undergraduate course. You can probably get away with just one: the assignment the software was submitted for.
Most programs can report a version number, either through an "About…" menu item
or through a command-line option like
--version. It helps a lot when people are
The other thing student projects usually have to deliver is some kind of final report. Most students short-change this part of the course, in part because it comes at the end, but also because they think, "I want to write code, not a novel." However, [Fogel2005] had this to say:
The ability to write clearly is perhaps the most important skill one can have in an open source environment. In the long run it matters more than programming talent. A great programmer with lousy communication skills can only get one thing done at a time, and even then may have trouble convincing others to pay attention. But a lousy programmer with good communication skills can coordinate and persuade many people to do many different things, and thereby have a significant effect on a project's direction and momentum.
Final reports can range from half a dozen to fifty pages, depending on the course's structure and the instructor's whims. Regardless of their size, they will usually include the following:
This report is neither a user's guide nor maintenance documentation. Instead, it is like the end-of-contract reports I prepare when I'm consulting. What have I done to earn my customers' money? What should the next person (who might not be me) do? What can I tell them that would save them time?
So much for what the final report should include; how should you actually go about writing it? It will probably include:
paragraphs of text;
vector graphics (such as graphs and line drawings); and
raster graphics (such as screen shots).
Lots of tools exist that will handle these, but they all have shortcomings. You can create your report as a set of wiki pages or Google Docs, but they don't flag conflicts between concurrent authors. On the other end of the spectrum are WYSIWYG editors like Microsoft Word and LibreOffice. Unfortunately, these get in the way at least as much as they help:
They store documents in non-text formats that version control systems can't diff or merge.
It's hard to write scripts to process these documents, so inclusions (such as code fragments) have to be done manually.
Neither one handles equations very well (although both are getting better).
It's very easy to format things using low-level primitives ("make this italic") rather than logical styles ("making this a book title"), which makes it difficult to keep the document consistent over time.
For these reasons, most teams format their reports as a set of Markdown pages under version control and use a static site generator (Chapter 10) to turn them into a report. That solves the problem of multiple authors (Markdown is a text format, so diff and merge will work), and if you know a little CSS, you can make it look as pretty as you want. Diagrams and screenshots work well, and you can embed MathML for equations if you need to. The downside is that you can't actually see what your document is going to look like until you compile it, and doing that breaks your flow.
LaTeX is a markup language that's much more sophisticated than HTML and has literally thousands of add-on packages for equations, code formatting, and just about everything else you could want. Like HTML, LaTeX is a text format, so it plays nicely with version control. However, its power comes at a steep price: LaTeX is as hard to master as a programming language. It also has a frustratingly slow formatting cycle, since documents have to be compiled several times to resolve cross-references.
The most valuable part of your project isn't the software you write, or the grade you're given: it's the post mortem. Literally, this is an examination of a deceased person; in a software project, it's a look back at what went right and what went wrong.
The aim of a post mortem is to help the team and its members do better next time by giving everyone a chance to reflect on what they've just accomplished. It is not to shame people, but it can be hard to critique someone's work without them taking it personally, so post mortems add a few extra rules to the ones introduced for meetings in Chapter 2:
Once everyone's thoughts are out in the open, organize them somehow so that you can make specific recommendations about what to do next time. For example, here are the recommendations that came out of one post mortem I did with students:
Do a better job of tracking actual progress, rather than reported progress. Maybe require a one-minute demo every time a feature is marked "complete"?
Teams should find one block of 2--3 hours per week when they can work side by side: IM meetings and email resulted in a lot of dropped balls.
Having someone who worked on the project in the previous term come in to get the new team up to speed made a huge difference.
Issue tracking system was too complicated for students' needs: really just want a shared online to-do list.
Teams should have to report test coverage at every progress meeting to make sure that a lot of untested code doesn't pile up during the term.
Pay it forward
Ask your instructor at the start of your course for copies of the post mortems written by previous student teams. Go through and pick out some common themes, then use them as a list of things to do or avoid in your own project. Sharing what you've learned with those who come after you is the most compassionate thing you can do.