Ryan Rampersad's Chronicles
an retired blog of thoughts, opinions, ideas and links
  • About
  • Podcast
  • Links

Archives

More On Shuffling An Array Correctly

I wrote on how to shuffle an array in Java nearly four years ago. Since then, it has come to my attention that the algorithms presented in that original post are wrong and definitely incomplete. Commenter Ken Arnold pointed this out and I was very curious to see some data on the variability of randomization using the original algorithm, his modified version and another powered my the built in Collections shuffle method in Java.

This all pertains to the randomness of cards and specifically the distribution of cards when shuffled from a fresh deck. Following that, any state after that initial shuffle is harder to predict but it may still be predictable. You can view the original algorithm defined in the original post from Leepoint. However, while this example is clearly defined in the context of cards, it is not strictly deck-card based – if you need to randomize any set, using that original algorithm probably will not yield the results you are looking for. You will see why soon.

The modified version runs along these lines.

public static int[] getOriginalShuffledDeck() {
  Random rnd = new Random();
  int[] cards = new int[52];
   
  for (int i = 0; i < cards.length; i++) {
    cards[i] = i;
  }
  
  for (int i = 0; i < cards.length; i++) {
    int position = i + rnd.nextInt(cards.length - i);
    int temp = cards[i];
    cards[i] = cards[position];
    cards[position] = temp;
  }
  return cards;
}

Aside from the minor stylistic differences, the major logical difference is the in the declaration of the position. The i + rnd.nextInt(cards.length - i) changes the position properly, so that elements are not repeatedly moved around the deck of cards. I am not entirely sure of the logic here – an example chart could be useful, but I’ll leave that to you.

The other algorithm I tested against was the built-in Collections.shuffle randomization. It appears that this method is consistent with the modified method above, which is good to know. Because there is a lack of shuffling for a regular non-object array, there is a cumbersome conversion between Integer objects and an ArrayList and then back to regular ints.

public static int[] getCollectionsShuffledDeck() {
  int[] cards = new int[52];
  ArrayList<Integer> cards_objs = new ArrayList<Integer>(); 
  
  for (int i=0; i < cards.length; i++) {
     cards_objs.add(i);
  }

  Collections.shuffle(cards_objs);
  
  for (int i = 0; i < cards.length; i++) {
    cards[i] = cards_objs.get(i);
  }
  
  return cards;
  
}

With those three methods, I ran a test with each. I ran one million iterations of randomizing fresh decks of cards. I recorded each position (position 0 to 51) and each card in those positions (card 0 to 51, because we don’t actually care which card, just that they’re all uniquely identifiable) and the number of times they appeared in those million trials. So without further ado, look at the astoundingly poor randomness generated by the original algorithm.

The Original Method

The spikes are where there is an obvious failure. I am definitely not a statistician but I can guarantee this is not a great distribution of what is supposed to be random values, especially when the number of trials is so high. With that said, I think it is quite clear that the original method of randomizing a deck of cards is flawed. Now, that’s not to say it is not random, since there is some randomness there, but just not enough. Now, on to the modified method’s chart.

Modified Random

The distribution here is much better. It just so happens that one million divided by 52 is approximately 19230, which is what most of these position-card indexes reach. Clearly, the modified version is better in this case.

The Collections.shuffle random was about the same. This is a great benefit of using the built in routine because you know that this way, it will always be random with that great low variance. That’s not to say there aren’t highs and lows in these two data sets, but it is lesser than the original. I want to be clear though: this may seem at first limited to strictly a card-deck problem but this could present itself anywhere that something starts ordered and needs to be non-ordered after some operation. You may need to randomize your genome project, your particle layout or maybe even your favorite file cabinet.

You can grab the testing program and the excel file for the raw data used to make the charts.

Update: You can read an interesting Stack Overflow question on, “Is Collection.shuffle random enough?“

Java: the left-hand side of an assignment must be a variable

After programming in Scheme for months, going back to Java can cause some problems as you can imagine. I encountered this error a few days ago while writing just the simplest searching loop.

public static void main(String[] args) {
	int[] arr = new int[] {2804, 2374, 6382, 1899};
	
	int index = 0, largest = arr[0];
	for (int i = 1; i < arr.length; i++) {
		(if largest > arr[i]) {
			index = i;
			largest = arr[i];
		}
	}
}

