550 likes | 567 Views
Explore Java exception handling, Queue-based algorithms, BFS, implement new exceptions, copy methods, test programs, and crawler for web page pathfinding.
E N D
ITI 1221. Introduction to Computing IILab-7 Dewan Tanvir Ahmed University of Ottawa
Today’s Objective • Understanding the current Assignment, e.g. Assignment 3 • Reviewing the solution of Assignment 2 • Reviewing the solution of Mid term • GUI and Event Driven Programming
Assignment 3 • Objectives • Further understanding of exception handling in Java • Learn about two implementations of Queues • Introduction to Queue-based algorithms • Breath-First Search (BFS) algorithm
Assignment 3 (cont..) Exceptions • Create a new exception type called EmptyQueueException • A subclass of RuntimeException • The class EmptyQueueException has two constructors • A default constructor with no parameters • A constructor with a parameter of type String, • which is used to save a reference to an error message for later retrieval by the getMessage method
Assignment 3 (cont..) Exceptions • Create a new exception type called QueueOverflowException • A subclass of RuntimeException • The class QueueOverflowException has two constructors • A default constructor with no parameters • A constructor with a parameter of type String, which is used to save a reference to an error message for later retrieval by the getMessage method
Assignment 3 (cont..) Exceptions • modify the methods of the classes LinkedQueue and CircularQueue • To validate the pre-conditions and • throw the appropriate exception when needed: • EmptyQueueException, • QueueOverflowException and • IllegalArgumentException
Assignment 3 (cont..) Copy • The method copy() creates a duplicate of a queue containing the same elements and be in the same order • It creates a copy of a queue such that the values of the queue and its copy are shared, Shallow copy. • Class LinkedQueue: public LinkedQueue copy() • Adding elements to a linked structure having a front reference and rear reference • You can’t use the instance methods of this class to implement this method • NB. Two queues are sharing the values but not the nodes • Class public CircularQueue copy() • Exercise of wrapping front and rear around the boundaries • You can’t use the instance methods of this class to implement this method • The elements of the duplicate should be stored at positions 0 to size- 1
Assignment 3 (cont..) public boolean equals( Object other ) Override the method public boolean equals( Object other ) • It returns • true if other designates a Queue (any implementation of the interface Queue) that contains the same number of elements as this queue, and each element of the other queue must be “equals” to the corresponding element in this queue • false otherwise • Both queues must not be changed by the method equals, i.e. before and after a call to the method equals, this and the other queue must contain the same elements, in the same order
Assignment 3 (cont..) Test • Write a Test program for the methods copy and equals of the classes • LinkedQueue and • CircularQueue.
Assignment 3 (cont..) • Questions??? (LinkedQueue, CircularQueue) • Size • Wrapping • Enqueue • Dequeue • Empty! • Full!
Assignment 3, Part II • Queue Based Algorithms • BFS
Assignment 3, Part II (cont..) • Class HTML • HTML document = new HTML( "http://www.site.uottawa.ca/~turcotte/a3/" ); int count=0; while ( document.hasMoreUrls() ) { String url = document.nextUrl(); count++; } System.out.println( "This document has " + count + " links." ); • How to get the content • document.getPage();
Assignment 3, Part II (cont..) • Class Solution • A Solution has two instance variables (both of type String). • One that designates the path represented by the solution. • The other stores the last URL of the path represented by the solution; • Constructors • The constructor Solution( String lastUrl ) • sets both instance variables to lastUrl. • The constructor Solution( Solution partial, String lastUrl ) • sets the path of this Solution to that of partial concatenated with lastUrl; • path = partial.getpath() -> lastUrl • It also sets the instance variable for the last URL of this object to lastUrl; • A solution has two access methods, • getPath and • getLasUrl
Assignment 3, Part II (cont..) Crawler • The class Crawler contains three static methods that are used to find a path from a Web page A to a Web page B • private static boolean isValid( String url ) • returns true • if url is a well formed URL designating an existing/readable Web page, and false otherwise. Use the fact that the constructor of an HTML object • Throws an exception, of type MalformedURLException, • if the url is not well formed • Throws an exception, of type IOException, • if the content of the page cannot be successfully read • Any Question?
Assignment 3, Part II (cont..) Crawler • private static Solution solve( String a, String b ) • Implement a breath-first search algorithm for finding a path from a Web page A to a Web page B. • The breath-first search uses a Queue data structure (this can be your own implementation of LinkedQueue) • The algorithm initializes the queue to contain just the partial solution that consists of the Web page A only, and repeatedly does the following: • dequeues a partial solution off the queue; • extend the partial solution by one URL in all possible ways • enqueues each of the “valid” extension
Assignment 3, Part II (cont..) Crawler • public static void main( String[] args ) • The main method prints the following message unless there are exactly two arguments on the command line, and exists immediately • Usage: java Crawler src dst • If the command line has two arguments, those arguments are used for calling the method solve • The main method prints the path if it exists, and “no path” if no such path was found
Solution – Assignment 2 • Let’s Go • Click here
Mid-Term Solution Q1 (cont..) • Part A • Implement the three classes, as well as the interface Player. • Make sure to include the constructors • For each attribute • write the access methods • The values of the attributes must be valid • If the value of the parameter is less than 0.0 then set the value of the attribute to 0.0 • Similarly, if the value of the parameter is larger than the upper limit then set the attribute to its upper limit • Finally, implement the methods attack
Mid-Term Solution Q1 (cont..) Implementation of interface Player: • All players of the game have a method double attack() that returns a value representing the strength of the attack. • Player is an interface declaring the method double attack() public interface Player { public abstract double attack(); }
Mid-Term Solution Q1 (cont..) Implementation of abstract class AbstractPlayer: • An AbstractPlayer defines the characteristics that are common to all the creatures • This abstract class implements the interface Player • All the creatures have • A name (a character String) • A life meter (a double ranging from 0.0 to 100.0) • The initial value of the life meter is 50.0 • Implement constructor method • Implement access methods • getters and setter methods for attributes name and life meter
Mid-Term Solution Q1 (cont..) public abstract class AbstractPlayer implements Player { private static final double LIFE_METER_INIT = 50.0; private static final double LIFE_METER_MAX = 100.0; private static final double LIFE_METER_MIN = 0.0; private String name; private double lifeMeter; public AbstractPlayer( String name ) { lifeMeter = LIFE_METER_INIT; this.name = name; } public String getName() { return name; } public String setName( String name ) { this.name = name; } public double getLifeMeter() { return lifeMeter; }
Mid-Term Solution Q1 (cont..) public void setLifeMeter( double value ) { lifeMeter = value; if ( lifeMeter < LIFE_METER_MIN ) { lifeMeter = LIFE_METER_MIN; } else if ( lifeMeter > LIFE_METER_MAX ) { lifeMeter = LIFE_METER_MAX; } } }
Mid-Term Solution Q1 (cont..) Class Uldra • An Uldra is a creature (player) that carries a bottle filled with poison (a double value in the range 0.0 . . . 100.0) • Uldra creatures have a tendency to misplace their bottles (a boolean value indicates if this Uldra has or not its bottle) • The strength of an attack is zero if the Uldra has no bottle. Otherwise, the strength of an attack is 10.0, or the remaining amount of poison (which ever value is smaller) • The strength of the attack reduces the quantity of poison left by the same amount
Mid-Term Solution Q1 (cont..) public class Uldra extends AbstractPlayer { private boolean hasABottle; private double poison; public Uldra( String name ) { super( name ); hasABottle = false; poison = 0.0; } public boolean hasABottle() { return hasABottle; } public void setHasBottle( boolean value ) { hasABottle = value; if ( ! hasABottle ) { poison = 0.0; } } public double getPoison() { return poison; }
Mid-Term Solution Q1 (cont..) public void setPoison( double value ) { if ( hasABottle ) { poison = value; if ( poison < 0.0 ) { poison = 0.0; } else if ( poison > 100.0 ) { poison = 100.0; } } } public double attack() { double result = 10.0; if ( ! hasABottle ) { result = 0; } else if ( getPoison() < result ) { result = getPoison(); } setPoison( getPoison() - result ); return result; } }
Mid-Term Solution Q1 (cont..) Class Yakku • Yakku creatures have magical powers (double, range 0.0 . . . 100.0, the initial value is 10.0) • The strength of the attack depends on both its life meter and its magical powers. Specifically, a weight w is calculated as being the value of the life meter divided by 10.0 • The weight w is then multiplied by the level of magical powers to obtain the strength of the attack • An attack reduces both the life meter and the magical powers by the strength of the attack.
Mid-Term Solution Q1 (cont..) public class Yakku extends AbstractPlayer { private static final double MAGIC_POWERS_MAX = 100.0; private static final double MAGIC_POWERS_MIN = 0.0; private static final double MAGIC_POWERS_INIT = 40.0; private double magicPowers = MAGIC_POWERS_INIT; public Yakku( String name ) { super( name ); } public double getMagicPowers() { return magicPowers; } public void setMagicPowers( double value ) { magicPowers = value; if ( magicPowers < MAGIC_POWERS_MIN) { magicPowers = MAGIC_POWERS_MIN; } else if ( magicPowers > MAGIC_POWERS_MAX ) { magicPowers = MAGIC_POWERS_MAX; } }
Mid-Term Solution Q1 (cont..) public double attack() { double w = getLifeMeter() / 10.0; double result = w * magicPowers; setLifeMeter( getLifeMeter() - result ); magicPowers = magicPowers - result; return result; } }
Mid-Term Solution Q1 (cont..) Part B • Write a polymorphic class method, duel, that has two parameters, both of type AbstractPlayer, first and second. • Rules • While both players are alive (i.e. their life meter is greater than zero) • The first player launches an attack onto the second one • If the second player is still alive, it launches an attack onto the first player • When a player “a” launches an attack onto a player “b”, you must reduce the value of the life meter of “b” by a.attack() • Finally, the method displays the name of the player that is still alive
Mid-Term Solution Q1 (cont..) public static void duel( AbstractPlayer first, AbstractPlayer second ) { while ( first.getLifeMeter() > 0.0 && second.getLifeMeter() > 0.0 ) { double strength; strength = first.attack(); second.setLifeMeter( second.getLifeMeter() - strength ); if ( second.getLifeMeter() > 0.0 ) { strength = second.attack(); first.setLifeMeter( first.getLifeMeter() - strength ); } } AbstractPlayer alive = first; if ( second.getLifeMeter() > 0.0 ) { alive = second; } System.out.println( alive.getName() + " is alive!" ); }
Mid-Term Solution Q2 Calculator c = new Calculator(); c.execute( "40 5 2 4 1 ~ print + print ^ print * print - print" ); -top- INTEGER: -1 INTEGER: 4 INTEGER: 2 INTEGER: 5 INTEGER: 40 -bottom- -top- INTEGER: 3 INTEGER: 2 INTEGER: 5 INTEGER: 40 -bottom- -top- INTEGER: 8 INTEGER: 5 INTEGER: 40 -bottom- -top- INTEGER: 40 INTEGER: 40 -bottom- -top- INTEGER: 0 -bottom
Mid-Term Solution Q3 • Correct at least 5 mistakes (logic, runtime or compile-time errors) in the partial implementation • "implements Stack" missing • constructor • declaration of a local variable elems masks the instance variable elem • ’capacity = capacity’ should be • ’this.capacity = capacity’, otherwise, the instance variable capacity will not be initialized • this.increment not assigned • increaseSize • needs a for loop to copy the elements or System.arraycopy • Pop • should decrease size then access the element • "return saved" missing • (should be calling decreaseSize after removing the element. )
Mid-Term Solution Q3 (cont..) • Complete the partial implementation of the class DynamicArrayStack public void push( Object element ) { if (size == elems.length) { increaseSize(); } elems[ size ] = element; size = size + 1; }
Mid-Term Solution Q3 (cont..) • Complete the partial implementation of the class DynamicArrayStack private void increaseSize() { Object[] newElems; newElems = new Object[elems.length + increment]; // Copying all the elements to the new array newElems = elems; // Replacing elems with the new and larger array elems = newElems; }
Mid-Term Solution Q3 (cont..) • Complete the partial implementation of the class DynamicArrayStack public Object pop() { size = size - 1; Object saved = elems[ size ]; // Scrubbing the memory! elems[ size ] = null; if (elems.length > capacity && ( elems.length - size ) >= increment) { decreaseSize(); } return saved; }
Mid-Term Solution Q3 (cont..) • Complete the partial implementation of the class DynamicArrayStack private void decreaseSize() { int newSize = elems.length - increment; if ( newSize < capacity ) { newSize = capacity; } Object[] newElems; newElems = new Object[ newSize ]; for ( int i=0; i<size; i++ ) { newElems[ i ] = elems[ i ]; } // Replacing elems with the new/smaller array elems = newElems; }
Mid-Term Solution Q4 • In the class CombinationLock, override the method equals. • Two locks are equals if • Their status are “equals” and both CombinationLock have the same combination (defined by the variables first, second and third) • Otherwise, the method returns false • No values are considered illegal; in particular, the method should be handling null values.
Mid-Term Solution Q5 (cont..) public boolean equals( Object obj ) { if ( obj == null || ! ( obj instanceof CombinationLock ) ) return false; CombinationLock other = (CombinationLock) obj; boolean result = true; if ( first != other.first ) result = false; else if ( second != other.second ) result = false; else if ( third != other.third ) result = false; else if ( status == null ) result = ( other.status == null ); else result = status.equals( other.status ); return result; }
Mid-Term Solution Q6 • LinkedPair - Part A • Draw the memory diagram representing the content of the memory after the execution of the following statement Pair p = new LinkedPair ( new Name("Joseph", "Rotblat"), new Name("Wangari", "Maathai"));
Mid-Term Solution Q5 (cont..) • LinkedPair - Part B • For the partial implementation of the class LinkedPair, write the instance method public sort() that sorts the (two) elements of a LinkedPair • Rules • Change the order of the elements (objects of the class Elem) • exchanging the values of the nodes is not acceptable. public void sort() { if ( first.value.compareTo( first.next.value ) > 0 ) { Elem newFirst = first.next; newFirst.next = first; first.next = null; first = newFirst; } }
Mid-Term Solution Q5 (cont..) • Part C • Complete the implementation of the method String toString(). It returns a String representation of the pair • starting with “(” • Followed by the String representation of the first object of the pair • Followed by “,” • Followed by the String representation of the second object of the pair • Followed by “)”. public String toString() { return "(" + first.value + "," + first.next.value + ")"; }
Mid-Term Solution Q6 • Part A • Define a new checked exception called ZendaIOException. • This should be a specialized IOException. public class ZendaIOException extends IOException { public ZendaIOException() { super(); } public ZendaIOException( String message ) { super( message ); } }
Mid-Term Solution Q6 (cont..) • import java.io.FileInputStream; • import java.io.FileNotFoundException; • public class Zenda { • private static void getConfig( String name ) throws ZendaIOException { • if ( name == null ) { • throw new IllegalArgumentException( "null value" ); • } • FileInputStream input; • try { • input = new FileInputStream( name ); • } catch ( FileNotFoundException e ) { • throw new ZendaIOException( "file not found: " + name ); • } • }
Mid-Term Solution Q6 (cont..) • private static void init() throws ZendaIOException{ • getConfig( "config.dat" ); • } • public static void main( String[] args ) { • try { • init(); • } catch ( ZendaIOException e ) { • System.err.println( "ERROR READING CONFIG FILE" ); • e.printStackTrace(); • System.exit( 1 ); • } • } • }
Mid-Term Solution (cont..) • Part C • Explain why a runtime exception will occur if the following statements are executed. public class Manager { private Object[] elems; public Manager( int capacity ) { if ( elems.length == 0 ) { elems = new Object[ capacity ]; } } public static void main( String[] args ) { Manager m = new Manager( 100 ); } } NullPointerException?
GUI and Event Driven Programming • Any component can be the source of an event • A button generates an event when you click on it. • Any class can be a listener for an event • It simply implements the method (s) of the interface • The object that handles the event generated from the click of a button needs to implement the interface ActionListener. • The object that handles the event generated when a window is closed must implement the interface WindowListener.
GUI and Event Driven Programming (cont..) • The event generated by the source component is sent to the listeners who registered with the component. • The source has a method addActionListener who needs as a parameter an object that implements the interface ActionListener. • Since the handler implements the interface ActionListener, the source knows that the handler has a method actionPerformed(...). • Example • private DisplayArea display = new DisplayArea(); • button.addActionListener(display); Object Source Listener Registration
GUI and Event Driven Programming (cont..) • import java.awt.*; • import java.awt.event.*; • public class GUI extends Frame { • private Button bLeft = new Button("Left"); • private Button bRight = new Button("Right"); • private DisplayArea display = new DisplayArea(); • public GUI() { • super("DGD - Week 8"); • setBackground(Color.WHITE); • add(display, BorderLayout.CENTER); • Panel p = new Panel(); • p.add(bLeft); • p.add(bRight); • add(p, BorderLayout.SOUTH);
GUI and Event Driven Programming (cont..) bLeft.addActionListener(display); bRight.addActionListener(display); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e){ System.exit(0); } } ); pack(); show(); } public static void main(String[] args) { new GUI(); } }