ITP Winter Show 2012

If you’re looking for something awesome to do on December 16th or 17th I would definitely recommend checking out the ITP Winter show which is sure to be chock-full of interactive multimedia goodness.  More info can be found on the ITP website – http://itp.nyu.edu/itp/

Poster for the ITP Winter Show 2012 December 16th 2-6PM and 17th 4-8PM. Free and open to the public.

Posted in ITP

Day 26 Wrap-Up

[ Download source code from Day 26 ]

Today we discussed three new topics – HashMaps, Abstract Classes and Interfaces. Note that HashMaps are not covered in your book, so they will not be on the final exam. But they’re incredibly useful so I built them into today’s lecture as an ‘FYI’ topic. Here’s an outline of what we discussed today:

  1. So far we have explored two different types of sequence structures – the “array” and the “ArrayList.” These structures are both designed to store references to zero or more objects or, in the case of arrays, primitive data elements.
  2. Here’s a quick breakdown of Arrays vs. ArrayLists
    // Arrays
    Size set on creation
    Can store 1 data type only *
    Can store primitives
    Can store reference types
    Accessed using index notation
    Items stored sequentially
    // ArrayLists
    Size can grow and shrink
    Can store 1 data type only *
    Can not store primitives
    Can store reference types
    Accessed using method calls
    Items stored sequentially

    And here are some identical code samples using both structures:

    // Arrays
    String[] a = new String[10];
    a[0] = “hello”;
    println( a[0] );
    println( a[0].length() );
    // ArrayLists
    ArrayList a = new ();
    a.add(“hello”);
    println ( a.get(0) );
    println ( a.get(0).length() );
  3. The HashMap is another sequence structure that can be used to store multiple objects in Java. Unlike arrays and ArrayLists, HashMaps do not organize their data elements using an integer index value. Instead, HashMaps use object references as their indexes. Often we use Strings as the index value, or “key” into the Hash Map. In other languages we sometimes refer to HashMaps as “associative arrays” or “dictionaries” because they can be used to associate one piece of data with another.
  4. Here’s how to create a HashMap in Java:
    // create a HashMap
    HashMap<String, String> myMap = new HashMap<String, String>();
    
    // add in some key / value pairs
    myMap.put(“section01”, “M/W 12:30pm WWH 102”);
    myMap.put(“section03”, “M/W 09:30am WWH 109”);
    
    // get info about section03
    System.out.println( myMap.get(“section03”) );
  5. The HashMap is a generic type, just like an ArrayList. When you construct a HashMap you need to specify two data types – they “key” and the “value.” The “key” data type is what you will use to access an element in a HashMap (instead of an integer index value). The “value” data type is the type of data that you want to store in your HashMap. For example:
    // create a hashmap that uses a String as a key
    // and stores objects of type Pokemon
    HashMap <String, Pokemon> myMap;
    
    // initialize the map
    myMap = new HashMap<String, Pokemon>();
  6. You can put elements into a HashMap by doing the following:
    // create a Pokemon object
    Pokemon temp = new Pokemon();
    
    // place the object into the map at the key “Pikachu”myMap.put(“Pikachu”, temp);

    And you can access elements in a HashMap by doing the following:

    // get an element based on a key
    Pokemon temp = myMap.get(“Pikachu”);

    If a key is not present in a HashMap then the get method will return “null” – you can use this to detect if a key is currently being used or not, like this:

    if ( myMap.get(“Charmander”) == null )
    {
    	// create a new object	
        Pokemon temp = new Pokemon();	
    
        // put it into the map	
        myMap.put(“Charmander”, temp);
    }

    Remove an element from a HashMap can be done in much the same way:

    if ( myMap.get(“Charmander”) != null )
    {
    	// remove item	
        myMap.remove(“Charmander”);
    }

    Finally you can iterate over all items in a HashMap by doing the following:

    for (String key : myMap.keySet() )
    {
    	// grab a reference
    	Pokemon temp = myMap.get(key);	
    
        // do something
        System.out.println( temp.name );
    }
  7. We then wrote a few programs that used HashMaps – see the downloads for today for more information.
  8. Next we moved on to discuss Abstract Classes. An abstract class represents a class in the inheritance hierarchy that is so generalized that it can not / should not be able to create an instance. For example:
    // very general, probably abstract
    public class Animal
    
    // more specific, probably concrete 
    public class Dog
  9. Abstract classes are marked with the “abstract” keyword in their class definition, like this:
    public abstract class Animal

    Note that abstract classes cannot be instantiated using the “new” keyword. Abstract classes can contain a mix of concrete (implemented) methods and abstract (unimplemented) methods. Unimplemented methods do not have a body associated with them – just a method header, like this:

    public abstract void respire();
    public abstract void eat();
  10. We then wrote a program that implemented an abstract class for a GeometricObject – here’s the code:
    package abstractclasses;
    
    public abstract class GeometricObject
    {
    
    	private double x;
    	private double y;
    
    	// constructor - note that we can't call this constructor directly
    	// by using the new keyword (i.e. we can never saw GeometricObject a = new GeometricObject() )
    	// because the class is marked as "abstract'
    	// we have it set as "protected" so that only its subclasses can access it via the "super" keyword
    	protected GeometricObject(double x, double y)
    	{
    		this.x = x;
    		this.y = y;
    	}
    
    	// getters and setters
    	public double getX()
    	{
    		return this.x;
    	}
    	public double getY()
    	{
    		return this.y;
    	}
    	public void setX(double x)
    	{
    		this.x = x;
    	}
    	public void setY(double y)
    	{
    		this.y = y;
    	}
    
    	// abstract methods that can be overrided by our subclasses
    	// note that we don't have to provide implementation details here
    	// we are simply defining that all GeometricObjects will have the getArea and getPerimeter methods
    	// but we can't implement them here because it wouldn't make sense
    	public abstract double getArea();
    	public abstract double getPerimeter();
    }

    And here’s a “concrete” implementation of this abstract class:

    package abstractclasses;
    
    public class Circle extends GeometricObject
    {
    
    	private double r;
    
    	public Circle(double x, double y, double r)
    	{
    		super (x,y);
    		this.r = r;
    	}
    
    	// getters and setters
    	public double getR()
    	{
    		return this.r;
    	}
    	public void setR(double r)
    	{
    		this.r = r;
    	}
    
    	// a concrete class (i.e. a class that can be instantiated via the 'new' keyword)
    	// that extends an abstract class MUST implement the abstract methods of its superclass
    
    	@Override
    	public double getArea()
    	{
    		return Math.PI * this.r * this.r;
    	}
    
    	@Override
    	public double getPerimeter()
    	{
    		return 2 * Math.PI * this.r;
    	}
    }
  11. So why do we need abstract classes? An abstract class helps a programmer to define a “base case” for a specific set of objects. It forces the programmer to implement certain shared behavior among this group. Abstract classes are also useful from a Polymorphism perspective. For example, the following is valid and will work as intended due to dynamic binding:
    GeometricObject a = new Circle(1,1,5);
    GeometricObject b = new Rectangle(5,6,10,2);
  12. Here are some general notes on the use of Abstract Classes:
    • Abstract methods can only be contained in abstract classes
    • Subclasses of an abstract class must implement all abstract methods. If the subclass cannot implement these methods it must also be marked as abstract.
    • You can’t instantiate an abstract class, but you can define a constructor for one. If you do this then its subclasses must call this constructor via the super() keyword as usual
    • You can use the data type of an Abstract class as you would any other data type. This allows for all sorts of polymorphic goodness :)
  13. Next we began discussing “Interfaces” in Java. An interface is a “class-like” structure in Java that can be used to define common functionality between unrelated classes. Because Java does not support “multiple inheritance” (i.e. a class cannot extend two classes) Interfaces are often used to define common behavior among classes that do not extend from the same superclass.
  14. Interfaces can only contains abstract methods and constant data fields. Interfaces allow us to define common operating behavior that can be “implemented” by any class, regardless of its inheritance lineage. This means that we can “cut across” inheritance hierarchy to implement functionality as we see fit.
  15. Here’s how to create an Interface:
    public interface Pet
    {
    	// only abstract methods & constants allowed
    	public abstract void petMe();
    }

    To associate a class with an interface we need to tell Java that the class will “implement” that interface. The “implements” keyword goes after the class definition, like this:

    public class Dog extends Animal implements Pet

    Classes that implement an interface MUST implement all its is methods in order to compile.

  16. See today’s lecture notes for a full overview on this as well as case study where we created some unrelated classes (Animals and Robots) and implemented an interface that allowed some of their subclasses to share functionality.
  17. Interfaces can be used as a data type, allowing you to store previously unrelated objects in the same collection. For example, RoboChickens and Dogs both implement the Pet interface. Therefore the following is valid:
    Pet[] thePets = new Pet[2];
    thePets[0] = new RoboChicken(“fred”);
    thePets[1] = new Dog(“george”);
  18. Note: if a superclass implements an interface then its subclasses must also implement that interface as well.
  19. Java has a number of built-in interfaces that programmers often use when writing their own software. One such interace is the “comparable” interface. Many classes implement the “comparable” interface in order to help evaluate how two objects relate to one another.
  20. The comparable interface only has one method that you need to implement, named “compareTo()” – this method accepts a reference to another object and returns an integer. It will return a +1 if the object in question is bigger than the one it is being compared to. It will return a 0 if the objects are the same. It will return a -1 if the object in question is smaller than the one it is being compared to. Here’s an example using Pokemon – we can tell Java how to evaluate the “size” of one Pokemon to another using the compareTo() method:
    package comparable;
    
    public class Pokemon implements Comparable<Pokemon>
    {
    
    	public String name;
    	public int hitPoints;
    
    	public Pokemon(String name, int hitPoints)
    	{
    		this.name = name;
    		this.hitPoints = hitPoints;
    	}
    
    	@Override
    	public int compareTo(Pokemon o)
    	{
    		// do we have more hit points than the object that is being passed to us?
    		// if so, return a positive number (1)
    		if (o.hitPoints < this.hitPoints)
    			return 1;
    
    		// same hit points - return 0
    		else if (o.hitPoints == this.hitPoints)
    			return 0;
    
    		// do we have less hit points?  if so, return -1
    		else
    			return -1;
    	}
    
    }
  21. Note the generic modifier in the interface declaration – this tells Java that Pokemon can only be compared to other Pokemon. You could open this up and make it so that Pokemon could be compared to ANY object, like this:
    public class Pokemon implements Comparable

    However, this is probably not what you want to do since it would be impossible to compare the size of a Pokemon to an unrelated object, like a Dog, String or ArrayList. So you would have to handle this eventuality by putting your code into a try/catch block. It’s easier to implement the generic form of the interface and let the compiler handle this for you.

  22. If an object is comparable then you can invoke the following method call to compare its size against a qualifying object:
    Pokemon a = new Pokemon("Pikachu", 100);
    Pokemon b = new Pokemon("Charmander", 50);
    System.out.println( "Is Pikachu bigger than Charmander? " + a.compareTo(b) );
  23. This is useful for comparing two objects, but what about hundreds or thousands of them? The comparable interface is used throughout Java to support sorting operations. For example, you can sort an array if it is storing data of type “int” because Java can easily compare the relative size of one element to another:
    int[] myList = new int[10];
    
    // fill array with random numbers
    
    java.util.Arrays.sort(myList);// now it’s sorted!

    But how can you sort Pokemon? A Pokemon may have many different criteria and Java isn’t smart enough to figure out if one object is bigger than another. The answer is the in the Comparable interface! If you implement this interface you can use Java’s built-in sort functionality to perform the sort without doing anything special!

    Pokemon[] myPokey = new Pokemon[5];
    
    // randomly create 5 pokemon
    
    // sort the Pokemon!
    java.util.Arrays.sort(myPokey);
  24. Note that you can also sort ArrayLists this way if the object they are storing implements the Comparable interface. However, you wouldn’t use java.util.Arrays.sort() to sort an ArrayList because it isn’t an Array. Instead, use this syntax:
    Collections.sort( myArrayList );

    Note that the above line will only work if myArryaList is storing an object that implements the Comparable interface.