It’s your typical searching for the largest value loop. It’s nothing special, but then again, it doesn’t work.

At least the error message is logical. No, not really.

the left-hand side of an assignment must be a variable

By studying very carefully and fully realizing that I am still in scheme mode, I notice that there is a parenthesis before the if-statement instead after the if keyword itself. Had I been helping someone else with this code and they showed me that error message along with this, would I have known it was a misplaced parenthesis? No way. I’d eliminate one possibility at a time by removing each successive layer of expressions and assignments until it stopped. I might even go so far as to retype the entire thing. It’s subtle.

It also turns out that if you try to assign a value to a method, you’ll cause this error too.

Happy language switching!

Java: syntax error on token “else”, delete this token

Before school ended, I donated some of my time to helping out the Intro to Java kids. In that class, I realized that when you tell beginning programmers “End each line with a semi-colon,” they think you really mean it. As in, every single line with actual code (e.g. not brackets) must end with a semi-colon. Well, it’s sad news but that is not true. Not every line needs a semi-colon.

Here’s an example. Look at this code. I dare you even to try running it. You’ll end up with an error.

public static void main(String[] args) {
	int magic = 10;
	if (magic < 20);
	{
		System.out.println("weak magic");
	} 
	else
	{
		System.out.println("strong magic");
	}
}	

The error is of course, uncommunicative of the true problem. Did you spot the error yet?

syntax error on token “else”, delete this token

The problem here isn’t the else or even the if. No, the problem is a semi-colon. Seriously. Take a look at the if-statement expression. The oddity comes about when you actually see the semi-colon attached to the end of it. And because the if-statement ended there, the else has no preceding pair so it has no choice but to error out.

This example is actually a clear cut case of putting a semi-colon after an if-statement expression. Imagine you didn’t have an error to remind you what you just did. You might just have a plain statement and proper following brackets.

public static void main(String[] args) {
	int magic = 10;
	if (magic < 20); {
		System.out.println("weak magic");
	}  
}

Without the else to throw an error message up, how easy would this be to spot? It’s tricky. What if your if-case was a rare edge case condition that you were hard pressed to demonstrate in testing but you theoretically knew it existed? You’d almost never know this wasn’t work until your nuclear reactor began to melt down.

The moral of story: kids will do what you tell them and mind you semi-colons at the end of constructs.

Java: Duplicate local variable

It’s usually easy to catch errors in Java, either through the IDE you’re using or at compile time. Recently, I helped a friend taking a course in Java with an error he was getting in a lab he was working on. It mentioned something about a duplicate variable.

Duplicate local variable

Unfortunately, I didn’t grab his erring source code earlier, so I can’t give the true real world source. Nevertheless, my own crafted code should illuminate the problem sufficiently.

public static void main(String[] args) {
	
	int magic = 10;
	if ( 10 < 11 ) {
		int magic = 12;
		magic++;
	}
	
}

Imagine you had a variable declaration and initialization at the top of some method. Then later you attempt to create another variable with the same name as before, but inside of a construct like a for loop or if. Unwittingly, you have attempted to redeclare an already declared variable.

Why doesn’t the IDE or compiler know that it’s a syntax error in that case, and that you obviously cannot redeclare variables? Java’s just funny like that, but I suspect it has something to do with the scoping rules in Java. The magic variable inside of the if-statement should be separate, and it is telling you it’s a duplicate, not that it isn’t allowed. So I suppose that’s helpful.

In short, the easy fix is to rename the inner-conflicting variable. So the magic that’s in the if-statement could be magic2 and anything that references it in the if should also be updated. That’s clear enough. The other possibility is to remove the int declaration. Imagine you were simply setting value instead of declaring. It’s an easy mistake to make, especially when you’ve a bunch of declarations repeated.

Happy deduplicating!

Correct Change in Java

When I was a freshmen in high school, one our earliest programs was to find the correct change for some number of cents. I remember when I wrote that first program, I did it an atypical way and got some strange looks. Instead of using nested modulus like everyone else, I used integer division and then subtracted out the difference from a running total.

Years later, I thought it would be cool to redo that program and it certainly was fun. I used the same methodology in fact, but with a couple of optimizations.

I start the program off by creating a Scanner object for user input and a prompt.

Scanner scanner = new Scanner(System.in);
System.out.println("Enter some amount in cents: ");
int cents = scanner.nextInt();

