Computer Science 333
The COS 333 project is an opportunity to undertake a larger and more elaborate task than any of the assignments: to design and implement a significant piece of software, working in groups of 3 to 5.
The intent is that this will not be just hacking, but a serious attempt to simulate some aspects of reality: choosing something suitable to work on, planning how to get it together, designing it before building it (though allowing for the inevitable changes of direction as things evolve), building it in stages, testing it thoroughly, trying it out on real users, and documenting and presenting the result, all as part of a small team. If you do it well, this should be something that you can show with pride to friends and prospective employers; you might even make money with it.
The project will involve many of the issues of software engineering as they occur in small, multi-person real-world projects. Some of this material will be discussed in class, and some will be found in assigned readings.
The considerations affecting the form of the project are:
A large number of real-world systems are based on what is often called the "three-tier model": a user interface, a database for persistent storage, and some process(ing) between them. Many web services use this architecture. For example Amazon has a web-based user interface; the data is a catalog and customer information, and the process is a wide variety of searching and data-mining operations. News and financial services are analogous: again, a user interface, a background information gathering and filing service, and mechanisms that let a client register for, access and process interesting items. Cell phone systems often have similar components, either on the device or elsewhere.
The project this year will be much the same as in the past few years:
build a three-tier system for any application that appeals to you.
This is a very open-ended specification, so the big problem is likely to be defining a topic of the right size. Almost every web service will suggest something, perhaps novel or perhaps "We can do that much better"; either would likely be fine. Hiding, selecting, or merging data from existing web services is a possibility; shopping, news and other bots are examples, as are the myriad mashups that combine information from multiple sources. Cell phone applications are often like this too.
Numerous web services (including Google, Amazon, Yahoo, Bing, and Facebook) provide program interfaces, which might be a way to put a different face on some aspect of their systems. Using these APIs could be good for potential projects, and creating a good API is a fine example of a non-graphical user interface.
Look around campus for other possibilities: maps, tours, notification services, databases, and so on are all potentially interesting and feasible, though make sure that the information that you want to use is available -- concerns for privacy, property and turf can all get in the way of a great idea. We often talk about projects with staff, faculty and other students. You might find something appealing on this list of project ideas from other people and by talking to people in other departments. If you want to explore further, come talk to the course instructors.
Some of the best projects come from noticing a task that is done by hand or poorly by machine, when it could be done really well by a suitable program, or where something complicated could profit from a neat user interface. Think about how Ajax might be used in some new application, or how some standalone program could be web-ified, or how some service could work on a smart (or dumb) phone. Or maybe focus on tools that make it easier to build such things, and create a couple of simple examples that demonstrate the wonders of your tools.
In my experience, in successful projects the people are really turned on by what they are doing, whether because it's their own idea and that's sufficient motivation, or because they are building something that someone else cares a lot about too. Either way, that kind of engagement usually leads to the best results. Be wary of projects where none of the group is really interested, or where one member is driving the whole thing, or where the application is too far away from your own experience.
Previous projects have included web-based calendars and financial systems; numerous improvements of campus services and agencies; rental and exchange systems; course evaluation, selection and scheduling; information services for the local environment; social networks; and several map mashups. Phone apps are becoming popular.
The assignment is to create such a system, using any combination of existing tools and new code. The functionality that you should provide includes the following:
How big? There's no official requirement, but it ought to ultimately involve some thousands of lines of code of your own; churning out a thousand lines of repetitive PHP or mechanically generating a bunch of Python with Django isn't enough. Some systems have been as big as 10,000 lines of C++; that's more than necessary, though it was great work. In any case, we will expect to see clean, well-written code, with appropriate attention to principles of sound software engineering.
Distributed or local? Most systems are distributed: the user interface runs on a client machine and the data is stored on a server. The processing might be at either end, or some of each. I strongly encourage systems that involve a network connection, even if it is only to a local host or the database, so as to leave open the option of distributed operation.
Make versus buy? Much modern software development is done by combining code and components that others have created. You can use as much of this as you like, as long as the finished product acknowledges the work of others, and has a substantial contribution of your own.
We have attempted to make this as open-ended as possible. This is your chance to invent something new, or to do something better than others do. You might think of this as practice for a new e-business or e-service, the sort of e-thing that made some of your predecessors here (like Meg Whitman and Jeff Bezos and the late Phil Goldman) into e-zillionaires. Of course if you have a really good idea and sell out to Google or do an IPO by Dean's Date, it's an automatic A+.
But you have only about 12-13 weeks, so you can't get too carried away. Part of the assignment is to plan exactly what you are going to create, what each team member will be responsible for, and what interfaces you will require between components so independently-created pieces will fit together. What schedule will you follow? How can you work on different parts in parallel and keep them integrated? How will you ensure, if your time estimates are too optimistic (as they inevitably will be), that you have a working subset, rather than a non-working collection of partially completed pieces? How will you convince a skeptical TA that you are making progress, not just writing code (or doing nothing at all)?
Since the project will involve multiple people, a major task is to divide the work into suitable pieces, with planned interfaces. Each of these components should be a separate entity that can be implemented and tested separately. But you will have to think carefully about the interfaces between them: the problems caused by poor interfaces are a recurring theme in comments from previous projects (and, happily, so are the strongly positive experiences reported by groups that did a good job on interfaces).
The project will represent 50 percent of your course grade. All team members will get the same grade (with the potential for a correction in the unlikely event of someone not carrying their fair share of the load), so be sure that you all agree on who will do what, by when, and to what standard. Each person must contribute their fair share, including writing a reasonable fraction of the code for the system, no matter what other role they play.
Here are some things you should start thinking about now:
Since the project involves more than half a semester, it is possible to develop a significant piece of software, but serious planning and steady work will be required for your project to be completed on time. To encourage planning, organization and regular activity, the project will have several deadlines that will be enforced. [Some of the dates near the end may shift a bit; there will be adequate warning.] The TAs will be responsible for primary supervision of the teams and the lead instructor will act as backup and second-level management. You will be required to meet with your TA manager/mentor each week after spring break. These meetings are a graded component of the course, so preparation and attendance are mandatory -- no excuses.
We will also try to follow good software engineering practice as much as possible. We will lean heavily on things that have been helpful in previous offerings, such as design documents, status reports and reviews aimed at helping you to organize and me to monitor. All of these are also mandatory and graded.
Your team should meet with the course's lead instructor for about half an hour to discuss your plans before they are set too firmly. If you need help finding a topic or choosing among several, please talk to the lead instructor and the TAs well before this meeting; we're happy to respond to ideas, make random suggestions, and help steer you, starting any time. But don't come to this meeting with 2 or 3 vague ideas, no team consensus, and no concrete plans. It is your responsibility to come up with a project and partners, so don't leave this to the last minute. If you want to explore projects that involve other parties on campus, come see the course instructors early so we can help you make connections.
Your team should create a project web site. The pages of the web site should reside on penguins in the
public_html directory of the team leader. The "home" page of the web site should be named
333.html. All files comprising the web site should be plain vanilla HTML files, perhaps with some image files.
333.html page should contain these items:
Your project's elevator speech should be a single paragraph that states clearly and succinctly what your system does.
The idea is this: What would you say if you were alone in an elevator with Bill Gates for 60 seconds, and had to ask him for funding for your project?
The speech should be a short attention-grabbing description without big words but with good buzzwords. You may be asked to give your team's elevator speech during one of the lectures; so be prepared.
The purpose of the Project Overview Document is to encourage you to do some detailed thinking about what your project is, and how you're going to work on it over the next 10-11 weeks. The more thinking you do ahead of time, the easier the pieces will come together when you do start to implement. Implementation before design is not a good idea.
The Project Overview Document should sketch out what you expect to accomplish in your project, and how. This should include an overview of what your system will do, the basic organization and components, a rough schedule of what you expect to accomplish each week, and who will be doing what. It should identify any significant risk factors and what you will do if bad things happen. ("We're expecting a large donation to buy a server; we will drop the course if this doesn't come through in time.")
The Project Overview Document should be roughly 3-4 printed pages. There's no need for fancy graphics or strong production values -- the content is what counts, though a reasonable level of detail, perhaps some diagrams and screenshots, and good English free of typos and spelling mistakes will help suggest that you have taken some care with it.
This link points to a good Project Overview Document from a couple of years ago, used with permission. Beware that this year's format is a little different.
Project name, project manager, group member names and email addresses.
This section should provide a few sentences that tell what your project is, what it hopes to accomplish and the like; the first sentence or two should tell the main story. A second paragraph might list the major features. It might also compare and contrast your system if it is like some existing system. A third paragraph might spell out the likely organization and operating environment: for example, a web-based application with Ajax in the browser and PHP on a Linux server, or an iPhone app that accesses a remote server.
This section should provide a few sentences describing the problem that your system will solve. More specifically, you should describe in detail the intended users of your system, and how your system will benefit them.
This section should give some scenarios, perhaps a couple of paragraphs each, of what a typical user of your system would do in a typical session. If you work through some scenarios carefully, the rest of the system will be a lot easier. Joel Spolsky's articles on functional specifications are worth reading. You don't need as much detail as he suggests but the kind of thinking behind it is very helpful. In particular, figuring out the main screens of the user interface will help organize your system.
For example, if you were doing a new version of Point, how would you describe some typical sequences of interactions, including what the user would see and do for each? If you were building an iPhone app, what would be the screens and what controls would be on each one?
Focus on this part before you worry about implementation languages and the like; until you know what you're going to build, it may be premature to worry about languages and tools, though those do affect what you can actually accomplish and for some things there's no choice anyway.
A brief description of the major components, what they do, how they connect and interact, and the most likely implementation. This is roughly what Spolsky calls a technical specification.
One major component will be the user interface. Web users might see a GUI that lets them search for information, select parts of it for update, and see the updated information. What form will this interface take? For example, it might be written with Flash to provide something graphically sophisticated, or it might use Ajax to provide rapid response, or it might be vanilla HTML. Which seems most likely?
Another component is likely to be a database where information is stored and subsequently retrieved. What information is stored in the database? What is the source of the data? Is there more than one source, as in a mashup? What are the basic relational tables likely to be? Does your system require an administrative interface to manage things like user accounts and bulk database updates? Some frameworks like Django create an admin interface for you -- is this an option?
A typical 3-tier system will have logic in the middle that extracts query requests from forms, builds database queries, and formats the results. This processing is the most specific to your project, so you want to plan it and spell it out carefully. What kinds of information are presented to the user, what responses are received, what processing is done on those before something is sent back to the user?
Describe interfaces between components, at least at a high level: what information passes in each direction, in what format, and what the major interfaces will look like. Interfaces insulate each part of the system from details of the other parts. For example, you should specify interfaces to the database in such a way that you could reasonably replace one database system (say MySQL) by another (e.g., Postgres or SQLite) without much change, and you could make major changes to the database tables without affecting much of the rest of your system. Similarly, you should be able to make significant changes to the user interface appearance without changing the code that processes the information from the user or retrieves information from the database.
Include a brief discussion of the likely implementation choices: languages and tools for various parts, operating environments for servers and clients, choice of database system, code repository, and the like. None of this is binding, but you should have thought seriously about it.
Include a list of significant milestones that you plan to have achieved roughly every week or two until the end. Allow for slippage, and for all the required components at the end: preparation of a talk and demo; documentation and other writeups; submission package; working version running perfectly by Dean's Date.
What's a milestone? Basically, it's some task or feature that is either 100% done, or not done, and you only count it as met when it is 100% done. Installing a web server on a personal machine or shipping a beta version to a friend is a milestone, but "coding is done" is not, since you don't know what "done" means. And "all bugs removed" is absolutely not a milestone.
What are the stages of your delivery? What will you build first to demonstrate minimal but working end to end functionality? What do you plan to have working for your first prototype? Plan for a sequence of stages where you can stop at any time and declare success.
This timeline from a previous project tells how a well-run project progressed; you might study that as you think about your own schedule. You will have to maintain your own timeline, so plan to start soon.
This is the place to show that you've thought about what you need to do and what might go wrong or cause delay. We're not interested in generic risks like someone getting sick or the dog eating your hard drive, but in perils specific to your project. Do you need to learn a brand new language or tool or system? Are you dependent on getting data or software or hardware or access to a particular system? What will you do if your preferred path is blocked? It's important to give this some thought, so you don't discover a month from now that you simply can't do something that you were counting on.
For example, if you plan to use Flash, do you have to acquire a copy somewhere, and does it cost money? If only one of you knows Python, while two know Java but not well, there's a potential problem either way, and you have to assess which path to follow and allow some time for getting up to speed. Do PHP and MySQL run on OIT machines? Where will your SVN repository be stored? Do you need a CS account? Do Java programs work with campuscgi? Can you test iPhone applications without a real phone? Do you need a developer certificate? Where are you going to host your system? Do you need web hosting and your own domain? You should find out right away whether your intended software is available on your intended platforms, and have a fallback plan if it is not. This is especially true for any aspect that depends on anyone or anything outside your group.
The timeline document should indicate, on at least a weekly basis, the tasks that each member of the team accomplished recently. You should update the timeline throughout the second half of the course. You should review your timeline with your TA during each weekly status meeting. Again, here's a good example Timeline document from a previous semester, used with permission.
Your team should meet with its TA on a weekly basis. In the first meeting you should go over the project in more detail, describe the project schedule, the components and interfaces, and the allocation of people to tasks. It is highly desirable to plan a sequence of stages such that each represents a working system; if your schedule proves too optimistic, this gives you a fallback that you can still demonstrate.
Before your first meeting with your TA:
In subsequent meetings you should describe your progress since the previous meeting, as documented in your project timeline (as described below).
Our intention is that the meetings will encourage you to think about what you have done and what you're going to do next. The meetings are a chance to talk things through, and get advice and opinion from someone supportive who is looking over your shoulder. The TA's job is not to solve your technical problems, and it's certainly not to tell you what to do -- it's your project. But pay attention, especially if your TA is concerned about something.
Everyone must come to all meetings if at all possible. If you absolutely must be away, courtesy and a concern for your grade mandates sending an explanation well before the meeting. Unannounced absences, and especially total no-shows, are unacceptable.
Be prepared. You might find it a good idea to meet among yourselves the day before your TA meeting. The time you spend thinking about and organizing for your meeting will pay off. The TA's are looking for you to be obviously prepared, with an organized agenda, and volunteering information; they should not have to drag things out of you, and they will definitely be unhappy if you're clearly just winging it with no evidence of effort ahead of time.
Everyone participates, is engaged, contributes. It should not be one or two people doing all the talking while others sit passively or fall asleep.
Given the short time scale, there really has to be progress every week. The TA's will be looking for evidence that you're getting somewhere, though of course there will be setbacks and dead ends; we just want to make sure those are under control.
We're also looking for evidence of planning, that you have a clear idea of what the next steps are each time. Fuzzy ideas or more of the same ("We're still working on getting the bugs out") are not a good sign.
Of course in return, you have every right to expect that the TA's will meet you at the scheduled time, will be well prepared, will have been thinking about your project, and will do their best to advise you well.
Your team should develop a bare-bones prototype that shows approximately what you are trying to do, and what your system will look like. It need not do much, but it must do some minimal part of the job. Your team should not be considering major or even many minor feature changes after this meeting, though your team need not have them all implemented.
Your team should demonstrate an "alpha" version -- an almost working version of the core functionality of your project. "Core" means the basic operations that form the essence of your project; if you were doing Amazon 2.0, for instance, this might mean searching for books and accepting orders. "Almost working" means that wizards (you) can help experienced programmers (us) to use the system. Your code may crash and need restarting. But you must be able to convince us that your project can be completed by the deadline.
Your team should demonstrate a "beta" version of your system. The beta version should largely work, all intended features should be installed and working, no major component should be incomplete. A determined sadist might be able to break your system, but a casual experimenter should not. It's very helpful if you can get real users before the beta: ask other teams, your friends and roommates, and anyone else to try your system to see how well it works. Drafts of written material (as described below) should be underway.
Each team should give a public presentation/demonstration of its work. All team members should attend the event.
Each team is required to attend two other presentations and you are strongly encouraged to attend more, for edification and moral support. Visitors are welcome, so bring your friends and family. Typical projects are great; come and hear about them. We will arrange a signup for presentation/demonstration slots during the last week of classes.
You can divide the presentation/demonstration responsibilities any way you like; there is no need for everyone to speak, but all team members must attend.
The presentation/demonstration will determine a significant portion of your grade, so you (and and the course instructors) want them to go as smoothly as possible. In order to assure this, start thinking about your presentation/demonstration now. You could picture your presentation/demonstration as an event that will make or break your "company" -- you'll be on the spot in a foreign place, with an audience, though the audience is really just a group of very supportive potential customers, investors, friends and family.
As to content, the "trade show" metaphor is useful, but you should aim for more than just a glitzy demonstration. The instructors really will be looking for evidence that you accomplished something, that you learned something, and that you can present something clearly. You might think of:
You will be allotted 30 minutes. Plan on using about 25 minutes, to leave time for questions, setup and teardown, and other delays.
Here are some minor suggestions that might help things go smoothly.
Grading criteria include the following:
For the demonstration, what kind of hardware and software and network access will you require? One solution is to install your project on a laptop that one of you owns. (This is a good chance to check out your installation procedure.) The room will have the usual computer projector (ONLY 1024 x 768!! Be prepared for the smaller screen size!!!), an overhead projector, and wireless access.
Whatever you plan to use for your demonstration, you should still be able to present if something breaks. Murphy's Law applies to all of us: bring along something that you can use in an emergency.
By the end of the semester your
333.html page also should contain these items:
The User's Guide should provide an overview of the system from the point of view of its (typically non-technical) end users. The User's Guide should describe what the system does and how to get it to do what it does. The User's Guide should not describe how the system works. (The System Design document should do that.)
The User's Guide should begin with a description of how to access or create/install a running version of your system. The installation part should contain enough detail that a user could install the executables on a suitable system. Think about the installation processes for some of the systems you used. There's often a file called INSTALL that explains what to do. Yours might be analogous. A single printed page might well be enough for this part.
Thereafter the User's Guide should describe how to use the system. More precisely, it should describe all features of the system in enough detail that the course instructors know of their existence, and know how to give them a try.
Your User's Guide Document should describe what your system does; its audience should be (typically non-technical) end users of the system. In contrast, your Design document should describe how your system works; its audience should be (certainly technical) software engineers who will maintain your system over time.
Your Design Document should describe the internal structure of the system's software. Imagine that you are writing this document for developers who will be maintaining the code after you hand it over. Help them understand how it's put together. If you were in that position, what would your like to have? Don't get mired in detail; half a dozen printed pages is likely to be more than sufficient.
The purpose of the Design Document is mostly to get you to think about an orderly and compact description of the components and their interfaces, striking a balance between too much detail and not enough. The document should provide a good working description of the system and its implementation, but not a line-by-line walkthrough of the code.
This also is the place where you implicitly acknowledge the software systems that you used but did not create.
Collect all code and code-related files that you created for your project in one place, and compress them into a single file. More specifically...
Create a directory for named
src. Copy all source code to that directory. That includes anything you created, especially source code and similar material. If you have help files, images, data, etc., put them in the
src directory too. Sub-directories are fine. Do not include other files that are created by compilation or downloaded from somewhere else: no object files, executables, class files, etc. We don't want to exceed some CS quota.
src directory to create a gzipped tar file named
src.tar.gz. This is an appropriate command sequence:
cd directory_above_src tar -cf src.tar src gzip src.tar
Be sure that your code is complete before you copy it to the src directory. We will be looking through your source code to get an idea of what you did and how well you did it, so everything should be there.
Your final report should describe how well the project worked out.
How good was your original planning? How did your milestones go? What was your experience with design, interfaces, languages, systems, testing, etc.? What surprises, pleasant or otherwise, did you encounter on the way? What choices did you make that worked out well or badly? What would you like to do if there were more time? How would you do things differently next time?
Imagine that you are writing this document for your (friendly!) boss or professor and want to explain what you learned that could be applied to the next project. This report is the most important component of the written part, so put some effort into it. A page is too short for this part.
Some groups present a single unified report, synthesized from the thoughts of all group members. Other groups prefer to write separate pieces of the report, since they focused on different project components and learned different things. Either style or some mixture is fine, but try to avoid too much repetition and "this was really interesting and we learned a lot."
We will be experimenting with your system starting on Dean's Date, so you must provide access to a running version. If the system is web-based, make sure it's up and running and we have whatever passwords and other controls are necessary to play with the system; that includes administrative rights if part of the functionality involves administration, though we will try to be very careful not to intrude or to break things.
If your system runs on specialized hardware (for example an iPhone or Android platform), then it probably will be necessary for someone to lend the instructors that hardware for a few hours some day. The instructors might be able to use simulators for some of it; suggestions would be appreciated.
If your system is meant to run standalone on Windows or Mac OS X or whatever, you can include a zip file or tarball that contains all the necessary files, along with any project files for the compiler you used. In this case, be sure to include installation instructions in your User's Guide.
You should test carefully to ensure that someone not in your group can exercise all aspects of the system, working only from the information in your submission.
It will be a great help if you follow these directions and try to make it easy for the instructors to look at and play with your project. If things go well, the instructors tend to be happy; if things go badly, they get grumpy. Happy graders tend to give better grades. And speaking of grading...
Grading for the project will be based on a number of criteria, including the quality of your:
You are encouraged to ask questions that will help clarify things for everyone. Murphy's Law applies to projects and their administration, so there will undoubtedly be screwups. We course instructors apologize for those in advance, but of course they too will be a simulation of reality...
This page was written mostly by Brian Kernighan and partly by Robert M. Dondero, Jr.