Day 25 Wrap-Up

download source code from Day 25 ]

download graphics source code from Day 25 ]

  1. So far we have explored how we can instruct Java to work with File objects that are stored on our local hard drive. We can also extend Java’s input and output capabilities to use data sources that are not local to a client’s machine. One of the easiest ways to do this is to interface with resources available on the World Wide Web.
  2. We started off by talking about the structure of a URL:

    
    http://www.nyu.edu/path/to/file
    
    

    The protocol (“http://”) defines the “language” that should be used when communicating with the computer that is hosting the content you wish to access (referred to as a “server” or “webserver”). The machine name & domain (“”www.nyu.edu”) comes next, and is usually represented by the DNS name or IP address of the computer that you wish to contact. The path (“path/to/file”) is the location on the server’s hard drive that you want to visit.

  3. You can load data that exists at a particular URL by using the following syntax in Java:

    // define our URL
    URL serviceUrl = new URL("http://www.nyu.edu");
    // read in dataScanner 
    input = new Scanner( serviceUrl.openStream() );
    String data = input.nextLine();
    

    Note that working with external data always carries some risk of the data not existing or your network connection not being active. Eclipse will force you to place the appropriate try/catch blocks or “throws” statement in order to deal with any exceptions that may arise.

  4. Also note that you can read in data from any URL that you’d like, but the result that you recieve may not be what you are looking for. We demonstrated this by trying to access the NYU homepage directly via the method outliend above. We quickly realized that the content that we received was less than usuable due to the fact that it was written in HTML and was destined to be parsed and understood by a web browser.
  5. For those of you who haven’t studied it before, HTML (Hyper Text Markup Language) is a language that is used to describe the layout of a web page to a web browser. It consists of textual elements interspersed with “tags” to describe the look and feel of a page. For example:

    Not bold <strong>This is some bold text</strong>
    

    Will render:

    Not bold This is some bold text

  6. We then wrote a program that obtains non-HTML formatted text that represented some weather data for NYC from November 2012. Here’s the code:

    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.Scanner;
    
    
    public class Ex08_WeatherDataViaURL
    {
    	public static void main(String[] args) throws IOException
    	{
    		// define our URL
    		URL weatherURL = new URL("http://i5.nyu.edu/~cmk380/cs101/NYCWeather_2012_11.txt");
    		
    		// connect and obtain data from this URL
    		Scanner input = new Scanner( weatherURL.openStream() );
    		
    		// accumulator variables
    		double highest = -1000;
    		double lowest = 1000;
    		double total = 0;
    		double numLines = 0;
    		
    		// read in our data
    		while ( input.hasNext() )
    		{
    			// grab a line
    			String data = input.nextLine();
    
    			// if this is the first line we should ignore it - it is the header row
    			if (numLines != 0)
    			{
    				// split up the line based on the position of the commas
    				String[] splitData = data.split(",");
    
    				// grab out the max temp, min temp and average temp
    				double max = Double.parseDouble(splitData[1]);
    				double min = Double.parseDouble(splitData[2]);
    				double avg = Double.parseDouble(splitData[3]);
    				
    				// update our accum vars
    				if (max > highest)
    					highest = max;
    				if (min < lowest)
    					lowest = min;
    				total += avg;
    			}
    			
    			// increase our line count
    			numLines++;
    		}
    		
    		// close our URL
    		input.close();
    		
    		// report back to the user
    		System.out.println("Higest temperature for the month: " + highest);
    		System.out.println("Lowest temperature for the month: " + lowest);
    		System.out.println("Average temperature for the month: " + total / (numLines-1));
    
    	}	
    }
    
  7. We cannot directly write data to the web in the same way in which we can write data to a file on our hard drive. If we could we could do something like this, which would be very, very bad!

    URL myURL = new URL("http://www.nyu.edu");
    PrintWriter myWriter = new PrintWriter( myURL );
    myWriter.println(“Hello, World!”);
    
  8. To send information to the web we can use the “Common Gateway Interface” specification or "CGI". The CGI allows us to send data to a web accessible service in one of two ways, called GET and POST. A GET request lets us append variables to a URL as name/value pairs. Variables are placed after the "?" of a URL and are combined into pairs using the equals sign. The "&" character separates multiple variables in a sequence. For example:

    
    http://www.test.com/?var1=Hello&var2=World
    
    

    We showed this by "hacking" a URL and making it behave differently than originally anticipated. We did this by opening up a browser and visiting http://www.yahoo.com and searching for “cats”. We then looked at the URL and noticed that variables are being sent to the server:

    
    http://search.yahoo.com/search;_ylt=AuHB82.GhKYaxkSzOa_SUaSbvZx4?p=cats&toggle=1&cop=mss&ei=UTF-8&fr=yfp-t-701
    
    

    If we change the value of the “p” variable to dogs and hit Enter we can resubmit the search request and cause the server to load a different set of results.

  9. Next we discussed Application Programming Interfaces. An Application Programming Interface (API) is a well defined set of methods that can be used to interface with a 3rd party data source. Many websites and services now offer public access to their data via APIs One of the most popular ways of interfacing with an API over the web is to interact with the service using a custom generated URL.
  10. Take Twitter for example. You can get information about Tweets in real time by constructing a call to the Twitter API (https://dev.twitter.com/docs/api/1/get/search) -- the API specifies that you can send a String variable (q) that represents a Query. The API will return an encoded String that represents your results. Example call:

    
    http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed
    
    

    See the lecture slides for today for a detailed overview of this process, along with some URLs for some APIs and some working code that you can use to interface with them.

Day 24 Wrap-Up

download source code from Day 24 ]

  1. You may run into a situation where you will need to generate your own exceptions in your code
    For example, say you have a method that is designed to compute the result of a division operation (a / b)

    public static int divideBy(int a, int b)

    The method is designed to return the integer result of the division operation, and most times it will be able to do this. However, if b is 0 then we have a problem – what do we return? Since a method is pre-declared to return a specific type of data we are stuck!

  2. One solution would be to exit the program. But this isn’t a very elegant solution at all since the method is now taking over the program and causing it to crash without the consent of the main program.
    if (bad_condition_exists)
    {
    	// exit the program
    	System.exit(1);
    }
  3. A cleaner solution would be to have the method throw an exception and allow the caller to deal with the issue. You can do this by creating a new Exception object (or one of its subclasses) and throwing it inside the method. For example:
    // create an exception
    Exception bad = new Exception(“You broke this!”);
    
    // throw it back to the caller – if they don’t catch it
    // then the program crash is on their head not mine!
    throw bad;
  4. We then wrote a program that demonstrated this via a method called “quotient” which attempts to divide two numbers. Here’s the code:
    public class Ex04_QuotientWithException
    {
    
    	public static void main(String[] args)
    	{
    		// attempt to divide two numbers
    		try
    		{
    			System.out.println( quotient(5,0) );
    		}
    		catch (ArithmeticException e)
    		{
    			System.out.println("You broke the method!");
    			System.out.println("This is the message from the exception: " + e.getMessage() );
    		}
    	}
    
    	// attempt to divide two numbers
    	// also we can define that this method could potentially throw an ArithmeticException
    	public static int quotient(int a, int b) throws ArithmeticException
    	{
    		// if the number is zero then we can "throw" a new error
    		// if the programmer is smart then they will catch it!
    		if (b == 0)
    		{
    			throw new ArithmeticException("Divisor can't be zero! Be more careful in the future!");
    		}
    
    		return a / b;
    	}
    
    }

    Note that Eclipse and Java will force you to declare that your method may end up throwing an exception. This is represented by the “throws” statement after the method definition.

  5. Exceptions in Java are just objects. All exceptions inherit from the Throwable class in java.lang, and each exception is designed to capture and describe a particular error condition. See the lecture notes today for a graphical flowchart of some Exceptions and their inheritance relationships – and here’s a link to the Java Docs on the Exception class that describe some of the subclasses of Exception and how/when to use them.
  6. You can create your own exceptions by extending the Exception class (or any of its subclasses). For example, say I wanted to write a Circle class that only accepts positive numbers for the Circle’s radius I could write an exception called InvalidRadiusException that could be throw in the event of this condition occurring. This would allow the caller to decide how to deal with the issue rather than having the object itself have to decide. Here’s an example:
    public class InvalidRadiusException extends Exception
    {
    	@Override
    	public String toString()
    	{
    		return “Invalid radius! Bad!”;	
        }
    }
    public Circle
    {
    	int radius;	
    
        // note – Eclipse will force you do declare	
        // that this method throws an Error	
        // (hence the “throws …” statement)	
        public Circle(int r) throws InvalidRadiusException	
        {
        		if (r < 0)
        			throw new InvalidRadiusException();		
                else
                	this.radius = r;
        }
    }

    And here’s a code fragment that catches an InvalidRadiusException:

    try
    {
    	Circle a = new Circle(-5);
    }
    catch (InvalidRadiusException e)
    {
    	System.out.println(“What are you doing??”);
    	System.out.println( e.toString() );
    }
  7. Next we moved on to discuss permanant storage. All of the programs that we have written so far have reset themselves each time they execute. This is because the data associated with the program are stored in your computer’s memory (RAM). RAM is a volatile place – it serves as a computer’s short term memory. RAM that is being used by a program is automatically reclaimed by the JVM upon the termination of a program.
  8. If programs are to retain data between executions then we need to find a more permanent way to store and save information for future use. A computer will almost always has at least one type of long-term storage device at its disposal (usually some kind of hard drive). We can use the long term storage capabilities of a computer to store data in the form of a file. This requires us to request access to write and/or read to/from the file from the Operating System. Once we save a file it will remain on the long term storage device after the program is finished running, and can be accessed and retrieved later on.
  9. There are two main families of files that we work with when writing programs – Text Files & Binary Files. Text files are files that contain data that is encoded as text (i.e. ASCII or Unicode characters) – data stored in a text file is visible and can be read by a program that is designed to view / edit textual data (i.e. a word processing program). We will be working with text files exclusively in this class
  10. Binary files contain data that is not encoded as a text format. Binary files are intended to be read by other programs and not by humans directly and generally appear unintelligible when viewed via a word processing program
  11. The File class is built-in class that can be used to interface with files stored on a user’s computer The File class in Java is pretty bare-bones as compared to File classes in other languages – it’s only really used to define a connection between a File and your program. It has no built in capability to read data from or write data to the file it connects to.
  12. In order to use the File class you need to import it from java.io.File . Next, you can instantiate an object of type File which takes a String as an argument for construction. This String should represent the relative path to the file you wish to work with. I generally create a folder called “data” in my project’s “src” folder. Then I can reference a file in that folder by doing the following:
    File testFile = new File(“src/data/myfile.txt”);
  13. Once you create a File object you can call a number of methods on the object to learn more about the file you are pointing to, such as:
    System.out.println("File exists? " + testFile.exists());
    System.out.println("File full path: " + testFile.getAbsolutePath());
    System.out.println("Can I read from the file? " + testFile.canRead());
    System.out.println("Can I write to the file? " + testFile.canWrite());
  14. Writing to a file involves data being sent from your program to the File object and (eventually) into the appropriate file on your hard drive. The File class does not have the ability to write directly to a File. To do this we need to use a new class called PrintWriter (which must be imported from java.io) – here’s an example:
    PrintWriter myWriter = new PrintWriter(myFile);

    Important note! If the File passed to the PrintWriter does not exist it will be created for you. Upon opening, the PrintWriter class will destroy the contents of a file. This isn’t an error – it’s just the behavior of the class.
    No warning will be given to the user that this will happen, so be careful when opening up files for writing!

  15. Also note that the PrintWriter class can throw a FileNotFoundException. You need to deal with this or Eclipse won’t let your program compile. You can either use a try/catch block to handle the error or you can let it slide by adding “throws FileNotFoundException” to your method definition. This will “pass the buck” and make the caller of your method deal with the exception.
  16. Once a file has been opened we can call methods on the PrintWriter class to write data to it. These methods mirror the output methods that we have been using via the System.out class since the beginning of the term. For example:
    File a = new File(“src/data/test1.txt”);
    PrintWriter writer = new PrintWriter(a);
    writer.println(“Hi there!”);
    writer.println(“What’s up?”);
  17. When you are finished writing to a file you must close your PrintWriter object. If you don’t you risk losing or corrupting the data in the file. Here’s the syntax:
    PrintWriter writer = new PrintWriter(someFile);
    writer.println(“some data”);
    
    // close the file!
    writer.close();
  18. We then wrote a program that asked the user to enter in a series of cites and then writes them to a file. Here’s the code:
    import java.io.*;
    import java.util.Scanner;
    
    public class EX08_FileWriteCities
    {
    
    	public static void main(String[] args) throws FileNotFoundException
    	{
    		// open a file object
    		File theFile = new File("src/data/cities.txt");
    
    		// create a Scanner
    		Scanner input = new Scanner(System.in);
    
    		// attempt to open up the file for writing
    		// note we are omitting a try/catch block here - this is becuase
    		// I had Eclipse add the "throws FileNotFoundException" to this method's
    		// header (see above) - if an exception is raised we will "pass the buck"
    		// up the chain.  Essentially this means the program will crash since
    		// there is no one above us!  (i.e. no one had to call "main" to start
    		// the program - that was done by Java)
    		PrintWriter writer = new PrintWriter(theFile);
    
    		// continually get city names from the user
    		while (true)
    		{
    			// get a name
    			System.out.print("Enter a city, or hit enter to end: ");
    			String city = input.nextLine();
    
    			// was there any data?  
    			if (city.length() == 0)
    			{
    				break;
    			}
    
    			// put the city into the file
    			else
    			{
    				writer.println(city);
    				}
    			}
    
    		// close the print writier
    		writer.close();
    
    		System.out.println("All done!");
    	}
    
    }
  19. Reading from a File requires you to use the Scanner class, which you should be familiar with from our work with console input. When we want to get input from the console we can instantiate a new Scanner like this:
    Scanner input = new Scanner(System.in);

    When we want to get input from a file we can instantate a new Scanner like this:

    File theFile = new File(“src/data/file1.txt”);
    Scanner fileInput = new Scanner(theFile);

    Opening a File with Scanner is non-destructive – you won’t affect the contents in the file by opening up a File in this way. Note that Eclipse will also force you to wrap the instantiation of a Scanner inside a try/catch block, or declare a “throws” statement at the top of the method.

  20. Once the file has been opened you can read from it using standard Scanner methods, like this:
    File theFile = new File(“src/data/file1.txt”);
    Scanner input = new Scanner(theFile);
    // read the first line of data
    String data = input.nextLine();
    // close the Scanner to be nice
    input.close();
  21. Reading one line is useful, but you will often need to read many lines of data from a File. You can do this by using the hasNextLine() method on the Scanner class, like this:
    Scanner input = new Scanner(theFile);
    // while there is more data to read
    while ( input.hasNextLine() )
    {
    	String line = input.nextLine();
    	System.out.println(“Line is: “ + line);
    }
    input.close();

Day 23 Wrap-Up

download source code from Day 23 ]

  1. We started off by discussing the “final” keyword in Java. More often than not we want to be able to create subclasses based off of superclass definitions. However, there are times when we want to explicitly prevent a class from being extended. We can enforce this by using the “final” keyword in the class definition. For example:
    public final class MyClass

    In the example above MyClass is at the end of the inheritance chain – no classes can choose to extend it and use it as a superclass.

  2. The “final” keyword can also be used on methods within a class. For example:
    public final void myMethod()

    Methods marked as final can not be overrided by subclasses.

  3. The final keyword can also be applied to variables, like so:
    public final int numShoes = 100;

    When used in this way, the “final” keyword will mark the variable in question as being read-only. It can no longer be changed by the current class or any sub-classes. Variables marked as “final” are sometimes known as “constants”. In Java we generally capitalize constants, like so:

    public final int NUMSHOES = 100;
  4. Next we began discussing the ArrayList class and how it can be used to store sequences of objects in Java. As you recall, regular arrays are the most fundamental sequence structure in Java. They give us the ability to store multiple items of the same type within the same data structure. With that said, Arrays in Java are limited in the following ways:
    • They can only hold items of the same data type
    • Their size is fixed upon creation and cannot grow or shrink once initilaized
  5. The ArrayList class is a class that exists in the Java library that can be used to store an unlimited number of objects of the same type. However, unlike arrays, ArrayLists can grow and shrink beyond their initially declared size.
  6. ArrayLists can only store objects that are reference types. They cannot store primitive types such as ints, floats and doubles.
  7. ArrayLists are known as a “generic class” in Java. This means that you have to specify a “concrete type” for your ArrayList when you create it. For example:
    import java.util.ArrayList;
    
    […] // code goes here
    
    ArrayList<String> myList = new ArrayList<String>();
  8. You do not access elements in an ArrayList using index notation. Instead, you use a series of methods built into the class to work with data stored in the list. Here’s an example of adding, removing and viewing items in an ArrayList:
    public static void main(String[] args)
    	{		
    		// create an ArrayList
    		ArrayList<String> cities = new ArrayList<String>();
    
    		// add in some cities
    		cities.add("London");
    		cities.add("Paris");
    		cities.add("New York");
    		cities.add("Tokyo");
    		cities.add("Beijing");
    
    		// report out the list as a single string
    		System.out.println(cities.toString());
    
    		// report out the list as individual elements
    		for (int i = 0; i < cities.size(); i++)
    		{
    			// get the current city
    			String thisCity = cities.get(i);
    
    			// print it out
    			System.out.println("City # " + i + " is " + thisCity);
    		}
    
    		// add in an element at the beginning
    		cities.add(0, "Mexico City");
    		System.out.println( cities.toString() );
    
    		// remove the 2nd item
    		cities.remove(1);
    		System.out.println( cities.toString() );
    
    		// remove New York
    		cities.remove("New York");
    		System.out.println( cities.toString() );
    	}
  9. We then built an ArrayList that stores instances of Circle objects that we created. Here’s the code – note the syntax for getting an object reference out of the ArrayList and calling a method on it:
    	public static void main(String[] args)
    	{
    		// create an ArrayList
    		ArrayList<Circle> theCircles = new ArrayList<Circle>();
    
    		// add in 100 randomized Circle objects
    		for (int i = 0; i < 100; i++)
    		{
    			// create a new random Circle
    			Ex05_Circle temp = new Ex05_Circle( Math.random() * 10, 
    												Math.random()*500-250, 
    												Math.random()*500-250);
    
    			// add the circle to our ArrayList
    			theCircles.add(temp);
    		}
    
    		// now get the total area of all circles
    		double total = 0;
    		for (int i = 0; i < theCircles.size(); i++)
    		{
    			// pull out the area from each object and add it to an accum var
    			total += theCircles.get(i).getArea();
    		}
    
    		System.out.println("Combined area: " + total);
    
    		// next get the average position
    		double x = 0;
    		double y = 0;
    
    		for (int i = 0; i < theCircles.size(); i++)
    		{
    			// pull out the x & y positions and add them to an accum var
    			x += theCircles.get(i).x;
    			y += theCircles.get(i).y;
    		}
    
    		System.out.println("Average location: " + x/theCircles.size() + ", " + y/theCircles.size() );
    
    	}
  10. During our discussion on methods we introduced the concept of a “stack” which Java uses to organize method calls as they are invoked. Stacks are incredibly important / useful in Computer Science as they allow us to model a “last-in-first-out” structure.
  11. In general, a stack can do the following:
    • (PUSH) – Add an element to the end of the stack
    • (PEEK) – Look at the element at the end of the stack
    • (POP) – Remove the element at the end of the stack
    • (SIZE) – Return the total size of the stack
    • (REPORT) – Return a String version of the stack
  12. We then wrote a class to model the Stack Abstract Data Type (ADT) and simulate its operations using an ArrayList. We ended up declaring our ArrayList to hold objects of type Object so that any object can be stored in the Stack (since all objects can qualify as an Object)
    import java.util.ArrayList;
    
    public class Ex06_Stack
    {
    	// create our ArrayList
    	private ArrayList<Object> theStack = new ArrayList<Object>();
    
    	// isEmpty - is our stack empty?
    	public boolean isEmpty()
    	{
    		return this.theStack.isEmpty();
    	}
    
    	// getSize - return the size of our stack
    	public int getSize()
    	{
    		return this.theStack.size();
    	}
    
    	// peek - look at the top most item on the stack
    	public Object peek()
    	{
    		// get the last index of the stack
    		int lastIndex = this.theStack.size() - 1;
    		return this.theStack.get( lastIndex );
    	}
    
    	// push - put something on the stack
    	public void push(Object o)
    	{
    		this.theStack.add( o );
    	}
    
    	// pop - look at the top most item on the stack and remove it
    	public Object pop()
    	{
    		// get the last index of the stack
    		int lastIndex = this.theStack.size() - 1;
    
    		// grab the item
    		Object item = this.theStack.get( lastIndex );
    
    		// remove the item
    		this.theStack.remove( lastIndex );
    
    		// return the item
    		return item;
    	}
    
    	// toString
    	@Override
    	public String toString()
    	{
    		return "Stack : " + this.theStack.toString();
    	}
    }
  13. Next we moved on to discuss Exceptions. Java is a fairly robust programming language that can handle a wide range of situations and scenarios in an efficient and graceful manner With that said, there will be times when Java encounters an issue that it is not prepared to be able to deal with. In these situations Java will throw up its hands in frustration and scream out “Sorry, I just can’t do this!” and your program will end up crashing.
  14. In Java, errors are represented as “exceptions” which are really nothing more than objects. When Java encounters an error or condition that prevents execution from proceeding normally Java will “throw” an exception. If the exception is not “caught” by the programmer then the program will crash and you will see the exception description and current stack trace printed to the console
  15. One way to deal with exceptions is to simply avoid them in the first place. For example, the following code will throw an exception because you can’t divide an integer by zero in Java:
    int divisor = 0;
    int answer = 5 / divisor;

    However, we can prevent this from happening by using conditional logic to test if the condition will arise prior to performing the potentially risky operation:

    int divisor = 0;
    if (divisor == 0)
    {
    	System.out.println(“Can’t be zero!”);
    }
    else
    {
    	System.out.println( 5 / divisor);
    }
  16. Unfortunately not all exceptions can prevented in this way because you don’t always know whether a given operation will fail or not before it is invoked. Another strategy is to use Java’s built in exception handling infrastructure which can be implemented using the “try / catch” block
  17. Java allows you to isolate potentially dangerous code inside of a special block called a “try” block. Any exception that is raised inside of a “try” block will not automatically crash your program. Instead, Java gives you the ability to decide how it should respond if an error is thrown inside this block.
  18. Identifying how Java should respond to a given exception is described using a series of “catch” blocks which appear directly after a “try” block, like this:
    // this might be bad!
    try
    {
    	int answer = 5 / 0;
    }
    // here is a potential solution
    catch (ArithmeticException e)
    {
    	System.out.println(“Arithmetic Error!”)
    }
  19. When Java encounters an exception in a “try” block it will immediately cease execution of the “try” block (just like the “break” statement inside a loop or the “return” statement in a method). Java will then proceed to any “catch” blocks that appear directly after the “try” block. Catch blocks look just like method definitions – they have arguments inside parenthesis that define what kind of data they need in order to operation. The arguments after a “catch” block will always be of type Exception (or one of its subtypes) – we will talk more about this in our next lecture.
  20. Java will compare the exception raised inside the “try” block to the signature of each “catch” block – as soon as it finds one that matches the exception that was raised it will run the code inside that block. If Java successfully “catches” an exception then your program will not crash. Here’s an example of multiple exceptions behing “caught”:
    	public static void main(String[] args)
    	{
    		// create a scanner
    		Scanner numberScanner = new Scanner(System.in);
    
    		// create a new array
    		int[] storage = {0,0,0,0,0};
    
    		// get a number
    		System.out.print("Give me a number: ");
    		int number1 = numberScanner.nextInt();
    
    		System.out.print("Give me a number: ");
    		int number2 = numberScanner.nextInt();
    
    		System.out.print("Where should I put the result?");
    		int index = numberScanner.nextInt();
    
    		// anything wrapped in a "try" block is considered "Quarantined"
    		// if an exception is raised inside this block then Java will immediately stop
    		// and will try and see if we have provided it with a way to deal with the issue
    		try
    		{
    			// attempt the division
    			int answer = number1 / number2;
    			System.out.println("Answer is: " + answer);
    
    			// attempt to store the number
    			storage[index] = answer;
    		}
    
    		// if an ArithmeticException occurs in the try block above then this block will execute
    		// note that if the "catch" block executes then the program will not crash from the exception
    		// that was raised in the "try" block above
    		catch (ArithmeticException e)
    		{
    			System.out.println("Got a division error! ");
    		}
    
    		// if an ArrayIndexOutOfBoundsException occurs then this block will execute
    		catch (ArrayIndexOutOfBoundsException e)
    		{
    			System.out.println("That slot doesn't exist in the array!");
    		}
    	}
  21. Note that if you’re lazy and you just want to catch all exceptions that are raised in a “try” block you can do the following – all exceptions inherit from the Exception class so this “catch” block will end up catching all exceptions that may be thrown:
    try
    {
    	// potentially bad code goes here
    }
    catch (Exception e)
    {
    	// any Exception or subclass of Exception	
        // will be handled by this block
    }

