Skip navigation

3D Motion and Control in Processing. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES
1. Describe the difference between camera transformations and screen transformations, and outline which is appropriate to use in which circumstance.

2. Describe the phenomenon of motion parallax, and demonstrate usage of it in 3D motion.

3. Demonstrate how to implement circular motion (rotation).

4. Demonstrate how to implement camera motion using a range of inputs, including the mouse and the keyboard.

5. Show how to use 3D motion in a creative context, to implement things such as animation and special effects.

3D Graphics in Processing. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES

1. Explain how 3D images are represented and displayed on a two dimensional screen.
 
2D objects have only two dimensions, their length and height, and any point on the object can be specified by two coordinates, x and y. When we consider 3D objects, we have a third dimension, depth and a point within a 3D object is represented by three coordinates, x, y and z.
 
When we view 3D objects on a 2D screen we view them through a viewport or viewing rectangle, which is a 2D plane with some orientation to the object. This is analogous to looking through a window at a scene, we see a 2D representation of the 3D scene. When viewing a 2D object on a 2D plane, the object is actually on the viewing plane (although it could be rotated, and at any point along the length and height of the plane), analogous to looking at a stain-glassed window art work. When we view a 3D object the 2D viewport plane could be on, above or below the object (as well as being rotated around the object, with the object at any point along the length and height of the plane).
 
2. Describe and use image rendering

The objects that we see on our 2D viewport or screen are rendered onto it, a process of calculating which points of the 3D object would be visible from the viewport.

To continue the window analogy, the same 3D scene viewed through different windows of a house will appear differently. Some objects are only viewable through certain windows because other objects get in the way (walls, other buildings, trees etc).

The rendering process also allows for perspective ensuring that objects that are further away from the viewpoint appear smaller than objects that are closer to the viewpoint.

The following code, ©UoL creates a scene that visualises a 3D space showing the inside of a cube with a sphere at the origin using the line() and sphere() methods. The code has been adjusted from the original to add the right-hand side and ceiling of the cube. The viewport in this example is at the origin (top-left) perpendicular to the z-axis. It is convention to assume that the positive z axis is toward the viewer and therefore the negative z axis is into the screen away from the viewer.

Because the sphere is centred at the origin, only a proportion of it can be seen in the sketch.

CODE: ©UoL grid_sphere.pde

import processing.opengl.*;
int sz = 512;
size(sz, sz, OPENGL);
background(255);
strokeWeight(3);
noFill();
int step=64;
for(int k=0; k<=sz; k+=step)
{
  //bottom grid
  line(k, sz, 0, k, sz, -sz);
  line(0, sz, -k, sz, sz, -k);
  //top grid
  line(k, 0, 0, k, 0, -sz);
  line(0, 0, -k, sz, 0, -k);
  //back grid
  line(0, k, -sz, sz, k, -sz);
  line(k, sz, -sz, k, 0, -sz);
  //left grid
  line(0, sz, -k, 0, 0, -k);
  line(0, k, 0, 0, k, -sz);
  //right grid
  line(sz,0,-k,sz,sz,-k);
  line(sz, k, 0, sz, k, -sz);
}
sphereDetail(20);
sphere(128);

The code above creates the following image:

Sphere and cube constructed using Processing

3. Use various OpenGL methods in creating 3D images

The code below ©UoL again uses the sphere() OpenGL method, along with the box() method which creates a cube automatically.

CODE: ©UoL red_sphere_blue_box.pde

import processing.opengl.*;
void setup()
{
  size(512, 512, OPENGL);
  sphereDetail(20);
  noFill();
}
void draw()
{
  background(255);
  translate(width/4, height/2, 0);
  stroke(255, 0, 0);
  sphere(100);
  translate(width/2, 0);
  stroke(0, 0, 255);
  box(100);
}

This code creates the following sketch:

red sphere and blue box constructed in Processing

In this code we use the sphereDetail() method which specifies the density of the triangles used to create the sphere wireframe. Note also the import statement at the beginning of the code which allows the usage of the OpenGL classes and methods, along with the OPENGL attribute in the size() method that tells the computer to use specialised 3D hardware in the computer, rather than software, to render the sketch. OpenGL was developed by Silicon Graphics Ltd (SGI) as an open specification API (Application Programming Interface) for software to use specially-designed 3D graphics hardware and typically provides higher performance than software-only graphic rendering.

The OpenGL methods, sphere() and box() are always rendered at the origin, so to construct sketches using these methods we must translate() the origin as we have in the example above.

An additional method, camera() can be used to manipulate the position of the viewport rather than the object itself. It has nine 3D coordinate parameters, three sets of three. The first set positions the camera, the second sets the point where the camera is aiming and the third specifies which axis is pointing upwards (usually the y-axis).

If we consider the previous sketch, with the red and blue sphere, we can change the scene by repositioning the camera. The following code repositions the camera to the origin (0,0,0), the top-left hand corner of the screen and aims it at the bottom-right hand corner of the screen, still on the z-axis origin (width, height, 0) so that instead of looking at the scene we are actually looking across the scene. Finally we tell Processing that the y-axis is ‘up’.

CODE: red_sphere_blue_box_camera.pde

import processing.opengl.*;
void setup()
{
  size(512, 512, OPENGL);
  sphereDetail(20);
  noFill();
  camera(0,0,0,width,height,0,0,1,0);
}
void draw()
{
  background(255);
  translate(width/4, height/2, 0);
  stroke(255, 0, 0);
  sphere(100);
  translate(width/2, 0);
  stroke(0, 0, 255);
  box(100);
}

The code above creates the following image:

red sphere with blue box in Processing using camera() method

4. Discuss the representation of lines in three dimensions and also how this can give the viewer the perception of depth and perspective

A postulate by a famous 17th century mathematician, Desargues, states that all parallel lines appear to meet at a point at infinity. This postulate from the mathematics of projective geometry, the mathematics used in calculating perspective, is the basis for all 3D graphics.

Parallel lines are drawn so that they converge at a vanishing point. This process causes objects that are further away from the viewport to appear smaller than closer objects, creating the illusion of depth and perspective.

As a point of interest and a request from the study notes, this postulate is based on axioms of projective geometry, one of which holds:

Any two lines in a plane have at least one point of the plane (which may be the point at infinity) in common.

Source: Weisstein, Eric W. “Projective Geometry.” From MathWorld–A Wolfram Web Resource.

Projective geometry is an evolution of the more intuitive Euclidean geometry, which is based on the assumption that the x, y and z planes are inherently flat (as opposed to be being spherical, hyperbolic or some other construct). Within Euclidean geometry, a 5th, or parallel postulate holds:

If two lines are drawn which intersect a third in such a way that the sum of the inner angles on one side is less than two right angles, then the two lines inevitably must intersect each other on that side if extended far enough.

Source: Weisstein, Eric W. “Euclid’s Postulates.” From MathWorld–A Wolfram Web Resource.

Both geometries are used in the rendering algorithm to project a 3D object onto a 2D viewport.

5. Perform various manipulations, including scaling, rotation and transformations to change the way an image is presented, in both 2D and 3D

Considering the scale() method first, that allows us to stretch and contract the x, y and z-axes in a Processing sketch. The code to draw the red sphere and blue box from the previous example has been modified to include the scale() method that increases the z-axis scale by 4. Because we have inserted this code after the sphere has been drawn but before the box, only the box has been scaled, elongating the box along the z-axis by a factor of 4.

When the scale() method is used within a draw() method loop, each time the loop starts again, the transformation is reset so that the effect is not cumulative, as scale(2) followed by scale(2) is the equivalent to scale(4).

CODE: red_sphere_blue_box_scaled.pde

import processing.opengl.*;
void setup()
{
  size(512, 512, OPENGL);
  sphereDetail(20);
  noFill();
}
void draw()
{
  background(255);
  translate(width/4, height/2, 0);
  stroke(255, 0, 0);
  sphere(100);
  translate(width/2, 0);
  stroke(0, 0, 255);
  scale(1, 1, 4); //scale z-axis by 4
  box(75); //reduce size of box to stay viewable with scaled
            //dimensions (from 100 to 75)
}

The code above produces the following sketch.

red sphere and blue box rendered in Processing using scale() method

Let us now consider the rotateX(), rotateY() and rotateZ() methods. Each of these methods allow us to rotate a scene around the x, y or z axes. If we think about a airplane in flight: rotating around the x-axis is the equivalent of pitching, climbing or diving; rotating around the y-axis is the equivalent of yawing, to the left or right; rotating around the z-axis is the equivalent of rolling, to the left or right.

Unlike the scale() or transform() methods, the order in which we apply the rotate() methods has an effect on the resulting image.

The following code illustrates the concept of rotating about the y-axis.

CODE: ©UoL rotateY_sketch.pde

size(512, 512, P3D);
rotateY(PI/3);
noStroke();
background(255);
fill(0);
ellipse(256, 256, 512, 512);
rect(512,0, 512, 512);
rect(1024, 512, 512, 512);
rect(1536, 0, 512, 512);
rect(2048, 512, 512, 512);
rect(2560, 0, 512, 512);
rect(3072, 512, 512, 512);
stroke(0);
strokeWeight(3);
line(0, 0, 1e6, height);
line(0, height, 1e6, height);
line(0, 2*height, 1e6, 2*height);

The code above produces the following image:

Processing sketch using rotateY() method

Finally, consider the transform() method. We have seen this used in different code and images already in this post, but the code below uses the translate() and rotate() methods within three for() loops to construct a cube of spheres (©UoL). In this example, after each sphere is rendered, the translation and rotation applied is reversed to allow the for()loops to reposition the next sphere easily relative to the original.

CODE: ©UoL cube_of_spheres.pde

