COS 333 offers an opportunity to undertake a design project, larger and more elaborate than typical course assignments, working in groups of 3 to 5 to design and implement a significant piece of software.
The intent is that this will not just be hacking, but a serious attempt to simulate some aspects of real software engineering: choosing something of intrinsic interest or utility to work on, planning an appropriate project trajectory, 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 create a marketable product or a new standard tool.
The project will involve many of the issues of software engineering as they occur in small, multi-person real-world projects. It should be relevant to the general themese and topics of the course, such as programming techniques, languages, tools, components, and interfaces. This should leave plenty of room for trying out interesting ideas with a broad spectrum of platforms, tools, and languages.
A large number of real-world systems are based on what is often called the "three-tier model": a user interface, a database or other back-end persistent storage system, and some business logic process(ing) between them. 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. We can see similar architectures even in radically different applications: YikYak has a (primarily) mobile device interface; the data is of post, voting, and user data; and the process is their spatial, temporal, and popularity logic for displaying new and top posts.
In light of this real-world status quo, the design project has one core objective: build a three-tier system for any application that appeals to you, using any combination of existing tools and new code. The functionality that you should provide includes:
User interface: This is what the user sees: an interface, often graphical, that supports some kind of direct interaction between user and system. Stand-alone graphical interfaces, Web-based interfaces, mobile device interfaces, and programming interfaces all satisfy this requirement.
Process: This is the business logic of your application -- presumably the "value added", since this is where you process and glue together what the user wants with information sources and repositories.
Data management: Somewhere there's some persistent data, whether maintained by your system on a local machine, or accessed as needed from the web, stored in a structured, engineered manner. You don't absolutely have to have a proper database, but you should put the same focus into your backend storage (used for recording significant state and using it in subsequent interaction) that you would into a database's architectural design.
There is no requirement for your application to be a distributed system, as opposed to a local stand-alone aplication, nor that it use any specific technology. However most successful projects have had some networked elements and use some modern frameworks. This can take many forms, however, from a dumb client interface using a hand-rolled web front-end and everything else on the server to a smart client built using a templating system that does all the processing and relies on the server only for backend data (and every possibility in between). You can use any combination that appeals for any aspect -- web-based or stand-alone; Windows or Unix or Mac or phone; Java or Python or Javascript or C#; CGI or PHP or JSP; Google Web Toolkit or Ruby on Rails or Django; your own machine or someone else's. The only restriction is that your running system must be readily accessible so you can demo it effectively and we can run it for grading.
Much modern software development is done by combining code and components that others have created. Projects will often use open source code and other publicly available material as building blocks or as the basis for modification and adaptation. This is permitted and indeed encouraged, but such code must be properly attributed, and the project as a whole must be a substantial contribution of your own work.
Project groups are encouraged to share insights and information about how things work, how to get things done, useful resources, and other aspects of programming knowledge.
This is a very open-ended specification, so the big problem is likely to be defining a topic of the right size and scope. You might think of this as practice for a new business or 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. A general guide is to pick a service or product that is novel and/or currently underserved, or that addresses a well-studied problem from a new angle, or that does one or more facets of it much better than existing solutions. Hiding, selecting, or merging data from existing services is a possibility; shopping, news and other bots are examples, as are the myriad mashups that combine information from multiple sources.
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. Broad categories include automating workflows, turning standalone programs into automated web services, or adapting extant processes to the brave new world where everything in life revolves around a smartphone. Another option could be to focus on tools or APIs that make it easier to build such things, and create a couple of simple examples that demonstrate the wonders of your tools.
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 other entities on campus, and they often have excellent project ideas in mind that can make a real difference on campus life. You might find something appealing from other people you encounter in all phases of your life on campus.
In this course, successful projects are those in which 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.
You have only about 12-13 weeks, even if you start at the very beginning of the semester, 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 60 percent of your course grade. All team members will get the same grade for all deliverables except for peer review (with the potential for a correction in the unlikely event of someone drastically shirking their repsonsibilities) 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.
How big a task are you proposing to take on? It should be big enough to justify spending well over half a semester on it, but not so big that it's unrealistic.
What are the components or pieces going to be? How will you organize your project into stages so that you can stop at any point and still have something that works? You don't want a project where everything must be finished before anything works -- "big bang" projects are a bad idea.
What will you learn from it? You should try a project that will force you to learn something new, like a significant language or tool or system, but you don't want to take on too many new things all at once.
What technical issues lie on the critical path? If you plan to use some particular tool or language or component or communication technique, what quick experiments can you perform now to be sure that it works and does what you need? Connecting components across a network in the face of security restrictions is sometimes harder than might appear; you want to know about potential roadblocks early. Even installing a language or a database or a development kit can take much longer than expected. Browser compatibility is a nightmare if you want to do it thoroughly. If you need someone else's data or other resources, make sure early that you can get access to them. If you're expecting to use the beta version of some software "about to be released", watch out; don't rely on other people to finish their work on your schedule.
How will you divide the work among the members of the team? This is partly personalities and partly interests and aptitudes. Some people are better coders, others write English better, or are great at designing web pages; some plan ahead, others work well under last-minute pressure. Some take charge naturally; others are happier with a defined task set by someone else. Organize yourselves to match the work to the people, and try to have a balanced group -- mere mortals who work well together can get more done than a team of prima donna superprogrammers.