Day 19 Wrap-Up

download source code from Day 19 ]

Today we continued our discussion on inheritance & polymorphism.  Here’s an overview of what we talked about:

  1. In Java you can create “packages” to organize classes that belong to the same category. In Eclipse you can create a new package by clicking on File -> New -> Package. A package can hold any number of classes and is really nothing more than a folder that Java uses to organize your classes on your hard drive (open up your workspace and double click on your Java project to see this). Note that the “protected” modifier can be used in conjunction with packages to make a data field or method only accessible from within a particular package.
  2. In order to use a package in your code you will need to import it first. For example, if you created a class named Fork in the package utensils you could do the following:
    // import the Fork class
    import utensils.Fork;
    
    // or to import all classes from the package
    import utensils.*;
    
    public static void main(String[] args){	
       Fork a = new Fork();
       }
  3. The “super” keyword can be used within a class to refer to its superclass. We often use the “super” keyword to call the constructor method on a superclass. This will invoke the constructor on the superclass and then return control back to the subclass once it has completed. You must invoke the superclass’s constructor prior to doing anything else in the subclass’s constructor method. For example:
    public class A
    {
       public int x;
    
        public A(int c)
       {
          this.x = c;
       }
    }
    
    public class B extends A
    {
       public B(int d)
       {
           super(d);
           println(“hi!”);
       }
    }

    See the code samples above for more examples of constructor chaining.

  4. We have already learned that you can define multiple versions of the same method through overloading. Overloading requires that we define at least two methods with the same name, but each of these methods accepts a different set of arguments. Overriding is a technique where we replace a method of a superclass with one in a subclass.
    public class A
    {
    	public void saySomething()
    	{
    	   println(”superclass!");	
        }
    }
    
    public class B extends A
    {
    	@Override
    	public void saySomething()
    	{
    	   println(”subclass!");	
        }
    }
  5. With overriding we are providing a new implementation of an existing method in the superclass. The @Override directive should be placed before you override a method in a subclass, but it technically isn’t required. See the code samples above for more examples of overriding methods.
  6. If no inheritance relationship is defined when you set up a class then the class will inherit directly from the “source” class of Java, which is the “Object” class. “Object” is parent class of all classes, and contains basic methods that are applicable to any class in Java. Docs for the Object class are available here: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html
  7. Object contains a method called toString which returns a String version of the name of the class along with its memory address. You can override the toString() method in a subclass to provide more information about that class to the user, like this:
    @Override
    public String toString()
    {
    	// implement
    }
  8. Classes define a type. For example, variable a is of type “Bird”
    Bird a;

    Subclasses can define subtypes. For example, “Duck” extends “Bird” so it is considered a subtype of “Bird”

    Duck b;

    In the example above, “Duck” is a subtype of “Bird”, and “Bird “is a supertype of “Duck”. Ducks can do anything that Birds can do because Ducks extend Birds in our program.

  9. When you create a subclass you are inheriting instance variables and methods from a superclass. A subclass can then implement new features that are independent of the superclass, but it still contains all of the methods and fields available to the superclass. A subclass can do everything a superclass can do, and more.
  10. Because Java is a strictly typed language we need to define the data type of every variable before we can use it. For example:
    Bird a = new Bird();
    Duck b = new Duck();

    Polymorphism allows us to treat a variable as though it was of a different type. For example:

    Bird a = new Bird();
    Bird b = new Duck();

    The above example may look wrong, but in our world Ducks extend Birds. They are Birds – but with more stuff added to them. We can safely call any Bird method on a Duck object and be guaranteed that it will be available. See the “Animal” code sample above for a detailed overview of this concept.

  11. In the Animal example we told Java that each object was of type Animal. This is considered the “declared” type of the object. However, two of the three objects were not of type Animal – they were subtypes of Animal. In this case these two objects had “actual” types that are different from their declared types. The question is – when you call a method on an object with a declared type that differs from its actual type, which method gets called? The method on the declared type (Animal) or the method on the actual type (Chicken)?
  12. The answer is that Java uses the “actual” type when determining which method to call. This is called “dynamic binding” – Java waits until the run time to determine which method to call by checking an object’s actual type and calling the appropriate method.
  13. Often times your subtypes will contain instance variables and methods that don’t exist in the supertype. This can result in a compiler error. For example, the following isn’t valid even though the method “meow” is available via the Cat class:
    Animal a = new Cat(); // valid, Cat subclasses Animal
    a.meow(); // error!  Animals can’t meow!

    We can fix this by casting the Animal as a Cat and then calling a method on it. For example:

    Animal a = new Cat(); // valid, Cat subclasses Animal
    ( (Cat) a ).meow();   // valid, treating a as a Cat

    Note that this can be dangerous if you aren’t 100% sure that the object in question is of the correct type. For example:

    Animal a = new Dog(); // valid, Cat subclasses Animal
    ( (Cat) a ).meow();   // invalid! A is of type Dog!
  14. We can use the “instanceof” operator to test to make sure that the object is of the correct type. For example:
    Animal a = new Dog(); // valid, Dog subclasses Animal
    if (a instanceof Cat)
    {
       ( (Cat) a ).meow();
    }
    else
    {
       System.out.println(“Error! Incorrect type.”);
    }

    “instanceof” compares an object with a data type
    If they match, the expression will evaluate to true. Otherwise it will evaluate to false.

  15. “instanceof” is safe to use and won’t throw an error in the even that an object does not match a particular type.

Day 18 Wrap-Up

download source code from Day 18 ]

download graphics source code from Day 18 ]