Then the optimizations kick in. There is a denominations array, which has a list of coin values, from 1 dollar, a quarter, a dime, a nickel and finally a penny.

int[] denominations = { 100, 25, 10, 5, 1 };

One of the original requirements of the program was that the amount of coins needed must be in their proper plurality. I can do this easily by having a two dimensional array of strings that store both forms of each word. You might ask, why not just attach an extra s to the end if it’s plural? Well, penny doesn’t turn into pennys.

String[][] terms = { { "dollar", "dollars" },
        { "quarter", "quarters" }, { "dime", "dimes" },
        { "nickle", "nickles" }, { "penny", "pennies" } };

The program will spit out values for each of the denominations listed, so it will contains dollars, quarters and so on and it’s store in this values array.

int[] values = new int[denominations.length];

I use a rolling total to keep track of how much change is left over still.

int rolling = cents;

The magic happens in the for-loop. It’s completely standard, initialized to 0, counting towards the length of the denominations array and incrementing by 1.

for (int i = 0; i < denominations.length; i++) {

The calculations happen in the next section. Basically, the denomination integer pulls the proper value from the denominations array. Then, the value in the values array is set to the integer division of the rolling total and current denomination. Finally, the rolling value is truncated by the denomination by modulus.

    int denomination = denominations[i];
    values[i] = (rolling / denomination);
    rolling = rolling % denomination;

To pick the proper singular or plural, the value is checked against being 1. Keep in mind that values of fractions are indeed plural. You have .1 dollars, e.g. ten cents, or a dime.

    String term = (values[i] == 1 ? terms[i][0] : terms[i][1]);

Finally, there is the printing logic which always gets in the way. I certainly wish there was a better way, but this was the best I found. Basically, by counting up until the last value, I print without a new line the value and then the matching proper term, and when it reaches the last value, I print an and, value, term and finally a period.

    if (i < (denominations.length - 1)) {
        System.out.print(values[i] + " " + term + " ");
    } else {
        System.out.println("and " + values[i] + " " + term);
    }

Here’s a short sample run with different amounts of cents.

Ryans-MacBook-Air:APCS3 ryanrampersad$ java CorrectChange
Enter some amount in cents: 
119
Your change is: 1 dollar 0 quarters 1 dime 1 nickle and 4 pennies.
Ryans-MacBook-Air:APCS3 ryanrampersad$ java CorrectChange
Enter some amount in cents: 
169
Your change is: 1 dollar 2 quarters 1 dime 1 nickle and 4 pennies.
Ryans-MacBook-Air:APCS3 ryanrampersad$ 

I remember when I wrote this program four years ago. This program is 35 lives with a bunch of whitespace. My code from youth was probably more like 70 lines. As you code, you mature. As you read others’ code, you mature too. Experimenting is the best way to grow. You can of course download the full source code.

Happy counting.

Multiplication Table in Java

One of my friends came to me the other day asking I could help out with the logic for printing a multiplication table out. Go back to those days in second grade when you were learning all the combinations of small numbers from 1 to 12 for multiplication products. That was a long time ago. Quick, what’s 7 times 9?

Anyway, printing out a multiplication table like this one isn’t too hard.

x	1	2	3	4	5	
1	1	2	3	4	5	
2	2	4	6	8	10	
3	3	6	9	12	15	
4	4	8	12	16	20	
5	5	10	15	20	25	

Let’s think of the logic behind this. In the first row, we have the X value, so it counts from 1 up to Xmax. In the first column, we have the Y value, so it counts from 1 up to Ymax. It is duly noted that the table only has a X listed, but that’s for simplicity, though there is a X and a Y, horizontal and vertical.

In the next row, where X is 1 and Y is 1, we have simple multiplication, 1 times 1, so the value is 1. In the second row and column we have the same numbers as the first row and column because of that by 1 multiplication. Now, we’ll take a look at some code.

public static String getNumber(int i, int j) {
	int value = i * j;
	
	if ( i == 0 ) {
		value = (i+1) * j;
	} else if ( j == 0 ) {
		value = i * (j+1);
	}
	
	if ( i == 0 && j == 0 ) return "x";
	else return value+"";
}

So let’s break this down. You have a value which is obvious in its purpose: it’s the resultant multiplication of some row and some column. Then things get complicated. Since we’re, what? Either computer scientists or insane, we count from zero. Counting from zero makes us think about out logic.

If you’re in the first row, you’ll need to print out what would be the next row. What? Imagine you’re making a table for 5 by 5. You’ll need 1 2 3 4 5. How do you get that? You multiply the column value by 1. But you only want this to happen naturally in the first row (which is actually the zeroth row by our zero-count). And we’ll need the same for the columns going down. So that’s what happens in that first if-else-if stack. If i or j is 0, then it will be temporarily incremented by 1 and it’ll print out the proper rows.

The the if-else stack at the end of this statement is pretty easy too. The if-statement checks to see if i == 0 && j == 0, or if i and j are equal to zero, it will return the X that is the first value in the table. If that condition isn’t true, then it’ll print out either the regular i * j value or the specialized first row/column value.

Now we’ll need a loop.

	for (int i = 0; i <= height; i++) {
		for (int j = 0; j <= width; j++) {
			System.out.print( getNumber(i, j) + "\t" );
		}
		System.out.println("");
	}

This is a nested for-loop. The outside loop will handle the rows (e.g. the height) and the inner loop will handle the columns (e.g. the width). There is a method call to the getNumber with arguments i and j, and a printout that has getNumber and appends a tab character at the end. Finally, in the outside loop, when the inner loop is done running, a newline is printed so that the next row will begin to form.

The logic for this type of program is an exercise in looping and conditional logic with index values. You can grab the source code here.

Happy multiplying.

Find the Index of Largest Array Element in Java

Finding the index of the largest element in an array is relatively easy. I remember seeing a couple free response questions in the AP Computer Science Exam that involved this type of problem too, so it’s good to know.

You’ll need an array full of numbers, those could be integers, doubles, longs, whatever, as long as it is comprised of a number. My solution uses two data keeping variables, largest and index. The largest variable will keep track of the biggest value in the array while the index variable keeps track of where the largest value was found.

Optionally, I like to set the largest and index variables before I start any testing. largest is set to array[0] and index is set to 0 so that we can skip that initial value.

int[] array = {29, 42, 1, 32, 44, 49, 0, 13, 43, 30};
int largest = array[0], index = 0;
for (int i = 1; i < array.length; i++) {
  if ( array[i] > largest ) {
      largest = array[i];
      index = i;
   }
}

This will set index to 5 because 49 is the largest in the array.

If there had been two instances of 49 in the array, which would have been returned? The first one as the code stands. To change it, one would simply have to change the conditional from greater than to equals or greater than.

int[] array = {29, 42, 1, 32, 44, 49, 0, 13, 43, 49};
int largest = array[0], index = 0;
for (int i = 1; i < array.length; i++) {
  if ( array[i] >= largest ) {
      largest = array[i];
      index = i;
   }
}

This would set index to 9 because 49 is the last largest in the array.

Wouldn’t it be nice of Java had a method that did this for you? Like: Arrays.largest or Arrays.smallest which would work for primitive numeric values. Simple and obvious.

Happy indexing.

Java – Failed to download required installation files

Have you ever been watching a movie and Windows will throw its UAC screen up busting you out of full-screen during your movie alerting you that Java has an update? It’s happened to me.

So you relent and you take it upon yourself to be diligent and actually update Java, you tell UAC it’s fine and to proceed. And then the Java installer comes up asking you to accept some terms of service before the update is downloaded and installed. But then. This.

Java - Failed to download required installation files

Now what? What can you do? The little Java icon in the task tray is gone and it won’t pop up again for a few hours. There is no solution to this problem, except for downloading the new version of Java directly. Or you can wait again until the prompt comes back up. That’ll work too.

APCS FRQ Soon!

Over the next few days, I’ll be pushing out my answers to this year’s free response questions from the AP Computer Science exam last week, just like last year.

Free Response Links

  • FRQ #1: Sound
  • FRQ #3: FuelTanks & FuelRobot
  • FRQ #4: Encryption

I may or may not cover FRQ #2: GridWorld. If anyone else has posted about it, leave a comment with a link.

AP Computer Science Green Packet

The infamous APCS Green Packet!

I’ll update the series of posts so they all have links to the other problems. Good luck on any other AP/IB tests!

Needle and Haystack in Java

For a little assignment, I needed to count the number of particular characters in a string and return the number. This is painfully trivial in a language where arrays have a contains method. In java however, it’s not as simple.

	/**
	 * Counts the number of occurrences from a char array in a string.
	 * 
	 * @param needles An array of characters that should be counted in the string.
	 * @param haystack A string that should be searched in.
	 * 
	 * */
	private int count(char[] needles, String haystack) {
		int counter = 0;
		for (char c : needles) { // Loop through each character needle.
			for (int i = 0; i < haystack.length(); i++) { // Loop through each character in the string.
				char v = haystack.charAt(i);
				if ( c == v ) counter++; // If they're equal, increment the counter.
			}
		}
		return counter;
	}

Breaking that down, basically you have a character array of needles – things you want to find in the string. The second argument is the string where the searching takes place. There’s a counter set to zero, then we foreach through a single char at a time. Then there’s another loop, a for loop this time, so that it can increment properly so the haystack can use charAt. Finally, a comparison is made and if it’s true, it increments the counter.

That’s cool then. In action, it’s effortless.

	private int numberOfVowels(String input) {
		char[] needles = new char[]{'a','e','i','o','u'};
		int count = count(needles, input);
		return count;
	}

An array of characters goes in as needles and some input string is thrown in and out comes the number of characters. It’s a good demonstration of loops of different natures and selective counting.

Happy counting.

Download 64-bit Java

At home I use only 64-bit versions of Windows 7. At school, my laptop remains the original 32-bit install. Despite that, I use the 32-bit version of Java at home (and everywhere else) because it is just so easy to get.

However, the 64-bit version does offer some enhancements. On every computer I compare with, the x64 Java is always 30% faster. I think everyone agrees that Java needs to be faster. Only the 64-bit version of Java will work with the incredible x64 Eclipse.

Java.com’s explanation of whether or not to download the x64 version is kind of silly as it focuses on if you use Internet Explorer.

If you’re looking for the 64-bit version of the JRE or the 64-bit version of the JDK, you can find those at the Java SE Download page.

Of course, if you download either of the x64 Java packages, you’ll need to update your enviroment variables, probably. You may also want to checkout which version is right for you.

Delete an Element in an ArrayList – Java

Adding elements to ArrayLists is an easy procedure. Assuming you have an ArrayList<Kitten>, adding is as easy as kittens.add(new Kitten("Bob")).

Deleting elements from the list is not quite as simple. For instance, let’s pretend our previously Kitten named Bob needed to removed from the list. How could you remove that object from the list?

There are two methods – a just-okay-way and a clever way. Let’s start with the former.

Basically, you could loop through the list of elements and compare each object to a known property you’re looking for. In your application, probably for displaying the list, you might already have a portion of code dedicated to search and sorting your array of Kittens.

String searchFor = "Bob";
int remove = -1;
for (int i = 0; i < kittens.size(); i++) {
  if ( searchFor.equals(kittens.get(i).getName()) ) {
	remove = i;
	break;
  }
}
if ( remove != -1 ) kittens.remove(i);

This method relies on getting an index by a known property. It works and does it’s job well and of course, it’s implementation is clear.

The other method assumes a different scenario. If you already have a reference to the object in question, you can easily go down the clever route. In what situation do you already have the object? As I mentioned before, you probably already have a method to search your list of objects. I admit, it’s probably very similar to the method presented above as far as searching goes, but if you have the reference to the object, you can do this.

Kitten k = new Kitten("Bob");
kittens.add(k);

// ... later

int index = kittens.indexOf(k);
if (index == -1 || index > kittens.size())
  {/*do nothing in this case; print an error maybe*/}
else
  kittens.remove(index);

Confused? I include the code to create the Kitten called Bob, and to add him to the list. Later, probably in another method somewhere, or maybe in a conditional, with a reference called k, is being removed. Instead of using yet another loop to compare each object to the known property, just the fancy indexOf method to get the index that matches the particular object. A test is there to make sure nobody goes out of bounds and that the element does in fact exist. Otherwise, the element is deleted in the same way.

Deleting elements in ArrayLists isn’t hard but it can be conceptually annoying to have to loop multiple times or to pass around indexes.

Happy deleting.

Prepopulate Data Files – Java

Sometimes an application needs some data to start. Applications written like this often supply some initial data so that it appears seamless to the user. It’s pretty easy to do this in Java.

To get started, make a class called Setup. This name is good because that’s what’s happening – the program data files are being setup. After that, there’s some basic properties that need to be made: a folder location and the initial data.

	public static String location = "app-data";
	
	// files,data
	public static String[][] files = new String[][] {
		{"people.txt",
				"Ryan Rampersad|18|M|Minnesota|55105\n" +
				"Brian Reinhardt|50|M|Minnesota|55104\n" +
				"Gill Bates|55|M|California|90840\n"
		},
		{"gadgets.txt",
				"iPod touch|Google Laptop|HP Laptop|Android Phone|Kindle\n" +
				"iPad 1|MacBook Pro|iMac\n" +
				"Zune HD Ultimate Signature Editon\n"
		}
	};

This sets a specific folder so the data files can be in a safe and separate place from the rest of the application. The 2-dimensional string array is where the magic comes in. While there may be better ways to do this, this method works decently for small applications that depend on some initial data being present upon first run. The first item in each array is a data file’s filename. The second item in each array is a concatenated string contained data to be parsed out and worked with. In this example, I list people in the first data array and then their gadgets in the second data array.

Now a little private method that does some heavy lifting.

	private void create(String path, String data) throws Exception {
		BufferedWriter bw = new BufferedWriter(new FileWriter(path));
		bw.write(data + "\n");
		bw.close();
	}

Here’s what happens. This method will be called and given as arguments the path of the file to be created and then the concatenated data. All this does is make a file with data. Easy, right?

The next method needs to be broken down into discrete parts. It’s long and arduous but you’ll manage. Try not to get confused between the create method above and this aptly named created method.

	public boolean created() {
		boolean created = false;
		File d = new File(location);
		if (!d.exists()) {
			created = true;
			d.mkdir();
		}
// continues ...

This method will check each file in our files 2D string array and do a couple of other cool things. First, a flag is setup. This glad gets set to true if something is ever created whether that’s the directory where the files are stored or a file itself. Then a File object is constructed. That object is used to see if the location directory exists. If it doesn’t, it’ll be created.

for (String[] file : files) {
			String filename = location + file[0];
			File f = new File(filename);
			if (!f.exists()) {
				created = true;
				try {
					f.createNewFile();
					this.create(filename, file[1].trim());
				} catch (Exception e) {
					// there may be silent errors.
				}
			}
		}
		return created;
} // ... created ends

Long and scary, yes, but powerful. Notice the loop? It’s looping through the 2D array right now! The filename is pieced together by connecting the instance variable location and the first index of the 2D sub-array. Another new File object is created. Its existence is also checked. If it doesn’t exist, it proceeds to be created with the lovely createNewFile method attach to all File objects. Then the data is populated by looking at the second data field and passing the filename and data to the aforementioned create method. If it already exists, we simply move on. File, we return that flag setup at the top of the method: it should be true if anything as been created, at all.

Now what? It’s time to test it out!

public static void main(String[] args) {
	Setup setup = new Setup();
	
	System.out.println("Checking application data...");
	if ( setup.created() )
		System.out.println("Application data initialized...");
	else
		System.out.println("Application data ready...");
}

This is basic. Make a new Setup object. Inside of an if-statement, call created. If everything already exists, the flag from earlier will be false when returned and then the ready alert will come up. If something was created, like the folder or any files, then the initialized alert will come up.

Loading some basic initial data like this is great. It makes your program’s state stay consistent and allows you to focus on more than error handling code for when there are no established files to draw from.

Happy prepopulating!

Text Based Menu in Java

Making a text based menu in Java is pretty easy – it’s easier than learning how to code a graphical menu at least.

First, let’s discuss the nature of a text based menu. You have a menu. It’s comprised of a bunch of choices you could select. Those selections could be numbers or characters or maybe even strings. When a selection is entered, it should decide if it is an acceptable selection and if it is, do something with it, otherwise report that it’s invalid. Finally, when a selection causes an action, the menu must be presented again when the action is finished working it’s magic.

Those are pretty general requirements for a text based menu. Let’s get started. Make a class called Menu and put a private Scanner listening to System.in

private Scanner input = new Scanner(System.in);

Now let’s make a method called display.

public void display() {
		System.out.println("-- Actions --");
		System.out.println(
				"Select an option: \n" +
				"  1) Run\n" +
				"  2) Jump\n" +
				"  3) Dodge \n" +
				"  4) Exit\n "
		);
		
		int selection = input.nextInt();
		input.nextLine();
// continues...

First, print out a title and then the possible selections. A call to the scanner’s nextInt will get the integer of the selection the user enters. This could become more involved if some major error handling was needed. There is a special line right after the nextInt: a single non-storing nextLine. Why? To stop input skipping.

Right after the input is stored in selection, use a switch structure to decide what to do.

		switch (selection) {
		case 1:
			this.run();
			break;
		case 2:
			this.jump();
			break;
		case 3:
			this.dodge();
			break;
		case 4:
			this.exit();
			break;
		default:
			System.out.println("Invalid selection.");
			break;
		}

This switch is based on selection and has four cases. Each case will trigger an action that mirrors the list printed out for the user. After each method is run, it will also break out of the switch statement.

Can you believe that’s all you need for the display method? So we can actually get some compilable code, just add these methods in. They don’t really do anything though.

	private void exit() {
                System.out.println("Exiting...");
		System.exit(1); 
	}

	private void dodge() {
	}

	private void jump() {
	}

	private void run() {
	}
} // ... ending display

One thing to notice is System.exit. We’ll need that for later after we setup a little loop. Basically, if the user enters the corresponding selection to exit, the program will terminate regardless. Feel free to add some print out lines to the empty methods so you know they’re actually working when you run it.

Finally, let’s try it out. Add a main method to your Menu class.

	public static void main(String[] args) {
		Menu menu = new Menu();
		while (true)
			menu.display();
	}

First, an menu is constructed. Then what may appear to be bizarre is an infinite loop calling menu.display forever. This serves a very important function. When display runs once, it will wait for the user to enter something. If they enter something invalid, it will tell them so (where invalid right now just means not a selection, not bad input). If they enter a valid case in the switch, the actions will be performed. Then what? The loop takes care of it! It starts over again, waiting for input and so on. But how can you exit the program? The reason for the System.exit is to exit the program. In this program, hitting 4 will cause the program to exit despite the loop.

What about multiple menus? It’s pretty much the same, except you have a choice. You can force the user to navigate back down through the previous menu or you can optionally use another loop. Imagine a display2 method.

	public void display2() {
		
		display: while(true) {
			
			System.out.println("-- Secret Actions --");
			System.out.println(
					"Select an option: \n" +
					"  1) Dive\n" +
					"  2) High Jump\n" +
					"  3) Back\n "
			);
			int selection = input.nextInt();
			input.nextLine();
			
			switch (selection) {
			case 1:
				this.run();
				break;
			case 2:
				this.jump();
				break;
			case 3:
				System.out.println("Returning...");
				break display;
			default:
				System.out.println("Invalid action.");
				break;
			}
			
		}
		
	}

Yes, this looks long and complex. In reality much of the code is repeated directly from the first display method. The major difference is the while loop inside. display: while (true { is interesting. The display: is called a label. Labels allow you to break out of code segments easily without complex conditional triggers. In this case, when the user selects case 3, the loop will be broken and thus they will return to their previous menu.

Text based menus can end up being quite interactive despite their appearance.

Happy menu-ing.

Cleanup an Eclipse Workspace Directory

After an incredibly short summer, I needed to clean up my flash drives. I ran Eclipse on a workspace stored on one. All my source code for every project was stored neatly and distinctly in their own project folders. Of course Eclipse stores all sorts of meta data and even the compiled classes in those project directories too. Since I wanted to donate my code base to my old teacher, I needed to clean it up.

I tried to use the Windows Command Prompt, but I totally failed. So I quickly whisked my files over to a temporary directory on my Linux server. Once there, I could leverage the awesome power of the terminal.

There are four major things to remove in the Eclipse workspace directories: /bin, /.settings, .classpath and .project. So we know what to target. I used the follow four commands (but surely could be merged into a single line by an expert!):


rm -rf */.settings
rm -rf */bin
rm -rf */.classpath
rm -rf */.project

I should note that before running those commands, I copied the original directory to make a backup. Please, make a backup! because you don’t get to recover from the Terminal’s rm command.

When you inspect your workspace directories, you should notice those four things gone. It’s really that easy!

Happy eclipsing.

Next>

© 2021 Ryan Rampersad's Chronicles.