Prerequisites for SWEA

This page is a bit about 'what it takes to start the SWEA course'. Not all students have followed the 'Introduction to Programming' course (Java based) in the AU computer science/it product bachelor, which contains the primary topics that SWEA is based upon.

So I will try to organize this information package as a set of recommendatations and exercises (with hints) preparing you for starting the course without being overwhelmed.

The programming language, Java, is important

"You can express any program in any programming language." True.

"You can program any program in a language you do not know, in the same time as in a language you do know." Not true.

So if you have followed a course in Python, or is used to C#, or Go, or whatever, you can of course follow SWEA, but you should spend some time before starting SWEA to get used to Java.

Conclusion: Program some code in Java to get a bit of experience and training. I will provide some exercises below.

The Integrated Development Environment is important

SWEA does not dictate choice of programming environment so you can use Emacs, BlueJ, Eclipse, or IntelliJ as development platform, but IntelliJ is the course recommended tool! And the TA's know that particular IDE.

You need a good editor and compilation system, to be efficient and spend time on the mandatory project. BlueJ is a good learning platform, but it is not sufficient for coding the kind of projects that SWEA is geared towards.

Conclusion: Spend some time developing Java using IntelliJ (if you are not already highly proficient in another professional Java IDE).

(It should be mentioned that I have actually coded all the exercises below using only a good editor (Emacs) and the standard shell based java compiler and jvm, and it suffices for these small examples, but --- it does not scale to the mandatory project.)

The Java Core that is central for SWEA

Below I will outline the areas of programming that we again and again base ourselves upon in SWEA.

Object orientation and classes

Java is an object oriented (OO) programming language, and SWEA is rooted in this OO paradigm: we will develop classes, and create objects from these classes again and again.

I have found a number of Java basic OO tutorial videos on youtube (those that I watched were not fantastic, but well...), so if you are really rusty, try to find something there.

Once the core is in place, you can rehearse a bit on the exercises below.

Exercises:

  1. Program a class to represent a bank account. The account should have a balance, and there must be methods to insert and withdraw money. Create a Java main method which creates three accounts and inserts/withdraw money.
  2. Program a class representing a playing card having a rank and a suit. (See wikipedia). The rank and the suit should be enumeration types (like Clubs, Ace, _7, etc.). The class should be immutable, that is, it value (like "(7, Clubs)") must be assigned in the constructor and there must be no setter methods, only accessor methods. The 'toString()' method should return a value like "(10, Diamonds)" or "(King, Spades)".
  3. Program a class to represent "time in the 24-hour clock" so you can set a time in the constructor like
                Time24Hour mytime = new Time24Hour(8, 58); 
                System.out.println( "The Time: " + mytime + ". Must be 08:58.");
              
    That is, there are prefixed zeroes, like "07:05". Then add a 'addMinutes()' method which allows you to add to the time respecting the normal 24 clock:
                mytime.addMinutes(3);
                // 3 minutes added to 08:58 is 09:01
                System.out.println( "Three min later: " + mytime + ". Must be 09:01.");
              
    You can make the exercise progressively harder; start out by only supporting adding up to 60 minutes, then support subtracting minutes, then support adding/subtracting multiple hours (in same day), ala
                // 3 minutes added to 08:58 is 09:01
                System.out.println( "Three min later: " + mytime + ". Must be 09:01.");
    
                mytime.addMinutes(-3);
                System.out.println( "Three min sooner: " + mytime + ". Must be 08:58.");
    
                mytime.addMinutes(180);
                System.out.println( "180 min later: " + mytime + ". Must be 11:58.");
                mytime.addMinutes(-240);
                System.out.println( "240 min sooner: " + mytime + ". Must be 07:58.");
              
    Alternatively, you can aim for a more general solution from the start which solves all cases.

Solutions: At the bottom of this page, you will find hints for solving these (and all the following exercises.)

Encapsulation - "public" and "private"

A object contains state (via its instance variables) and provides methods to inspect and modify its state (via its methods).

In general, an object should shield itself from modifications that are invalid or not properly controlled.

Example: a class to represent a circle may (wrongly) look like this:

        class Circle {
          public double radius;
          public double perimeter; // "omkreds"
          public Circle(double radius) {
            this.radius = radius;
            this.perimeter = 2 * radius * Math.PI;
          }
        }
      
Argue why it is problematic before reading on.

Well. The radius and perimeter is linked by a well-known mathematical law, but the code above allows me to change them independently and without respecting that law, like:

        Circle c = new Circle(2.0); // Perimeter = 2 * PI * 2.0
        c.perimeter = 1234567.89; // Ups - not anymore
      

Java allows you to control access to methods and member variables, using "public" and "private" (and a few others), thus providing "encapsulation" = the object itself ensures that the law is always respected.

