Running
[Agent practical 9 of 9]


Now let's look at getting hold of those arguments we're so eager for.


We'll need to adjust our main to pass the args to the constructor, and adjust the constructor to receive them. If we get any command line arguments, we'll want to just set up and run the model, rather than building the GUI, so our structure for the key elements of the code wants to look like this:

public Model (String args[]) {

   if (args.length == 0) {

      buildGui(); // All that was in our constructor previously!

   } else {

      numberOfAgents = Integer.parseInt(args[0]);
      numberOfIterations = Integer.parseInt(args[1]);
      eatingRate = Double.parseDouble(args[2]);
      fullUp = Double.parseDouble(args[3]);
      String fileIn = args[4];
      String fileOut = args[5];
      File fIn = new File(fileIn);
      File fOut = new File(fileOut);

      world.setData(io.readData(fIn));
      setSize(world.getWidth() + getInsets().left + getInsets().right,
        world.getHeight() + getInsets().top + getInsets().bottom);
      buildAgents();

      runAgents();

      io.writeData(world.getData(), fOut);

   }

}

public static void main (String args[]) {

   new Model(args);

}

Again, the fact that we've separated our code into methods means that we can pick-and-mix how we set those methods running. In the absence of any command line arguments we can run a GUI, while in their presence we can just run the model without one, doing all the actions a user usually would.

Note also the use of the primitive wrapper classes like Integer to do the conversion from Strings. Ideally we'd not only put try-catch blocks around these (catching the Runtime Exception NumberFormatException, which is thrown when a String doesn't represent a number, and reporting format issues to the user) and we'd test whether we had the right number of arguments, reporting to the console when we don't. It is common in such cases to use the err (error logging) stream, rather than out, though for most people both will appear at the console:

System.err.println("Usage: java Model numberOfAgents numberOfIterations eatingRate fullUp fileIn fileOut");

Anyhow, to keep the code clear for the moment, we'll leave these elements out. Here, as promised, is a new version of Model.java and Nibbler.java that implements these changes:

Download them to your directory for this practical.


To test the new code, compile it and first run it with the GUI to check nothing is broken. Then, type (or cut-and-paste) the following into the command line and run the code. You'll need to make sure you have a copy of our in.txt in the same directory as your code.

java Model 10 3360 1 120 in.txt out.txt

Hint: if you want to see the results in the "out.txt" file, you should be able to open it with the Model run with a GUI as the output and input files have the same format.


So, this is all terrific fun, but where does it get us? If we wanted to allow the user to set up the model, aren't we better off spending our time developing these options in the GUI?

Well, this would certainly be a good thing to do (we haven't here, as we have limited time, but there's plenty we could do). However, the real power of retaining a command-line option is that we can run our model in batches -- running the model several times with different arguments. The usual way of doing this is with a shell script, that is, a file written in the language used by the operating system ("OS": Windows, Linux, etc.) at the command line. Most OS come with some kind of command line scripting languages -- indeed, most come with several. For Windows, we can write a script using the language of DOS, the old command-line operating system that used to underlie most of Windows. To do this, we write a sequence of commands in a "Batch" file, with the extension ".bat" (intro; intro2; detailed tutorial, plus info on setting variables). Here's an example that will also work on most other operating systems:

Model1.bat

and here's one that's a *bit* more sophisticated, so wouldn't: Model2.bat

On a Mac, etc., you could write something similar using bash scripting. On newer versions of Windows you can also write in Powershell script, but this requires some permissions setting up, so most people still use DOS.

To run a batch script, download it to the directory with your compiled code in it, and type the name of the batch script at the command line (with Windows you can miss off the ".bat"). The batch file will then run the commands in it. Give it a go with the new code.


So, shell scripts allow us to run our command line model easily and multiple times. We could use this, for example, in Monte Carlo sensitivity testing, where we want to run our model with potentially thousands of slightly different arguments. Indeed, we could get a Java program to write an appropriate bat file for us (if you've had the lecture introducing Monte Carlo sampling, there's code for doing the sampling on the associated webpage).

However, for more sophisticated jobs, for example calibrating our model, we may have to codeup something that runs the model and analyses the results entirely in Java. Having the option for command line arguments still helps us with that. Let's have a look.