COS 333: Comments from Final Reports

Sat Nov 11 16:29:00 EST 2017

The following comments are taken from final reports in previous years; many thanks to the writers for sharing their experiences. The emphasis is on things that were a good idea, or that in hindsight would have been a good idea. He that hath ears to hear, let him hear; there is a stunning amount of truly good advice here.

New from 2017

We were able to get feedback on a prototype, something that we would recommend that all future teams consider before beginning their projects. The feedback we received both gave us confidence in our idea and saved us time in choosing features because we already knew what people wanted.

Success begets success. Your enthusiasm for working on a project increases when things start working properly and looking good.

Don't gloss over your design document; we would have been lost without it.

We were able to learn from attending the presentations of groups that had earlier slots.

We had a working prototype before our first TA meeting, and this initial momentum carried us through the rest of the semester.

If we could redo the last month, we would have users test our app as early as two to three weeks before the demo date, in order to get some constructive feedback to guide the final changes we were making to the site.

We kept a detailed document of the API routes to our server, and each one had a detailed description of what parameters went in the request body or in the url, and what it would return on success and on failure, complete with examples of each. We also kept a running list of unhandled issues: whenever someone found a bug, thought of a new feature or something that we might want to change in the future, we would write it down in a document. This way, when it came time to debug our app, instead of trying to remember or reproduce all the problems we had, we could go one-by-one through our list and work on those issues which were most pressing or immediate.

Things are going to take more time than you think. You should plan to have most of your functionality done at least a week before demos.

Trying to add new features the night before the demo is a recipe for disaster -- don't do it!

Learning web development is a lot like riding a bike, since it's terrifying when you don't know what you're doing and deceptively straightforward once you do.

Our "simple" application needed twenty hours of work from each of us each week to stay on schedule. Be sure to take on a project that can be reasonably accomplished, and don't be afraid to halt the development of features not essential to core functionality if you find yourselves struggling to keep up.

A divide and conquer model was more efficient for development, but a more centralized allocation of labor was better for future learning, combining different parts together, and debugging. In the end, we are happy with our decision to be on the latter side, but wish we had leaned a little more towards the former.

One of the most rewarding but also nerve-wracking aspects of working on this project was realizing that we have real users. With approximately 150 users, our website could be getting hits every hour of the day. Therefore, it is even more vital to deploy clean versions of our program and to employ defensive programming in order to reduce potential crashes.

In our academic work, we often focus on getting assignments turned in and mastering abstract concepts. However, this project required a different approach to problem-solving. There wasn't always a right answer, and we needed a new level of self-direction and accountability in order to make progress.

The biggest surprise of the project was realizing that it would require a lot more effort than we anticipated to get the data we needed.

Remember that deploying a tested app is still too soon for celebration; the deployed app itself needs testing!

Learning Git is like going to the dentist's: you know you really should do it, but you know it's going to be really painful, and if you don't do it, it'll come back to bite you really hard.

Unit Testing and Code Review are the bread and butter of a bug-free app. Establish your testing suite and get used to code reviewing before you submit code early on. The returns of adhering to these practices are exponential!

One of the most important lessons we gleaned was to approach everything incrementally, rather than in a haphazard mishmosh of intertwined coding.

We learned how to decompose, then learn, and then to do, rather than simply diving into the deep end without a swimming lesson.

We made the decision to deploy our project on Heroku early before our app had any real functionality to ensure that we knew how the deployment process operates as well as to show that our frontend, backend, and server can integrate fully as one whole. We were very glad of this decision later on.

Deployment wasn't even mentioned in our initial milestones. If our experience has taught us anything, it's that deployment can ruin even the best local applications. It's possibly the hardest part of getting an app running. Deploy early!

Save many minutes for your 'last minute' modifications - there are tons of them you'll uncover.

Take screenshots as you go along - we wish we had pictures of our initial implementations (mainly to laugh at)

Try to get people to actually start using your app early on. There's nothing that can replace real-world, user feedback. Often, your friends will help you find bugs or give ideas on what is missing.

Nobody in our group learned more than when we were up at two in the morning scouring documentation trying to fully understand what exactly we were adding to our program. This process, although painful, was extremely informative and extremely valuable to us.

It is much easier to build off of a central feature that is working properly than to throw together a bunch of semi-functioning components. A fully functional MVP also opens the application to many different pathways. With a product that you know functions in the way that you desire, building off of this product suddenly becomes a whole lot easier.

If you are dealing with data, be careful to write intermediate tests that check whether your data are consistent. Make sure that your code does not pollute your database - check for duplicate records as well as janky stuff.

Pick a project that you know you will enjoy to work on. These projects will take some time so you do not want to get wrapped up in a project that you do not enjoy.

New from 2015

StackOverflow is perhaps one of the most useful forums that we have ever encountered. Nearly every question that we had was answered on StackOverflow at some point, and usually the answers were exceptionally detailed.

Stack Overflow is a godsend. Apple's documentation was helpful too, but Stack Overflow was amazingly helpful. We did have to take Stack Overflow with a grain of salt, because older versions of iOS and Xcode have their own quirks and different features and best practices.

Ironically, writing a real-time 3D game with no networking for graphics (COS 426) took far less time and was much easier than writing a turn-based board game using networks. Networking is much harder than 3D graphics.

Debugging code is harder than writing it, which means that adding more features takes more time than you initially expect. We figured out that it's better to aim for a polished product rather than an app with lots of unfinished, buggy features -- there's a difference between what you want to add and what you should add when deadlines are involved.

Meeting in person and working as a group in the same room was very helpful for getting work done. When one of us was stumped with a bug, often someone else would have experienced the same issue and would sometimes be able to chime in with an answer. It also allowed us to quickly discuss what we wanted the app's behavior to be in specific situations. Also, because we had designated that time for work, meeting together encouraged us to continue working on our next goal even after implementing our current goal.

We realized that the best people to make design choices were users themselves. Hence, we consistently had mini-launches, in which we asked friends to use our product (without any guidance from us) and give us feedback. This allowed us to get input from people removed from the development process, who actually were seeing the product for the first time and interacting with it from a new user's point of view.