Exercises:

  1. Encapsulate the 'radius' and 'perimeter' instance variables, and provide methods so you can set radius but only read the perimeter value.
  2. Augment the class with a method, so you can change the perimeter (and the radius is then correctly computed).
  3. There are two more modifiers: "protected" and package visibility (the latter represented by no modifier). Study what they mean. (We will not deal with them in SWEA, though).

Interface

You will hear me say "Program to an interface" about five times in every lecture. Interface is both an abstract concept but also a central language concept in Java, allowing you to separate "the contract from the actual implementation". So, we will train it a lot in SWEA.

Still, it is nice that you have "seen it before". A java interface is simply 'the contract' without any implementation details. Therefore, an interface cannot contain instance variables, and it never has any method bodies, only the signatures.

Exercises: Rename the Circle class (last exercise) to CircleImpl and let it implement a Circle interface, that defines the 'contract' of a circle (=public methods only).

Collection classes

A lot of programs are geared around "handling large sets of data". In Java the 'util' package contains "collection classes" which are standard implementations of classic data structures like lists and maps. You should know these, and 'List' and 'Map' in particular.

Exercises:

  1. Study and run the List of integer program.
  2. Study and run the HashMapExample in Section 2.1.

Iteration/'Sweep'

Once you have collections, you quickly find yourself in a situation where you compute something based upon inspecting each element in the collection. This is a 'sweep' or a 'for-each-loop' or an 'iteration' - many names, same thing.

Java supports iteration in many ways, both the 'old-school' for each loop

        for (Card c: cardDeck) { "do something with c" }
      
or the Java8 streaming API (which allows a ton of cool things but is also a big topic in itself)
      cardDeck.stream().forEach( c -> { "do something with c" } );
    

Exercises:

  1. Create a 'Deck' class which contains a List of 52 Cards (from the previous playing card exercise). The constructor should initialize the deck to have a single card of each type in the deck: (Ace, Clubs), (2, Clubs), etc.
  2. Create a 'toString()' method that prints the whole deck.
  3. Create a 'shuffle()' method that shuffles the deck so all cards appear in random order in the deck.
  4. Create a 'pickTopCard()' method that draws the top card from the deck (so it is removed from the deck).
  5. Create a 'count(Rank rank)' method, which computes how many card are left in the deck of that particular rank.

Java packages

Large programs are ... large. Packages are a java mechanism for grouping related interfaces and classes into a folder hierarchy, so you do not have to overview 2.000 files in the same folder.

In java, a class in package "com.baerbak.minidraw" must be in a folder named "(something)/com/baerbak/minidraw". And the (something) must be in the java classpath, so the compiler and jvm knows where to find the package.

Exercises: Put the card related classes in a package 'card' and the deck related class in a package 'deck'; that is reorganize the code from the above exercise.

Subclasses and Abstract classes

In OO languages, a class can inherit features of a superclass by subclassing. Abstract classes define commonality between a set of subclasses but leaves implementation details to these subclasses.

A classic example is from computer graphics that can draw/render a number of geometrical shapes: circles, rectangles, etc. Some things are commen to all shapes: they have a position on the screen, they can be moved some (dx,dy) to a new position---and other aspects are special for each shape, notably how they are drawn on screen.

In OO/Java you would declare an abstract (base)class 'Shape' with (at least) an instance variable to hold the position of the shape, and a method to move it to a new position. And then you would declare an abstract method for the 'draw' behaviour. An abstract method has no method body (just like a method declaration in an interface), it must be overridden in a subclass.

