User Tools

Site Tools


at-m42:lecture4

~~SLIDESHOW~~

Simple IO and a Case Study

Simple input and output and introduction of the case study.

The slides and notes in this presentation are adapted from Groovy Programming (See Recommended Reading).

An index to the source code for all the examples in this lecture is available.

Simple IO

Console input and output is not part of the Groovy language. Nonetheless, real programs need to communicate with their environment.

  • to produce text output in Groovy we use:
print xxx       print(xxx)
println xxx     println(xxx)

The methods print and println are used to display the value concerned (denoted by xxx). The value may represent a String literal, a variable or expression, or an intepreted String. Method print outputs its value, and any further output appears on the same line. Method println advances to the next output line after displaying its value. Java programmers will be interested to observe that print and println are actually calls to System.out.print and System.out.println respectively. Parenthesis are optional.

Simple output

1 | Example 1: Simple output (at-m42/Examples/lecture04/example1.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/example1.groovy

Example 1 demonstrates how to print a simple String literal using the print and println methods.

When the groovy script is executed, the output is:

My name is Chris.
This is my first program.
Isn't this fun!

Lines 2 and 3 are responsible for the first line of output. Method print displays its parameter on the console (standard output). any further output continues on the same line. The simple method call println() prints a line break (new line). Note how the value parameters may optionally be encosed in parentheses.

Printing numbers

1 | Example 2: Printing numbers (at-m42/Examples/lecture04/example2.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/example2.groovy

From lecture 2, we know that Strings enclosed in double quotes are interpreted, and any ${expression} is evaluated and becomes part of the String. Example 2 shows this at work with some integers.

The output from running this script is:

My age is: 49
My age is: 49

Printing lists and maps

1 | Example 3: Printing lists and maps (at-m42/Examples/lecture04/example3.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/example3.groovy

We can also print the contents of a List or a Map. Example 3 shows how we use the same scheme as already cited.

The output is:

numbers: [11, 12, 13, 14]
staff telephones: [Chris:5580, Joe:5582, Tim:5583]

Formatted output

Formatted output is achieved with the printf method call. The formal description of printf is:

printf(String format, List values)

Example

l
//Simple formatted output
printf('My name is Chris', [])
printf('my name is Chris\n' [])

The printf method prints its values to the console. The values are any expressions representing what is to be printed. The presentation of these values is under control of the formatting string. this string contains two types of information: ordinary characters, which are simply copied to the output, and conversion specifications, which control conversion and printing of the values.

Two examples of printf are shown in the slide. in both examples, the List of values to be printed is empty. The format string comprises ordinary characters. The first printf method call (line 2) displays its format String. Further output continues on the same output line. The second example (line 3) includes the escape character \n, representing a newline. Any output after that will begin on the next line.

The expression on line 2 is equivalent to print 'My name is Chris'. The expression on line 3 is equivalent to println 'My name is Chris'.

Conversion specifications

1 | Example 4: Formatted output (at-m42/Examples/lecture04/example4.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/example4.groovy

In these examples, we include a list of values. The format string then includes conversion specifications for each of the values. The conversion specifications are introduced by the percent (%) character. In the first example (line 6), %d denotes printing an integer value. In the second (line 11), the %f is used for printing floating point values.

The output is:

The sum of 10 and 15 is 25
56.780000 from 1.234000 gives -55.546000

Lines 14–16 illustrates using the %s conversion to print a String. In all three examples, the output string is enclosed in [ and ] to reveal the effect of the conversions. We see that %s simply outputs the string. The conversion %20s outputs the string right justified in a field of 20 characters. The conversion %-20s left justifies the output.

The output is:

[Hello there]
[         Hello there]
[hello there         ]

A more detailed discussion of the conversion specifications is available.

Simple input

1
// Get an input reader
def input = new BufferedReader(new InputStreamReader(System.in))
 
print "Please enter your first name: "
def name = input.readLine()
println "Hello ${name}!"

The object in in the Java class System represents the standard input. unfortunately, it is an InputStream and is not designed for text input. To make it usable for text input, it has to be wrapped in an InputStreamReader which itself has to be buffered using a BufferedReader. This arcane formula, shown on line 2 in the slide, is required to enable console input from the keyboard. Once we have the BufferedReader input we can use the method readLine to get a line of text from the keyboard and return it as a String.

Inputting data values

def a = input.readLine().toInteger()
def x = input.readLine().toDouble()

Method readLine returns a String value. In Java/Groovy there is no equivalent to C's scanf. Instead, we can use the method toInteger on the String to convert it into an integer value or toDouble to convert it to a floating point value.

In Example 5, below, we define three helper methods to make it easier to read a String, Integer and Double from the console. We have to pass in the BufferedReader input as an argument in order to enable the method to access the input. The methods toInteger and toDouble expect that the input String be correctly formatted with no unexpected characters and no leading or trailing spaces.

1 | Example 5: Simple input (at-m42/Examples/lecture04/example5.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/example5.groovy

Note Scripts with keyboard input cannot be run inside the groovyConsole. Instead you have to run it from the windows command line using groovy example5.groovy. If you run the script this way, the output is: <html> <pre>

e:\dev\at-m42-2009\Examples\lecture04><b>groovy example5.groovy</b>
Please enter your first name: <b>Chris</b>
Hello Chris!
Please enter your surname: <b>Jobling</b>
Please enter your age: <b>49</b>
Please enter your weight in kg: <b>100</b>
Hello Chris Jobling: your age is 49 and you weigh   100.00 kg

</pre> </html>

The Console class

package console
 
class Console {
  def static readString() { ... }
  def static readLine() { ... }
  def static readInteger() { ... }
  def static readDouble() { ... }
  def static readBoolean() { ... }
}

The methods readString, readInteger, etc. are very useful and will find uses in other examples to come. They have been collected as a set of static methods in the the class Console that can be imported into other examples. The code for the Console class is provided in the source-code download in <at-m42\src\lib\console\Console.groovy>.

The methods of class Console tokenize the input, so that for example, leading whitespace on an integer value is ignored by method readInteger. Example 6 shows the use of these methods to reimplement Example 5.

1|Example 6: Input using the Console class (at-m42\Examples\lecture04\example6.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/example6.groovy

To use Console you have to ensure that at-m42\src\lib is on the CLASSPATH for your project. Let us say that you download the example code and install it at h:\work\at-m42. To set the classpath, open the windows command window and type: <cli prompt='>'> h:\work\at-m42> set CLASSPATH=h:\work\at-m42\src\lib;%CLASSPATH% </cli> If the classpath is set properly, Example 6 should run ok.

Case Study: An Adventure Game

This part of the lecture module will illustrate how Lists and Maps might be used in practice. For this first case study we construct a simple model of the items in a text-based adventure game. More elaborate solutions are presented in the case studies.]

  • For the first iteration we use a List to define players in a location.
  • For the second iteration we use a Map to make a more elaborate implementation.

The iterative approach illustrated here is in keeping with modern practice

Iteration 1: Specification

  • A text-based adventure game maintains a record of items being carried by its players.
  • Each item is known by its name and each player by his/her name.
  • The database of items being carried could be represented in a number of ways.
  • We will use List and Map.

Iteration 1: Using a List

  • The game is represented by a List
  • Each element in the List is another list of two elements:
    • the player's name;
    • an item that the player is carrying.

Iteration 1: List Implementation

1
def dng = [ ['Chris', 'Sword'],
                ['Chris', 'Food'],
                ['Jenny', 'Dagger']
              ]

The List dng (dngs and Dragons) is a list of three elements, each of which is a list of two elements. The first shows that player Chris has a Sword and the second also that he has Food. The third states that Jenny has a Dagger.

Adding a new item

dng <<['Jenny', 'Food']
dng.add(['Joe', 'Magic Wand'])

Printing a location

println "dng: ${dng}"

A simple adventure game

The attached code (listed in the notes) produces the following output:

dng: [[Chris, Sword], [Chris, Food], [Jenny, Dagger], [Jenny, Food], [Joe, Magic Wand]]
Player Chris has a sword? true
Number of items in the dng: 5

l|Case study iteration 1: Adventure game location with List (at-m42\Examples\lecture04\casestudy1.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/casestudy1.groovy

We can determine if Chris has a sword with

dng.contains(['Chris', 'Sword'])

and determine the number of items being carries by players in the location with;

dng.size()

Iteration 2: Using a Map

  • Each location is represented by a Map
    • Each key in the Map represents a player;
    • Each value in the Map is a List of the items that the player is carrying.

Iteration 2: Map Implementation

1
def dng = [ 'Chris':  ['Sword', 'Food'],
                'Jenny': ['Dagger']
              ]

in this revised implementation we associate a list of items with a player in a location. The key is the player's name and the value is a List of items being carried. Here is the code to initialise the location dng. The result is a Map with two entries. The first has player Chris as the key and an associate value which is a list of items that Chris is carrying. The second entry records that states that Jenny has a Dagger.

Adding items

1
// add a new player
dng['Joe'] = ['Magic Wand']
 
// update an existing player
dng['Jenny'] = dng['Jenny'] << 'Food'

We can add a new player and his items to the game as shown in line 2. To update a player's items we have to be careful to add to the player's items rather than over-writing the values as shown in line 5.

Location queries

1
def hasSword = dng['Chris'].contains('Sword')
def nPlayers = dng.size()

As with the List implementation, we can determine if Chris is carrying a particular Item with the code shown in line 1 in the slide. We can also determine the number of players in the room as shown in line 2.

More Queries

l
def players = dng.keySet().sort()
def carriedItems = dng['Chris'].size()

Line 1 in the slide obtains the players' names and presents them as a sorted list. Line 2 determines how many items Chris is carrying.

Putting it all together

The attached code (listed in the notes) produces the following output:

dng: [Chris:[Sword, Food], Jenny:[Dagger, Food], Joe:[Magic Wand]]
Player Chris has a sword? true 
Number of items in the dng: 3
Players: [Chris, Jenny, Joe]
Number of items being carried by Chris: 2

l|Case study iteration 2: Adventure game location with Map (at-m42\Examples\lecture04\casestudy2.groovy)
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture04/casestudy2.groovy

We can determine if Chris has a sword with

dng.contains(['Chris', 'Sword'])

and determine the number of items being carries by players in the location with;

dng.size()

Summary of this Lecture

Simple input and output and introduction of the case study.

Lab Exercises

at-m42/lecture4.txt · Last modified: 2011/01/14 12:45 by 127.0.0.1