CS 212 Assignment Guidelines & Expectations

About this document

I have a number of "views" about programs and what I like to see in assignments. Usually, I express these in class, or they get tucked away in homework assignments, so I decided to just start writing them down. You treat this as a living document — I'll continue to add to it as the semester progresses as things come up or occur to me.

Coding Conventions

Pretty much anywhere you work, you will probably have to deal with coding conventions — ways that you are expected to write your code. Mostly, I am not that strict, but we will follow some basic conventions.

Packages

All of your source code should be placed in a package called cs211.hw# (where the # is obviously the number of the assignment). All test cases should be in a package called cs211.hw#.test. This will make sure that you aren't using the default package, and it will mean that everyone's code will look the same, which will make grading easier.

Naming

All Java code should follow the Java naming conventions. Here are some of the most important ones:

In addition to these rules, I frequently will begin instance variables with an underscore to make them distinct from local variables (you are not required to do this).

Finally, while I would hope that I wouldn't have to say this, use sensible names that reflect their purpose. I won't lay down specifics unless I have to, but I will be on the lookout in your code for abuses of this.

Comments

All classes and methods should have Javadoc style comments. These should not be copied from descriptions provided in assignments, which are directions, not comments. Your comments should provide an overview of what the method or class does and how to use it. If relevant, these may also provide some insight into how it is implemented, but these comments are primarily intended to be read by someone who will be using your code (think about the documentation for the Java API). Implementation decisions should be explained using single lined comments. Any choice you make with respect to variables or functionality that you will not understand in five years should be commented (I say five years, but I mean five hours — many programmers are overly optimistic about how "obvious" their solutions and choices are).

Organization

I will not hold you to strict standards with respect to organization, but there are a couple of things that I think makes code more readable.

Testing

In this class, I expect you to be doing test-driven design. That means that you should start by writing tests for all of the functionality of your classes and only then do you start implementing your functions. I do not want to see assignments handed in that have no tests, "because you ran out of time". I will be much happier with code that prints out "didn't get this far" messages and has a full suite of tests (this is not arbitrary busy-work, it really is to make you better programmers).

When you bring code to me that doesn't work for one reason or another, I will expect to see a test that tests that specific problem. Try to come up with the smallest possible test that demonstrates the issue.

While you should write tests before you write code, you should also add to your tests as you implement so that your tests cover all of your code. There will be some exceptions, but by and large, this is the goal. Remember that for complex conditional expressions, you will need tests that test all sub conditions.

One thing I do not want to see is one big giant tests methods. Each test method should test one specific thing. This may involve multiple assertions, and it may be difficult to be pure due to the getter/setter relationships, but again, this is the goal. The problem with big giant tests is that they stop as soon as the first failure is reached. Your goal should be to get as much information as you can out of a test run, and you will get this by having a lot of small test that you can quickly glance over to see what is working and what is not.

Handing in Work

While your work is "just" homework, I would like you to take it seriously and consider handing your work in like you would releasing software for sale. I realize that not everyone will get everything working 100% all of the time, but there are a couple of things that I expect from work that is submitted to me.

All work should compile. There is no excuse for code that doesn't compile. Eclipse points out every line that has a problem and provides potential solutions. If you really can't figure it out, you need to ask someone else to look at it. If you can't get your code to compile at the very last minute, it either means that you haven't been testing your code as you went along or it is something you added at the very last minute. so it should be easy enough to take it back out. Work that does not compile will not be graded.

If your code doesn't work, I would like you to show some awareness that you know that it doesn't work. Add comments that describe what doesn't work, what it doesn't do, and where you think the problem is. I would rather you spent ten minutes doing this right before a deadline than spending those ten minutes banging your head against the bug and turning it in as is.

Writing Interfaces and Coding Defensively

When we write user interfaces, one of our goals is to never let the user get a peak behind the curtain. We want our interface to be the program to the user. One way that we do that is to make sure that we never release our control over the user's experience. A fairly common way to let go accidentally is through errors that cause your program to crash. This is a Very Bad Thing. Never let the user see you fail.

There are two main causes for crashes. First, you may actually have some bugs in your program. This is hard to work around because if you knew they were there and you knew how to fix them, you would. This is why we test our code before we give it to someone else. The second cause is that your code has been handed input that it doesn't understand (this can also happen when you code talks to other code as well). No matter how obvious you make it that you want one particular type of input, some user will inevitably try something different. No matter how bizarre or illogical it may seem to you, someone will probably try it. This may happen because the user didn't think it was bizarre or illogical, or maybe they just made a mistake. Or perhaps they are trying to break things (hint, this will be true in your case).

To combat this later problem, you need to code defensively. Assume nothing. Trust no one. Trust no input. Don't even trust code you wrote earlier or code you will write later. Write programs as if every input could be used against you. Be paranoid. If something could be null, make sure it isn't before you use it. If the user gave you something that should be a number, make sure to check before you use it. Be ready for blank inputs and missing files.

Another important aspect of keeping control of the interface is providing feedback when you do things. We will be writing a couple of command line interfaces, and that reduces the visibility of the interface. For our purposes, the user needs to be told what inputs are valid. You should provide some kind of prompt so the user in not just staring at a blank screen waiting for something to happen. When you get input, good or bad, make sure the user knows what you did with it. Getting back to the point about handing in work, even though you and I will probably be your only "users" and we presumably know what your program does (or should do), you should write your program as if someone else was going to use it. Don't write programs that you would be embarrassed to show your mom, or the cute boy/girl you are trying to impress.


Last modified: Tue Jan 22 15:29:32 EST 2013