Exercises:

  1. Declare an abstract class Shape with a position and a common 'moveBy(int dx, int dy)' and an abstract 'draw()' method. Next create two subclasses, Circle and Rectangle, which overrides the 'draw' method (no real graphics, just output something like "Rectangle at (56,88)" and similar for the circle. Ignore height, width, radius, and all other attributes.
  2. Create a Main program that "draws" a few rectangles and circles, and moves them by adjusting their position.
The java.awt.Point class can be used as a position data type (x,y).

Hints Level 1

This section presents a bit of nudging towards a solution.

Account

You need an instance variable for 'balance' and two methods, one for 'withdraw()' and one for 'deposit()'.

You need a 'main(String[] args)' method which is the starting point of every Java program. In this method you have to instantiate account object and manipulate them. Something like

  public static void main(String[] args) {
    // Create an account
    Account henriksAccount = new Account();
    System.out.println("Henrik's account balance is: "
                       + henriksAccount.balance());
    ...
  }
      

Playing cards

To make a object immutable, you simply do not add any 'setter' methods (i.e. there are no public methods that can change the value of the instance variables.) Set the values in the constructor instead.

An 'enum' is a rather peculiar type of class, which (usually) only contains a list of names, those names that is the range of values. Like

public enum Suit {
  Clubs, Diamonds, Hearts, Spades
}
      

The names must be identifiers, so you cannot have a Rank value of "2". Circumvent it by prefixing with an underscore, like "_2".

Internally, Java treat enums as integers, and you can get that integer by the 'ordinal()' method. Suit.Clubs.ordinal() == 0 is a true statement.

24 hour clock

Well, this is more of a algorithmic exercise. A naive (but fine) implementation is to have instance variables for both hour and minute. Then adding/substracting requires some use of divivion and the modulo operator. A more general approach is to only store 'total minutes since midnight' and then compute the hour and minute to display.

To ensure prefixed '0' in the toString() method you can make an 'if-statement' to handle cases where hour/minute is less than 10.

Circle - encapsulation

Encapsulation is well supported by Java: simply declare the instance variables 'radius' and 'perimeter' as 'private' and no outside object may alter their values.

In the setter methods, be sure to recalculate 'the other variable'. That is, in 'setRadius()' method be sure to update the perimeter according to the mathematical law.

Do not enter Pi youself. Find it in the Math package in Java's standard libraries.

Circle - interface

Call the circle class for 'CircleImpl' and let it implement the 'Circle' interface which only lists the public methods.

Deck - Iteration

Remember to declare the List using Card as generic type, ala List<Card>, and use a concrete implementation (like ArrayList) for the actual type.

List have a lot of different methods for manipulating the list, for the exercises given, you should look for methods 'add()', 'get()', and 'remove()'.

To initialize the deck, you can use a nested iteration (two for-loops), that each runs over all elements in the suit and rank. To get the set of values in an enum, use Suit.values() etc.

Regard shuffling, search the www for Fisher-Yates algorithm.

Packages

Remember, putting a class A into package 'dk.au.cs' requires three things: a package statement in A, import statements in consuming classes, and respecting that class A must be in a specific folder.

Abstract Shape Class

The visibility 'protected' can be used to give access to an instance variable in all subclasses but not "outside" classes, that is, something like "public" for subclasses but "private" for other classes. So that makes sense for a 'position' instance variable.

As stated, Java has the 'java.awt.Point' class which encapsulate a (x,y) point, so you can use that to store position in the shape.

The method Point.translate(dx,dy) can be used to "move" a point.

Hints Level 2

This section presents much more nudging towards a solution.

Account

A class is declared like this

        public class Account { (stuff here) }
      
and must be in a class named Account.java. Classes begin with capital letters in Java.

Instance variables in the class holds the object's internal state. You declare them by specifying the type like

        private int balance;
      

A class should have a constructor, a special method that initializes the object. The constructor has the same name as the class, but no return type like:

        public Account() {
          balance = 0;
        }
      

Methods are the things we can ask our object to do. You declare a method header and provide the implementation of that method.

        public void deposit(int amount) { balance += amount; }
      

Playing cards

No further hints.

24 hour clock

A short if form is something like

    String hourAsString = (hour < 10) ? "0"+hour : ""+hour;
      

To do formatting with prefixed 0 you can actually use the 'format' method of String. Have a look at that...

Circle - encapsulation

Something like

public class Circle {
  private double radius;
  private double perimeter; 
  ...
      

Make the 'adjustment' into a private method, so you can call it from both the constructor and the set method.

  public Circle(double radius) {
    this.radius = radius;
    adjustPerimeter();
  }

  private void adjustPerimeter() {
    this.perimeter = 2 * radius * Math.PI;
  }
      

Circle - interface

The interface may look like

public interface Circle {
  double getRadius();
  double getPerimeter();

  void setRadius(double newValue);
}
      

Note that you do not need to specify 'public' on methods as they are by definition public. (But you can do it without Java complaining.)

Deck - Iteration

You could try to solve the iteration exercises with both the classic for-loop, or with the streaming API.

For instance, counting the number of cards in the deck having a given 'rank' can be done via 'filter' and 'sum':

    return theDeck
      .stream()
      .filter( c -> c.getRank() == rank )
      .sum();
      

And shuffling? The Java collection library already has it.

        Collections.shuffle(theDeck);
      
Morale: Never implement anything unless you can not found it in trust-worthy libraries!

Packages

To state a class, A, is in a package, start the .java file with "package dk.au.cs" or whatever package it belongs to.

To import it in consuming classes use "import dk.au.cs.A" or the more lazy "import dk.au.cs.*" to fetch all classes in that package.

Abstract Shape Class

An abstract class is declared as any other class, but you prefix it with public abstract class Shape. Methods and instance variables are declared as you normally would. The 'draw()' method should be declared abstract as well: public abstract void draw().

Hints Level 3

Below you can find a Zip file with my own proposals for solving the exercises. Note that programming is not like math: there is no such thing as the one correct solution. There are several solutions possible, so just take mine as inspiration. In several places you will find code commented out, representing alternative ways of doing this or that.

Find my proposals for solving the exercises in this zip file: prereq-proposals.zip.


- Henrik Bærbak Christensen