There is nothing more rewarding than the accidental discovery that a friend has decided to use your product for a second time - because it matters. To future 333ers of the world, Hack on.

We highly recommend that future students come into the class with a group already formed and a rough idea of the problem they would like to address. It is imperative to start early: the earlier you start, the more you can accomplish and test!

Github made group development incredibly painfree. We rarely if ever pair programmed, and weren't in the same rooms much either. But its merge functionality was awesome and (along with careful planning) allowed us to all work on what we wanted to when we wanted to.

Although we were all most familiar with Java and appreciated its abilities to integrate with various libraries and the GWT framework, we would definitely be willing to find ways to accomplish our goals in another language in order to avoid having to deal with GWT.

We would highly recommend investigating the documentation and other resources available for a tool or framework before deciding to implement it into your system.

In retrospect, we really should have made talking with OIT our first priority, even before diving into any implementation details such as learning Django; it would have saved us a significant amount of effort and stress and just required a little more planning and forethought.

Javascript certainly isn't the cleanest or nicest language to work with.

Figuring how to deal with someone else's code was perhaps one of the biggest learning experiences we had during the course of this project.

Another critical strategy was to reach out to others, both within our group and to those outside of the group.

When designing a new app that is fundamentally a utility app (as opposed to, say, a game), it is easiest for users if all the controls and behaviors are exactly as they'd expect from other apps.

We had been trying to develop independently of each other (meaning, we were all coding in different physical locations) and we realized just how much this hurt us when we actually coded together for the first time pretty late into the project. We were able to get a monstrous amount of work done simply by having other people around to make decisions with and discuss problems. We should have done this from the beginning.

We would definitely program together in the same room much more often; once we started doing that more, the rate of progress increased dramatically. This is not only because we can ask questions and collaborate on code if we get stuck; it's also because when developing disparate components that are supposed to interface with each other, like a server and a client or even two controllers or models, it is useful to know exactly what the behavior is instead of stumbling around guessing at what certain functions do.

Use Heroku or some other easy deployment service. You want to spend all of your time working on your application, not trying to debug deployment issues.

If you project follows a client/server model, develop both together. It's much easier to hook up the client and the server when they're being programmed in a unified way rather than splitting them up and hoping the interface lines up in the end. This is usually for granted with web applications in HTML, but is especially important for mobile apps. Build a barebones prototype and add functionality from there, rather than building all the functionality first.

Establish conventions with naming variables and functions (we struggled with that). Establish areas of ownership where you can, but also work across the product wherever possible.

Watch out for features that rely on other peoples' APIs and documentation. You may find yourself facing unexpected, arbitrary constraints.

The fact that each group member could work individually most of the time significantly increased our productivity. Rather than being dependent on someone else to make progress, or only being able to work when the group met as a whole, we each could check out and modify our own version of the Git repository.

There are simply too many unforeseen challenges and unexpected feature requests that will come up in order to be able to make a perfect schedule of milestones. That said, however, I think our group was very good at keeping on track. Though the goals of each week often diverged from our initial plan, we did have goals for each week that helped keep us moving forward.

We also took away a lesson on the importance of a solid foundation when building a large code base. The fact that we put a lot of extra thought into the initial architecture of how our code would work paid significant dividends toward the end of the semester. Because we had developed solid foundations, we were able to build lots of cool features on top. We also learned the importance of well-defined APIs; with a group of four different programmers all working concurrently, if APIs are ill-defined, a lot of time can be wasted by both programmers trying to get their code to synch up.

This project also exposed us to a lot of aspects of the software engineering process that we hadn't really seen in other classes, concepts like planning an architecture and collaborating on a common code repository.

The process of learning, in and of itself, was a major challenge as GWT is not particularly well documented.

We needed to enforce strict version control and documentation throughout this project. Since more than one person was contributing to the project at any one time, it was imperative that we set up good documentation so that others could understand what we had implemented.

It is extremely helpful to start planning early. This gives you more time to make design decisions and think about the best way to implement the project before you write a single line of code. We also believe it is helpful to keep a schedule and implement a few features per week, instead of trying to implement the entire project towards the end.

If you are stuck on an individual task and cannot figure it out reasonably quickly, you should immediately ask your group for help.

Next time we would try to give a working version of our project to potential users sooner, so that we could gather feedback and use it to improve our product. We did not share our project with anyone outside our team until the week we presented, at which point we had limited time to make changes based on the user feedback we received.

We should have launched earlier and worked faster--especially in the first weeks of the project.

Having weekly meetings with our TA was very helpful in meeting milestones, as showing your work to an outside observer is always inspiration enough when it comes to making progress. That is, deadlines are really very helpful.

It has been particularly nice to hear from our peers who have seen the site; the feedback has been great, and it just feels really good to have made something that can be so useful to so many people.

We found that the ability to constantly be in touch via chat programs and text messaging was vital to the success of the project.

Having a solid idea that is achievable and marketable (in both monetary and nonmonetary way) is the most important thing to enjoy this class fully.

It would have been better if we created a schedule that took into consideration other courses (e.g. the weekend right before the Networks Router assignment was not particularly productive).

We wished we had done more over spring break. start early, use spring break wisely, and think about implementing the larger concepts before considering small cool features.

Something else that was suprising was the difference between Google's documentation on Google Web Toolkit and Google App Engine. We found that the App Engine documentation was straightforward with clear guidlines on how to do any and everything. Guides were more straightforward and self help books for Web Toolkit just seemed overly complicated and confusing.

Choosing to start with Google Web Toolkit primarily on the "Java" label for programming language was a big mistake. We did not take into account the complexity of the system or how everything would work. Switching to Python and Google App Engine early was the best decision we could have made

Start early and ask questions. If anything, fail quickly! As soon as you know the path you're on may be too painful or complicated, switch. You'll thank yourself later.

Her feedback helped us focus on the most important things and highlighted many places where our UI needed tweaking.

With regards to our milestones, it suffices to say that we were never ahead of schedule.

