Lecture 6 : Starting on Java


Contents of a "good" program

So, if you're going to be writing your 'real' code, how should you go about doing that? First of all, the code you will be writing now will be in the Java language. This language was chosen because it is a powerful language with the ability to write most any kind of code you'd like, but it's relatively simple to learn compared to many other programming languages like C, C++, Pascal, etc. C and C++ are still very widely used languages, but they give the programmer control over some aspects - such as managing internal memory - that beginning programmers (or even experienced ones) can have a lot of trouble managing. So, we'll go with Java to limit some of the annoying little coding details that you'll have to worry about.

The link given here has the code for a very basic program. It merely prints out a line of text introducing itself to the outside world: "Hello World".

Looking at this simple block of code, here's what everything does, line by line:

public class Basic1 {
Tells the compiler (the thing that interprets your code for the computer) that you're creating something called a class to be named Basic1. Don't worry about what a class is and what the word public does right now. That will soon be covered in later lectures. Right now just think of this as the way to name your program and note that (1) your class needs to be in a file with the same exact name, followed by ".java" (here creating a filename of "Basic1.java" and, (2) by general coding practices your class name should be capitalized. This tends to make it easier to seperate class names from variable names and other things. Finally, note that everything that makes up this class called Basic1 is the code that comes after the left bracket on this line, and a matching right bracket at the bottom of the page.
public static void main(string args[]) {
This line defines a method (often called a function in other languages) called main. A method is just a collection of programming lines that have been grouped together and given a name. Every program needs a place to start, and every Java program has to start with a method called "main" defined with exactly this header. Again, right now just take this as a line you need to put in to get your program working. Finally, note that this line also has a left curly brace, and that the method definition continues on until the matching right curly brace on the next-to-last line of code. So, both "classes" and "methods" are delimited by starting and ending curly braces.
System.out.println("Hello World");
As you might have guessed, this is the line of code actually responsible for outputting those two words of text. The code System.out.println(); tells the program to print out a line of text, then return down to the next line. As we'll see in later lectures, "println" is actually a method (like "main"). If we'd used "print" instead of "println" then we would have not returned down a line after printing out "Hello World". The quotations create something called a string object with the characters Hello World, but for now you can just think of that as the text that will get printed out. Once again, treat most of this line as just stuff that you need to do to get your program to work. Each part will be explained in due time.

Now that we've down a quick overview of a simple program, lets get the program to do something a bit more complicated. In the Math1.java program, we calculate 7! (seven factorial). You may recall that is value is calculated as 7! = 1*2*3*4*5*6*7 = 5040. The program certainly prints out the correct answer, but since I had to know the answer and type it in beforehand it's really quite useless.

However, if I use the definition of calculating factorials, I can slightly improve the program to make Math2.java. The program starts out by defining a variable of type int (as in integer) and naming it answer. Variables are vital parts of any interesting program. If variables are new to you, one way to think of them is like labeled buckets. Each bucket (variable) is labeled with a name, and some sort of requirement about what can be placed into that bucket. Here, the variable is labeled with the name "answer" and can hold "int" (integer) values.

For the line immediately after "answer" is created we have "answer = 1;". This initializes the value of the variable answer to be 1. Think of this as evaluating the right side of the equals sign and assigning its value to the variable on the left side of the equals sign. The right side of the equals sign can be more complicated, as it is in later lines, so long as it still evaluates to the proper variable type, in this case an int. (We'll cover variables types tomorrow.) So, for example, the right side of this equation can have integer numbers or integer variables combined by mathematical functions like +, -, *, /, etc. Still, having the variable on the left side of the equation, "answer", also appear on the right side can be confusing. Just remember to think of the left and right sides differently. Using the bucket analogy, for the right side we've got integer constants (1, 2, 3, etc.) and buckets holding integer values. To calculate the value of the right side its the integer values we need and not the buckets themselves. So, just take the values out of the buckets and insert them into the proper places in the equation. Once we're done figuring the final value of the equation, take the resulting value and place it in the bucket whose name appears on the left side of the equation.

One other thing to note is the ";" at the end of most of the lines. This semi-colon will have to be at the end of most of your lines of code to signal to the compiler that the line of code is finished. One exception is those lines that involve curly braces, as with the class and method definition lines in this program. Lastly, you may have noticed that the "println" method is used slightly differently. In addition to the characters inside the quotation marks, we've also got +answer tacked onto the end. The use of the addition symbol here is a little too advanced to explain right now, so for now just take it as being a way for you to print out a variable.

Well, after all of that we've got a slightly more useful program. Still, it can only calculate one value: 7!. If I wanted a different factorial, like 9!, I would have to add a couple more lines of text. If I wanted a much bigger factorial, like 100!, I would have to add a 'lot' more lines of text. The next example Math3.java does a much better job addressing these concerns. It uses something called a for-loop to iterate through several values, reducing what would be many lines of code now to just the loop's few lines.

The for-loop has a header, and a body. The body is delimited by starting and ending curly braces (just like with classes and methods). The header of the for-loop is the section inside the parantheses and has 3 parts: initialization, condition, and iteration. Note that the 3 parts are seperated by 2 semi-colons.

The initialization part sets a starting value for the variable that we're working with. This statement is only run before any other part of the for-loop and is only run once. Here we're defining a new variable called "i" and setting it's starting value to "1". Note that this is just like the definition/initialization statements for the variables "answer" and "iterations" in the lines of code above.

The condition part is checked before every iteration of the loop. If the condition evaluates to "true", then the body of the for-loop is run once before returning to check this condition again. If the condition evaluates to "false", then the body is not run and we skip down to the next line of code after the for-loop (in this case, a "println" statement). This particular condition statement "i <= iterations" will evaluate to 'true' so long as the value of "i" is less than or equal to the value of "iterations".

Lastly, the increment part of the for-loop is run after each time that the body of the for-loop is run. The "i = i+1" statement here is just like the assignment statements in the lines of code above, or like those we saw in Math2.java. In this case, after every time that the body of the for-loop is run, we take the value of "i" and increase it by 1. In this way, we'll run through the loop exactly 9 times, which is just right for calculating 9!. This gives an overview of a simple use of a for-loop. These loops can be more complicated, and we'll cover them in-depth later in the course.

After a few improvements to the math program, we've now got something that can do a pretty good job of calculating factorials. Using Math3.java, I would only have to change the intialization value of one variable, "iterations", to have the program calculate different factorial values. This still means I'll have to change my code and re-compile (have the computer interpret it again) the code each time. To save myself this trouble, I could make the program more adaptable by first having it request input from the person running the program. In this way I can calculate a different factorial value each time the program is run. This is the option chosen for the program in Math4.java.

This code first prints out a line informing the user that it is waiting for input:
System.out.println("Enter the number you want the factorial of, here->");

...then receives that input and stores it into a variable:

iterations = Keyboard.getInput();

In this way the program becomes adaptable enough to be able to calculate different things without someone having to actually change its code. This makes a very substantial improvement in the program's usefulness. Finally, the addition of comments to the program makes a substantial improvement in how easy is is for other people to understand the code. On each line that has two consecutive slashes, "//", everything on the line to the left of those symbols is regarded as a comment. Comments are visible to a person reading the code, but are ignored by the computer when it interprets and runs the code.

Comments are extremely valuable for providing insight to other humans - and even to yourself - about what different parts of the code are meant to accomplish. After you've written a few programs, you may find it harder to remember what each part of every program is supposed to do. Well-written comments can eliminate that problem. Comments are also necessary to explain your program to someone else who hasn't seen it before - like a professor trying to grade it. Note that in addition to having two consectuive slashes you can also delimit a comment by staring with /* and ending with */. Just like with curly braces, these pairs of symbols are matched up to create the start and finish of a comment. This means that they can denote a single line comment, or one that takes up several lines. Later you may even find them useful to "comment out" certain parts of your code so you can test just one or two parts at a time.

Through 4 different versions we've gradually improved various parts of the factorial-calculating program. In general, programs that you write will be meant to solve some sort of problem, so having a good approach to problem solving will likely lead to writing better programs. The textbook gives one possible set of steps to follow:

  1. Understand the problem.
  2. Dissect the problem into manageable pieces.
  3. Design a solution.
  4. Consider alternatives to the solution and refine it.
  5. Implement the solution.
  6. Test the solution and fix any problems that exist.

For the purposes of this class, one part that you may find most useful is to seperate the "design a solution" and "implement a solution" parts as much as possible when you begin to approach a problem. Writing Java code may be a very new thing to you. So, first think about how you would solve a problem yourself, rather than the computer, and go through the process you would use step by step. Then after you feel like you have a good idea what you would do, begin translating that step by step program into code. This will hopefully seperate some of your solution design problems from pure coding problems like using improper syntax on a for-loop, forgetting a semi-colon at the end of a line, or accidentally forgetting an ending curly brace for the body of a method.

To avoid some of these, when you first start implementing your solution in code you may find it helpful to start out simple. Get something basic - anything - able to compile and run first. Then, gradually add each part of your solution one at a time, trying to make your code still compiles at each step along the way. In larger projects where this is neglected, it is sometimes easier to start part or all of a program from scratch rather than try to fix or "debug" a broken program with thoroughly mind boggling errors.

Lastly, think about what elements made the Math4.java program an improvement over each of its predecessors. We made it more general or robust by giving it the ability to calculate something more than just a single value (like 9!). We generalized it even further by limiting how much we had to change for it to calculate different things, eventually relying on user input so that no changes to the code were needed. Using a for-loop instead of hard-coded variable assignments was necessary to make this happen. Using a for-loop was also much more efficient in that it used far less code. In later programs that you will write, you will have to worry about how efficient your code is other aspects, like how much time it takes to run. Finally, our final version of the factorial program was easily understandable for other humans to read because of the comments (and because the program was fairly well formatted). Without comments or without whitespace to make the program easy to read, the computer could still understand the code but humans could not.