Programming 1, fall 2007 -- Demonstration 5

Where I want everybody to be after demonstration 4, or at least very soon. This demo paper contains additional information that I had no time to provide last week.

Now the overall structure of our programs is as complicated as it ever gets during Programming 1. There is the obligatory main-method (to make the program executable), and there is any number of additional methods. A generic example:

public class TheNameOfYourProgram {

    public static double fahrenheitFromCelsius(double cels){
        double result = (9.0/5)*cels + 32.0;
        return result;
    }

    public static void printHello(String username){
        System.out.printf("Hello %s! Hope you're well.%n", username);
    }

    /* ... any number of method declarations ... */

    public static void main(String[] args){

        /* We can call other methods from here. Example: */
        printHello("user, whose name I do not know");
        double t = temperatureRightNow();
        printf("It is now %f celsius which is %.4f fahrenheit.",
                t, fahrenheitFromCelsius(t));

        /* ... any number of method calls ...
         * preferrably not very many; we'll see that methods can
         * call each others, and also re-call themselves recursively.
         * It means that each method can be made nice and small by
         * itself.
         */
    }
}

Agenda for the next step:

In this demonstration, we try to make proper programs where subroutines are using each other. Always follow strictly the code conventions!

Contents

Type system of Java

Last time I showed this on the whiteboard, but here it is also in printed format. These are the types available in Java, and their purpose. Each variable type is essentially a numerical value, represented in bits. Some considerations:

  • The integer types are coded as "two's complement" values where the most significant bit denotes the sign, zero is represented as "all bits zero", and -1 is represented as "all bits one".

  • The character type is a 16-bit Unicode character encoding.

  • float and double are the standardized single and double precision floating-point encodings (specifically, in Java, they are the 32 and 64 bit variations of floating point numbers; there might be some platform-specific issues, which you'll have to find out from other sources; seek information about the keywords "Java floating point strictfp", if you need to know more).

  • Boolean (truth value) type is encoded in bits, but the number of bits is unspecified (might depend on the JVM implementation)

  • Reference types ("addresses of objects") are numerical values; the number of bits, and how these are used internally, depends on the implementation of JVM. What you need to understand are two things:

    1. Where there is a reference, there is a numerical value of a certain length in bytes. (I suppose it's 4 bytes in Sun's JVM working on 32-bit Windows, but I'm not sure.)
    2. You don't care how the value is used by the JVM to address objects, i.e., you can't see, and you don't need to see, how this translates to the actual location of an object, or how an object or class is represented in the machine. You just need to understand.

OK. Here's the table:

Meaning Type size in bits Example of a literal
truth value boolean ? true, false
character char 16 'A', '\u0041'
integer byte 8 14, 123, -128, 0x7A
integer short 16 -14, 0123, 32767
integer int 32 14, -1234, 32767
integer long 64 14L, 9223372036854775807
real numbers float 32 14.0, 1.234, 3.4e38
real numbers double 64 14.0, 1.234, 4.9e-324
reference AnyIntf ? String, Scanner, short[]

There are no more types in Java, but you must note that an object reference can be to any type of object (or, actually, an object with the specified interface). So there are as many types of references as you can think of different kinds of objects (Car, BillingSystem, GameBoard, CrissCrossPotato, SalsaSauce, LittleGreenPerson, UniversityStudent, ... in theory, an infinite number of classes of objects). But there are only eight kinds of primitive types. All data structures in Java boil down to objects that contain these types of numerically coded values.

Subroutines over again

Exercise 1:

Learn about the Gregorian Calendar and leap years here: http://en.wikipedia.org/wiki/Leap_year

Using the information, make a subroutine that takes as an integer parameter a year, and provides as return value a truth value that tells you whether the year is a leap year or not. A common way to name this kind of subroutine (method) in Java would be "isLeapYear". Usage:

if (isLeapYear(someYear)) /*... Handle differently somehow...*/

Exercise 2:

Make a subroutine that uses double-valued parameters and return values. It's purpose is to make a conversion between monetary units. It has to take as parameters: an amount of money in a currency, and a conversion rate between two currencies. It has to return: the same amount of money in the different currency. For example, you'd be converting like this:

/*Today's rate of 1 euro in AED (currency of United Arabic Emirates)*/
double dirhamRate = 5.2793;

double moneyInEuros = 70.0;
double moneyInDirham = convertMoney(moneyInEuros, dirhamRate);

Exercise 3:

Let's make a lot of subroutines for handling temperatures. Last time you made a method callable like the following:

double tempFahr = calcFahrFromCels(2.0);

Now, make a completely new program that has the following:

  • Subroutine rankineFromKelvin that returns a temperature in the Rankine scale (Kelvin degrees times 1.8)
  • Subroutine kelvinFromRankine that returns a temperature in the Kelvin scale (Rankine divided by 1.8)
  • Subroutine celsiusFromKelvin that returns a temperature in the Celsius scale (Kelvin - 273.15)
  • Subroutine kelvinFromCelsius that returns a temperature in the Kelvin scale (Celsius + 273.15)
  • Subroutine fahrenheitFromKelvin that returns a temperature in the Fahrenheit scale (Kelvin times 1.8 minus 459.67)
  • Subroutine kelvinFromFahrenheit that returns a temperature in the Kelvin scale ((Fahrenheit plus 459.67) times 1.8)
  • Subroutine fahrenheitFromCelsius that works in the following way: It first computes kelvin using the subroutine kelvinFromCelsius and then returns fahrenheit using fahrenheitFromKelvin. Verify that this works in the same way as the previous direct conversion. This is to show you that subroutines can call each other, and that you can convert things into a convenient internal representation. This is a trivial example, but a small and understandable one.

Reading data from the console user: first tries

You can have interactive console programs where the user inputs some values from the keyboard. In a Java program, you get to this by using the standard input. We'll look more into this when we enter object orientation properly, but first let us just use the following code:

import java.util.Scanner; /*This goes to the beginning of your
                            program, where the syntax allows the
                            import statements*/

...

Scanner sc = new Scanner(System.in);
/* This makes an object that is able to read numerical values from
the character input stream that comes from the user's keyboard.*/

/* Read like this:*/

int someInteger = sc.nextInt();
double someDouble = sc.nextDouble();
String aWholeLineOfText = sc.nextLine();

In the near future, you'll need to be able to read the so-called API documentation of the Java classes. Begin by skimming through the Scanner documentation:

http://java.sun.com/javase/6/docs/api/java/util/Scanner.html

There's a lot of text over there. Try to manage the documentation on different levels: Introduction, Summaries, Details. You should be able to locate the methods invoked on a Scanner object that were used in the above example, and also a lot of others with very similar names and interface definitions. Look at what you can do with a scanner.

Exercise 4:

Make an addition to your currency program: The program should ask the user (Print out a question and expect an answer that is stored to a variable) both the currency exchange rate and the amount of money to be converted. It should then output the result, as the original program that used a "hard-coded" test case.

New constructs

We have seen how the for structure iterates over some values. Let us look at some simpler loop structures. Examples:

do {
    interactiveCurrencyExchange();
} while (userWantsToContinue());

The above would call the subroutine interactiveCurrencyExchange at least once. And this would be repeated as long as the truth value returned by the subroutine userWantsToContinue is true. Another:

while (userWantsToConvertMoney) {
    interactiveCurrencyExchange();
}

This would repeat interactiveCurrencyExchange as long as userWantsToConvertMoney is true; perhaps the loop never happens, if userWantsToConvertMoney returns false in the first place.

Exercise 5:

Make two programs where you do the following:

  • interactiveCurrencyExchange performs like the program in Exercise 4.
  • userWantsToConvertMoney and/or userWantsToContinue asks the user if he/she wants to continue using the program, and returns the answer as boolean value.
  • your main method will contain exactly the loops given in the examples above.