Although our individual assignments tested successfully before integration into the final product, there were more issues than we expected when we put all of our individual pieces of code together. We spent most of reading period fixing integration bugs and testing the final product.

We also did not leave enough time for preparing our presentation. We did not factor into our schedule that we would need more than a trivial amount of time to put together our demo for the teaching staff. We would offer this advice to future groups: you need more than a working product to show off, make sure you leave time to plan out and practice a polished presentation.

It took us a lot longer than we expected to get acquainted with XCode and with the iOS programming environment since it was quite different from what we had been in contact before.

One task we assigned ourselves for spring break was to familiarize ourselves with the languages and tools we would be using.

In COS 226 and 217, the assignments never required knowledge outside of what was learned in class. We simply had to be creative in applying it. The programming assignments were like puzzles to be solved rather than things to be built. For this project, a significant amount of time was spent figuring out how to do things, either by searching on the internet or "guestimating" with experimental code.

New from 2014

This project was an incredible experience and we are really proud of what we have created.

The biggest lesson was that we vastly underestimated the amount of time each feature would take to implement.

None of us had used Django or Postgres before, and one of us had no web development experience at all. It took a long time to get the initial site running, both locally and deployed on Heroku. We underestimated how much time we needed to learn the basics.

Spend more time designing, then start implementing.

Start early, and work consistently. These are things that everyone knows, but that does not make them any less valid.

Be sure not to jump into a group with too many people unless you can ensure from the outset that coordinating tasks and schedules will not get too complicated.

Our demo was a case in point of the fact that live demos are unreliable and terrifying. We should have had screenshots of everything we wanted to show during the live demo to fall back on in case of emergency. Future COS 333ers be warned!

Keep the big picture in mind constantly. Each member should at least be familiar generally with what every lump of code does to avoid bottlenecking during integration.

Beta-testing earlier is better because it's easy to develop a skewed concept of "intuitive UI" as the developer.

In the frenzy to implement features quickly, we often forgot to follow good coding practices. There is a reason they are good practices.

Completing a CS project is more than just implementing a list of features.

If possible, come into the class knowing what your project is going to be so that you can work on it early,.

Research can only bring you so far when you are deciding on what tools you would like to use. The only way to find the best combination of tools for your project is to try a few different things out.

New from 2013

Certainly the lowest point during our work this semester was the demo day. We felt the need to demonstrate the project with its full functionality, which drove us to make a multitude of last-minute changes. Because of this, we were not able to test the system as a whole and upon merging our changes, found that the website had actually lost functionality rather than gained it.

Plan to be delayed and have issues. Our initial timeline was way too ambitious and we quickly fell behind.

What helped us most in completing our milestones was getting an early start. When we submitted our design document, we already had our development environment, ec2 server, database, and github repository set up and our technology stack picked.

Xcode made it easy to drag buttons, text fields, and table views on to an app, but it did not make it easy to do slightly more complex tasks like change the border radius of a button, add 2 textviews above a table view, or make the application looks like something than other that a collection of default page elements.

We strongly urge next year's class to consider NodeJS and Express for their projects. Our experience with these tools was very positive; they were easy to use and gave us a very flexible web framework.

In hindsight it would probably have been good to get some user feedback during the development process.

If you feel like you are ahead on the project, you are working at the right pace. If you feel like you are working at the right pace, you are behind.

You know that bug that magically disappeared? It's waiting for when you give your project demonstration.

Figure out the front end first! For our prototype, we created front-end mockups for each page that had buttons that clicked through the site without any of the business logic/database access. By creating a "dummy site", by the time we were ready to start writing the backend, we already knew the workflow for the entire site and knew exactly what we wanted the end product to look like. This made it very easy to document our progress and create weekly to-do lists

If we had the chance to do this project over, the best improvement we could make to our process would be to plan more carefully before beginning. Our project saw a fair number of changes in direction as we went along, but if we had had a clearer understanding of what our end product would turn out to be, we probably could have avoided a bunch of branches in directions we didn't end up taking.

Take the time to come up with a really great idea. We bounced around many lesser ideas for a while and kept thinking until we had to declare our project and ended up with a much better idea, having had the time to flesh it out.

Read the documentation on any technology you plan on using incredibly thoroughly before you start using it. Not only will this minimize the number of surprises and mysteries along the way, but it will show you some of the easiest ways to do things.

GitHub rollback features saved us a lot of time in the long run.

Orange, as we've found, does not go well with anything--even more orange.

Bootstrap makes handsome website design a snap; the generic design was an issue, but we made sure to spend time personalizing it.

If we were to start a new project from scratch, we would definitely be able to plan every component in more detail (perhaps even with some pseudo-code) instead of being high-level and saying something like, "We'll use Django."

In keeping with the trial-and-error theme, keep a log of every challenge, bug, or problem that you faced and how you fixed it. Often another team member will encounter the same problem (or you yourself will), and you'll be making so many changes that it's easy to forget if you don't write it down.

Perhaps taking a week to make a hello world website on a framework over break would have helped with the steep learning curve that many of us experienced.

jQuery ended up working out really well; every time we wanted jQuery to do something, it existed as a built-in jQuery function and was named exactly as we expected it to be named. The intuitive nature of jQuery was pleasantly surprising, especially the ability to use CSS-style selectors in a very general way.

We focused first and foremost on functionality and layout, and thus left the "minor details" of fonts, color, background, etc. up to whoever happened to be working on that feature at the time. Due to differences in taste and the lack of a framework like Bootstrap, we ended up with some inconsistent styling that had to be resolved through much debate within the group.

Get started early. That means both choosing a project and group early in the semester and actually starting to build things as soon as is reasonable. Have a clear idea of what you want your site/app/whatever to be able to do, and focus on getting the basic features implemented before trying to do fancy things.

It's important to make sure that for every tool you use, there is at least someone in your group that understands it.

If we had to do it again, we would have started working from the very beginning of the semester.

Meeting as a group is very important. It allows the whole group to stay up to date on the progress of the project and to establish what priorities need to be accomplished, who is going to work on them, and how they are going to be done. This should be in addition to the meetings with the TAs. The TA meetings should really just be about getting input from an experienced developer and holding your group to the deadlines established.

