Embarrassments

From Juneday education
Jump to: navigation, search

On this page, we, the authors (Henrik and Rikard) will publish embarrassing mistakes we've made in the classroom and elsewhere.

Expect this page to becom quite lengthy as time goes by.

Stupid question in a Java exam we wrote

Recently (November 2016) we wrote a question in one of our exams which read something like this:

Write code which would change the variable name below, to represent a String with all upper case letters from its prior content, using the toLowerCase() method in class String (the API description of the toLowerCase() method is included in the appendix of the exam):

String name = "Charlie";

Of, course, this was an embarrassing. Why would anyone use toLowerCase() in order to create a String with all upper case characters?

And both Henrik and I proof-read the exam questions without spotting this. And we sent it to colleagues as well. No one saw this blunder.

In order to save our face, we'll here provide one correct answer to this question (the only acceptable answer would actually be "Are you nuts?"):

name = name.toLowerCase();
char[] res = new char[name.length()];
int i = 0;
for(char c : name.toCharArray()){
  res[i++] = (char)(c + ('A' - 'a'));
}
name = new String(res);

Of course, we'd be ashamed of this mistake question (if we weren't so used to making mistakes) and shouldn't provide this stupid answer. But we'd thought it'd be fun to show you that doing something as stupid as using toLowerCase() for the same functionality as toUpperCase() provides, is actually possible.

The method makeUpper(String s) works like this:

First, the argument is converted to all lower case letters, using toLowerCase(). Then we create a char array of the same size as the argument's length. We also create a local variable i to keep track of positions in this array. Then we loop through all the characters in the String when the string is exported as a char array.

In the loop, we assign our array at index i the current character of the String's array representation plus the difference of ('A' - 'a'). The index i is incremented, and we'll do this for each letter in the argument string. When we're done, we return a new String based on our array which we populated in the loop.

The reasoning is like this:

The distance in the Unicode table between a lower case letter and the same letter in upper case, is the difference between 'A' and 'a'.

Since all letters in the Unicode table comes consecutively (in a row), we might use for instance 'A' and 'a' to calculate the distance between them. Let's look at a hypothetical example of how this works:

Let's pretend 'a' has value 97 in the Unicode table, and that 'A' has value 65. The distance between 'a' and 'A' is then (65-97 = -32). We can use this value (-32) in an expression to convert any letter in lower case to upper case:

'a'(97) + (-32) = 'A'(65)

If 'a' is 97, then 'b' is 98 (they are consecutive). So the same operation would work also for 'b':

'b'(98) + (-32) = 'B'(66)

In fact, it works for all letters (since they are consecutive in both lower case and upper case). The distance between any lower case letter and any upper case letter is always the same (32 or (-32) depending on the direction).

So, we could create an upper case representation of a String by first making it all lower case, then running our loop.

This way, compared to using toUpperCase() instead, is about as smart as Rikard and Henrik combined.