import processing.opengl.*;
int sz=512;
void setup()
{
  size(sz, sz, OPENGL);
  fill(0, 127, 255);
  stroke(0);
  noLoop();
  sphereDetail(12);
}
int boxVol=2*sz/3;
int nBoxes=8;
int boxSZ=boxVol/nBoxes;
float ang1=PI/(4/sqrt(2));
float ang2=PI/(4/((1+sqrt(5))/2));
void draw()
{
  background(255);
  translate(sz/4, 0 , -sz/4); //position
  for(int i=0; i   {
    for(int j=0; j     {
      for(int k=0; k&rt;-boxVol; k-=boxSZ)
      {
        rotateY(ang1);
        rotateX(ang2);
        translate(i, j, k);
        sphere(boxSZ/2);
        translate(-i,-j,-k);
        rotateX(-ang2);
        rotateY(-ang1);
      }
    }
  }
}

The code above creates the following image:

cube of spheres constructed in Processing

To avoid having to restore the coordinate system after every transform() we can use the methods pushMatrix() and popMatrix() to store and restore the current coordinate system. Up to 20 calls to pushMatrix() can be made before a popMatrix() is required and because the coordinate data is stored on a stack, the last item on the stack is the first item off the stack, so coordinates are restored in reverse order.

We can see these methods in use in the following code ©UoL.

CODE: ©UoL popMatrix_3D.pde

import processing.opengl.*;
int sz=512;
void setup()
{
  size(sz, sz, OPENGL);
  fill(200,200,255);
  noStroke();
  noLoop();
  sphereDetail(12);
}
float boxVol=sz;
float nBoxes=8.0;
float boxSZ=boxVol/nBoxes;
float ang1=PI/(4/((1+sqrt(5))/2));
void draw()
{
  background(255);
  rotateY(ang1);
  translate(sz/2, sz/2, sz/2);
  directionalLight(255,255,255,1,1,-1);
  for(int j=0; j   {
    for(float i=sz/2 - j*boxSZ/2; i <= sz/2+ j*boxSZ/2; i+=boxSZ)
    {
      for(float k=-sz/2 + j*boxSZ/2; k&rt;=-sz/2 - j*boxSZ/2; k-=boxSZ)
      {
        pushMatrix();
        translate(i, j*sqrt(2)*boxSZ/2, k);
        sphere(boxSZ/2);
        popMatrix();
      }
    }
  }
}

In this code, we construct a pyramid from spheres a row at a time, using the pushMatrix() and popMatrix() methods. Also included in this code is a method called directionalLight(). This method has six parameters. The first three set the colour of the light, either RGB or HSB depending on the current colorMode(). The second three set the direction the light is facing along each axis which is usually 0, 1 or -1.

The code creates the following image:

pyramid of spheres created using popMatrix() method in Processing

Expanding lighting further, another useful method is lights(). This method activates various lighting methods with default values. Firstly it sets ambientLight(125, 125, 125). This method lights objects equally from all directions and the parameters set the RGB or HSB values for the light. In addition lights() sets directionalLight(128, 128, 128, 0, 0, -1). Two other methods are initiated, lightFalloff(1, 0, 0) and lightSpecular(0, 0, 0). lightFalloff(1, 0, 0) reduces the amount of light reaching an object as a proportion of its distance from the light source. In the default case the amount of light is inversely proportional to the distance from the source. lightSpecular() is a method that controls the colour of light that bounces off objects in a certain direction due to the properties of those objects (for instance, shiny objects) rather than diffusing in all directions. At default values the light is black so there is no specular light set through the lights() method.

It is important for both the lights() and directionalLight() method in a dynamic-mode Processing sketch to include the them within the draw() section, rather than the setup() section, otherwise they will only be set during the first loop and not adjust from that point.

An example of using lights() and the directionalLight() method in a dynamic sketch can be seen below. This is based on code ©UoL, but with orange directional light applied in the directional of negative-z and negative-x (from behind and to the right).

CODE: sphere_lighting.pde

import processing.opengl.*;
float theta=0;
float dTheta=TWO_PI/360;
float radius=200;
//Lights, Camera, Action
void setup()
{
  size(800, 600, OPENGL);
  noStroke();
  //camera(width/2, height/2, width, width/2, height/2, 0, 0, -1, 0);
  fill(255,255,255);
}
void draw()
{
  lights();
  background(0);
  float x, z;
  x=radius*cos(theta);
  z=radius*sin(theta);
  directionalLight(255, 127, 0, -1, 0, -1);
  pushMatrix();
  translate(width/2+x, height/2, z);
  sphere(50);
  popMatrix();
  pushMatrix();
  translate(width/2-x, height/2, -z);
  sphere(50);
  popMatrix();
  pushMatrix();
  x=radius*cos(theta+PI/2);
  z=radius*sin(theta+PI/2);
  translate(width/2, height/2+x, -z);
  sphere(50);
  popMatrix();
  theta=(theta+dTheta)%TWO_PI;
}

This code creates the following animation of three spheres rotating around the x- and y-axis.

6. Incorporate texture into images

We can apply ‘texture’ to 3D objects by overlaying 2D images to the surfaces of the objects. We can only use P3D mode for this (not supported in OpenGL). We anchor the 2D images to the vertices of the object and the algorithm renders the image texture in 3D in the same way it does primitive objects.

Some new methods are required to utilise this technique in Processing. Firstly, we initialise a PImage type variable with the loadImage() method. This method is capable of loading a .gif, .jpg, .tga, or .png file (the files must be in the same directory as the Processing sketch).

We use the texture() method to apply the image to the object face. It must be called between beginShape() and endShape() methods and before end calls to vertex(). The vertex() method has two additional parameters when using the texture() method which are the x- and y-coordinates in pixels of the point in the texture image that should be fixed to the vertex.

The code below show the texture() method being used. In this code we have created a cube using vertices and textured with images of dice, originally designed by Evgeniy Grigoriev in 2010 (Source)

CODE: vertex_texture_dice.pde

int sz = 336; //this is the size of the di face in pixels
int x1 = (width-sz)/2; //position the di in the middle of the screen
int y1 = (height-sz)/2; //position the di in the middle of the screen
int z1 = 0; //position the front of the di on the z-axis origin
int x2 = x1+sz; //set the relative positions of the other points of
                //the cube
int y2 = y1+sz;
int z2 = z1-sz; //z-axis negative into screen
size(500,500, P3D);
background(255, 127, 0); //orange background
camera(width, -300, 100, width/2, height/2, -200, 0, 1, 0);
/* camera positioned at the far right hand edge of the x-axis screen, 
300 pixels above the origin and 100 pixel back from the origin. 
Looking at the centre of the screen 200 pixels behind the origin on 
the z-axis with the y-axis as up.
*/
//face1 - front
beginShape();
PImage dice_1 = loadImage("dice-1.gif");
texture(dice_1);
vertex(x1,y1,z1,0,0);
vertex(x2,y1,z1,sz,0);
vertex(x2,y2,z1,sz,sz);
vertex(x1,y2,z1,0,sz);
endShape();
//face4 - top
beginShape();
PImage dice_4 = loadImage("dice-4.gif");
texture(dice_4);
vertex(x1,y1,z1,0,0);
vertex(x2,y1,z1,sz,0);
vertex(x2,y1,z2,sz,sz);
vertex(x1,y1,z2,0,sz);
endShape();
//face6 - back
beginShape();
PImage dice_6 = loadImage("dice-6.gif");
texture(dice_6);
vertex(x1,y1,z2,0,0);
vertex(x2,y1,z2,sz,0);
vertex(x2,y2,z2,sz,sz);
vertex(x1,y2,z2,0,sz);
endShape();
//face3 - bottom
beginShape();
PImage dice_3 = loadImage("dice-3.gif");
texture(dice_3);
vertex(x1,y2,z1,0,0);
vertex(x2,y2,z1,sz,0);
vertex(x2,y2,z2,sz,sz);
vertex(x1,y2,z2,0,sz);
endShape();
//face5 - right
beginShape();
PImage dice_5 = loadImage("dice-5.gif");
texture(dice_5);
vertex(x2,y1,z1,0,0);
vertex(x2,y2,z1,sz,0);
vertex(x2,y2,z2,sz,sz);
vertex(x2,y1,z2,0,sz);
endShape();
//face2 - left
beginShape();
PImage dice_2 = loadImage("dice-2.gif");
texture(dice_2);
vertex(x1,y1,z1,0,0);
vertex(x1,y2,z1,sz,0);
vertex(x1,y2,z2,sz,sz);
vertex(x1,y1,z2,0,sz);
endShape();

The code above creates the following image of a 3D dice:

3D dice created using texture() method in Processing

EXERCISES
The exercises for this chapter concern matrix algebra which forms part of the Mathematics for Computing course and will be covered in that section of the notes in time. Therefore the exercises for this chapter have been omitted.

Colour in Processing. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES

1. Distinguish between the RGB and HSB colour modes.

In Processing there are two distinct colorModes(). The RGB mode represents colours in the way that a computer stores colour data. RGB has three attributes which each represent the intensity of the light emitted by the monitor for the red, green and blue primary additive colours. Therefore the color red is represented by (255, 0, 0), green by (0, 255, 0) and blue by (0, 0, 255). All other colours are created by mixing a combination of these three primary colours.

There is an alternative way to manipulate colours, using the HSB mode, which represents colours according to three attributes, hue, saturation and brightness. Hue specifies the angle around the color wheel where the particular color lives (0 representing red, TWO_PI radians or 360 degrees bringing you back round to red. Saturation specifies the amount of white included in the mix, so 100% saturation represents a complete absence of white mixed with the hue. Brightness represents the intensity of the light transmitting the colour from the monitor with 0% brightness representing black.

HSB is a more intuitive way for humans to think about colours and combinations of colours. RGB on the other hand is how the underlying data in stored and manipulated by a computer. Different modes suit different programming circumstances but in general RGB is more difficult to use because you need to manipulate all three attributes to create differing amounts of saturation and brightness of a particular colour.

2. Use the color type in Processing to create interesting images.

Colours in Processing are stored in a new type called color which is actually of type int. There are a variety ways of assigning a value to a color type. We can use the color() method in conjunction with the colorMode() method and we can also directly assign color values using hex (0x) and web hex (#) values. The following code uses both hex and the color() method. Note that the default colorMode() for Processing is RGB with values ranges of 0 – 255 for each value of red, green and blue.

CODE: _4_color_design.pde

size (400,400);

//first two colors
color color1=0xFF00FFFF;
color oppcolor1=color(255-red(color1), 255-green(color1), 
255-blue(color1));

//second two colors
color color2=0xFFFF00FF;
color oppcolor2=color(255-red(color2), 255-green(color2), 
255-blue(color2));

//design

background(color1);
noStroke();
fill(oppcolor1);
rect(50,50,100,100);
fill(color2);
rect(width/2,0,200,400);
fill(oppcolor2);
rect((width/2)+50,50,100,100);
rect(0,200,200,200);
fill(color2);
rect(50,height-150,100,100);
fill(oppcolor1);
rect(200,200,200,200);
fill(color1);
rect(250,250,100,100);

This code creates a design using opposite colours. We calculate the opposite of a colour in RGB mode by creating a colour which takes away its red, green and blue components from 255. In HSB, the opposite colour is the colour PI radians or 180 degrees around the colour wheel.

Here is the design.

4 colour design in Processing

3. Describe how the red, green, blue and alpha channels together contribute to colour in images.

Using the hex method of assigning colour values to a pixel, we use 2 bits for each of the alpha, red, green and blue colour channels. The alpha channel represents the degree of transparency of the pixel. So a value of 127 (7F in hex) represents a 50% transparency. Therefore a non-transparent red pixel is assigned by the following code:

color RED = 0xFFFF0000;

A green non-transparent pixel by:

color GREEN = 0xFF00FF00;

And a blue 50% transparent pixel by:

color BLUE50 = 0x7F0000FF;

If we are using the color() method, we can specify the individual channels with specific methods alpha(), red(), green() and blue() as we did in the code above when we wanted to create the opposite colours.

Red, green and blue are the additive primary colours. Their opposites are respectively cyan, magenta and yellow which are known as secondary colours. Whilst a primary colours only has one of its colour channels active, the opposite secondary colour (each of the colour channels respectively subtracted from FF) has the two remaining channels active so is therefore a blend of the remaining primary colours. Consider the colour red (0xFFFF0000) and its opposite colour cyan (0xFF00FFFF). Cyan is an equal blend of green and blue.

So, all the secondary colours can be created by combining equal quantities of two of the primary colours. The tertiary colours are created by combining one primary colour with a non-opposite secondary colour in a ratio of 2:1. We don’t combine with the opposite secondary colour because this would mean blending three primary colours together which is not the definition of a secondary colour.

When we use the alpha channel at 50% transparency we are effectively reducing the proportion of the colour mixed with that transparency by half. So red combined with yellow (at 50% transparency) in a 1:1 ratio is the same as red combined with yellow (with no transparency) in a 2:1 ratio. Both create orange.

The tertiary colours (with their radian values for HSB mode) are:

  • Red (0*PI) + 50% Yellow (PI/3) = Orange (PI/6)
  • Red (0*PI) + 50% Magenta (5*PI/3) = Fuschia (11*PI/6)
  • Green (2*PI/3) + 50% Yellow (PI/3) = Lime Green (PI/2)
  • Green (2*PI/3) + 50% Cyan (PI) = Aquamarine (5*PI/6)
  • Blue (4*PI/3) + 50% Cyan (PI) = Azure (7*PI/6)
  • Blue (4*PI/3) + 50% Magenta (5*PI/3) = Violet (3*PI/2)

 
The quaternary colours are similarly created by combining a primary colour with a non-opposite secondary colour but in the proportions 4:1 and 4:3. There are therefore 12 quaternary colours, however they do not have generally agreed names which is problematic when trying to define or discuss them!!

4. Use the concept of transparency and implement the concepts of colour blending and colour gradients.

Colour gradients, a design technique that progressively blend two colours can be constructed easily in Processing. We can use system variables like height and width to simplify our code. An example is shown below:

CODE: colour_gradient.pde ©UoL

int sz=512;        //define screen dimensions
size(sz,sz);      //set screen size
//use screen dimension as color range
colorMode(RGB, sz-1, sz-1, sz-1);
noStroke();
int step=1;
for (int x=0; x<width; x+= step)
{
   fill (x, width-x, 0);
   rect (x, 0, step, height);
}

Here we’re using the width system variable to control the red and green channels in the for loop. This code produces the following output.

2 colour gradient, green to red, in Processing

We can use the concepts of colour blending to create the secondary and tertiary colours. The following examples show code that creates the secondary and tertiary colours.

CODE: secondary_colours.pde

int sz=512;
void setup()
{
  size(sz,sz);
  noStroke();
}
//Primary colors
color Red = color(255,0,0);
color Green = color(0,255,0);
color Blue = color(0,0,255);
//Secondary colors
color Yellow = color(255,255,0);
color Magenta = color(255,0,255);
color Cyan = color(0,255,255);

void draw()
{
  int x=0; int hop=width/3;
  fill(Yellow); rect(x,0,x+=hop,height);
  fill(Cyan); rect(x,0,x+=hop,height);
  fill(Magenta); rect(x,0,x+=hop,height);
}

The code above creates the following output.

sescondary colours constructed using blending in Processing

To create the tertiary colours, we can use the following code.

CODE: tertiary_colours.pde ©UoL

int sz=512;
//Primary colors
color Red = color(255,0,0);
color Green = color(0,255,0);
color Blue = color(0,0,255);
//Secondary colors
color Yellow = color(255,255,0);
color Magenta = color(0,255,255);
color Cyan = color(255,0,255);
//setup
void setup()
{
  size(sz,sz/3);
  noStroke();
  noLoop();
}
color tertiary(color prim, color sec)
{
  //use bit-wise OR and the color() method to construct a new color
  //using half the red, green and blue values of the secondary
  return prim | color(red(sec)/2, green(sec)/2, blue(sec)/2);
}
void draw()
{
  int x=0; int hop=width/6;
  //orange
  fill(tertiary(Red, Yellow)); rect(x,0,x+=hop,height);
  //fuschia
  fill(tertiary(Red, Magenta)); rect(x,0,x+=hop,height);  
  //chartreuse
  fill(tertiary(Green, Yellow)); rect(x,0,x+=hop,height);
  //aquamarine
  fill(tertiary(Green, Cyan)); rect(x,0,x+=hop,height);
  //violet
  fill(tertiary(Blue, Magenta)); rect(x,0,x+=hop,height);
  //orange
  fill(tertiary(Blue, Cyan)); rect(x,0,x+=hop,height);
}
  

This code creates the following output. It uses bit-wise operators, ‘OR’-ing the primary and secondary colours together in the correct ratio to create the tertiary colours.

tertiary colours created using bit-wise operations in Processing

5. Discuss colour schemes and the use of primary, secondary and tertiary colours.

Colour schemes allow designers to ensure the final result of their work is pleasing to the eye. The HSB mode is more helpful than the RGB mode in constructing colour schemes. In general, when using two colours it is best to use opposite colours, that is, colours that are PI radians away from each other around the colour wheel. Or putting it another way, a two colour scheme will use one primary colour and one secondary colour. When using three colours, colours that are evenly spaced around the wheel (or a large proportion of it) create a pleasing scheme. Thinking in terms of primary, secondary and tertiary colours, three colour schemes tend to look best when the three colours are all primary, all secondary or all tertiary. It’s best to avoid selecting colours from a small proportion of the wheel (that is a mix of primary, secondary and tertiary colours close to the original primary colour on the wheel).

EXERCISES

Q: Make different three-colour schemes using colours chosen at intervals around the hue circle. Draw three different filled shapes (e.g. triangle, rectangle, ellipse) using your scheme including each of the following colours in your scheme: a) red; b) lime green; c) violet.

The way I’ve tackled this problem is by drawing the three shapes and then creating a three-colour scheme spread out equally around the colour wheel, TWO_PI/3 and 2*TWO_PI/3 radians on from the first and second colours respectively. The program begins with red being the first colour in the scheme. Then, I advance the first colour by small incremental angle, which in turn advances the second and third colours by the same increment. In this way, the program covers all colours including red, lime green and violet.

CODE: three_colour_scheme.pde

int sz=512;
void setup()
{
  size(sz,(int)(sz*0.61)); //rectangle height 61% of length
  noStroke();
  colorMode(HSB, TWO_PI, 1, 1);
  background(0);
  frameRate(10);
  ellipseMode(CORNER);
}
float a=0; //starting angle
float dAng=TWO_PI/512; // angle to advance loop by each time
float B=sz*0.61;
float A=sqrt(3)*B/2.0;
void draw()
{
  float n=sz;
  float m=sz*0.61;
  color c1 = color(a%TWO_PI,1,1); //beginning colour
  //1/3 around colour wheel
  color c2 = color((a+TWO_PI/3)%TWO_PI,1,1);
  //2/3 around colour wheel
  color c3 = color((a+2*TWO_PI/3)%TWO_PI,1,1);
  background (0);
  fill (c3);
  triangle(m/2-B/2, A, m/2+B/2, A, m/2, 0);
  fill(c1);
  ellipse(m,n-m,n-m,n-m);
  fill(c2);
  rect(3*(m/4)+100,20,m/2,m/2);
  a+=dAng; //advance the angle
}

The image below was taken as the code was running.

image created in processing creating a three-colour scheme

Q: Make a four-colour scheme using equal intervals around the hue circle and use it to lay out a design with four objects.

Using the same code as above, but changing the angle of the colours to be spaced out a quarter of the way around the circle each.

CODE: four_colour_scheme.pde

int sz=512;
void setup()
{
  size(sz,(int)(sz*0.61)); //rectangle height 61% of length
  noStroke();
  colorMode(HSB, TWO_PI, 1, 1);
  background(0);
  frameRate(10);
  ellipseMode(CORNER);
}
float a=0; //starting angle
float dAng=TWO_PI/512; // angle to advance loop by each time
float B=sz*0.61;
float A=sqrt(3)*B/2.0;
void draw()
{
  float n=sz;
  float m=sz*0.61;
  color c1 = color(a%TWO_PI,1,1); //beginning colour
  //1/4 around colour wheel
  color c2 = color((a+TWO_PI/4)%TWO_PI,1,1);
  //1/2 around colour wheel
  color c3 = color((a+TWO_PI/2)%TWO_PI,1,1);
  //3/4 around colour wheel
  color c4 = color((a+3*TWO_PI/4)%TWO_PI,1,1);
  background (0);
  fill (c3);
  triangle(m/2-B/2, A, m/2+B/2, A, m/2, 0);
  fill(c1);
  ellipseMode(CORNER);
  ellipse(m,n-m,n-m,n-m);
  fill(c2);
  rect(3*(m/4)+100,20,m/2,m/2);
  fill(c4);
  ellipseMode(CENTER);
  ellipse(n/2,m/2, 180, 180);
  a+=dAng; //advance the angle
}

This code creates the following image during its execution.

four-colour scheme created in Processing

Q: Make a non-uniform interval five-colour scheme. A non-uniform scheme might take three colours from the upper half of the hue circle and two from the lower half. Use principles of trigonometry to space the colours evenly in each half of the hue circle. Use your colour scheme to make a five-colour design, rotating the hue wheel for your scheme using a loop so that the colours change but the hue angles between the colours remain constant.

As per the previous exercises, have adapted the code. This time the colour spacing from the first colour are a quarter and a half way around the hue wheel meaning the first three colours cover half of the wheel. The remaining colours are at 5/8ths and 7/8ths respectively, equally spaced across the second half of the wheel (4/8ths = 1/2 and 8/8ths = 1, which are both already part of the colour scheme).

CODE: five_colour_scheme.pde

int sz=512;
void setup()
{
  size(sz,(int)(sz*0.61)); //rectangle height 61% of length
  noStroke();
  colorMode(HSB, TWO_PI, 1, 1);
  background(0);
  frameRate(10);
  ellipseMode(CORNER);
}
float a=0; //starting angle
float dAng=TWO_PI/512; // angle to advance loop by each time
float B=sz*0.61;
float A=sqrt(3)*B/2.0;
void draw()
{
  noStroke();
  float n=sz;
  float m=sz*0.61;
  color c1 = color(a%TWO_PI,1,1); //beginning colour
  //1/4 around colour wheel
  color c2 = color((a+TWO_PI/4)%TWO_PI,1,1);
  //2/4 around colour wheel
  color c3 = color((a+TWO_PI/2)%TWO_PI,1,1);
  //5/8 around colour wheel
  color c4 = color((a+5*TWO_PI/8)%TWO_PI,1,1);
  //7/8 around colour wheel
  color c5 = color((a+7*TWO_PI/8)%TWO_PI,1,1);
  background (0);
  fill (c3);
  triangle(m/2-B/2, A, m/2+B/2, A, m/2, 0);
  fill(c1);
  ellipseMode(CORNER);
  ellipse(m,n-m,n-m,n-m);
  fill(c2);
  rect(3*(m/4)+100,20,m/2,m/2);
  fill(c4);
  ellipseMode(CENTER);
  ellipse(n/2,m/2, 180, 180);
  strokeWeight(30);
  strokeCap(SQUARE);
  stroke(c5);
  line(50,50, n-50,m-50);
  a+=dAng; //advance the angle
}

This code creates the following image during its execution.

five colour scheme created using Processing

Q: Make a colour gradient, with two tertiary colours as the end-points, that changes horizontally across the scheme.

This took sometime to figure out. The code below creates a gradient that changes vertically across the screen from lime green to violet.

CODE: tertiary_colour_gradient.pde

int sz=400; //define screen dimensions
size(sz,sz); //set screen size
//use screen dimension as color range
colorMode(HSB, TWO_PI, 1, 1);
for (int i=0; i {
    float startAngle;
    float endAngle;

    startAngle = (3*TWO_PI/12); //lime green
    endAngle = (9*TWO_PI/12); //violet

    float sizeEnd = (endAngle-startAngle)/sz;
    float newHue = startAngle + (i*sizeEnd);
    stroke(newHue, 1, 1);
    line(i,0,i,sz);
}

This creates the following image.

tertiary colour gradient created in Processing

Q: Make a colour gradient, with two different colours as the end-points, that changes vertically down the screen.

This code creates a vertical gradient from orange to aqua marine.

CODE: tertiary_colour_gradient_vertical.pde

int sz=400; //define screen dimensions
size(sz,sz); //set screen size
//use screen dimension as color range
colorMode(HSB, TWO_PI, 1, 1);
for (int i=0; i {
    float startAngle;
    float endAngle;

    startAngle = (PI/6); //orange
    endAngle = (5*PI/6); //aqua marine

    float sizeEnd = (endAngle-startAngle)/sz;
    float newHue = startAngle + (i*sizeEnd);
    stroke(newHue, 1, 1);
    line(0,i,sz,i);
}

The code above creates the following image.

vertical colour gradient created in Processing

Q: Make a colour gradient, with two different tertiary colours as the end-points, that changes diagonally across the screen.

This gradient starts in the top left corner as azure and changes to fuschia by the bottom right of the image.

CODE: tertiary_colour_gradient_diagonal.pde

int sz=400; //define screen dimensions
int dsz=sz*2;
size(sz,sz); //set screen size
//use screen dimension as color range
colorMode(HSB, TWO_PI, 1, 1);
for (int i=0; i {
    float startAngle;
    float endAngle;

    startAngle = (7*PI/6); //azure
    endAngle = (11*PI/6); //fuscia

    float sizeEnd = (endAngle-startAngle)/dsz;
    float newHue = startAngle + (i*sizeEnd);
    stroke(newHue, 1, 1);
    line(0,i,i,0);
}

Below, the image created by the code.

diagonal tertiary colour gradient created in Processing

Q: Explain why, due to the limitations of physical display devices, the entire range of possible visible colours, perceivable by the eye, is not representable by the RGB model. Is it possible to represent the entire range of possible visible colours using the HSB model? Explain why or why not.

In Processing, and Java, the colour value of each pixel is represented by a 32 bit (4 byte) integer. Each byte controls the following: the Alpha channel and the Red, Green and Blue colour channels respectively. Each byte (8 bits) has a maximum number of values of 255 (excluding zero) (28=256). Therefore, excluding the degree of transparency that each pixel has, the maximum number of colours that can be displayed is 28 x 28 x 28 = 224 = 16,777,216. Nature does not have the same constraints on the information it can use to process colour, therefore the computer can only display a sub-set of the possible colours perceivable by a human being. The HSB mode is simply an interpretative layer, created for ease of use by humans, which sits on top of the underlying RGB model that the computer uses, and is therefore subject to the same memory constraints. It, therefore, cannot display the full range of potential colours either.

Vectors in Java. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES

1. Explain the similarities and differences between a Vector and an a array.

A Vector is similar to an array. Arrays hold elements of specific types (like int, char, double). Vectors hold elements of type Object. Whereas we need to specify how large an array should be when we initialise it, Vectors can grow or shrink as the program is running.

2. Explain how Vectors are used for storing arbitrarily large amounts of data.

If you don’t know how many elements you are going to need in an array in advance, you can use a Vector. There are several instance methods that are useful for the Vector class.

  • void addElement() :adds an object to the end of a Vector
  • Object elementAt(int i) :returns the ith element of the Vector
  • int Size() :returns the number of elements in the Vector
  • void removeElementAt(int i) :removes the ith element of the Vector
  • void setElementAt(Object x, int i) :changes the ith element to x

 
The following program courtesy of ©UoL allows us to store as much data as we like and find the largest element.

CODE: LargestInVec2.java

package Lecture23;
import java.util.*; //always needed if you use vectors
import java.util.Scanner;
public class LargestInVec2
{
    
public static void main(String[] args)
    {
        
Vector <Integerv = new Vector<Integer>();
        
v = readInVectorOfIntegers();
        
System.out.println("The largest you typed in was " +
        
largest(v));
    }
    
    
public static Vector <IntegerreadInVectorOfIntegers()
    {
        
Scanner in = new Scanner(System.in);
        
Vector <Integerw = new Vector<Integer>();
        
while (in.hasNextInt()) w.addElement(in.nextInt());
        
return w;
    }
    
    
public static int largest(Vector <Integerv)
    {
        
int largestsofar;
        
if (v.size()>0)
        {
            
largestsofar = v.elementAt(0);
            
for (int i=0i<v.size(); i++)
            
if (largestsofarv.elementAt(i))
                
largestsofar = v.elementAt(i);
            
return largestsofar;
        }
        
return 0;
    }
}

In the code above we have defined the type of the Vector using . Vectors can be untyped, but we can also assign a type to them if we want them to hold only one type of data. This is useful as it helps when passing data from Vectors to other variables and helps us keep track of what a Vector is holding, avoiding bugs. Note we specify the type as and not .

3. Explain how to sort Vectors

Vectors can be sorted using exactly the same algorithm as we do for arrays. The code below from ©UoL shows one method of sorting a Vector.

CODE: SortVector.java

package Lecture23;
import java.util.*;
class SortVector
{
    
public static void main(String[] args)
    {
        
System.out.println("Enter some integers terminated by a non-"
        + 
"integer: ");
        
Vector <Integervec = LargestInVec2.readInVectorOfIntegers();
        
Vector <Integeranswer = sort(vec);
        
System.out.println("Sorted gives: ");
        
for (int i=0i<answer.size(); i++)
        {
            
System.out.println(answer.elementAt(i));
        }
        
System.out.println("The original order was: ");
        
for (int i=0i<vec.size(); i++) 
        {
            
System.out.println(vec.elementAt(i));
        }
    }
    
    
public static void swap (Vector wint iint j)
    {
        
Object temp = w.elementAt(i);
        
w.setElementAt(w.elementAt(j),i);
        
w.setElementAt(temp,j);
    }
    
    
public static Vector <Integersort(Vector <Integerv)
    {
        
Vector <Integerw = new Vector<Integer>();
        
for (int i=0i<v.size(); i++)
        {
            
w.addElement(v.elementAt(i));
        }
        
for (int i=0i<w.size()-1i++)
        {
            
for (int j=i+1j<w.size(); j++)
            {
                
if (w.elementAt(i) > w.elementAt(j))
                {
                    
swap(w,i,j);
                }
            }
        }
    
return w;   
    }
}
    

4. Explain how to manipulate the contents of files by storing them in a Vector and then manipulating the Vector.

We can read the contents of a file into a Vector of a char at a time using the read() and addElement() methods and by creating a new FileReader object. Alternatively, we can read the contents of a file into a Vector of s a line at a time using a new Scanner object and new FileReader object and the methods nextLine() and addElement().

From that point, we can manipulate the Vector rather than the file and finally, if required, write the Vector back out to file. The code to demonstrate all of these concepts is shown in the exercises section.

EXERCISES

Q: Work out the output of the code below, which uses an untyped Vector.

CODE: Vector1.java

package Lecture23;
import java.util.*;
class Vector1
{
    
public static void main(String[] args)
    {
        
int k=5;
        
Vector nums = new Vector();
        
for (int i=0i<ki++)
        {
            
nums.addElement(i);
        }
        
nums.addElement('z');
        
nums.addElement("zz");
        
nums.addElement("Goldsmiths is great");
        
for (int i=nums.size()-1i>=0i--)
        {
            
System.out.println(nums.elementAt(i));
        }
    }
}

The code above outputs the following:

Goldsmiths is great
zz
z
4
3
2
1
0

Q: What does the following code do?

CODE: RefParama

package Lecture23;
import java.util.*;
class RefParams
{
    
public static void main(String[] args)
    {
        
System.out.println("Enter some integers terminated by a non-"
        + 
"integer: ");
        
Vector <Integervec = LargestInVec2.readInVectorOfIntegers();
        
Vector <Integeranswer = sort(vec);
        
System.out.println("Sorted gives: ");
        
for (int i=0i<answer.size(); i++)
        {
            
System.out.println(answer.elementAt(i));
        }
        
System.out.println("The original order was: ");
        
for (int i=0i<vec.size(); i++) 
        {
            
System.out.println(vec.elementAt(i));
        }
    }
    
    
public static void swap (Vector wint iint j)
    {
        
Object temp = w.elementAt(i);
        
w.setElementAt(w.elementAt(j),i);
        
w.setElementAt(temp,j);
    }
    
    
public static Vector <Integersort(Vector <Integerv)
    {
        
for (int i=0i<v.size(); i++)
            
for (int j=i+1j<v.size(); j++)
            {
                
if (v.elementAt(i) > v.elementAt(j))
                {
                    
swap(v,i,j);
                }
            }
        
return v;   
    }
}
    

The code above prints out to screen the integers entered in ascending order. When it tries to print out the original order it also prints out the sorted order becuase the original Vector has been over-written in the sort() method.

Q: Write a program that reads some numbers (terminated by a non-integer), stores them in a Vector and prints out the smallest element entered.

CODE: SmallestInVec2.java

package Lecture23;
import java.util.*; //always needed if you use vectors
import java.util.Scanner;
public class SmallestInVec2
{
    
public static void main(String[] args)
    {
        
Vector <Integerv = new Vector<Integer>();
        
v = readInVectorOfIntegers();
        
System.out.println("The smallest you typed in was " +
        
smallest(v));
    }
    
    
public static Vector <IntegerreadInVectorOfIntegers()
    {
        
Scanner in = new Scanner(System.in);
        
Vector <Integerw = new Vector<Integer>();
        
while (in.hasNextInt()) w.addElement(in.nextInt());
        
return w;
    }
    
    
public static int smallest(Vector <Integerv)
    {
        
int smallestsofar;
        
if (v.size()>0)
        {
            
smallestsofar = v.elementAt(0);
            
for (int i=0i<v.size(); i++)
            
if (smallestsofarv.elementAt(i))
                
smallestsofar = v.elementAt(i);
            
return smallestsofar;
        }
        
return 0;
    }
}

Q: Write a program that reads some numbers (terminated by a non-integer), stores them in a Vector and prints out the the sum of all elements entered.

CODE: SumVector.java

package Lecture23;
import java.util.*; //always needed if you use vectors
import java.util.Scanner;
public class SumVector
{
    
public static void main(String[] args)
    {
        
Vector <Integerv = new Vector<Integer>();
        
v = readInVectorOfIntegers();
        
System.out.println("The sum you typed in was " +
        
sum(v));
    }
    
    
public static Vector <IntegerreadInVectorOfIntegers()
    {
        
Scanner in = new Scanner(System.in);
        
Vector <Integerw = new Vector<Integer>();
        
while (in.hasNextInt()) w.addElement(in.nextInt());
        
return w;
    }
    
    
public static int sum(Vector <Integerv)
    {
        
int sum = 0;
        
if (v.size()>0)
        {
            
for (int i=0i<v.size(); i++)
            
sum = sum + v.elementAt(i);
            
return sum;
        }
        
return 0;
    }
}

Q: Write a program that reads some numbers (terminated by a non-integer), stores them in a Vector and prints out the the average of all elements entered.

CODE: AverageVector.java

package Lecture23;
import java.util.*; //always needed if you use vectors
import java.util.Scanner;
public class AverageVector
{
    
public static void main(String[] args)
    {
        
Vector <Integerv = new Vector<Integer>();
        
v = readInVectorOfIntegers();
        
System.out.println("The average you typed in was " +
        
average(v));
    }
    
    
public static Vector <IntegerreadInVectorOfIntegers()
    {
        
Scanner in = new Scanner(System.in);
        
Vector <Integerw = new Vector<Integer>();
        
while (in.hasNextInt()) w.addElement(in.nextInt());
        
return w;
    }
    
    
public static double average(Vector <Integerv)
    {
        
int sum = 0;
        
if (v.size()>0)
        {
            
for (int i=0i<v.size(); i++)
            
sum = sum + v.elementAt(i);
            
return (sum / v.size());
        }
        
return 0;
    }
}

Q: Write a program that asks the user to enter some numbers (terminated by a non-integer) and then prints them out in the opposite order to which they were entered.

CODE: ReverseVector.java

package Lecture23;
import java.util.*;
class ReverseVector
{
    
public static void main(String[] args)
    {
        
System.out.println("Enter some integers terminated by a non-"
        + 
"integer: ");
        
Vector <Integervec = LargestInVec2.readInVectorOfIntegers();
        
//Vector  answer = reverse(vec);
        System.out.println("Reversed gives: ");
        
for (int i=vec.size()-1i>=0i--)
        {
            
System.out.println(vec.elementAt(i));
        }       
        
System.out.println("The original order was: ");
        
for (int i=0i<vec.size(); i++) 
        {
            
System.out.println(vec.elementAt(i));
        }
    }
    
}

Q: Write a program where first the user enters some numbers and then the program asks the user to pick a number. The program tells the user how many of the these numbers the user entered. For example, if the user entered 7 4 4 3 1 7 and then the number 7 was chosen. the program would output 2 because the user had entered two sevens previously.

CODE: NumberMatch.java

package Lecture23;
import java.util.*;
class NumberMatch
{
    
public static void main(String[] args)
    {
        
System.out.println("Enter some integers terminated by a non-"
        + 
"integer: ");
        
Vector <Integervec = LargestInVec2.readInVectorOfIntegers();
        
        
System.out.println("Number to match?> ");
        
Scanner inputObj = new Scanner(System.in);
        
int numIn = inputObj.nextInt();
        
        
System.out.println();
        
System.out.println("Number of matches = " + match(vecnumIn));
        
    }
    
    
public static int match(Vector <Integervint n)
    {
        
int count = 0;
        
for (int i = 0i<v.size(); i++)
        {
            
if (v.elementAt(i) == ncount++;
        }
        
return count;
    }
}

Q: Write a program where the user types in a number of Strings stored in a Vector of Strings and then the program prints out the longest String.

CODE: longestStringVector.java

package Lecture23;
import java.util.*; //always needed if you use vectors
import java.util.Scanner;
public class longestStringVector
{
    
public static void main(String[] args)
    {
        
Vector <Stringv = new Vector<String>();
        
v = readInVectorOfStrings();
        
System.out.println("The longest String you typed in was '" +
        
longestString(v) + "'");
    }
    
    
public static Vector <StringreadInVectorOfStrings()
    {
        
System.out.println("Input your strings, terminate by typing "
        + 
"EXIT> ");
        
Scanner in = new Scanner(System.in);
        
Vector <Stringw = new Vector<String>();
        
String s=null;
        
boolean exit = false;
        
while (exit==false
        {
            
s = in.nextLine();
            
w.addElement(s);
            
if (s.compareTo("EXIT")==0exit=true;      
        }
        
return w;
    }
    
    
public static String longestString(Vector <Stringv)
    {
        
String longestsofar="";
        
if (v.size()>0)
        {
            
longestsofar = v.elementAt(0);
            
for (int i=0i<v.size(); i++)
            
if (longestsofar.length() < v.elementAt(i).length())
                
longestsofar = v.elementAt(i);
            
return longestsofar;
        }
        
return null;
    }
}

Q: Write a method that reads in a series of integers from the user but sorts them into ascending order as it puts them into the Vector.

CODE: SortIntVectorOnInput.java

package Lecture23;
import java.util.*;
import java.util.Scanner;
public class SortIntVectorOnInput
{
    
public static void main(String[] args)
    {
        
Vector <Integerstore = new Vector <Integer>();
        
System.out.println("Input your integers> ");
        
        
        
Scanner inObj = new Scanner(System.in);
        
int s;
        
int count = 0;
        
while (inObj.hasNextInt())
        {
            
s = inObj.nextInt();
            
store.addElement(s);
            
//count ++;
            findWhereToInsertAscending(sstore /*, count*/);
        }
        
        
        
System.out.println();
        
System.out.println("In Ascending Order: ");
        
for (int i=0i<store.size(); i++)
        {
            
System.out.println(store.elementAt(i));
        }
        
System.out.println();
    }
    
    
    
public static void shuffle(int elementPosVector <Integerv)
    {
        
Vector <Integerclone = new Vector <Integer>();
        
for (int j=0j<v.size(); j++)
        {
            
clone.addElement(v.elementAt(j));
        }
        
for (int i=elementPosi<v.size()-1i++) 
        {
            
//System.out.println("Shuffling...");
            //System.out.println("Setting value of object at " + (i+1
            //+ " element to " + clone.elementAt(i));
            v.setElementAt((clone.elementAt(i)), i+1);
        }
    }
        
        
    
public static void 
    
findWhereToInsertAscending(int sVector <Integerv)
    {
        
int pos=0;
        
boolean exit=false;
        
for (int i=0i<v.size(); i++)
        {
            
//System.out.println("Value of object at " + i + 
            //" element = " + v.elementAt(i));
            if (s < v.elementAt(i)) 
            {
                
//System.out.println(s + 
                //" should be inserted at element " + i); 
                shuffle(iv);
                
v.setElementAt(si);
                
return;
            }
            
//System.out.println();
            
        }
        
return;
    }
}
        

Q: Adjust the code above to sort the elements in descending order on input.

CODE: SortIntVectorOnInputDesc.java

package Lecture23;
import java.util.*;
import java.util.Scanner;
public class SortIntVectorOnInputDesc
{
    
public static void main(String[] args)
    {
        
Vector <Integerstore = new Vector <Integer>();
        
System.out.println("Input your integers> ");
        
        
        
Scanner inObj = new Scanner(System.in);
        
int s;
        
int count = 0;
        
while (inObj.hasNextInt())
        {
            
s = inObj.nextInt();
            
store.addElement(s);
            
//count ++;
            findWhereToInsertAscending(sstore /*, count*/);
        }
        
        
        
System.out.println();
        
System.out.println("In Ascending Order: ");
        
for (int i=0i<store.size(); i++)
        {
            
System.out.println(store.elementAt(i));
        }
        
System.out.println();
    }
    
    
    
public static void shuffle(int elementPosVector <Integerv)
    {
        
Vector <Integerclone = new Vector <Integer>();
        
for (int j=0j<v.size(); j++)
        {
            
clone.addElement(v.elementAt(j));
        }
        
for (int i=elementPosi<v.size()-1i++) 
        {
            
//System.out.println("Shuffling...");
            //System.out.println("Setting value of object at " + (i+1
            //+ " element to " + clone.elementAt(i));
            v.setElementAt((clone.elementAt(i)), i+1);
        }
    }
        
        
    
public static void 
    
findWhereToInsertAscending(int sVector <Integerv)
    {
        
int pos=0;
        
boolean exit=false;
        
for (int i=0i<v.size(); i++)
        {
            
//System.out.println("Value of object at " + i + 
            //" element = " + v.elementAt(i));
            if (s > v.elementAt(i)) 
            {
                
//System.out.println(s + 
                //" should be inserted at element " + i); 
                shuffle(iv);
                
v.setElementAt(si);
                
return;
            }
            
//System.out.println();
            
        }
        
return;
    }
}
        

Entirely the same code only with a > symbol rather than a < symbol in the line if (s > v.elementAt(i)).

Q: Write a method that does a binary search for an Integer in a Vector. It must return the position of the Integer in the Vector and -1 if it's not there. Assume the Vector is sorted in ascending order.

CODE: InputBinarySearchVec.java

package Lecture23;
import java.util.*;
import java.util.Scanner;
public class InputBinarySearchVec
{
    
public static void main(String[] args)
    {
        
Vector <Integerstore = new Vector <Integer>();
        
System.out.println("Input your integers> ");
        
        
        
Scanner inObj = new Scanner(System.in);
        
int s;
        
int count = 0;
        
while (inObj.hasNextInt())
        {
            
s = inObj.nextInt();
            
store.addElement(s);
            
//count ++;
            findWhereToInsertAscending(sstore /*, count*/);
        }
        
        
System.out.println("Input integer to search for> ");
        
        
Scanner inSrchObj = new Scanner(System.in);
        
int sObj = inSrchObj.nextInt();
        
        
System.out.println();
        
System.out.println("Array Position = " 
        + 
binarySearchPos(storesObj));
        
        
/*
        
        This stuff is just printing out the vector - don't need it
        for this particular exercise
        
        System.out.println();
        System.out.println("In Ascending Order: ");
        for (int i=0; i         {
            System.out.println(store.elementAt(i));
        }
        System.out.println();
        
        */

        
    }
    
    
//the following is the same algorithm as the one we used previously
    //to search through arrays
    
    
public static int binarySearchPos (Vector <Integervint x)
    {
        
int first=0last=(v.size()-1);
        
int mid;
        
while (first <=last)
        {
            
mid = first + (last-first)/2;
            
if (v.elementAt(mid)==xreturn mid;
            
else if (v.elementAt(mid) > xlast = mid-1;
            
else first=mid+1;
        }
        
return -1;
    }

    
    public static void shuffle(int elementPosVector <Integerv)
    {
        
Vector <Integerclone = new Vector <Integer>();
        
for (int j=0j<v.size(); j++)
        {
            
clone.addElement(v.elementAt(j));
        }
        
for (int i=elementPosi<v.size()-1i++) 
        {
            
//System.out.println("Shuffling...");
            //System.out.println("Setting value of object at " + (i+1
            //+ " element to " + clone.elementAt(i));
            v.setElementAt((clone.elementAt(i)), i+1);
        }
    }
        
        
    
public static void 
    
findWhereToInsertAscending(int sVector <Integerv)
    {
        
int pos=0;
        
boolean exit=false;
        
for (int i=0i<v.size(); i++)
        {
            
//System.out.println("Value of object at " + i + 
            //" element = " + v.elementAt(i));
            if (s < v.elementAt(i)) 
            {
                
//System.out.println(s + 
                //" should be inserted at element " + i); 
                shuffle(iv);
                
v.setElementAt(si);
                
return;
            }
            
//System.out.println();
            
        }
        
return;
    }
}
        

The method that the exercise requested is binarySearchPos().

Q: Write a method for removing all duplicates from a Vector of Objects.

CODE: removeDup.java

package Lecture23;
import java.util.*;
public class removeDup
{
    
public static void main(String[] args)
    {
        
//first create a Vector of Objects
        
        
Vector vOO = new Vector();
        
vOO.addElement("Hello");
        
vOO.addElement(1);
        
vOO.addElement(2);
        
vOO.addElement("Hello");
        
vOO.addElement(2);
        
        
/*
        
        Bug check code
        
        for (int i=0; i         {
            System.out.println(vOO.elementAt(i));
        }
        
        */

        
        
removeDupes(vOO);
        
printVec.printVector(vOO);  //wrote a method to print out Vector
                                    //as bored of writing the same
                                    //code in each class
        
    }
    
    
public static void removeDupes(Vector v)
    {
        
        
Object check=null;
        
Object compare=null;
        
        
for (int j=0j<v.size(); j++)
        {
            
check = v.elementAt(j);
            
//System.out.println("Checking for duplicates of "
            //+ v.elementAt(j));
            //System.out.println();
            for (int i=(j+1); i<(v.size()); i++)
            {
                
compare = v.elementAt(i);
                
//System.out.println("Comparing to " + v.elementAt(i));
                //System.out.println();
                if (check.equals(compare)==true
                {
                    
//System.out.println("duplicate");
                    v.removeElementAt(i);
                }
            }           
        }
    }
}
        

Q: Write a program that reads a file into a Vector of Strings, one element per line and then finds the longest line (and in so doing find the longest word in the English language by assessing the file words).

CODE: longestLineInVec.java
\
package Lecture23;
import java.io.*;
import java.util.*;
public class longestLineInVec
{
    
/* this section reads the file into a Vector */
    
    
public static Vector <StringfileToVector(String sthrows
    
Exception
    {
        
Vector <Stringv = new Vector <String> ();
        
Scanner inone = new Scanner(new FileReader(s));
        
while (inone.hasNextLine()) 
        {
            
v.addElement(inone.nextLine());
        }
        
return v;
    }
    
    
/* this is where the hard work is done */
    
public static Object lenLonLineInObj(Vector <Stringv)
    {
        
Object qIsLong = null;  //holds the object for length testing       String s = null;
        int maxlen = 0//holds the maximum String length so far of all
                        //objects tested
        int len = 0;    //holds the length of String to be tested
        int counter = 0;    //holds the position in the Vector of the
                            //object with the maximum length
        for (int i=0i<v.size(); i++)
        {
            
qIsLong = v.elementAt(i);   //read in object to be tested
            s = qIsLong.toString();     //convert object to String
            len = s.length();           //work out length of String
            if (len>maxlen)             //check if longest String
            {
                
maxlen = len;           //if it is, set maxlen to 
                                        //new maximum String length
                counter = i;            //set marker in Vector so we
                                        //know which element is longest
            }       
        }
        
return v.elementAt(counter);    //return longest Object
    }
    
    
public static void main(String[] argsthrows Exception
    {
        
//use command line input to specify the file to assess
        Object longest = lenLonLineInObj(fileToVector(args[0]));
        
//print out to screen longest Object
        System.out.println(longest);
    }
}

//works like a DREAM!!!!

Q: Write a program occ1.java which prints out the number of occurrences of each printable character in a file. Assume the printable characters are those whose Unicode values lie between 30 and 126 inclusive.

Struggled with this one - wrote a routine which used a Vector to store all the characters from the file and another to store the occurrences of those characters. Had a lot of duplicates in it, so then had to clean out the duplicates from both Vectors. The algorithm for that was problematic. Worked fine for small files, but ran out of memory and took too long when using it on larger files.

Here is the very elegant solution provided by the ©UoL.

CODE: fileToVector.java

package Lecture23;
import java.io.*;
import java.util.*;
public class fileToVector
{
    
public static Vector <CharacterfileToVector(String s)
    
throws Exception
    {
        
Vector <Characterw = new Vector();
        
FileReader inone = new FileReader(s);
        
int t=inone.read();
        
while (t!=-1)
        {
            
w.addElement((char)t);
            
t=inone.read();
        }
        
return w;
    }
}

CODE: occ1.java

package Lecture23;
import java.io.*;
import java.util.*;
public class occ1
{
    
public static int occurrences(char xVector <Characterv)
    {
        
int total = 0;
        
for (int i=0i<v.size(); i++)
        {
            
if (v.elementAt(i)==xtotal = total + 1;
        }
        
return total;
    }
    
public static void main(String[] argsthrows Exception
    {
        
Vector <Characterv = fileToVector.fileToVector(args[0]);
        
for (int i=30i<127i++)
        {
            
int n = occurrences((char)i,v);
            
if (n>0System.out.println((char)i + " " + n);
        }
    }
}

Q: Using a Vector, write another program like occ1.java which prints out the occurrences of each character in a file but, this time, prints them in order of popularity. Order the output so that the most frequently occurring characters comes first.

CODE: occSorted.java

package Lecture23;
import java.io.*;
import java.util.*;
public class occSorted
{
    
public static int occurrences(char xVector <Characterv)
    {
        
int total = 0;
        
for (int i=0i<v.size(); i++)
        {
            
if (v.elementAt(i)==xtotal = total + 1;
        }
        
return total;
    }
    
public static void main(String[] argsthrows Exception
    {
        
Vector <Characterv = fileToVector.fileToVector(args[0]);
        
Vector <CharacterchStore = new Vector <Character>();
        
Vector <IntegerintStore = new Vector <Integer>();
        
for (int i=30i<127i++)
        {
            
int n = occurrences((char)i,v);
            
if (n>0
            {
                
//System.out.println((char)i + " " + n);
                
                
//create two new Vectors to hold chars and ints
                chStore.addElement((char)i);
                
intStore.addElement(n);
            }
        }
        
//print out in reverse order
        System.out.println();
        
System.out.println("In reverse order...");
        
while (chStore.size()>0)
        {
            
//find the largest occurrence and save position
            int largestsofar;
            
int largestpos=0;
            
if (intStore.size()>0)
            {
                
largestsofar = intStore.elementAt(0);
                
for (int i=0i<intStore.size(); i++)
                {
                    
if (largestsofar<intStore.elementAt(i))
                    {   
                        
largestsofar = intStore.elementAt(i);
                        
largestpos = i;
                    }
                }
            }
            
//print out largest occurring char and frequency
            System.out.println(chStore.elementAt(largestpos) + " " 
            + 
intStore.elementAt(largestpos) + " ");
            
//remove both values from their respective Vectors
            chStore.removeElementAt(largestpos);
            
intStore.removeElementAt(largestpos);
        }               
    }
}

Q: Complete the previous exercise without using a Vector - use an array instead.

The solution below is ©UoL. The algorithm is really interesting because it was something I was considering using for the frequency exercise. As there are only 255 Unicode characters, you can set up a 'score board' within an array for each Unicode character. As each one occurs, we increment the score on the array 'score board'. The method cat() below does the scoring.

CODE: occs3.java

package Lecture23;
import java.io.*;
import java.util.*;
public class occs3
{
    
public static int biggest(int[] athrows Exception
    {
        
int biggestsofar=0position=0;
        
for(int i=0i<a.lengthi++)
        
if (a[i]> biggestsofar)
        {
            
biggestsofar=a[i];
            
position=i;
        }
        
return position;
    }
    
    
public static void cat(String sint[] athrows Exception
    {
        
FileReader inone = new FileReader(s);
        
int t = inone.read();
        
for (int i=0i<a.lengthi++) a[i]=0;
        
while (t!=-1)
        {
            
a[t]=a[t]+1;
            
t=inone.read();
        }
    }
    
    
public static void main(String[] argsthrows Exception
    {
        
final int max = 255;
        
int[] occs = new int[max];
        
cat(args[0],occs);
        
int huge=biggest(occs);
        
while (occs[huge]!=0)
        {
            
System.out.println((charhuge + " " + occs[huge]);
            
occs[huge]=0;
            
huge=biggest(occs);
        }
    }
}

Q: Write a program occs4.java which you can use to find the frequency as a percentage of each character in a piece of text.

CODE: occs4.java

package Lecture23;
import java.io.*;
import java.util.*;
public class occs4
{
    
public static int biggest(int[] athrows Exception
    {
        
int biggestsofar=0position=0;
        
for(int i=0i<a.lengthi++)
        
if (a[i]> biggestsofar)
        {
            
biggestsofar=a[i];
            
position=i;
        }
        
return position;
    }
    
    
public static void cat(String sint[] athrows Exception
    {
        
FileReader inone = new FileReader(s);
        
int t = inone.read();
        
for (int i=0i<a.lengthi++) a[i]=0;
        
while (t!=-1)
        {
            
a[t]=a[t]+1;
            
t=inone.read();
        }
        
a[10]=0;    //remove line returns
    }
    
    
    
public static int sum(int[] a)
    {
        
int sum=0;
        
for (int i=0i<a.lengthi++)
        {
            
sum=sum+a[i];
        }
        
return sum;
    }
    
    
public static double roundTwoDec(double d)
    {
        
int i = (int)(d*100.0);
        
double d2 = ((double)i)/100.0;
        
return d2;
    }
    
    
    
public static void main(String[] argsthrows Exception
    {
        
final int max = 255;
        
int[] occs = new int[max];
        
cat(args[0],occs);
        
int huge=biggest(occs);
        
double total = sum(occs);

        while (occs[huge]!=0)
        {
            
double d = roundTwoDec((((occs[huge]/total)*100)));
            
System.out.println((charhuge + " " + d + "%");
            
occs[huge]=0;
            
huge=biggest(occs);
        }
    }
}

Notice the method roundTwoDec() which allows us to round a double to two decimal places by converting it into an int and scaling it by 100.0, then converting back to a double and dividing by 100.0.

Q: Write a program searchDictionary.java so that a command line argument 'fred' causes the program to say 'yes' if 'fred' is an English word and 'no' if it isn't.

CODE: fileToVectorLines.java ©UoL

package Lecture23;
import java.io.*;
import java.util.*;
public class fileToVectorLines
{
    
public static Vector <StringfileToVectorLines(String s)
    
throws Exception
    {
        
Vector v = new Vector();
        
Scanner inone = new Scanner(new FileReader(s));
        
while (inone.hasNextLine()) v.addElement(inone.nextLine());
        
return v;
    }
}

CODE: dictionarySearch.java

package Lecture23;
import java.io.*;
import java.util.*;
public class dictionarySearch
{
    
public static void main(String[] argsthrows Exception
    {
    
        
Vector <Stringsearch = new Vector <String>();
        
search.addElement(args[0]);
        
Vector <Stringdictionary = new Vector(
                
fileToVectorLines.fileToVectorLines("words.txt"));
        
        
boolean flag = false;
        
for (int i=0i<dictionary.size(); i++)
        {
            
if
            (
search.elementAt(0).equals(dictionary.elementAt(i))==true)
            {
                
System.out.println("Yes");
                
flag = true;
            }
        }
        
if (flag==falseSystem.out.println("No");
    }
}

Q: Write a program firstlast.java that can be used to print out all English words that start and end with the same letter. The choice of the letter should be a command line argument.

Took a while, but solution (including debug code commented out) below.

CODE: firstlast.java

package Lecture23;
import java.io.*;
import java.util.*;
public class firstlast
{
    
public static String firstLastMatch(Object vObject search)
    {
        
String s = v.toString();
        
//System.out.println("s = " + s);
        int len = s.length();
        
char first = s.charAt(0);
        
//System.out.println("First char = " + first);
        //System.out.println("(int)first = " + (int)first);
        char last  = s.charAt(len-1);
        
//System.out.println("Last char = " + last);
        //System.out.println("(int)last = " + (int)last);
        boolean match = false;
        
int intf = (intfirst;
        
int intsearchf = (int)(search.toString().charAt(0));
        
//System.out.println("intf = " + intf);
        //System.out.println("intsearchf = " + intsearchf);
        if (((int)first == (int)last) && (intf==intsearchf))
        
        
//above we have already checked that the first and last letter
        //are the same, so the second condition in the if statement
        //checks if the first letter of the dictionary word and the 
        //first letter of the search string are the same. Only if they
        //are both the same do we return a match, else 'no match'
        
        {
            
match=true;
            
//System.out.println("Match = " + match);
        }
        
if (match == truereturn s;
        
else return "no match";
    }

    public static void main(String[] argsthrows Exception
    {
    
        
Vector <Stringletter = new Vector <String>();
        
letter.addElement(args[0]);
        
Vector <Stringdictionary = new Vector(
                
fileToVectorLines.fileToVectorLines("words.txt"));
        
        
for (int i = 0i<dictionary.size(); i++)
        {
            
String s = firstLastMatch(dictionary.elementAt(i), 
            
letter.elementAt(0));
            
            
if (s!="no match")
            {
            
System.out.println(firstLastMatch(dictionary.elementAt(i),
            
letter.elementAt(0)));
            }
        }
    }
}

Q: Write a class studentsinVector which has one field called students of type Vector (each element of which is a student) and a constructor which reads from a file and then stores all the students in the Vector Students.

Following code inspired by the ©UoL coursenotes answers.

CODE: studentsinVector.java

package Lecture23;
import java.util.*;
import java.io.*;
public class studentsinVector
{
    
public Vector <Studentstudents = new Vector <Student> ();
    
    
public studentsinVector(String sthrows IOException
    {
        
String name;
        
int exam;
        
int cwk;
        
Scanner in = new Scanner(new FileReader(s));
        
while (in.hasNextLine())
        {
            
name = in.nextLine();
            
cwk = Integer.parseInt(in.nextLine());
            
exam = Integer.parseInt(in.nextLine());
            
Student x = new Student(nameexamcwk);
            
students.addElement(x);
        }
    }
    
    
public String toString()
    {
        
String t = "";
        
for (int i=0i<students.size(); i++) t = t + 
        
students.elementAt(i) + "\n";
        
return t;
    }
    
}

Write a program printstudentsinVector.java which stores all the students in a Vector and prints out the results in the Vector.

Answer courtesy of ©UoL.

CODE: printstudentsinVector.java

package Lecture23;
import java.io.*;
import java.util.*;
public class printstudentsinVector
{
    
public static void main(String [] argsthrows IOException
    {
        
studentsinVector V = new studentsinVector("marks");
        
for (int i=0i<V.students.size(); i++)
        
System.out.println(V.students.elementAt(i));
    }
}
    

Q: Write a program printsortedstudentsinVector.java which stores all the students in a Vector and prints out the results in the Vector but this time sorted in descending order of total mark.

The answer to this exercise is detailed below, inspired by the ©UoL course notes.

CODE: printsortedstudentsinVector.java

package Lecture23;
import java.io.*;
import java.util.*;
public class printsortedstudentsinVector
{
    
public static void main(String [] argsthrows IOException
    {
        
studentsinVector V = new studentsinVector("marks");
        
while (V.students.size()>0//note, although we have defined
                                    //vector V we still have to refer
                                    //to the Vector students defined in
                                    //the Vector studentsinVector when
                                    //referencing anything in the
                                    //constructor - confusing!!
        {
            
int biggest = V.students.elementAt(0).total;        
            
for (int i = 0i<V.students.size(); i++)
            {
                
if (V.students.elementAt(i).total > biggest)
                {
                    
biggest = V.students.elementAt(i).total;
                }
            }
            
            
System.out.println(V.students.elementAt(biggest));
            
V.students.removeElementAt(biggest);
        }       
    }
}
    

Exception Handling in Java. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES

1. Explain how to handle exceptions using try and catch.

Consider the following code courtesy of ©UoL which asks a user to enter a file name and print the file to screen. It has two exception handling conditions built into it. The first, tries to print out a file that has been input by the user within the try statement. It is contained within a while loop that only terminates when a file has been found with the same file name as the user input. Where a file cannot be found, an IOException is thrown by the FileReader method which is then caught in the catch statement and a message to re-enter the file name is displayed to the user.

The second exception handling condition is set-up to deal with stopping the program printing at the end of the file. Here we throw a new EOFException when we reach the EOF character (-1), which is then caught by the catch statement and ends the while loop which is printing out the chars in the file one by one.

CODE: catchEOF.java

package Lecture22;
import java.io.*;
import java.util.*;
class catchEOF
{
    
public static void main(String[] argsthrows IOException
    {
        
System.out.print("Enter File Name ");
        
Scanner kbin = new Scanner(System.in);
        
String s = null;
        
FileReader in = null;
        
boolean exists=false;
        
while (!exists)
        {
            
try
                {
                    
skbin.nextLine();
                    
in = new FileReader(s);
                    
exists = true;
                }
            
catch (IOException f)
            {
                
System.out.print("File " + s + " not found. Please"
                + 
" Re-enter: ");
            }
        }
        
int c;
        
boolean end = false;
        
try
            {
                
while (true)
                {
                    
c=in.read();
                    
if (c==-1throw new EOFException();
                    
System.out.print((char)c);
                }
            }
        
catch (EOFException e)
        {
            
end = true;
        }
    }
}

2. Explain what it means to throw an exception.

When an error occurs in a program, an exception is said to have occurred. To throw an exception means to signal that error has occurred. To catch an exception means to try to handle or recover from the error that has been thrown.

EXERCISES

Q: Write a program that asks a user to enter a file name and prints out the third line of the file to the screen, providing an error message if the file cannot be found.

CODE: thirdlineExcep.java

package Lecture22;
import java.io.*;
import java.util.Scanner;
public class thirdlineExcep
{
    
public static void main(String[] argsthrows IOException
    {
        
System.out.print("Enter file name ");
        
Scanner kbin = new Scanner(System.in);
        
String s = null;
        
FileReader in = null;
        
boolean exists = false;
        
while (!exists)
        {
            
try
            {
                
s = kbin.nextLine();
                
in = new FileReader(s);
                
exists = true;
            }
            
catch (IOException f)
            {
                
System.out.print("File " + s + " not found. Please"
                + 
" Re-enter: ");
            }
        }
        
int count = 1;
        
Scanner fileIn = new Scanner (new FileReader(s));
        
while (fileIn.hasNextLine())
        {
            
String t = fileIn.nextLine();
            
if (count==3System.out.println(t);
            
count++;        
        }
    }
}
                    

Q: Write a program that asks a user to enter a file name and prints out the file to the screen, providing an error message if the file cannot be found.

CODE: catChooseExcep.java

package Lecture22;
import java.io.*;
import java.util.Scanner;
public class catChooseExcep
{
    
public static void main(String[] argsthrows IOException
    {
        
System.out.print("Enter file name ");
        
Scanner kbin = new Scanner(System.in);
        
String s = null;
        
FileReader in = null;
        
boolean exists = false;
        
while (!exists)
        {
            
try //this bit tests whether the file exists or not
            {
                
s = kbin.nextLine();
                
in = new FileReader(s);
                
exists = true;
            }
            
catch (IOException f)
            {
                
System.out.print("File " + s + " not found. Please"
                + 
" Re-enter: ");
            }
        }
        
int t =  in.read();
        
while (t!=-1)
        {
            
System.out.print((char)t);
            
t = in.read();
        }
    }
}
                    

The course notes task us with rewriting all of Chapter 7′s exercises using try and catch for the user file name input. This seems like overkill to me as they are all going to follow the format of the code above.

Inheritance in Java. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES

1. Explain how to extend a class.

If we want to alter an existing class, we can go back to the original class and make amendments to it by re-coding and re-compiling the class or, alternatively, we can extend the class. When we extend a class we are effectively creating a new class that uses the code from the previous class. We can then add additional code into the new class rather than alter the old one. To do this we use the keywords extends and super.

2. Explain the use of the keyword super.

When we extend a class, the new class inherits all of the fields (instance variables) of the old class but not the constructors. The constructors are called into the new class using the keyword method super. If we wanted to extend the class Person from the previous chapter by adding in a middle name field we could use the following code.

CODE: Person.java

package Lecture21;
import Lecture20.*;
public class Person extends Lecture20.Person
{
    
public String middlename;
    
    
public Person(String fString mString lDate birthboolean s)
    {
        
super(f,l,birth,s);
        
middlename=m;
    }
    
public Person(String fString mString lDate birthString s)
    {
        
super(f,l,birth,s);
        
middlename=m;
    }
}

Notice that in this case the class that has been extended and the extending class have the same name but are part of different packages (and in different directories).

3. Explain instance methods and inheritance.

Instance methods can be created in classes that are extensions of other classes in the same way as if we added them into the original method. Again, they have a different name to the class and they do not have the keyword static in their definition.

4. Explain method overriding.

A method from a previous class can be overridden or superseded by another method in an extended class as long as it has exactly the same name and signature. In this way, we can completely replace a previous method with a new one rather than merely altering the method.

EXERCISES

Q: Write a program using the class HollowRectangle whose output is a 18 x 6 and a 7 x 12 hollow rectangle of stars

In order to understand the answer to this question you need to see all of the classes that combine to create the HollowRectangle class. They are detailed below and are all ©UoL.

The first class, which all the other classes are based on is HorizLine.

CODE: HorizLine.java

package Lecture21;
import java.io.*;
class HorizLine
{
    
int length;     //instance variable of HorizLine
    
    
public HorizLine(int l//constructor for HorizLine
    {
        
length=l;
    }
    
public void Draw()      //class method of HorizLine
    {
        
for (int i=0i<lengthi++) System.out.print("*");
    }
    
public void Drawln()
    {
        
Draw();
        
System.out.println();
    }
}

The class BetterLine extends the class HorizLine and overrides the method Draw() (but not the method Drawln()).

CODE: BetterLine.java

package Lecture21;
import java.io.*;
class BetterLine extends HorizLine
{
    
char endchar;
    
char middlechar;
    
public BetterLine(char endchar middleint len)
    {
        
super(len);
        
endchar=end;
        
middlechar=middle;
    }
    
public void Draw()
    {
        
for (int i=0i<lengthi++)
        {
            
if (i==0 || i==length-1)
            {
                
System.out.print(endchar);
            }
            
else System.out.print(middlechar);
        }
    }
}

The class Rectangle extends the class HorizLine and again overides the method Draw().

CODE: Rectangle.java

package Lecture21;
public class Rectangle
{
    
public int height;
    
public int width;
    
public Rectangle(int hint w)
    {
        
height = h;
        
width = w;
    }
    
public void Draw()
    {
        
HorizLine m = new HorizLine(width);
        
for (int j=0j<heightj++)
        {
            
m.Drawln();
        }
    }
}

The class BetterRectangle extends the class Rectangle using the BetterLine class and overrides the Draw() method again.

CODE: BetterRectangle.java

package Lecture21;
import java.io.*;
public class BetterRectangle extends Rectangle
{
    
char ends;
    
char middle;
    
public BetterRectangle(int hint wchar mchar e)
    {
        
super(h,w);
        
ends=e;
        
middle=m;
    }
    
public void Draw()
    {
        
BetterLine topandbottomline = new BetterLine(endsendswidth);
        
BetterLine middleline = new BetterLine(endsmiddlewidth);
        
for(int j=0j<heightj++)
        {
            
if (j==0 || j==height-1topandbottomline.Drawln();
            
else middleline.Drawln();
        }
    }
}

Finally(!) HollowRectangle extends BetterRectangle.

CODE: HollowRectangle.java

package Lecture21;
public class HollowRectangle extends BetterRectangle
{
    
public HollowRectangle(int hint w)
    {
        
super(h,w,' ','*');
    }
}

And we are left with the following test program to ensure everything works as it should.

CODE: testHolRec.java

package Lecture21;
import Lecture21.*;
class testHolRec
{
    
public static void main(String[] args)
    {
        (
new HollowRectangle(6,18)).Draw();
        (
new HollowRectangle(12,7)).Draw(); 
    }
}

Q: Extend Rectangle to produce a class Square.

CODE: Square.java

package Lecture21;
public class Square extends Rectangle
{
    
public Square(int size)
    {
        
super(sizesize);
    }
}

Q: Extend BetterRectangle to BetterSquare.

CODE: BetterSquare.java

package Lecture21;
public class BetterSquare extends BetterRectangle
{
    
public BetterSquare(int sizechar mchar e)
    {
        
super(sizesizeme);
    }
}

Q: Use BetterLine etc. to define a class HollowLeftBottomTriangle in a similar way by extending a class called BetterLeftBottomTriangle etc.

I started this exercise by creating a LeftBottomTriangle class similar to the Rectangle class. This class was then extended into a BetterTriangle class. Finally, this was extended into a HollowTriangle class. Code below.

CODE: LeftBottomTriangle.java

package Lecture21;
public class LeftBottomTriangle
{
    
public int height;
    
public int width;
    
public LeftBottomTriangle(int h)
    {
        
height = h;
    }
    
public void Draw()
    {
        
for (int i=1i<=heighti++)
        {
            
HorizLine m = new HorizLine(i);
            
m.Drawln();
        }
    }
}

CODE: BetterTriangle.java

package Lecture21;
import java.io.*;
public class BetterTriangle extends LeftBottomTriangle
{
    
char ends;
    
char middle;
    
public BetterTriangle (int hchar mchar e)
    {
        
super(h);
        
ends=e;
        
middle=m;
    }
    
public void Draw()
    {

        for (int i=1i<=heighti++)
        {
            
BetterLine middleline = new BetterLine(endsmiddlei);
            
BetterLine topandbottomline = new BetterLine(endsendsi);
            
if (i==1 || i==heighttopandbottomline.Drawln();
            
else middleline.Drawln();
        }
    }
}

CODE: HollowTriangle.java

package Lecture21;
public class HollowTriangle extends BetterTriangle
{
    
public HollowTriangle(int h)
    {
        
super(h,' ','*');
    }
}

Q: Similarly define a class called SolidLeftBottomTriangle which is entirely made up of stars.

CODE: SolidLeftBottomTriangle.java

package Lecture21;
public class SolidLeftBottomTriangle extends BetterTriangle
{
    
public SolidLeftBottomTriangle(int h)
    {
        
super(h,'*','*');
    }
}

Q: Write a program to test your classes.

CODE: testTriangle.java

package Lecture21;
import Lecture21.*;
class testTriangle
{
    
public static void main(String[] args)
    {
        (
new LeftBottomTriangle(6)).Draw();
        (
new BetterTriangle(6,'&','*')).Draw();
        (
new HollowTriangle(6)).Draw();
        (
new SolidLeftBottomTriangle(6)).Draw();
    }
}

Q: Repeat the exercise for right bottom triangles etc.

CODE: RightBottomTriangle.java

package Lecture21;
public class RightBottomTriangle
{
    
public int height;
    
public RightBottomTriangle (int h)
    {
        
height=h;
    }
    
public void Draw()
    {
        
int k;
        
for (int i=1i<=heighti++)
        {
            
k=height-i;
            
BetterLine m = new BetterLine(' '' 'k);
            
m.Draw();
            
BetterLine n = new BetterLine('*''*'i);
            
n.Drawln();
        }
    }
}

CODE: BetterRightBottomTriangle.java

package Lecture21;
public class BetterRightBottomTriangle extends RightBottomTriangle
{
    
char ends;
    
char middle;
    
public BetterRightBottomTriangle (int hchar mchar e)
    {
        
super(h);
        
ends=e;
        
middle=m;
    }
    
public void Draw()
    {
        
int k;
        
for (int i=1i<=heighti++)
        {
            
k=height-i;
            
BetterLine m = new BetterLine(' '' 'k);
            
m.Draw();
            
BetterLine middleline = new BetterLine (endsmiddlei);
            
BetterLine topandbottomline = new BetterLine(endsendsi);
            
if (i==1 || i==heighttopandbottomline.Drawln();
            
else middleline.Drawln();
        }
    }
}

CODE: HollowRightBottomTriangle.java

package Lecture21;
public class HollowRightBottomTriangle extends 
BetterRightBottomTriangle
{
    
public HollowRightBottomTriangle (int h)
    {
        
super (h' ''*');
    }
}

Didn’t bother with the SolidRightBottomTriangle class as follows the same technique. Class to test shown below.

CODE: testTriangle.java

package Lecture21;
import Lecture21.*;
class testTriangle
{
    
public static void main(String[] args)
    {
        
/*
        (new LeftBottomTriangle(6)).Draw();
        (new BetterTriangle(6,'&','*')).Draw();
        (new HollowTriangle(6)).Draw();
        (new SolidLeftBottomTriangle(6)).Draw();
        */

        
//(new RightBottomTriangle(6)).Draw();
        (new BetterRightBottomTriangle(6'*''&')).Draw();
        (
new HollowRightBottomTriangle(6)).Draw();
    }
}

Defining classes in java. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES

1. Explain how to define your own classes.

Often we need to create user-defined classes because the existing classes within the Java language don’t properly serve our requirements. We can, in effect, create a new type in Java using our own classes.

In order to do this we must define a class which contains a constructor. A constructor looks like a method except that it does not have a return type. Also, its name must be the same as the class which contains it. Constructors create Objects of the variable type defined by the class.

An example constructor is shown below.

CODE: exampleConstructor.java

package Lecture20;
public class exampleConstructor
{
    
public int one;
    
public int two;
    
public int three;
    
    
public exampleConstructor(int aint bint c)
    {
        
one = a;
        
two = b;
        
three = c;
    }
}

If we didn’t want to think up different names for the instance variables and the fields within the constructor, we can use a new keyword, this. We could rewrite the code above thus:

CODE: exampleConstructorTwo.java

package Lecture20;
public class exampleConstructorTwo
{
    
public int one;
    
public int two;
    
public int three;
    
    
public exampleConstructorTwo(int oneint twoint three)
    {
        
this.one = one;
        
this.two = two;
        
this.three = three;
    }
}

2. Explain how to use constructors.

We call a constructor using the keyword new. To call exampleConstructor above and print it we could use the following code.

CODE: printexCon.java

package Lecture20;
class printexCon
{
    
public static void main(String[] args)
    {
        
exampleConstructor x = new exampleConstructor(123);
        
System.out.println(x.one + " " + x.two + " " + x.three);
    }
}

We have essentially created a new variable of type exampleConstructor called x and have assigned values to x using the keyword new. In jargon, we say variable x references (or points to) an Object of type exampleConstructor. We have created an instance of the class exampleConstructor whose field values are 1, 2 and 3 respectively. These field values are assigned to instance variables, instances of the formal variable parameters (public int one etc) within the constructor, within the class exampleConstructor.

Once the exampleConstructor Object has been created we can directly access the instance variables using dot notation. Above we have printed out the values of one, two and three by writing x.one, x.two and x.three in the System.out.print() statement.

3. Understand what instance variables are.

Instance variables are the variables which which are created when a constructor creates a new Object of its class. They are based on the formal variable parameters in the original constructor class. In the example above, the instance variables are created based on public int one, public int two and public int three. When we call the constructor using new we assign values to these variables and instance variables are created.

4. Understand instance methods.

An instance method is a method within a class which contains a constructor. When the constructor is called using new new instances of the variables and the methods contained within the constructor are created. Again we access instance methods using dot notation and call them in the exactly the same way we do normal methods. When examining a constructor, we can tell which are the instance methods – do not have the same name as the class nor do they contain the keyword static in their definition.

5. How to define classes in terms of other user-defined classes.

Classes can be defined within other classes. In the example below exampleContainUDClass, when we declare the constructor’s formal variables, we have included an Object of type exampleConstructor called x (the previous example constructor we have been using). We pass the Object into the new constructor as a field.

CODE: exampleContainUDClass.java

package Lecture20;
public class exampleContainUDClass
{
    
public int four;
    
public exampleConstructor x;
    
    
public exampleContainUDClass(int fourexampleConstructor x)
    {
        
this.four = four;
        
this.x=x;
    }
}

We then need to call both constructors with the new keyword as in the code below.

CODE: printUD.java

package Lecture20;
class printUD
{
    
public static void main(String[] args)
    {
        
exampleConstructor x = new exampleConstructor(123);
        
exampleContainUDClass y = new exampleContainUDClass(4x);
        
System.out.println(x.one + " " + x.two + " " + x.three + " " +
        
y.four);
    }
}

EXERCISES

Q: Rewrite the following code so that it prints an IntAndDouble object as follows.

Double: 2.4367
Int: 6

CODE: IntAndDouble.java

package Lecture20;
public class IntAndDouble
{
    
public int i;
    
public double d;
    
    
public IntAndDouble(int xdouble y)    //a constructor
    {
        
i = x;
        
d = y;
    }
    
public String toString()                //an instance method
    {
        
return "(" + i + "," + d + ")";
    }
}

Answer below.

CODE: IntAndDouble1

package Lecture20;
public class IntAndDouble1
{
    
public int i;
    
public double d;
    
    
public IntAndDouble1(int xdouble y)   //a constructor
    {
        
i = x;
        
d = y;
    }
    
public String toString()                //an instance method
    {
        
String output;
        
output = "Double " + d + "\n" + "Int " + i + "\n";
        
return output;
    }
}

Q: Write a program that contains:

1) an assignment to variable x1 of the value of type Date, representing 2 March 2001;
2) an assignment to variable x2 of a value of type Person, representing the man Joseph Boteju born on 2 March 2001;
3) an assignment to variable x3 of a value of type Person, representing the man Pushpa Kumar born on 17 May 1942;
4) an assignment to variable x4 a value of type Person, representing the woman Ola Olatunde born on 27 August 1983.

CODE: printPerson2.java

package Lecture20;
class printPerson2
{
    
public static void main(String[] args)
    {
        
Date x1 = new Date(2,3,2001);
        
Person x2 = new Person("Joseph""Boteju"x1false);
        
Person x3 = new Person("Pushpa""Kumar"new Date(17,5,1942),
        
false);
        
Person x4 = new Person("Ola""Olatunde"new Date(27,8,1983),
        
"female"); 
    }
}

Q: Add toString() methods to each of the classes Date, Person, House and Street and write a program for testing your methods.

CODE: Date.java

package Lecture20;
public class Date
{
    
public int day;
    
public int month;
    
public int year;
    
    
public Date(int dint mint y)
    {
        
day = d;
        
month = m;
        
year = y;
    }
    
public String toString()
    {
        
return "birthday is " + day + " / " + month + " / " + year;
    }
}

CODE: Person.java

package Lecture20;
public class Person
{
    
public String firstname;
    
public String lastname;
    
public Date dob;
    
public boolean sex//true = female, false = male
    
    
public Person(String fString lDate birthboolean s)
    {
        
firstname = f;
        
lastname = l;
        
dob = birth;
        
sex = s;
    }
    
    
public Person(String fString lDate birthString s)
    {
        
firstname = f;
        
lastname = l;
        
dob = birth;
        
if (s.charAt(0)=='f' || s.charAt(0)=='F'sex = true;
        
else sex=false;
    }
    
public String toString()
    {
        
return firstname + " " + lastname + " " + dob + " " + sex;
    }

}
    

Adding a toString() method onto the House class was tricky as it contains an array of Objects of type Person. Had to convert this array of Objects into an array of Strings and then into one single String before I was able to return everything from the method as a String.

CODE: House.java

package Lecture20;
public class House
{
    
public int number;
    
public int rooms;
    
public Person [] people;
    
    
public House(int numberint roomsPerson[] p)
    {
        
this.number = number;
        
this.rooms = rooms;
        
people = p;
    }
    
    
public String toString()
    {       
        
//first convert object array people to a string array
        
        
String StringArray[] = new String[people.length];
        
for (int i=0i<StringArray.lengthi++)
        {
            
StringArray[i]=people[i].toString();
        }
        
        
//next, to use return type String we need to convert all
        //elements in the string array into OneLongString
        
        
String OneLongString="";
        
for (int i=0i<StringArray.lengthi++)
        {
            
OneLongString = OneLongString + "\n" + StringArray[i];
        }
        
        
//then finally return all instance variables from the object
        
        
return "Number: " + number + " Rooms: " + rooms + "\n" + 
        
"Occupants: " + OneLongString;
    }
}

Same issues with the Street class – used the same technique below.

CODE: Street.java

package Lecture20;
public class Street
{
    
public String name;
    
public House[] houses;
    
    
public Street(String nameHouse[] h)
    {
        
this.name = name;
        
houses=h;
    }
    
public String toString()
    {
        
String StringArray[] = new String[houses.length];
        
for (int i=0i<StringArray.lengthi++)
        {
            
StringArray[i]=houses[i].toString();
        }
        
        
String OneLongString="";
        
for (int i=0i<StringArray.lengthi++)
        {
            
OneLongString = OneLongString + "\n" + StringArray[i];
        }
        
        
return "Street Name: " + name + "Houses: " + OneLongString;
    }
}

Finally, program to test all the new classes.

CODE: testNewClasses.java

package Lecture20;
class testNewClasses
{
    
public static void main(String[] args)
    {
        
Date x1 = new Date(2,3,2001);
        
Person x2 = new Person("Joseph""Boteju"x1false);
        
Person x3 = new Person("Pushpa""Kumar"new Date(17,5,1942),
        
false);
        
Person x4 = new Person("Ola""Olatunde"new Date(27,8,1983),
        
"female");
        
House x5 = new House(124new Person[] {x2x3x4});
        
House x6 = new House(153new Person[] {x2x4});
        
Street x7 = new Street("Caine Road"new House[] {x5x6});
        
System.out.println(x1.toString());
        
System.out.println(x2.toString());
        
System.out.println(x5.toString());
        
System.out.println(x7.toString());
    }
}

Sorting arrays and searching. Learning objectives and exercises from the University of London BSc in Creative Computing.

LEARNING OBJECTIVES

1. Explain how to sort elements as they get put into an array.

If we are creating a new array, entering the elements in some sort of order allows us to more efficiently search the array at a later stage. To sort elements as they get put into an array we need to do three things:

1. We need to establish where in an array the new element needs to be inserted.
2. Move all existing elements from that point in the array right by one element to create room for the new element.
3. Insert the new element into the array.

The following code provided by ©UoL can be used to do that.

CODE: SortOnInput.java

package Lecture19;
import java.util.Scanner;
import java.io.*;
public class SortOnInput
{
    
    
public static void shuffle(int fromint toint a[])
    {
        
for (int i=toi>=fromi--) a[i+1]=a[i];
    }
    
    
public static int findWhereToInsertAscending
    (
int xint[] aint firstfree)
    {
        
int pos=0;
        
while(x>a[pos] && pos<firstfreepos++;
        
return pos;
    }
    
    
public static void insertAscending(int xint[] aint firstfree)
    {
        
int pos=0;
        
int z=findWhereToInsertAscending(xafirstfree);
        
shuffle(zfirstfree-1a);
        
a[z] = x;
    }
    
    
public static int[] readintsAscending() throws IOException
    {
        
Scanner in = new Scanner(System.in);
        
System.out.print("How many numbers do you want to enter? ");
        
int k=in.nextInt();
        
int num[] = new int[k];
        
System.out.println("Now type in the numbers");
        
for (int i=0i<ki++)
        {
            
insertAscending(in.nextInt(), numi);
        }
        
return num;
    }
}

2. Demonstrate one method of sorting an array.

One way to achieve this is to create a loop within a loop that compares the first element of an array with all the other elements. If we are trying to sort the array numerically, we check to see whether any of the elements of the array are smaller than the first element. If they are, we swap them over and continue the process. By the time we have reached the end of the array we are certain that the first element is the smallest numerically. We then move onto the second element of the array and repeat the process until we reach the last but one element of the array. Once this is sorted, we know the entire array is in ascending order. The code to do this, &copyUoL is detailed below.

CODE: SortArray.javs

package Lecture19;
public class SortArray
{
    
public static void SortArray(int[] aint size)
    {
        
for (int i=0i<size-1i++)
        {
            
for (int j=i+1j<sizej++)
            {
                
if (a[i]>a[j])
                {
                    
int temp=a[i];
                    
a[i]=a[j];
                    
a[j]=temp;
                }
            }
        }
    }
}

3. Explain what linear and binary searching is.

Linear searching is the process of starting a search at the beginning of an array or file and working through every element methodically in order until we find what we are searching for. We have to use this technique when there is no order to the elements that we are searching through.

Binary searching requires that the elements are in some form of order. For this example, let’s assume the elements are ordered numerically from smallest to largest. We start in the middle of all the elements and check to see whether the element we are searching for is the middle element. If it is not, if the element we are searching for is less than the middle element we discard the second half of the elements and again move to the middle element of the first half. We repeat the process, each time halving the number of elements in consideration. This method of searching is far more efficient than linear searching.

4. Explain complexity analysis.

Complexity analysis concerns itself with how fast an algorithm is at searching and sorting. Rather than measuring this in seconds, it is measured in terms of the relative increase in time it takes as we double and treble the number of elements in the array to be searched and sorted.

On average using linear searching, we have to compare half of the elements in the array before we find what we are looking for. As the number of elements in the array doubles, so does the time it takes a linear searching algorithm to find an element on average. We say that linear searching is of order n, written O(n).

With binary searching, because we halve the search space at each comparison, with 5 comparisons, we can check up to 32 elements (25). With 6 elements we can check 64 elements (26) and so on. We say that binary searching is of order log2(n), written O(log2(n)).

5. Demonstrate that sorting arrays of ints and sorting arrays of Strings is essentially the same.

See exercises below for evidence of this fact.

EXERCISES

Q: Considering the class ©UoL ArraysOfIntsNew.java below, write a program to test the class.

CODE: ArraysOfIntNew.java

package Lecture19;
import java.util.Scanner;
public class ArraysOfIntsNew
{
    
public static Scanner in = new Scanner(System.in);
    
//
    public static int[] readintArray()
    {
        
int kString s;
        
System.out.print("How many ints do you want to enter? ");
        
k=in.nextInt();
        
int a[] = new int[k];
        
System.out.println("Now type in the ints");
        
for (int i=0i<ki++)
        {
            
a[i]=in.nextInt();
        }
        
return a;
    }
    
//
    static boolean after(int sint t)
    {
        
return (s>t);
    }
    
//
    public static void printArray(int[] a)
    {
        
for (int i=0i<a.lengthi++) System.out.println(a[i]);
    }
    
//
    public static int [] readAndSortintArrayAscending()
    {
        
int kString s;
        
System.out.print("How many ints do you want to enter? ");
        
k=in.nextInt();
        
int a[] = new int[k];
        
System.out.println("Now type in the ints");
        
for (int i=0i<ki++)
        {
            
int z = in.nextInt();
            
insertAscending(zai);
        }
        
return a;
    }
    
//
    static void shuffle(int fromint toint a[])
    {
        
for (int i=toi>=fromi--) a[i+1]=a[i];
    }
    
//
    static int findWhereToInsertAscending(int xint[] aint firstfree)
    {
        
int pos=0;
        
while (pos<firstfree && after(x,a[pos])) pos++;
        
return pos;
    }
    
//
    static void insertAscending(int xint[] aint firstfree)
    {
        
int pos=0;
        
int z=findWhereToInsertAscending(xafirstfree);
        
shuffle (zfirstfree-1a);
        
a[z]=x;
    }
    
//
    public static void ascendingBubbleSort(int[] aint size)
    {
        
for (int i=0i<size-1i++)
        
for (int j=i+1j<sizej++)
        
if (after(a[i],a[j])) {int temp=a[i]; a[i]=a[j]; a[j]=temp;}
    }
    
//
    public static void descendingBubbleSort(int[] aint size)
    {
        
for (int i=0i<size-1i++)
        
for (int j=i+1j<sizej++)
        
if (after(a[j],a[i])) {int temp=a[i]; a[i]=a[j]; a[j]=temp;}
    }
    
//
    public static boolean linearSearch(int[] aint sizeint thing)
    {
        
int i;
        
for (i=0i<size && a[i]!=thingi++);
        
return (a[i-1]==thing);
    }
    
//
    public static boolean binarySearch(int[] aint sizeint thing)
    {
        
int first=0last=size-1;
        
int mid;
        
while (first <=last)
        {
            
mid=first + (last-first)/2;
            
if (thing==(a[mid])) return true;
            
else if (after(a[mid], thing)) last = mid-1;
            
else first=mid+1;
        }
        
return false;
    }
    
//
    public static int binarySearchPos(int[] aint sizeint thing)
    {
        
int first=0last=size-1;
        
int mid;
        
while (first <=last)
        {
            
mid=first + (last-first)/2;
            
if (thing==(a[mid])) return mid;
            
else if (after(a[mid], thing)) last = mid -1;
            
else first=mid+1;
        }
        
return -1;
    }
}

I wrote the following program to test the class above. Would appear that the method linearSearch() is not working correctly, but as supplied by the course notes, have not corrected it at this time.

CODE: TestArraysOfIntsNew.java

package Lecture19;
public class TestArraysOfIntsNew
{
    
public static void main(String[] args)
    {
    
    
//test readintArray()
    int a[] = ArraysOfIntsNew.readintArray();
    
int size = a.length;
    
    
//test ascendingBubbleSort and printArray
    
    
ArraysOfIntsNew.ascendingBubbleSort(asize);
    
System.out.println();
    
ArraysOfIntsNew.printArray(a);
    
System.out.println();
    
    
//test descendingBubbletSort
    
    
ArraysOfIntsNew.descendingBubbleSort(asize);
    
ArraysOfIntsNew.printArray(a);
    
System.out.println();
    
    
//test linearSearch -- DOES NOT WORK PROPERLY
    //search for the number 3
    
    
boolean result = ArraysOfIntsNew.linearSearch(asize3);
    
System.out.println(result);
    
System.out.println();
    
    
//test binarySearch
    //earch for the number 3
    
    
boolean result2 = ArraysOfIntsNew.binarySearch(asize3);
    
System.out.println(result2);
    
System.out.println();
    
    
//test binarySearchPOS
    //search for the number 3
    
    
int pos = ArraysOfIntsNew.binarySearchPos(asize3);
    
System.out.println(pos);
    
System.out.println();
    
    
//test readAndSortintArrayAscending
    
    
int [] b = ArraysOfIntsNew.readAndSortintArrayAscending();
    
System.out.println();
    
ArraysOfIntsNew.printArray(b);
    
System.out.println();

    }
}
    

Q: Write a similar class which works on arrays of Strings.

The class below is adapted from the class ArraysOfIntsNew. It is almost the same as the previous class, but the types have been changed from int to String, the method of comparison has been changed from logical operators to compareTo() methods and have had to insert some small elements of code to deal with a line return issue during user input.

CODE: ArraysOfStringsNew.java

package Lecture19;
import java.util.Scanner;
public class ArraysOfStringsNew
{
    
public static Scanner in = new Scanner(System.in);
    
//
    public static String[] readintArray()
    {
        
int kString s;
        
System.out.print("How many strings do you want to enter? ");
        
k=in.nextInt();
        
String a[] = new String[k];
        
System.out.println("Now type in the strings");
        
a[0]=in.nextLine(); //stop a CR being recorded
        for (int i=0i<ki++)
        {
            
a[i]=in.nextLine();
        }
        
return a;
    }
    
//
    static boolean after(String sString t)
    {
        
int compare = s.compareTo(t);
        
return (compare>0);
    }
    
//
    public static void printArray(String[] a)
    {
        
for (int i=0i<a.lengthi++) System.out.println(a[i]);
    }
    
//
    public static String [] readAndSortintArrayAscending()
    {
        
int kString s;
        
System.out.print("How many strings do you want to enter? ");
        
k=in.nextInt();
        
String a[] = new String[k];
        
System.out.println("Now type in the strings");
        
a[0]=in.nextLine(); //stop a CR being recorded
        for (int i=0i<ki++)
        {
            
String z = in.nextLine();
            
insertAscending(zai);
        }
        
return a;
    }
    
//
    static void shuffle(int fromint toString a[])
    {
        
for (int i=toi>=fromi--) a[i+1]=a[i];
    }
    
//
    static int findWhereToInsertAscending
    (
/* should this be int x?*/String xString[] aint firstfree)
    {
        
int pos=0;
        
while (pos<firstfree && after(x,a[pos])) pos++;
        
return pos;
    }
    
//
    static void insertAscending(String xString[] aint firstfree)
    {
        
int pos=0;
        
int z=findWhereToInsertAscending(xafirstfree);
        
shuffle (zfirstfree-1a);
        
a[z]=x;
    }
    
//
    public static void ascendingBubbleSort(String[] aint size)
    {
        
for (int i=0i<size-1i++)
        
for (int j=i+1j<sizej++)
        
if (after(a[i],a[j])) {String temp=a[i]; a[i]=a[j]; a[j]=temp;}
    }
    
//
    public static void descendingBubbleSort(String[] aint size)
    {
        
for (int i=0i<size-1i++)
        
for (int j=i+1j<sizej++)
        
if (after(a[j],a[i])) {String temp=a[i]; a[i]=a[j]; a[j]=temp;}
    }
    
//
    public static boolean linearSearch(int[] aint sizeint thing)
    {
        
int i;
        
for (i=0i<size && a[i]!=thingi++);
        
return (a[i-1]==thing);
    }
    
//
    public static boolean binarySearch
    (
String[] aint sizeString thing)
    {
        
int first=0last=size-1;
        
int mid;
        
while (first <=last)
        {
            
mid=first + (last-first)/2;
            
if (thing.compareTo(a[mid])==0return true;
            
else if (after(a[mid], thing)) last = mid-1;
            
else first=mid+1;
        }
        
return false;
    }
    
//
    public static int binarySearchPos
    (
String[] aint sizeString thing)
    {
        
int first=0last=size-1;
        
int mid;
        
while (first <=last)
        {
            
mid=first + (last-first)/2;
            
if (thing.compareTo(a[mid])==0return mid;
            
else if (after(a[mid], thing)) last = mid -1;
            
else first=mid+1;
        }
        
return -1;
    }
}

Q: Test the program by asking the user to enter some Strings and your program should sort them and print a different message depending on whether or not it can find the String "telephone"

The code below tests all elements of the class and prints out true and the position within the array if the user enters the String "telephone" and false if not.

CODE: TestArraysOfStringsNew.java

package Lecture19;
public class TestArraysOfStringsNew
{
    
public static void main(String[] args)
    {
    
    
//test readintArray()
    String a[] = ArraysOfStringsNew.readintArray();
    
int size = a.length;
    
ArraysOfStringsNew.printArray(a);
    
    
//test ascendingBubbleSort and printArray
    
    
ArraysOfStringsNew.ascendingBubbleSort(asize);
    
System.out.println();
    
ArraysOfStringsNew.printArray(a);
    
System.out.println();
    
    
    
//test descendingBubbletSort
    
    
ArraysOfStringsNew.descendingBubbleSort(asize);
    
ArraysOfStringsNew.printArray(a);
    
System.out.println();
    
    
//test binarySearch
    //search for the string "telephone"
    
    
boolean result2 = ArraysOfStringsNew.binarySearch
    (
asize"telephone");
    
    
System.out.println(result2);
    
System.out.println();
    
    
//test binarySearchPOS
    //search for the string "telephone"
    
    
int pos = ArraysOfStringsNew.binarySearchPos(asize"telephone");
    
System.out.println(pos);
    
System.out.println();
    
    
//test readAndSortintArrayAscending
    
    
String [] b = ArraysOfStringsNew.readAndSortintArrayAscending();
    
System.out.println();
    
ArraysOfStringsNew.printArray(b);
    
System.out.println();
    }
}
    

Q: Write a program that sorts its command line arguments into alphabetical order.

Solution below.

CODE: alphaCL.java

package Lecture19;
public class alphaCL
{
    
public static void main(String[] args)
    {
    
ArraysOfStringsNew.ascendingBubbleSort(argsargs.length);
    
System.out.println();
    
ArraysOfStringsNew.printArray(args);
    
System.out.println();
    }
}
    

Files and Streams in Java. Learning objectives and exercises from the University of London BSc in Creative Computing.
 
LEARNING OBJECTIVES
 
1. Explain the purpose of a file.
 
A file is an entity to store data that is not in the computer’s memory. This means that the data exists even when the program is not running. A file is often stored on a disk (a hard disk, flash memory [disk] drive and in the past on ‘floppy disks’). Java treats the computer screen as a file.
 
2. Explain how to read a file a character a line at a time.
 
To read a file a character at a time we use the method read() which is part of the class java.io.Reader. We can import this class and its methods to our program by using import java.io.*; at the start of our program. We have to create a new instance of a method called FileReader to use the method read() efficiently. Why? No idea – hopefully that will become clear in the fullness of time!
 
The method read() throws two IOExceptions according to Java’s documentation. At this stage, not sure what that means other than the fact that you have to include the following after you define your main method: throws Exception. If you leave this out then the compiler complains. Again, really hoping this becomes clear later on in the course.
 
The return type for read() is int, (see previous post for an explanation of why that is the case). It returns the Unicode value of the character it has read from the file, so to print out the characters we need to type-cast them back to type char.
 
A special character is stored at the end of a file which has a value of -1. We check for this as we read in the characters and end the reading process when we see the value -1.
 
A program to read in a file called fff.dat is shown below courtesy of ©UoL.
 
CODE: cat79.java

import java.io.*;
public class cat79  //this copies from file fff.dat
                    // to standard output (screen)
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone = new FileReader("fff.dat");
        
int t=inone.read();
        
while (t!=-1)
        {
            
System.out.print((char)t);
            
t=inone.read();
        }
    }
}

 
3. Explain how to read a file a line at a time.
 
To read data in from a file a line at a time, we can use the method nextLine() and hasNextLine() which are both part of the java.util.Scanner class. We create a new instance of both Scanner and FileReader to pull the data in from the file. We are then able to set up a while loop which checks whether or not the file has a ‘next line’ (hasNextLine() has a boolean return type), and if it does, reads in the data a line at a time.
 
In Java, a special character is used to represent the end of a line, written as a char as ‘\n‘.
 
A code example, courtesy of ©UoL is shown below.
 
CODE: cat1.java

import java.io.*;
import java.util.Scanner;
public class cat1   //this copies from file fff.dat
                    // to standard output (screen)
{
    
public static void main(String[] argsthrows Exception
    {
        
Scanner in = new Scanner(new FileReader("fff.dat"));
        
while (in.hasNextLine())
        {
            
System.out.println(in.nextLine());
        }
    }
}

 
4. Explain how to write to a file.
 
To write our data to a file, we need to use two other classes, PrintStream and FileOutputStream, both belonging to the java.io package. FileOutputStream is similar to FileReader in its function, but does the reverse – outputs to a file rather than reading in from a file. PrintStream is similar to Scanner, but outputs data from memory to a file rather than reading in data from the screen to memory. The expression PrintStream out = new PrintStream(new FileOutputStream("example.dat")); allows us to write out data to a file example.dat using methods out.print() and out.println(), as though we were writing to screen.
 
Writing to a file as opposed to the screen requires us to do one additional task, we must close the writing process with the out.close() method. By not doing this there is a very real chance that the data may not be written to a file at all.
 
Some ©UoL example code is shown below.
 
CODE: cat83.java

import java.io.*;
public class cat83
{
    
public static void main(String[] argsthrows Exception
    {
        
PrintStream out = new PrintStream(new FileOutputStream("hhh.dat"));
        
out.println("this");
        
out.println("file was written by");
        
out.println("a java program");
        
out.close();
    }
}

 
5. Explain how to write a simple spell-checking program.
 
We can write a simple spell-checking program by using the method java.lang.String.startsWith(). If we have a file, words, that contains natural language words, one per line, we can use this method to allow a user to double check how to spell a particular word in the file. We can use a command-line argument to allow the user to input the word and then check the file for words beginning with the letters input at the command-line at the time of program execution.
 
The following program, taken from the course notes ©UoL shows how to write such a program.
 
CODE: spell.java

import java.io.*;
import java.util.Scanner;
public class spell
{

    public static void main(String[] argsthrows Exception
    {
        
Scanner inone=new Scanner(new FileReader("words"));
        
while (inone.hasNext())
        {
            
String t = inone.nextLine();
            
if (t.startsWith(args[0])) System.out.println(t);
        }
    }
}

 
EXERCISES
 
Q. Write a program that prints out the third line of fff.dat
 
We modify the code in cat1.java above, including a count variable that increments as the while loop cycles. When the count reaches 3, the 3rd line of the file, we print out that line (stored in String t). Code below.
 
CODE: thirdline.java

import java.io.*;
import java.util.Scanner;
public class thirdline
{
    
public static void main(String[] argsthrows Exception
    {
        
Scanner in = new Scanner(new FileReader("fff.dat"));
        
int count = 1;
        
while (in.hasNextLine())
        {
            
String t = in.nextLine();
            
if (count==3System.out.println(t);
            
count++;
        }
    }
}

 
Q: Write a program that prints out the contents of a file of the user’s choice.
 
Here, we adapt cat.java above to allow for user input. We use the Scanner class to create a string to store the name of the file and then pass this to the FileReader class. Code below.
 
CODE: catChoose.java

import java.io.*;
import java.util.Scanner;
public class catChoose
{
    
public static void main(String[] argsthrows Exception
    {
        
System.out.print("Enter filename to print> ");
        
Scanner in = new Scanner(System.in);
        
String filename = in.nextLine();
        
FileReader inone=new FileReader(filename);
        
int t = inone.read();
        
while (t!=-1)
        {
            
System.out.print((char)t);
            
t = inone.read();
        }
    }
}
                    

 
Q: Write a program that prints out the third character of fff.dat.
 
For this we adapt cat.java which reads a file a character at a time but implement a character counting variable, count. As the while loop cycles this variable increments and when it equals 3 the program prints out the character at that point. In this case, the 3rd character is a space. Code shown below.
 
CODE: thirdChar.java

import java.io.*;
public class thirdChar
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader("fff.dat");
        
int count=1;
        
int t = inone.read();
        
while (t!=-1)
        {
            
char s = (char)t;
            
if (count==3System.out.println(s);
            
t = inone.read();
            
count++;
        }
    }
}

 
Q: Write a program that prints out the hundredth character of ggg.dat, The file ggg.dat contains all the integers from 1 to 100 in ascending order, one integer per line.
 
To tackle this problem, first I created the file ggg.dat using the following code.
 
CODE: createggg.java

import java.io.*;
public class createggg
{
    
public static void main(String[] argsthrows Exception
    {
        
PrintStream out = new PrintStream(new FileOutputStream("ggg.dat"));
        
for (int i=1i<=100i++)
        {       
            
out.println(i);
        }
        
out.close();
    }
}

 
Then, using the following program to count to the 100th character and print out its ASCII equivalent.
 
CODE: hundredch.java

import java.io.*;
public class hundredch
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader("ggg.dat");
        
int count=1;
        
int t = inone.read();
        
while (t!=-1)
        {
            
char s = (char)t;
            
if (count==100System.out.println(s);
            
t = inone.read();
            
count++;
        }
    }
}

 
Q: Write a program to print out the ASCII values of the odd chars of ggg.dat.
 
This doesn’t output as you would expect mainly because of the ‘\n‘ character that is not printable but occupies a position in the file at the end of every line. Code required below.
 
CODE: oddch.java

import java.io.*;
public class oddch
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader("ggg.dat");
        
int count=1;
        
int t = inone.read();
        
while (t!=-1)
        {
            
char s = (char)t;
            
if (count%2!=0System.out.print(s);
            
t = inone.read();
            
count++;
        }
    }
}
                    

 
Q: Write a program to print out the ASCII values of the even characters of ggg.dat.
 
A very small change to the code above is required, changing the if statement marginally.
 
CODE: evench.java

import java.io.*;
public class evench
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader("ggg.dat");
        
int count=1;
        
int t = inone.read();
        
while (t!=-1)
        {
            
char s = (char)t;
            
if (count%2==0System.out.print(s);
            
t = inone.read();
            
count++;
        }
    }
}

Q: Write a program called swapchars.java using command line arguments that allows any two characters to be swapped. For example if the program was called swapchars then to swap all ‘a’s and ‘b’s in the file fred we would type java swapchars fred ab.
 
Ok, this was a bit of a tough one – needed to get the logic right and to stop the character that the program had just substituted switching back to itself or doing something else weird. Below, the solution.
 
CODE: swapchars.java

import java.io.*;
public class swapchars

// debugging code left in to help revision

{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone = new FileReader(args[0]);
        
        
PrintWriter outone = new PrintWriter(new
        
FileOutputStream("swappedcharoutput.dat"));
        
        
int t = inone.read();
        
int first = (int)(args[1].charAt(0));
        
int second = (int)(args[1].charAt(1));
        
int count = 1;
        
boolean skip = false;   //used to stop the char just swapped,
                                //swapping back again
        while (t!=-1)
        {
            
if (t==first
            {
                
/* System.out.println("Char " + count + " is " + (char)t 
                + " and we're substituting first character");
                */

                
t=second;
                
outone.print((char)t);
                
skip = true;
                
count++;
            }
            
if (t==second && skip==false
            {
                
/* System.out.println("Char " + count + " is " + (char)t
                 + " and we're substituting second character");
                */

                
t=first;
                
outone.print((char)t);
                
count++;
            }
            
if (t!=first && t!=second)
            {
                
/* System.out.println("Char " + count + " is " + (char)t 
                 + " and we're making no substitution");
                */

                
outone.print((char)t);
                
count++;
                
skip = false;
            }
            
t = inone.read();
        }   
        
outone.close();
    }
    
}
                    

 
Q: Write a program, manycat.java that is the same as cat.java above except that many files can be entered as command line arguments and be printed out one after the other.
 
CODE: manycat.java
 

import java.io.*;   //this copies from anywhere we like
                    //to screen
public class manycat
{
    
public static void main(String[] argsthrows Exception
    {
        
//work out the length of the args array
        int len = args.length;
        
//dump the print routine in a for loop for each
        //command line file input
        for (int i = 0i<leni++)
        {
            
FileReader inone=new FileReader(args[i]);
            
int t = inone.read();
            
while (t!=-1)
            {
                
System.out.print((char)t);
                
t = inone.read();
            }
        }
    }
}
                    

 
Q: Write a program in Java, swapcase.java that is the same as cat.java except that all lower case letters are swapped for upper case and vice versa.
 
Struggled with getting the if...else logic right here, needed a bit of help from the course notes. Pretty simple stuff when you think about it though.
 
CODE: swapcase.java

import java.io.*;   //this copies from anywhere we like
                    //to screen
public class swapcase
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader(args[0]);
        
int t = inone.read();
        
while (t!=-1)
        {

            if (Character.isUpperCase((char)t)==true)
            {
                
System.out.print(Character.toLowerCase((char)t));
            }
            
else if (Character.isLowerCase((char)t)==true)
            {
                
System.out.print(Character.toUpperCase((char)t));
            }
            
else System.out.print((char)t);
            
t = inone.read();
        }
    }
}

 
Q: Write a program called ascii.java that is the same as cat.java above except that as well as printing out each character, it also prints out its Unicode value. What is the Unicode value for the newline character?
 
CODE: ascii.java

import java.io.*;   //this copies from anywhere we like
                    //to screen
public class ascii
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader(args[0]);
        
int t = inone.read();
        
while (t!=-1)
        {
            
            
System.out.println("Character = " + (char)t 
            + 
" Unicode Value = " + t);
            
t = inone.read();
        }
    }
}

 
The Unicode value of the newline character is 10.
 
Q: Write a program called remnewline.java that is the same as cat.java above except that it doesn’t print out the newline characters in the file.
 
CODE: remnewline.java

import java.io.*;   //this copies from anywhere we like
                    //to screen
public class remnewline
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader(args[0]);
        
int t = inone.read();
        
while (t!=-1)
        {
            
if(t!=10)   //this will not print out newline
                        //characters
            {
                
System.out.print((char)t);
            }
            
t = inone.read();
        }
    }
}
                    

 
Q: Write a new program called tenperline.java which is the same as remnewline.java above except that it prints out 10 characters on each line.
 
Struggled with this one, some nasty while loops. Still not great at getting the logic right on these problems. Here’s the answer inspired by the course notes ©UoL.
 
CODE: tenperline.java

import java.io.*;
public class tenperline
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader(args[0]);
        
int t = inone.read();
        
while (t!=-1)
        {
            
int count = 0;
            
while (count<10 && t!=-1)
            {
                
if(t!=10)
                {
                    
count ++;
                    
System.out.print((char)t);
                }
                
t = inone.read();
            }
            
System.out.println();
        }
    }
}

 
Q: Write a program that prints out every word in a file, one word per line.
 
To do this, we need to identify spaces between words as well as newline and end-of-file characters. Code below.
 
CODE: listwords.java

import java.io.*;
public class listwords
{
    
public static void main(String[] argsthrows Exception
    {
        
FileReader inone=new FileReader(args[0]);
        
int t = inone.read();
        
while (t!=-1)
        {
            
while (t!=32 && t!=10 && t!=-1)
            
/*checks to see if space, newline or endoffile*/
            {
                {
                    
//if not prints char
                    System.out.print((char)t);
                    
//reads new char
                    t = inone.read();
                }
            }
            
//if space, newline (note not endoffile as still in while
            //t!=-1 loop)
            //read next character and print a newline
            t = inone.read();
            
System.out.println();
        }
    }
}
                

 
Q: Write a spell checker that goes through a file and prints out all the words it finds that aren’t in the dictionary.
 
So, to tackle this problem here’s my thought process:
 
1. First, we have to convert the file containing the words to be checked into a file which holds each of the words on a separate line. We’ll call the original file the tbc file and the new file linetbc. We’ll have to remove all the special characters and punctuation as well as convert the words to lower case for accurate matching.
 
2. Then, we read in the first word of linetbc.
 
3. We then compare this word with each word in stored in the dictionary file, words, one by one.
 
4. If there is a match we do nothing and read in the next word from linetbc and repeat the process.
 
5. If there is not a match, we print out the word from linetbc, read in the next word from linetbc and repeat the process.
 
So, we need to write a method to create the linetbc file and then use compareTo() from the String class to check to see if they are the same word. Here’s how I did it below. Have commented out the debug code but left it in because I think I’ll be needing it in the future!
 
CODE: spellcheck.java

import java.io.*;
import java.util.Scanner;
public class spellcheck
{
    
public static void createlinetbc (String[] tbcthrows Exception
    {
        
PrintStream out = new PrintStream (new 
                            
FileOutputStream("linetbc.dat"));
        
//above sets up printing to a file
        FileReader in = new FileReader(tbc[0]);
        
int t = in.read();
        
while (t!=-1)   //checking for the end of the file
        {
            
while (t!=32 && t!=10 && t!=-1)
            
/*checks to see if space, newline or endoffile*/
            {
                    
//Ensures only letters are included in the analysis             
                    //file and strips out punctuation
                    if (Character.isLetter((char)t)==true)
                    {
                        
//System.out.print((char)t);    
                        //output to screen for debugging
                        out.print(Character.toLowerCase((char)t));      
                        
//convert to lowercase
                        //and print out to a file
                        //reads new char
                        t = in.read();
                    }
                    
else
                    {
                        
t = in.read();
                    }
            
            }
            
//if space, newline (note not endoffile as still in while
            //t!=-1 loop)
            //read next character and print a newline
            t = in.read();
            
//System.out.println(); //output to screen for debugging
            out.println();          //output to file
        }
        
out.close();                //close file writing method
    }
    
    
    
    
public static void main(String[] argsthrows Exception
    {
        
//Run method to transfer input file into a file that stores each
        //word separately, one per line, creating file linetbc.dat
        
        
createlinetbc(args);
                
        
// Object inTBC is used to read in the word from linetbc.dat
        Scanner inTBC  = new Scanner(new FileReader("linetbc.dat"));
        
        
// inWord stores a word read in from linetbc.dat
        String inWord;
        
        
//used to check whether the word is in the dictionary
        boolean match;
        
        
while (inTBC.hasNext()) //loop to read in words from inTBC
        {
            
inWord = inTBC.nextLine();
            
match = false;
            
            
// Object inDict is used to read in the
            // dictionary word files
            Scanner inDict = new Scanner(new FileReader("words"));
            
            
// To reset the guard condition in the second
            // while loop below we have to re-initialise the 
            // inDict object within the first loop as above
            
            
while (inDict.hasNext())
            {
                
String dict = inDict.nextLine();
                
//System.out.println(dict + " " + inWord);
                //System.out.println(compareResult);
                if (dict.compareTo(inWord)==0
                {
                    
//System.out.println(inWord + " is in the 
                    //dictionary");
                    match=true;
                }  
            }
            
if (match==falseSystem.out.println(inWord + 
            
" is not in the dictionary");
            
//System.out.println(inWord);
            inDict.close();
        }       
        
    }
}
    
        

 
Q: Write a spell checker that goes through a file and every time it finds a word not in the dictionary it prompts the user to either to accept the word or enter a replacement.
 
Ok – this was a tester and the solution is very much a hack rather than a well structured program. Again, in the interest of getting to the solution quickly rather than crafting an elegant method-based solution, hope you’ll forgive me. The way I have done this is to firstly scan the original file against the dictionary file, a line at a time.
 
When a word is found that is not in the dictionary the user is asked whether they want to replace it or not. If they do, an entry is written out to two files. The first is the incorrectly spelt word and the second is the replacement word entered by the user.
 
Then, we read the original file in, a line at a time. We check to see whether or not the string read in contains any of the incorrectly spelt words and if it does, replaces them with the user prompted replacement. A loop cycles through all the previously identified incorrectly spelled words for each line of the original file read in. Finally, each line of the original file which has now been corrected, is written out to screen.
 
CODE: bestSpell.java

import java.io.*;
import java.util.Scanner;
public class bestSpell
{
    
public static void main(String[] argsthrows Exception
    {
        
        
//set-up the output streams
        
        
//outputWords.dat is the file created which splits the input 
        //file into a new file containing each word, a line at a time.              
        
        
PrintStream outWords = new PrintStream(new
        
FileOutputStream("outputWords.dat"));
        
        
        
//outputCorrections.dat is a file that will contain the words
        //that need to be replaced in the original file, created by
        //the user entering replacement words when a word in the
        //original file is not found in the dictionary. Stored one 
        //word per line
        
        
PrintStream outCorrect = new PrintStream(new
        
FileOutputStream("outputCorrections.dat"));
        
        
//outputWrong.dat is a file that will contain all the words in
        //the original file that are not in the dictionary file.
        
        
PrintStream outWrong = new PrintStream(new
        
FileOutputStream("outputWrong.dat"));

        //read in file to be checked and convert to a file where each
        //original word is stored on a new line in the outputWords file
        
        
Scanner inLine = new Scanner(new FileReader(args[0]));
        
String inLineStr = "";
        
        
while (inLine.hasNextLine())    
        {   
            
//Read in a line of the file
            inLineStr = inLine.nextLine();
            
            
//Splits the string into a file of words and outputs to
            //file by considering a character at a time
            //if the character is a letter, prints to file, otherwise
            //prints a line return
            
            
int len = inLineStr.length();
            
for (int i = 0i<leni++)
            {
                
if (Character.isLetter(inLineStr.charAt(i))==true)
                {
                    
outWords.print(inLineStr.charAt(i));
                }
                
else 
                {
                    
outWords.println();
                }   
            }   
        }
        
//don't forget to close the stream or nothing will write
        outWords.close();
            
            
        
//Now we compare the outputWords.dat file to the dictionary
        //file and check for matches
            
        
Scanner inTBC = new Scanner(new FileReader("outputWords.dat"));
        
String inWord;
        
String replace ="";
        
boolean match;
        
        
while (inTBC.hasNext())
        {
            
inWord = inTBC.nextLine();
            
match = false;
            
            
//read in the dictionary file
            
            
Scanner inDict = new Scanner(new FileReader("words"));

            //compare word at a time against the dictionary file

            
while (inDict.hasNext())
            {
                
String dict = inDict.nextLine();
                
if (dict.compareTo(inWord)==0match=true;
            }
            
            
//if a word cannot be found in dictionary do the following
            
            
if (match==false
            {
                
                
//ask user if they want to replace the word or not
                
                
System.out.println(inWord + " is not in the"
                + 
" dictionary");
                
System.out.println("Do you want to replace it? y/n >");
                
                
Scanner ignoreIn = new Scanner (System.in);
                
String ignore = ignoreIn.nextLine();
                
                
//if the user does want to replace the word
                
                
if (ignore.compareTo("y")==0
                {
                    
System.out.println("Enter replacement > ");
                    
replace = ignoreIn.nextLine();
                    
                    
//write replacement word and word which does
                    //not match to the dictionary file
                    
                    
outCorrect.println(replace);
                    
outWrong.println(inWord);                   
                }
            }
            
            
//we have to close the inDict stream to force the routine to
            //start at the beginning of the dictionary file each time a 
            //new word is checked.
            
            
inDict.close();     
        }
    
        
outCorrect.close();
        
outWrong.close();
    
    
//now, scan the original file for the file with errors
    //import the incorrect and correct words a line at a time and place
    //in a variable.

    
Scanner inOriginal = new Scanner(new FileReader(args[0]));
    
String inOriginalStr = "";
    
String inWrongStr = "";
    
String inCorrectStr = "";
    
String finalStr = "";
    
int stringCheck = 0;
    
    
//import the original file a line at a time for comparison
    
    
while (inOriginal.hasNextLine())
    {
        
Scanner inWrong = new Scanner(new
        
FileReader("outputWrong.dat"));
        
        
Scanner inCorrect = new Scanner(new 
        
FileReader("outputCorrections.dat"));
        
        
inOriginalStr = inOriginal.nextLine();
        
        
//set up a while loop to scan each original file line
        //for all incorrect words identified in outWrong.dat
        
        
while (inWrong.hasNextLine())
        {
            
inWrongStr = inWrong.nextLine();
            
            
inCorrectStr = inCorrect.nextLine();
            
            
//check whether the line read in from the original
            //file contains an incorrect word
            
            
stringCheck = inOriginalStr.indexOf(inWrongStr);
            
            
//if it does, replace the wrong word with the correct
            //word
            
            
if (stringCheck !=-1)
            {
                
inOriginalStr = inOriginalStr.replaceAll
                (
inWrongStrinCorrectStr);
            }
        }
        
        
//reset the input streams for the wrong and correct word files
        
        
inWrong.close();
        
inCorrect.close();
        
        
//print the corrected line
        System.out.println(inOriginalStr);
    }
    }
}

 

Bits, Types, Characters and Type Casting in Java. Learning objectives and exercises from the University of London BSc in Creative Computing.
 
LEARNING OBJECTIVES
 
1. Understand that different variables of different types have different sizes.
 
A variable consists of some bytes (8 bits) of RAM. Different variable types have a different amount of memory required. A boolean variable only requires one bit as it can only be true or false. For storing characters, Java allocates two bytes which provides space for 216 different characters to be stored (which is 65,536 characters). For storing int variables, Java allocates 4 bytes, which is 232 integers.
 
2. Explain type casting.
 
You can force Java to treat an expression as belonging to a particular type by including the type in brackets before the expression. So the expression System.out.println((char)37); will print out the char ‘%’ rather than the int 37.
 
3. Explain the relationship between characters and Unicode.
 
Unicode is a method of allocating a particular integer value to a character so that the computer is able to display different types of natural language and alphabet. Each character and symbol in a specific alphabet is allocated a number within a specific Unicode encoding. There are many Unicode encodings. Some examples are UTF-8, UTF-16, ASCII, Mac OS Roman etc. Each encoding has a different mapping of characters to integers. Follow the Unicode link to Wikipedia for more information.
 
4. Explain why the read method returns an int.
 
As Java allocates all 216 possible spaces in char memory to characters there is no room for any ‘special characters’ like a ‘line return’ or ‘end of file’. These special characters have to therefore be stored in a variable type that has more memory space. The read() method uses the return type int which has 232 possible integers that it can store. Therefore we can use the read() method to input characters other than just char characters. Because they are stored as Unicode integers, we must type cast the output of read() back to char for proper display.
 
EXERCISES
 
Q: Research each type in Java and find out how big it is.
 
The size of primitive data types (those that are automatically part of the Java program language) can be found here. Below are the sizes of the key data types:
 
int: 32 bits
long: 64 bits (twos-complement)
float: 32 bit (floating point)
double: 64 bit (floating point)
boolean: 1 bit
char: 16 bits
short: 16 bits (twos-complement)
byte: 8 bits (two-complement)
 
String is not strictly a primitive data type, rather it is an object from the class java.lang.String.
 
Q: Write a program to check whether or not an int can be cast as a boolean.
 
An int cannot be cast as a boolean. The compiler complains if you try to do this.
 
Q: Write a program to check whether or not a boolean can be cast as an int.
 
No, this does not work either – a boolean cannot be cast as an int.
 
Q: Write a program to check whether or not a float can be cast as an int.
 
CODE: FloatToInt

class FloatToInt
{
    
public static void main(String[] args)
    {
        
float in = 1.0000f//the'f' defines the value as a float
        int out = (int)in;
        
System.out.println(out);
    }
}

 
Yes, it is possible to cast a float as an int. You will necessarily lose data and accuracy by doing this.
 
Q: Write a program to check whether or not a double can be cast as a float.
 
CODE: DoubleToFloat.java

class DoubleToFloat
{
    
public static void main(String[] args)
    {
        
double in = 1.0;
        
float out = (float)in;
        
System.out.println(out);
    }
}

 
Yes, a double can be cast to a float variable.
 
Q: Write a program to check whether or not an int can be cast as a float.
 
CODE: IntToFloat.java

class DoubleToFloat
{
    
public static void main(String[] args)
    {
        
double in = 1.0;
        
float out = (float)in;
        
System.out.println(out);
    }
}

 
Yes, it is possible to cast an int as a float.
 
Q: Write a program to check whether or not a float can be cast as a char.
 
CODE: FloatToChar.java

class FloatToChar
{
    
public static void main(String[] args)
    {
        
float in = 100.0f//f designates the value is a float
        char out = (char)in;
        
System.out.println(out);
    }
}

 
Yes, it is possible to cast a float as a char.
 
Q: Write a program to check whether or not an int can be cast as a short.
 

class IntToShort
{
    
public static void main(String[] args)
    {
        
int in = 1000;
        
short out = (short)in;
        
System.out.println(out);
    }
}

 
Yes, an int can be cast as a short but for large integers (above 32,768 and below -32,768) a loss of data and accuracy will occur.
 
Q: What is the next biggest int, n, after 0, such that System.out.println(n) gives 0.
 
This is another example of where I don’t agree with the answer in the course notes. The course notes indicate that the answer is 65536, however if you run System.out.println(65536); the program prints out 65536. If however, you run System.out.println((int)((char)65536)); the program prints out 0. This is because the char type has 216 (65,536) possible values whereas the int type has 232 (4,294,967,296) possible values. As the first char is zero the last char when cast as an int is therefore (65536-1). Java then essentially returns the integer conversion back to zero by calculating the value mod(65536) for any values above 65536.
 
Q: Why does the program below output 10 zeros?
 
CODE: IntShort1.java

public class IntToShort1
{
    
public static void main(String[] args)
    {
        
int i = 65536;
        
for(int j=0l j<10j++)
        
System.out.println((short)(j*i));
    }
}

 
The code above prints out 10 zeros due to the fact that the type short has a size of 216 bits which provides for up to 65,536 values to be stored (65,535 positive integers plus zero). The first time the loop executes, j = 0 so the expression (j*i) also equals zero. The second time, j is 1 but i is 65,536 which is one greater than the maximum numbers that can be stored in a type short so Java outputs mod(65536) which is zero. Each loop generates a multiple of 65536 and therefore each time mod(multiple of 65536) evaluates to zero. There are 10 loops within the for statement so the program prints out 10 zeros.
 
Q: What does the following program output?
 
CODE: LargestInt.java
 

public class LargestInt
{
    
public static void main(String[] args)
    {
        
int i = 2147483647;
        
System.out.println(i);
        
System.out.println(i+1);
    }
}

 
The program above outputs 2147483647 -2147483648. This is because the type int stores a possible 232 values (4,294,967,296) which are divided equally between postive and zero values and negative values. Hence the output of the program.