It is important to choose tools that you either know how to use or can quickly learn. Deciding on using a tool as a "blackbox" is a recipe for disaster since you won't know how to fix issues when the tool misbehaves.

When you want something done right, you have to do it yourself. Also, don't be afraid to dig into what looks like too much to learn; it will often save time to do things properly the "hard" way instead of trying to use quick fixes.

The biggest lesson we gleaned from testing is that - as one would expect - it should be done.

Formatting the web pages proved to be harder than expected. Something that looked great in one browser might suddenly look terrible in another or cease functioning altogether

Prior to this project, most of us had only experienced pair-programming, making the realization of the importance of team unity and an active leader less naive than it may appear.

Most everything is harder than it looks.

Tutorials with a small application as an end product are infinitely more useful than reading documentation.

Starting early on the mobile apps was extremely helpful since it took us significant periods of time to acclimate to the languages and to overcome the learning curves.

On Heroku, the database becomes ephemeral. We did not even notice this until we got everything up and running on Heroku. We realized that the data we had created the day before was no longer there

Perhaps the key lesson learned from our work on the project is that things that seem easy can take a lot of time. With projects that have a lot of different features and functionality, it is crucial that work is started early because everything can be fully tested only when put together.

Our testers were very useful for catching small mistakes in the user interface such as typos or inconsistencies and letting us know where things were a little confusing.

We were surprised by how quickly the semester ends!

First of all: try and really understand all the available features and moving parts of areas like the database that have long term organizational and operational implications for the rest of your progress. There's a fine line between planning too much and planning too little, but erring on the meticulous side when dealing with the database is a good idea. While you can still deliver a working product without it, you'll probably wish you did in the end.

Another piece of advice is to find good testers early. Get people looking at your application the minute you have a product even halfway respectable enough to show, and take note of the people who offer good feedback. They'll be invaluable in making decisions about what is most important for your application!

Another lesson learned was the importance of storyboarding and sharing a common vision for the website from the beginning. Before ever starting any coding, we sat down together and sketched out exactly what we wanted our website to look like. Our final product is actually remarkably similar to our original storyboarded ideas.

We made the mistake of hard coding our project name throughout the software. The day before the final presentation, we had to spend several hours fixing the web page names and modifying the Facebook permission urls. If we had put more thought into naming earlier or had at least realized that the name was likely to change, we could have saved a lot of time later in the project.

Using Github was a night and day change from what we had done prior: copy and pasting code messily into emails. With Github, we were finally able to work remotely and independently when our schedules did not match, and our project progress quickened dramatically.

One thing that we should have done differently was to create a base html template for all of our pages. Because we failed to do so, every time we changed something such as default font or the navigation bar at the top of the page, we had to edit every single html document.

When you put a lot of work and effort into it, and in the end you see this functioning website, you will be happy to know that wow, we created this. You can send the link to your friends and family, which is really exciting, and you become very proud of your website. The more work you put into the site, the prouder you'll be.