On day 18 we discussed how inheritance works in object oriented programming. Here’s an overview of what we covered:

  1. We started off by reviewing the “this” keyword and how it can be used to reference class variables and methods of an instance. You can also use the “this” keyword to pass a reference variable of one instance of a class to another. This essentially sends the current object as an argument to the second class, giving that class access to all of the public instance variables and methods of that class. We demonstrated this by using the “this” keyword to send an instance of a PApplet graphics canvas to a Java class so that the class could directly draw to the canvas. See the downloadable graphical examples above for a complete overview.
  2. Next we discussed object composition. As you know, instances of Objects can contain any number of data fields. For example:
    public class Planet
    {
    	double mass;
    
    	public Planet()
    	{
    	   this.mass = 1.0;	
            }
    }

    Objects can also contain references to other objects. For example:

    public class Planet
    {
    	double mass;
    	Satellite moon;
    	public Planet()
    	{
    		this.mass = 1.0;
    		this.moon = new Satellite();
    	}
    }
  3. We then designed a class that models a student. Students should be able to store their name and their student ID. Next, we designed a class that models a course. A course should store its name and an array of students. A course should be able to add students and display its roster. Here’s our code:Student.java
    public class Ex01_Student
    {
    
    	private String name;
    	private int studentID;
    
    	public Ex01_Student(String name, int studentID)
    	{
    		this.name = name;
    		this.studentID = studentID;
    	}
    
    	// getters
    	public String getName()
    	{
    		return this.name;
    	}
    	public int getStudentID()
    	{
    		return this.studentID;
    	}
    }

    Course.java

    public class Ex01_Course
    {
    
    	// instance vars
    	private String name;
    	private Ex01_Student[] students;
    	private int numStudents = 0;
    
    	// constructor
    	public Ex01_Course(String name)
    	{
    		// store our course name
    		this.name = name;
    
    		// create our array of students
    		this.students = new Ex01_Student[100];
    	}
    
    	// add students
    	public void addStudent(String n, int id)
    	{
    		// place this student into our array
    		this.students[ this.numStudents ] = new Ex01_Student(n, id);
    
    		// increase our total number of students
    		this.numStudents++;
    	}
    
    	public void printRoster()
    	{
    		// print our course name
    		System.out.println("Course: " + this.name);
    
    		// print our students
    		for (int i = 0; i < this.numStudents; i++)
    		{
    			System.out.println( (i+1) + ". " + this.students[i].getName() + " - " + this.students[i].getStudentID() );
    		}
    	}
    }

    CourseDemo.java

    public class Ex01_CourseDemo
    {
    
    	public static void main(String[] args)
    	{
    		// create a new course
    		Ex01_Course cs101 = new Ex01_Course("CS101 Section 01");
    
    		// add some students
    		cs101.addStudent("Smith, John", 12345);
    		cs101.addStudent("Jones,  Mary", 23456);
    
    		// print our roster
    		cs101.printRoster();
    
    	}
    
    }
  4. We then discussed class design guidelines. In general, classes should describe a single entity, and class operations should logically fit together to support a common purpose. For example, we could easily use the Student class that we just created to also store Faculty and Staff, but we probably shouldn’t – we should create new classes for these entities.
  5. Choose consistent programming style and naming conventions when designing your classes. Consistently provide public getters and setters when appropriate.
  6. Classes should try and use the private modifier to hide data when appropriate. This will help make the class easy to maintain, prevent tampering and cut down on logic errors.
  7. A variable or method that is associated with one instance of a class should be set as an instance variable or method. A variable or method that is not associated with any one instance should be set as a static variable or method
  8. Next we turned our attention towards the concept of inheritance. Classes that we design in Java can be used to model objects of the same type. For example:
    Pokemon a = new Pokemon();
    Pokemon b = new Pokemon();

    Sometimes we need to create new more “specialized” types that are similar to types we have already created. For example:

    Pikachu c = new Pikachu();
    Charmander d = new Charmander();

    In this case we would expect the Pikachu and Charmander types to have access to everything in the Pokemon type, but each one might have specialized functionality that goes above and beyond what the general Pokemon type can do.

  9. Object Oriented Programming lets us define new classes from existing classes. This technique is called “inheritance” and can be used to help you make your code more re-usable, avoid redundancy, and simplify maintenance of your software.
  10. Here is a simple demo of inheritance in action – in this code the Pikachu class inherits some class varialbes and methods from the Pokemon class.
    public class Pokemon
    {
    public String name;
      public char type;
      public int hitPoints;
    
      public String getName()
      {
         // implement
      }
      public char getType()
      {
         // implement
      }
      public int getHitPoints()
      {
         // implement
      }
      public void setHitPoints(int p)
      {
         // implement
      }
    public class Pikachu extends Pokemon
    {
    public int power;
    public void shock()
      {
         // implement
      }
      public void thunder()
      {
         // implement
      }

    The “extends” keyword tells Java that a class should inherit methods and class variables from another class. A class in Java can only inherit from one other class. The class being extended (i.e. Pokemon) is called the “superclass” and the class doing the extending (i.e. Pikachu) is the “subclass”. See the downloadable code examples above for code samples that show this technique in action.

  11. The “private” modifier prevents an instance variable or method from being directly accessed from outside the class. This also extends to subclasses – the private modifier will prevent a subclass from directly accessing a field or method.
  12. The “protected” modifier allows you to define a field that is inaccessible from outside the package that a class exists in (like the private modifier). However, the “protected” modifier does allow subclasses to directly access these fields as though they were public.