Preparing 110 Python programmers for 115 Java.

Introduction

This is a short tutorial designed for CSc110 students, who did their first course in Python and must do the second course in Java.  (Attn. Engineering students:  The September 2011 CSc 115, section for Engineers only, will use C#.  A tutorial from 110 Python to 115 C# will follow later in the summer. A link will be posted on the Labspg.)

Tools  (Assemble and test the tools)

You will need a Java compiler, a programmer's editor, and a command line (terrminal) window.

For Mac OS X users refer to the Using Java on a Mac document. 

Windows users refer to Using Java on a PC


Part 1.

Your first Java program should have compiled and run as part of the assembling the tools above.  If you have not succeeded with that you need to get help with the setup or get into a lab where the setup is available.

Explaining the program.
Every Java program must be contained in a class.
Everything in the class is enclosed in braces.
To run there must be one function called main defined as shown:
Functions are called methods in Java.  Method bodies are also
enclosed in braces.
This program will print My First Program
public class First
{
    public static void main(String [] args)
    {
        System.out.println("My first Program");
    }
}

This Java program must be saved as First.java in order to compile and run.  Program files must have the name of the one public class dot java in order for the runtime program to find the main and run.

The equivalent Python program could be as brief as one line although we have followed the convention of defining a main function:

print 'My First Program'
def main():
    print 'My First Program'

main()


Statements in Python are marked by the actual end of line instead of a semicolon, therefore in Python a long line must be continued using a line continuation character.  Indentation in Python delineates blocks of code instead of braces as in Java.  Indentation in Java is not required by the compiler but is most often required as a style feature.

Part 2

Variable types, scope, and control structures.

Here is a modest program in Python.  You may right click and download guess.py for the source code.



Here is the Java equivalent code with numbered annotations below.  You are given no source code as you should type in this program and compile and run it.  As a Python programmer you can expect to have difficulty with the braces, semicolons and managing variable types in Java.


 
Annotations:  When you compile the program above it is likely that you will encounter difficulties with many of the things that are numbered in the code image above.

  1. The library that is always included by Java automatically is java.lang.*.  It is in Java lang that the String classes and Math classes among a great many others are defined.  One class not defined however is the Scanner class which allows us to declare a Scanner variable to read from the keyboard.  While Java IO has improved it still remains more difficult than other modern languages.  Scanner introduced in version 5, is one of the simpler of the IO classes and can be used for keyboard or file input.  See the reference to the Scanner class for methods available to Scanner Variables.

  2. All Java programs must be in a class and must have a main that declares a array of strings as a parameter.  It is into this array that command line arguments are stored.  We will not use command line arguments here, but the array must be specified anyway.

  3. Typical output.  The System 'out' variable defaults to the monitor as the output device.  Print statements like all Java statements are terminated with a semicolon.

  4. Declaration of a Scanner variable with programmer chosen variable name 'input'.  (In Python input is a keyword.)

  5. Method random in the Math library returns double between 0.0 and 1.0.  (int) is cast of double result to integer.  All the math methods are static.  Calls to static methods are prefaced by the class name in which the method resides.

  6. Method nextInt() is a method in the Scanner class that interprets and returns the next token in the input stream as an int.  If it is not an int the program will crash.  While there are methods in the Scanner class that can validate the next token before reading it we will not use them here for the sake of simplicity.  Whereas Python redefines the variable type in the case of a mismatch, Java will crash if the value does not match the type of the variable.

  7. The control structures while and if are similar to Python except that the boolean expression must be bracketed and braces are used instead of colon and indents.  Mismatched braces will plague the Python programmer, since the compiler cannot not report the error until all existing braces are matched.  Therefore compiler errors often point to lines well after the actual location of the fault.  Mismatched braces also cause other errors to be reported that may not in fact be errors at all when the earlier errors are corrected.  Similarly correcting an early sytax error may expose more errors then were originally reported.  Novice programmers often mistakenly assume that a change that results in more errors being exposed, must be an incorrect change.  Control the number of errors by implementing relatively modest amounts of new code at a time.

  8. Note the last two lines printed.  The plus operator is overloaded the same way that it is in Python for string concatenation.  However in Java it has even more power.  Not only does it concatenate  strings but if one side of the plus is a string then it forces the other side to be converted to string without the need for an explicit method call.  If by precedence both sides are numbers then the numbers are added before conversion to string and concatenation. i.e.

    System.out.println("result 1: " + 20 + 11); outputs result 1: 2011 whereas:

    System.out.println("result 2: " + (20 + 11)); outputs result 2: 31.

    Note also that the single quote character does not also denote a string literal as it does in Python.  In Java it denotes a character literal. Character  'A' and String "A" are not the same type.

Part 3

Arrays, methods, parameters and returns.

 
  1. Methods in Java look more complicated because of the rigid type specifications.  This will give the Python programmer some extra syntax issues.  The parameters must be declared with type specifications too as all variables must in Java.  Return values must have a type specification in the method header.  The static keyword must be used for functions outside of a module that contains a class specification ... more about that later.

    Note the type of the array a:  It is an int [].  The presence of the square brackets indicate that a is an array. Because the square brackets are preceded by the keyword 'int' then it is an array of integers as opposed to an array of strings or any other object in Java including an array of arrays.  Arrays are a composite data type like a list in Python but they are restricted to one type and they are of a fixed size determined when they are defined.  Arrays are the only object in Java which is nameless.  Therefore they are defined by the type of the data they contain.

  2. A for loop in Java consists of 3 statements each separated by a semicolon.  The first initializes the counter variable, the second sets the stopping condition and the third determines the step.  Java does not stop one short of the stop statement as it does in Python.  Rather it continues as long as the condition in the second statement is true.  Since arrays are of fixed size and are subscripted by counting numbers, for loops are most often used to iterate over them.

  3. Here is an example of a fully functional method.  Note that the return value must also be type specified (int in the header instead of void).  Unlike Python the java compiler will disallow the return statement altogether if the method header specifies a void method.  The signature of a method in Java is determined by it's name and the number, type and order of the parameters.  Any variation in the order or type of the parameters specifies a unique method.  This is quite a bit more restrictive than Python functions which can not only be invoked with parameters of different types but can also have a variable number of parameters.

    Recently Java has added Generics to the language.  Generics when used correctly in object specifications does allow for the same method to handle different types.  Generics prevent run time problems by virtue of the compiler checking the type consistency of any reference at compile time.  The Python programmer can expect to make many compile time errors in Java due to the restriction of type or by frequently failing to type variables all together.  Loose typing in Python when it does cause errors, causes them at run time which is far more difficult and time consuming.  Compile time error detection is a good thing although the Python programmer may think otherwise especially in the beginning.

  4. Return value is specified as int.  Return values may be ignored by the calling program in Java.  There is however no equivalent to 'None' in Java.

  5. Arrays are fundamental objects in Java.  However the syntax of declaration and use is meant to mimic arrays in C.  They deserve special attention here. 

    Following is one of many ways of defining an array in Java.  While the usual Java object definition is like that of the Scanner object the array declaration is uniquely different.  It is worthwhile to look at both here:


    Arrays can be declared and initialized at the same time i.e.


    Arrays can be declared and sized later i.e.

  6. Basic method calls in Java are as expected by the Python programmer.  That is  a method  name is invoked with  parameters mapped to local copies in the method.  We did not use the exceptional characteristics available to Python functions so that there would be less to worry about in the transition.  Note that Java requires that the parameters are consistent in type, order and number.  While this was implied in our Python course, it is required in Java.

Part 4


Modules and Classes (object specification) in Java

Recall the contact and contact_list as they were presented in 110 Python.  The contact module specified attributes associated with a person and the contact_list was used as a container of contacts.  Following is the same idea presented in Java complete with a test program.  We present a Contact class, a ContactList class and a TestContacts program.  Since arrays are a often used composite data type in  Java and the other languages which derive their syntax from c, these objects are built on arrays.

To keep it simple a Contact will specify only a contact type, first name, last name, and address, all stored as strings.  A ContactList will be an array of Contacts, with methods to create a Contact list, append to it, sort it, remove from it and so on.  We show a number of private methods that help the normally fixed size array grow or shrink as needs be, as well as other helper methods. 

Private methods or variables are internal and can help with how a data structure works but may not be called from outside of the module.  Python has no equivalent to private access, although this may change.

The two module's as images are presented here with little or no documentation for considerations of size and so you can focus on the code and determine from the code level what it does.

Note: You may download the fully documented Contact.java and ContactList.java but you must type in and compile TestContactList.java yourself.  The image  for TestContactList.java  is presented first so that you may trace the functionality in Contact and ContactList as you encounter it.

To test the TestContactList program all three .java files must be in the same folder.  Compilation of TestContactList will force compilation of Contact and ContactList.



  1. Two contact lists are instantiated to demonstrate the two constructors in ContactList.  The first one is initialized to a size of 4 so that we have a practical example of increasing the size of the underlying array in our test.  The second which we do not emply further is not sent a size and examination of the ContactList specification will show that the second list is sufficient for 100 contacts before it needs to grow.

  2. Five contacts are created.

  3. The getters in one of the contacts are tested.

  4. Contacts are appended to the list, and the toString() methods are tested by printing.  We print the ContactList and we observe that the ContactList toString() method invokes the Contact toString() method for each contact.

  5. Further appends are made so that we can test the array grow function.  The contact list is printed again demonstrating that the appends must have worked.

  6. A call to sort shows that the list is now in alphabetical order by last name.

  7. Contacts are removed both by address and by whole contact until empty.

    Note that appends and removals return boolean true for success and boolean false for failure.  In this test we do not test the returns.
You should examine the code images Contact and ContactList in detail.  There are a number of methods in ContactList that cannot be called from outside the class since they have a private access specifier.  They are helper functions.   Note the state variables in both classes are also private.  This is the usual condition in java since most of the time it is desirable to control access to variables inside a class.

While object classes need not have a main and therefore will not run, they can and should be compiled as they are developed.  Individual static  mains are often put into a object module for the sole purpose of testing.  Unless the java command is focussed on the object class, it's test main does not run and can be left in the class throughout the development cycle.  Using this technique for testing is referred to as the Unit Test.  We do not show a Unit Test here since we are done testing the object modules from inside the modules themselves and have removed them.