There needs to be a balance between specialization and all-around knowledge for each team member. On one hand, it is easier for one person to always program for one part of the project and have another person handle another, and so on until everyone is responsible for their own part of the project. By specializing in an area, they can quickly program in that area. On the other hand, it is important to have an understanding of everyone`s code and what methodology they use to implement it. Without this sense of knowledge, two people working on different features simultaneously may contradict each other, cause the others to break, or create a nightmare when merging.

We would advise future groups to consider the tradeoff between familiarity and novelty carefully: the more your group departs from their areas of expertise, the more you will learn, but at the same time, this may make it harder to make concrete progress.

Writing a large chunk of code without testing as you go is always dangerous. Phoneless students must resist the temptation to delay testing until an opportune moment. Future groups may want to think twice about developing for a device that only some of their members possess

We designed our milestones to allow concurrent client/server software development so that neither end was held up by any lack of development on the other.

It was extremely helpful to have a central spreadsheet on Google Drive that tracked the entire project's progress at the feature-by-feature level.

We should have thought about our planned functionality and plotted out a solid database before moving forward with other development. That way, every component would know what to expect and mesh appropriately.

Be aware of how quickly the end of the semester arrives. After spring break, there is only a little over a month-and-a-half left to complete the website before Dean's Date. Thus, it is very helpful to accomplish a lot over spring break.

Any prior knowledge/specialty in a particular area can save a lot of time and significantly increase the efficiency of the work.

The first thing we would have done differently would have been to perform much more research even before the design document stage.

While it is one thing to hear "start early and plan hard!" it is quite another to be burned by a late start and anaemic planning. If we were to take this class again, there is no doubt that our project would be based on a better understanding of the subject matter and planned to a much greater extent; however, there's just about no way to teach that to students short of having them experience it.

Under no circumstances should you turn your testing code into a hacked-together final project. Do a prototype, learn from it, then start fresh for the final version.

Spend some more time deciding exactly what tools will be used and how they will fit together. We made these decisions with less research than we could have. Ultimately, we got everything to work, but five hours of research would have saved us fifty hours of debugging.

It would have been helpful to acquire more users earlier in the development process.

New from 2012

StackOverflow is perhaps one of the most useful forums that we have ever encountered. Nearly every question that we had was answered on StackOverflow at some point, and usually the answers were exceptionally detailed.

Stack Overflow is a godsend. Apple's documentation was helpful too, but Stack Overflow was amazingly helpful. We did have to take Stack Overflow with a grain of salt, because older versions of iOS and Xcode have their own quirks and different features and best practices.

Ironically, writing a real-time 3D game with no networking for graphics (COS 426) took far less time and was much easier than writing a turn-based board game using networks. Networking is much harder than 3D graphics.

Debugging code is harder than writing it, which means that adding more features takes more time than you initially expect. We figured out that it's better to aim for a polished product rather than an app with lots of unfinished, buggy features -- there's a difference between what you want to add and what you should add when deadlines are involved.

Meeting in person and working as a group in the same room was very helpful for getting work done. When one of us was stumped with a bug, often someone else would have experienced the same issue and would sometimes be able to chime in with an answer. It also allowed us to quickly discuss what we wanted the app's behavior to be in specific situations. Also, because we had designated that time for work, meeting together encouraged us to continue working on our next goal even after implementing our current goal.

We realized that the best people to make design choices were users themselves. Hence, we consistently had mini-launches, in which we asked friends to use our product (without any guidance from us) and give us feedback. This allowed us to get input from people removed from the development process, who actually were seeing the product for the first time and interacting with it from a new user's point of view.

There is nothing more rewarding than the accidental discovery that a friend has decided to use your product for a second time - because it matters. To future 333ers of the world, Hack on.

We highly recommend that future students come into the class with a group already formed and a rough idea of the problem they would like to address. It is imperative to start early: the earlier you start, the more you can accomplish and test!

Github made group development incredibly painfree. We rarely if ever pair programmed, and weren't in the same rooms much either. But its merge functionality was awesome and (along with careful planning) allowed us to all work on what we wanted to when we wanted to.

Although we were all most familiar with Java and appreciated its abilities to integrate with various libraries and the GWT framework, we would definitely be willing to find ways to accomplish our goals in another language in order to avoid having to deal with GWT.

we would highly recommend investigating the documentation and other resources available for a tool or framework before deciding to implement it into your system.

In retrospect, we really should have made talking with OIT our first priority, even before diving into any implementation details such as learning Django; it would have saved us a significant amount of effort and stress and just required a little more planning and forethought.

Javascript certainly isn't the cleanest or nicest language to work with.

Figuring how to deal with someone else's code was perhaps one of the biggest learning experiences we had during the course of this project.

Another critical strategy was to reach out to others, both within our group and to those outside of the group.

When designing a new app that is fundamentally a utility app (as opposed to, say, a game), it is easiest for users if all the controls and behaviors are exactly as they'd expect from other apps.

We had been trying to develop independently of each other (meaning, we were all coding in different physical locations) and we realized just how much this hurt us when we actually coded together for the first time pretty late into the project. We were able to get a monstrous amount of work done simply by having other people around to make decisions with and discuss problems. We should have done this from the beginning.

We would definitely program together in the same room much more often; once we started doing that more, the rate of progress increased dramatically. This is not only because we can ask questions and collaborate on code if we get stuck; it's also because when developing disparate components that are supposed to interface with each other, like a server and a client or even two controllers or models, it is useful to know exactly what the behavior is instead of stumbling around guessing at what certain functions do.

Use Heroku or some other easy deployment service. You want to spend all of your time working on your application, not trying to debug deployment issues.

If your project follows a client/server model, develop both together. It's much easier to hook up the client and the server when they're being programmed in a unified way rather than splitting them up and hoping the interface lines up in the end. This is usually taken for granted with web applications in HTML, but is especially important for mobile apps. Build a barebones prototype and add functionality from there, rather than building all the functionality first.

Establish conventions with naming variables and functions (we struggled with that). Establish areas of ownership where you can, but also work across the product wherever possible.

Watch out for features that rely on other peoples' APIs and documentation. You may find yourself facing unexpected, arbitrary constraints.

The fact that each group member could work individually most of the time significantly increased our productivity. Rather than being dependent on someone else to make progress, or only being able to work when the group met as a whole, we each could check out and modify our own version of the Git repository.

There are simply too many unforeseen challenges and unexpected feature requests that will come up in order to be able to make a perfect schedule of milestones. That said, however, I think our group was very good at keeping on track. Though the goals of each week often diverged from our initial plan, we did have goals for each week that helped keep us moving forward.

We also took away a lesson on the importance of a solid foundation when building a large code base. The fact that we put a lot of extra thought into the initial architecture of how our code would work paid significant dividends toward the end of the semester. Because we had developed solid foundations, we were able to build lots of cool features on top. We also learned the importance of well-defined APIs; with a group of four different programmers all working concurrently, if APIs are ill-defined, a lot of time can be wasted by both programmers trying to get their code to synch up.

This project also exposed us to a lot of aspects of the software engineering process that we hadn't really seen in other classes, concepts like planning an architecture and collaborating on a common code repository.

The process of learning, in and of itself, was a major challenge as GWT is not particularly well documented.

We needed to enforce strict version control and documentation throughout this project. Since more than one person was contributing to the project at any one time, it was imperative that we set up good documentation so that others could understand what we had implemented.

It is extremely helpful to start planning early. This gives you more time to make design decisions and think about the best way to implement the project before you write a single line of code. We also believe it is helpful to keep a schedule and implement a few features per week, instead of trying to implement the entire project towards the end.

If you are stuck on an individual task and cannot figure it out reasonably quickly, you should immediately ask your group for help.

Next time we would try to give a working version of our project to potential users sooner, so that we could gather feedback and use it to improve our product. We did not share our project with anyone outside our team until the week we presented, at which point we had limited time to make changes based on the user feedback we received.

We should have launched earlier and worked faster--especially in the first weeks of the project.

Having weekly meetings with our TA was very helpful in meeting milestones, as showing your work to an outside observer is always inspiration enough when it comes to making progress. That is, deadlines are really very helpful.

It has been particularly nice to hear from our peers who have seen the site; the feedback has been great, and it just feels really good to have made something that can be so useful to so many people.

We found that the ability to constantly be in touch via chat programs and text messaging was vital to the success of the project.

Having a solid idea that is achievable and marketable (in both monetary and nonmonetary way) is the most important thing to enjoy this class fully.

It would have been better if we created a schedule that took into consideration other courses (e.g. the weekend right before the Networks Router assignment was not particularly productive).

We wished we had done more over spring break. Start early, use spring break wisely, and think about implementing the larger concepts before considering small cool features.

Something else that was suprising was the difference between Google's documentation on Google Web Toolkit and Google App Engine. We found that the App Engine documentation was straightforward with clear guidlines on how to do any and everything. Guides were more straightforward and self help books for Web Toolkit just seemed overly complicated and confusing.

Choosing to start with Google Web Toolkit primarily on the "Java" label for programming language was a big mistake. We did not take into account the complexity of the system or how everything would work. Switching to Python and Google App Engine early was the best decision we could have made.

Start early and ask questions. If anything, fail quickly! As soon as you know the path you're on may be too painful or complicated, switch. You'll thank yourself later.

User feedback helped us focus on the most important things and highlighted many places where our UI needed tweaking.

With regards to our milestones, it suffices to say that we were never ahead of schedule.

Although our individual assignments tested successfully before integration into the final product, there were more issues than we expected when we put all of our individual pieces of code together. We spent most of reading period fixing integration bugs and testing the final product.

We also did not leave enough time for preparing our presentation. We did not factor into our schedule that we would need more than a trivial amount of time to put together our demo for the teaching staff. We would offer this advice to future groups: you need more than a working product to show off, make sure you leave time to plan out and practice a polished presentation.

It took us a lot longer than we expected to get acquainted with XCode and with the iOS programming environment since it was quite different from what we had been in contact before.

One task we assigned ourselves for spring break was to familiarize ourselves with the languages and tools we would be using.

In COS 226 and 217, the assignments never required knowledge outside of what was learned in class. We simply had to be creative in applying it. The programming assignments were like puzzles to be solved rather than things to be built. For this project, a significant amount of time was spent figuring out how to do things, either by searching on the internet or "guestimating" with experimental code.

Planning

We believe that we might have been able to get a little bit more accomplished if we had been able to get a clear grasp of the goals and requirements for our project.

If we were starting from scratch and repeating our project, it seems like one of the most significant and worthwhile changes would be to spend more time perfecting each stage of its development rather than simply going into the next stage.

One thing we wish we could get another shot at was initial planning - the second time around, we would focus more heavily on input from the general population in terms of design and functionality.

One of the best decisions we made in organizing the project was to meet several times to plan out the project in detail before writing our first line of code. In our first meeting, which was well before spring break, we first came up with our project idea. Then we debated the best architecture for the system and the best way to divide it into pieces. These debates forced us to think through many of the important details early on, reducing the number of "surprises" that we encountered later in the semester. Once we figured out these aspects of the project, we sat down as a group to develop the interfaces between the user-interface web pages, the middle layer, and the database. Although some changes to these interfaces were necessary, especially because we made feature changes as the project went on, the interfaces stayed intact for the most part. Because of the continuity of the interfaces, pieces of the project that we wrote separately (like the web pages and the database) came together with little effort.

The long term nature of this assignment and the division of labor among multiple developers, made the approach of careless and unplanned hacking impossible. Rather than storming ahead to finish the project as quickly as possible, this project was completed by continuously taking two steps forward and one step back. This required a significant amount of planning, and the willingness to stop and clean up, refactor, and sometimes delete code completely.

I learned the hard way about the importance of having a strong initial design. Several times in this project, we changed our main interface in order to allow for more functionality. While I believe these changes were good in the long run, there was a lot of work involved re-writing to fit the new interface. I think our project would have greatly benefited from a more well thought-out initial design/interface.

If we were to do it over again I think we would need to spend a lot more time working on our initial design and stick to it even in cases where there is an obvious improvement if this improvement requires significant changes to the current architecture.

As a side note, when writing the design document, the process of writing the plan felt tedious and unnecessarily detailed for such an early stage of development. However, looking back, having a detailed and well-thought out plan before we started coding allowed us to avoid some possible problems along the way. The original plan put everyone on the same page and gave everyone the same expectation of the design of the website.

Our design experience showed that, although you can have an acceptable, working design concept at the very beginning, opportunities to make the design simpler (for the programmers and the end users) pop up all through the production process, and you must take advantage of them.

Our early design work was essential in laying out a framework for our code. However, at times the project suffered from overplanning. Too often, we relied on preconceived ideas about how the code would work; without sitting down and writing code, it was impossible to know the technical constraints that would inevitably influence our implementation.

We started too late. We just barely came up with a topic before spring break, and as far as planning, we had nothing more than a rudimentary initial meeting until after the break, which left us with effectively seven weeks to write code. Having known that we would have to do this project since the beginning of the semester, we certainly could have gotten started with the planning before and (maybe) during spring break, which would have made things significantly less rushed afterward. This problem was compounded by the fact that we were all busy with independent work and other projects during the second half of the semester

Scheduling

I think that you need to be more realistic (pessimistic?) when doing the initial timeline. It's better to plan for something being done on April 20th and being pleasantly surprised when it is done on the 14th than plan for the 14th and be working fervently on the 20th to get it working a week late.

Our intent was to have a fully functional version by April 1st (which soon became April 29th) and we planned for many unique features that flopped for various reasons.

We soon learned that as college students, schedules work better in theory than they do in practice. Progress on our project was interrupted by work in other courses, as well as independent work and thesis deadlines.

We underestimated the amount of time required to set up the environment -- i.e. waiting for other people to activate our accounts through the CS department and set up the SQL database.

Because no one in our group was familiar with any of these programs [Python, Django, SQLite, Apache], the set-up process for our web site took us over a week and quickly put us behind schedule.

We had a lot of trouble setting milestones at the beginning of our project because we literally had no idea what we were doing. We jumped into the deep end of the pool without floaties or a lifeguard. Because we did not know what was really going on at first, we indiscriminately set unrealistic goals for every week. Looking back now at the initial proposal, we can just laugh at how fast-paced our original schedule was.

We have met or exceeded each of the project milestones, in part because we made an effort to start seriously working on the project early in the semester. We had much of the planning and interface work completed before the end of spring break, and we had our initial prototype completed almost a week before the goal date.

Thinking that we were going to get anything done over Spring break was a mistake seeing as we were scattered across the country.

We started early. We had 1 - 2 meetings before Spring Break, and then daily on-line meetings throughout Spring Break itself. If we had started any later, we would have been in a lot of trouble.

We now know that it is always better to assemble the final product sooner rather than later. The project was just very easy-going at first, and all of a sudden when we put together the product with a full database, we were rushed.

I was surprised with how time consuming just setting things up could be. For example, when I went to the Friend Center to set up the database, I thought it would take an hour or two to get ready to program. However, talking to CS staff, working out driver problems, shifting through FAQ after FAQ ended up taking a very long time. Also, the Java connection to the MYSQL Database was very clunky and tedious to program in.

I feel like our initial schedule was very poorly designed. I feel like we guessed fairly badly at how long things would take to implement as well as what things we would decide to focus on implementing. As a consequence of the fact that we needed to make constant progress, I feel like we created things out of order but I don't know of any other way we could have done it and still had anything to show at our weekly meetings.

We started with the core structure, and then kept adding Christmas ornaments on the tree until it was full. At any point along the way, we would have been able to stop, which was a nice reassurance when we started out.

Working Together

We settled into a routine of meeting as a group at 1:30 pm on Wednesdays and working until late. It was a brutal schedule, but we found these sessions to be very productive, and we were generally able to finish what we had set out to do at the beginning of the week. There's no better way to code and debug than to have the person who wrote the code you're using sitting right next to you.

There has *got* to be a time when the whole group can meet (outside of the meeting with the TA) each week to really get a handle on where they are and what needs to be done. It was also very helpful for us to have clearly defined 'roles' (in addition to the project manager) so that someone was 'on point' for various aspects of the project.

The necessity of leadership was immediately apparent. For the first few weeks we would make plans to meet at a certain time, and then as the time elapsed each of us would independently realize that we didn't know where the meeting was supposed to be. Having someone step up and make most of the easy decisions, definitely facilitates building a project like this one.

Probably the most important learning experience was figuring out how to work on a team towards building a sizable CS project. The necessity of leadership was immediately apparent. For the first few weeks we would make plans to meet at a certain time, and then as the time elapsed each of us would independently realize that we didn't know where the meeting was supposed to be. Having someone step up and make most of the easy decisions, definitely facilitates building a project like this one.

We met in person at least once a week. In addition to our weekly meetings with Bill (after which we would always stay and talk to coordinate), we occasionally met an additional time if it was felt that it was necessary. During our final push, much of the work was done when we were all in the same room. Working together in person was definitely very helpful, as it made coordination easy.

We would probably try to put more effort into spending more time coding together (as in, side-by-side) on some of the parts. Breaking the work into parts and working individually sounds great in theory, but when you are not sure how the parts of a website will ultimately work together, it's much easier when there is verbal communication as interconnecting parts of a site is being built side-by-side.

Programming projects benefit tremendously from working meetings. You get so much more done if all of you just sit in the same room and code. We really should have done a lot more of that.

We were honest with each other about what we we had time for. Each week, before we took on our assignments for the week, we made sure to consider how much other work we had. There were weeks when some of the members of the group were not able to contribute at all, but it was not a problem since it was known beforehand. Thus, other group members with less work were able to compensate.

It takes some time and effort to think weeks ahead, but the rough skeleton of the game plan is very important as the group goes forward. Without this general idea of what should be completed by when, it is easy for a group to lose focus in the middle of a busy semester and find themselves far behind in their project.

Coding

From the very beginning, we agreed on a general style of naming and organizing our files, code, and variables. As a result, all of the files in our project have natural, intuitive names and have homogeneous capitalization and abbreviation patterns, and our functions and variables are likewise. We also chose to store code that performs similar tasks together (all code that communicates with the database, for example, is in a subdirectory labeled "dbaccess"). As a result, we believe that throughout our project we succeed in conveying an idea of the code's substance through its style. This is, in general, a most helpful tool in a group setting.

Cascading style sheets offer a good lead-in to the look and feel as a whole, since CSS really tied everything together. It was our plan from the beginning to leave this until the end, since it was the most likely to change over time and the least crucial to the site's functionality. In retrospect, it would have been a much smarter idea to decide on a set of font and table classes at the beginning.

The modularization of the program structure helped a lot. At various stages, major components were restructured or reimplemented but since it was so modular, these changes didn't affect any of the other components.

We learned that modularity is a great boon when implemented. As an example, we made the authentication functions (though not the variables because they had to be visible) very modular (we never ran the same segment of code twice without putting it in a function). This much better than just placing the code somewhere in a file, because we actually made several changes to the code and tweaked with the timeout period. We are very confident that those changes are uniform across the website, which we would not have been had the code been scattered about.

Because of good modularity, changes in one part often had no effect on other parts, and if it did then the necessary changes were easy and natural. Each person knew their portion well enough, too, that many times a verbal description of problematic behavior was all that was needed for a person to pinpoint a bug.

Our inability to create a working system on each of the group member's computers was definitely a great problem. All the parts were tested separately as they were developed and as new features were added. However, the final product could only be tested once all the parts were put together at the end, and some features that worked independently did not always work in the final product.

Languages

Another thing I gained from this project may not be a very positive one, but I really got to experience all of the biggest problems with Java like never before. Working on a big project like this forces developers to use packages, which is very difficult and frustrating, and it is hard to get them working correctly. Another huge problem is the classpath issue at compilation time. It is very difficult to get all the build paths correct, and even to run the whole project, in order to get all of our third party libraries running all kinds of classpath issues need to be resolved.

Java's classpaths are a heat-seeking land-mine: come anywhere near them and you are in trouble.

Swing code would often cause heartbreaking and fundamentally bizarre errors that resulted either in progress stagnating for a period of time or in the need to rework large parts of the program. Furthermore, in several cases the group's lack of experience with Swing resulted in creating parts of the program in an unnecessarily complex or time-consuming manner.

Another major surprise was the improvement in the speed of the course browser after the migration from Java to PHP.

Debugging in PHP proved to be a endless task at some points during the project.

I've become familiar enough with PHP to call myself fluent at an intermediate level, which is especially nice since the language is one of the more common ones that we didn't cover in class.

Python has especially become a close friend of mine, and it is a language which I feel combines many of the best elements of each other language I've learned.

I spent almost all of my time working on the GUI, in Javascript and PHP. If there was one thing I go back and tell myself from the beginning, it's to always read the documentation first. HTML/CSS/Javascript is a really tricky combination; the usual debugging technique of "tinkering" is guaranteed to make things worse.

My advice for a future COS 333 student would be to spend a good few hours in the beginning of the project reading up on how PHP and SQL actually work as it makes things far easier than just googling things as they come up.

Version Control

It probably would have been a good idea to have a system where we sign out code to edit it, so everyone knows not to edit the same code at the same time.

This project also marks the first time I'd used a CVS server. Looking back on it now, I don't know what I would have done without it. It helped us synchronize our efforts and really increased our capacity to work cooperatively.

Once all the somewhat arcane configuration had been done, however, CVS was an absolutely indispensable tool for our cooperation as a group, and we used it for the remainder of the project almost without thinking about it at all.

On several occasions, one of the group would accidentally wipe out the work of another due to overwriting a file that had been changed. In most cases we were able to restore from backups, but data was irretrievably lost more than once. Even if data was not overwritten, functionality could break down if two people were working on related files simultaneously. ... After learning our lesson the hard way a couple of times, we all became mindful of backing up old files before uploading new ones, and sending group emails detailing the files that we were working on at any given time. If we were to start over again, we would use a CVS from the beginning, as it would be both easy to use and more reliable than our group email methods.

Using SVN was wonderfully easy.

Testing

Test scripts for each basic module were developed simultaneously with the module and were a great help in debugging.

We made an effort to test our project as we developed rather than waiting until the end of the semester to begin testing. This philosophy of, "test early, test often", turned out to be a good strategy because it gave us confidence in our code and it reduced the likelihood of us having to make major changes at the last minute.

Due to some unfortunate choices in implementation, the program runs much more slowly than we had originally hoped.

We started with a small core set of features, then built them larger. This had two benefits. First, it allowed us to have a close set of friends as our user base early on so that we could get constant feedback, not only on the site, but bugs we missed.

We tried to fix bugs as soon as we found them, which usually made life easier down the road.

One other thing that we learned about PHP and javascript is that it's very difficult to test and debug the code completely. The hardest part about PHP is that if you have a syntax error in your PHP and it's nested within a loop that rarely gets executed, it will not get an error until that inner loop is executed. This places a particularly strong burden on the programmer to manually test all code rigorously.

Another important lesson that we learnt was the importance of testing. No matter how confident you are in a piece of code to work, and no matter how short it seems, it is always prudent to not proceeed until you have tested the code written so far to your satisfaction. Often you would find that adding further functionality increases the number of potential pitfalls in your earlier version, making you go back to testing the code that you thought you had already tested. If you had indeed done a good job of testing this earlier version, you can then focus on ironing out the problems introduced by the new code.

We learned to never trust anything that came from the front end and to put all error checking on the back end.

Although using 3rd party code is crucial in developing a powerful application in a reasonable amount of time, consistent and thorough testing is important in avoiding complicated bugs and ensuring security of your site.

It is easy to forego testing when under time pressure, but it is an unwise decision.

Start early, plan carefully, and test thoroughly.

The Real World

The administrative interface that we put together at the beginning was not particularly complex, however, it did require repeated and varied calls to the database, which was a good way to become familiar with the back-end.

We also learned that it is much easier to write code on a machine that you have full control over. Patience and spare time before a deadline are a must in these situations, we were lucky to catch this issue early in our development stage, otherwise things could have gone very badly.

When developing in a less familiar language, don't be afraid to throw out code when you find a new and better solution -- it will save you time in the future and you still learned something from implementing the old code.

Future students should anticipate some difficulty and plan ahead accordingly if they require copyrighted materials (maps, pictures, etc.) for their project. Being upfront and honest with the owner by telling them what it will be used for will generally prevail, though it can take some time.

Certain tasks are often more difficult than they seem. In particular, the parts of the project that seem complicated will almost certainly become even more complicated once the coding begins. Starting early on the most difficult parts of the project will pay off in the end.

If there is a manageable feature that could be added to the project that would make the application useful to a whole new audience, it should definitely be considered. Never become so focused on the coding that you lose sight of the end-product and the interests of the consumer.

Having done this program, I have a new appreciation for all real world application programming. The only types of programs I have been exposed to so far were simple programs like "compress this" or "create this little algorithm." To make a jump to "make this system and make sure it never crashes and accounts for all user inputs" was just a huge jump.

Probably the most valuable lessons we learned from this project came the day of the demo, during which we naively decided to add a few more features to our code hours before presenting the website. Falling victim to Murphy's law, we found ourselves with a major bug within minutes of the project. The scrambled effort to fix it interrupted our presentation planning. Though we were fortunate enough to fix the bug in time for the demo, our demo suffered because of it. We have all thus learned the hard way that ample testing should occur well before the day of the demo so we can prevent dramas such as the one we lived through.

This was the first piece of software we wrote for an actual user base, meaning that most of the specifications for end functionality came from our users, rather than arbitrary decisions on what we thought might be useful. The consultation process resulted in a number of surprises, most notably the customer's desire for a feature which we hadn't encountered in any of our searches through the literature or heard of previous to our work.

I think the lesson I learned the most was simply: listen to your peers and users, even if it means throwing away something you spent a lot of time on.

The Bottom Line

Working with the users was an enjoyable experience, and we are glad that we could provide them with something that will be useful in real-world applications.

This project has been a very positive experience for us all. To see an idea all the way through, from its inception to the final product is an incredibly satisfying feeling. Furthermore we have learned much about groupwork, interfaces, php, mySQL, and much more along the way.

In the past when I've worked with groups, especially in computer science, I've felt that we got in each others' way a lot. With this group I really feel that we helped each other a lot, gave each other suggestions, and really used our other group members to our advantage to help make our project better.

All in all, though, it was a wonderful experience. I am amazed at how well it turned out, and I am very pleased with the work of our group. It may not sound that impressive to say that the things that went right far outweighed the things that went wrong, but in the seemingly chaotic world of developing software, I'd say that's pretty good.

Overall, however, we all feel it was one of the most enjoyable projects we've been involved in at Princeton, and also one from which we have gained the most practical skills.

I really love what we've built.