Wednesday, July 03, 2013

Restaurants: A novel way to remember orders!!

On a recent trip to the US, we used to go out for lunch with our clients to various places.

One hotel we went to seemed to be pretty popular, and there was usually a crowd during lunch. On this particular day, we sat down and placed our orders. We were a huge group, so our entire order was not easy to remember. But I remembered reading somewhere that waiters were good at remembering orders, and hence I decided to ignore it. "She has noted it down on a notepad anyway, so it shouldn't be a problem for her," I thought.

Our first order arrived, carried by a different waiter from the one who took the order. She came straight to the table, and placed it right in front of the person who had asked for that item.

I was surprised that even though she was different from the one who took our order, she knew which customer had ordered that item. I put it down to the original waiter informing the new one of who had placed that order.

The subsequent orders came and the same thing happened again and again. I was surprised. I looked around at another table, and after some time, noticed the same pattern. Different waiters would serve the same tables, and each waiter knew which customer had ordered what. These same waiters were also serving other tables, and even there, they seemed to know who had ordered what.

"Can they really remember to such an extent?," I wondered. I didn't think I could.

------------------

I forgot about the incident and was reminded of it on another day, when we went to a mobile diner of sorts. The mobile diner is just the same as the street food stalls and vans that we see in India.

I placed my order, and the lady gave me my copy of the receipt she wrote the order on. Here it is:




Notice the top row of figures?

There are various shapes with some numbers arranged around them. There is also a circled 'S' symbol.

The shapes are the tables in the restaurant. The numbers around the shapes are the customers that can sit on those tables. Each customer is assigned a number. The circled 'S' symbol is the waiter. Its expansion is probably "server".

When the waiter arrives to take your order, she stands in the position marked by the circled 'S'. She then notes down your order according to the position in which you sit. Thus, if you are the first on her left side, your order is marked against number 1.

This paper is then maintained until the orders are ready, at which point the waiter brings the food to the table along with the paper. Since she knows the name of the food, it's easy to find the customer's position from the paper. She then serves it directly to the customer!! This ensures that any free waiter can serve the food back to the table, and it is not necessary to wait for the original waiter to serve, or to ask the original waiter whom to serve to.

I saw this for the first time in my life in the US, and am not sure whether it exists in India. In most Indian restaurants I have been to, when the waiter comes to serve me food, I am the one indicating to the waiter which food should go to whom.

Thursday, January 24, 2013

JAXB - Generating an <simpleType> with more than 256 <enumeration>s


So this was a strange error that we faced a few weeks ago.

The client we work for has various teams with each exposing their functionality to other teams via web services. So, in effect, a web application can be built, with it talking to various web services to get work done. Our work that day was to make a new web service. This was similar to another web service, with certain differences in inputs and functionality between the two. For various reasons, we decided to create a copy of the first web service's WSDL file and make the changes in inputs to the second WSDL.

While we were doing so, we found that the previous WSDL has a field for accepting the country code, but its data type was marked as string. We felt that this could lead to wrong country codes in the database as people could input any value. Our database also had a master table that stored the country codes. While the web service code did verify the input against the table, we decided to change from string to a simpleType that had restricted elements. This would mean that our clients would never be able to provide invalid values.

Basically, we wanted to change from:

<element name="countryCode" type="string"></element>
to
<element name="countryCode" type="CountryCode"></element>
with CountryCode type being defined thus:
<simpletype name="CountryCode">
  <restriction base="string">
    <enumeration value="IN"></enumeration>
    <enumeration value="US"></enumeration>
  </restriction>
</simpletype>

Since our database has 262 country codes, we decided to list all of them, thus having 262 <enumeration> entries in CountryCode. This wasn't a very big work as we initially thought, thanks to copy-paste and IDEA's column selection feature.

We use Apache's cxf-codegen-plugin in our project to generate the Java classes that do much of the XML-Java conversions. cxf-codegen-plugin ties into Maven's generate-sources phase to generate the Java classes. So when we ran mvn generate-sources, we expected an enum type called CountryCode with 262 fields.

In reality, the class was not generated at all.

I immediately had a suspicion over the number of enum fields, because I had never written or seen a Java enum with that many fields. So we trimmed the simpleType to one entry and ran mvn generate-sources, and the result was that the CountryCode class was generated, with one field. When we brought back the entire list, no class was generated. So we commented out the entire list and slowly uncommented a few entries (from the top) one by one to see at which point the error occurred. The Java file was generated fine all along until we reached the final few entries (about 6 or so). At that point, the Java file was not generated.

Again, the thought of some count limitation entered our heads. We were also entertaining the possibility of some character we pasted being of a different encoding or some whitespace character inadvertently getting into our code because of the copy-paste. To rule out the second possibility, we deleted the <enumeration> entries for the 6 country codes and manually keyed them in ourselves. Still, it did not work. To further rule out this possibility, we commented all entries and then slowly uncommented entries from the bottom up. The Java file was generated until we reached the top few entries, at which point it failed.

So we were back to our count hunch.

We were thinking that maybe WSDL had an issue with so many <enumeration>s. We didn't think it would be so, but we decided to check anyway. The WSDL spec did not mention about any restrictions in number for the <enumeration> tag of <simpleType>. So we felt it had to be an issue with either the cxf-codegen-plugin or Java. Googling revealed that Java had a limit for the number of fields in an enum, and that was 65535. Since we were much below this, we ruled out Java as the problem.

So now the only thing left out was the cxf-codegen-plugin. Googling revealed that it internally made use of JAXB. Further Googling brought up this link which said that you had to add the typesafeEnumMaxMembers attribute to your <globalbindings> tag to enable it to generate more than 256 elements in an enum type. This <globalbindings> tag is present in the bindings.xjb file in our project. We set typesafeEnumMaxMembers to 300 and found that we were able to generate the CountryCode.java file, with it having all 262 enum elements!!

<globalBindings typesafeEnumMaxMembers="300"/>

This was a great relief since we had been Googling for many hours and had become frustrated. Googling further, we learnt more about JAXB and the xjc tool. I was aware that JAXB was a tool that could be used to do the conversions from XML to Java and vice versa, but I had never really dwelt into and learnt more about it. Hence xjc was new to me. In the end, I understood that it was xjc that did the job of generating the Java classes. You could customise the way xjc generates the classes by creating an external bindings file, which had to have the extension '.xjb'.

And that's where the file, 'bindings.xjb' in our project came in. You can inform JAXB about the presence of this binding file by passing the file name to the -b parameter of the xjc command. Since we were using the cxf-codegen-plugin and not using the xjc command directly, we configured these arguments via the <executions> tag of <plugin> tag in pom.xml. Basically, we did this:


<plugin>
  <groupid>org.apache.cxf</groupid>
  <artifactid>cxf-codegen-plugin</artifactid>
  <executions>
    <execution>
      <configuration>
        <defaultoptions>
          <extraargs>
            <extraarg>-b,${basedir}/src/main/resources/bindings.xjb</extraarg>
          </extraargs>
        </defaultoptions>
      </configuration>
    </execution>
  </executions>
</plugin>



One thing that made us wonder was why there was a limit in the first place, and why the default value was 256. We were not able to find any answers for this, but the JAXB spec itself lists the default value to be 256. I read somewhere on the Internet that this was because having a Java enum with 256 entries is unmanageable and unmaintainable. But we felt that even having 100 - 200 entries should be unmanageable - in that case, why is not the default value somewhere between 100 and 200? Why specifically 256?

Friday, October 29, 2010

Great circle routes

In late March, my company informed me I had to travel to the US. They asked me to get all required stuff ready. By the time my visa was ready and I was able to book tickets, it was already the third week of April. It looked like I could book tickets for any day from the 4th week of April or the 1st week of May only.

On April 14th, the Eyjafjallajökull volcano exploded.

As you probably know, all airline schedules went haywire. However, I was not worried much. After all, the volcano was in Iceland, and the affected areas were mostly in Europe. Surely, my flight to the US wouldn't be travelling over Europe!! Why should it? When travelling from India to the US, I thought, my flight would probably take the Saudi Arabia - Egypt - Algeria - Atlantic Ocean - US route, wouldn't it? After all, when you have a map of the world in front of you, that seems to be the most straight and efficient route. A map of the route I thought my flight would take is shown below:



Of course, if the ash cloud grew to the extent where it began to intrude into North Africa, then I would have some problems - but I thought I would think about what to do if it ever came to that.

By the time I was ready to book my tickets, the situation had eased a little - flights were allowed so long as they flew via routes where the ash was less concentrated. When I went to the travel desk, I was told there were no bookings being done, as all flights were cancelled. I was somewhat surprised and reminded the travel desk that flights were being allowed up in the air. The travel desk replied that though flights were being allowed, the airlines were concentrating on clearing the backlog of passengers first. I reported this to my manager, who told me that as my travel was urgent, I would have to get tickets somehow.

I went back to the travel desk. "I need a ticket to the US".

"No sir... as we already said, the airlines are not accepting bookings. They are only trying to clear the backlog".

"Ok... which route are you considering?"

The lady mentioned some routes via Europe and the Middle East. I understood it was impossible via Europe as that was the most affected area, but why were there no tickets for routes via Middle East?

Me: "Can't you book on the Chennai - Singapore - US route?" I was thinking Singapore to US would probably fly Phillippines - Pacific Ocean - US, which meant that they would avoid the ash cloud.

"No sir... no bookings".

Confused, I tried to be even more clear. I said, "No.. I mean the Chennai - Singapore - Tokyo - US route. Surely, there should be some tickets there!!"

"No sir... bookings not allowed".

Even more confused now, I asked the lady why bookings were not allowed on that route. Surely the ash cloud was not affecting those areas!!

"I don't know sir... but bookings are not allowed".

Not wanting to argue any further, I reported this to my manager. There followed a long series of trips to and from the travel desk, trying desperately to book a ticket ASAP. Every day was spent with me atleast visiting them once, and in some cases twice. No change. Another manager suggested booking on the India - Johannesburg - US route, which the lady frowned upon. In between I learnt that my company had an upper limit on the total cost of a ticket booking, which meant that some routes were effectively removed from consideration.

Finally, after one or two weeks, my tickets were confirmed. My route was Chennai - Doha - Washington by Qatar Airways - a hop through the Middle East. I wondered why this ticket was not available earlier.




With packing and other travel-related work, this issue went to the back of my mind. Finally, the day came, and I boarded the Qatar flight to Doha. The 5-hour journey was uneventful and I landed in Doha. Two hours later, I boarded my Doha - Washington flight.

Once settled into my seat, I looked around and noticed that this plane had TV screens behind each seat, and at the beginning of every passenger section. These were showing the route we would take and the route shown was this:


(Note: The route shown here is not the exact route my flight took. Though it has been a few months since my flight, I do remember the route going over Finland as well as Iceland and Greenland. But you do get the general idea).

Hello?

I didn't believe it at first!! Surely this must be a mistake. The flight was not going to travel over the Mediterranean Sea or North Africa. This meant that the flight was taking a roundabout route. I immediately rejected what the display was showing and thought to myself to note what route the plane actually took.

We departed. As I had a meeting the day after I landed in the US, I had planned to have naps during the flight to avoid jet lag as much as possible. I had a short nap. Lunch was served. All along, I kept watching the display. The flight took the route shown before. I thought at some point, the flight would turn and go on the route I had thought it would take, but no, the flight kept going on and on on the route shown, until many hours later, I reconciled myself to the fact that the flight was not going to change direction.

I was angry - I shall accept it. I was needlessly being kept in a flight for 14 hours when a shorter direct route existed, one that would take lesser time. But I soon realized I could be mistaken. No pilot would do that; he could be reprimanded by the airlines. I also knew that sometimes flight plans were generally prepared by somebody other than the pilot, and if that somebody had prepared this route, the pilot would want to know why. Also controllers on the ground would want to know why the flight was taking this route. And more important, I remembered reading somewhere that flight fuel costs alone were a significant percentage of an airline company's expenses - no pilot would be foolish enough to run a route longer than the shortest one, unless there were reasons. To top it all, this was my first international flight, and there was always a possibility that I might not know something.

In short, everything was loaded against me. If my thoughts about the flight's route were right, then it had to be a very very exceptional case, and I would hear about it on landing; otherwise, I was surely wrong. I suspected the latter.

Realization dawned somewhere over the Atlantic, I guess.

Great circle


The initial route I had arrived at (Chennai - Saudi Arabia - Egypt - Algeria - Atlantic Ocean - US) had been based on a paper map of the world. I had plotted the most direct route if the Earth had been flat, as shown on a paper map. But the Earth is not flat - it is a sphere, which means that Doha and Washington were on opposite sides of the Earth. On this spherical image of the Earth, my expected route would look like this:



Adding the route my flight actually took to the above map makes it look like this:



Clearly, the actual route is a straight line, rather than the one I initially thought of, which is curved, and travels a greater distance. And we all know from our geometry class that a straight line is the shortest distance between any two points. Note the route taken - it passes over Europe, crosses the Atlantic Ocean and enters North America over Canada, which is also the route my flight roughly took.

So yes, I was wrong and the flight route taken was the shortest one. But if my new understanding was right, then it had to be documented somewhere. A search on Google/Wikipedia should reveal whether I was right. And yes, Wikipedia has an article on it. Such routes are known as "great circle routes", since the shortest line joining any two points on a sphere is known as a great circle in geometry. A great circle on a sphere is equivalent to a straight line in linear geometry.

Good.. my flight was like this. How about other flights? For example, Europe to America. Let us take Frankfurt - Washington since we have a Chennai - Frankfurt flight and there is a chance I could have flown on it.



Great circle again!!

Ohkay, now how about Singapore - Washington? Does it also take a great circle route?



Aha, it does!! So this is the reason why the travel desk could not book on this flight. Probably, this flight too was cancelled!!

Interestingly, this flight seems to pass right over the North Pole. That should be exciting - imagine sitting on an airplane, having your lunch and looking at the display in front of you, which says you are flying over the North Pole. How thrilling would that be? In fact, while there is no flight between Singapore and Washington currently, we do have a Singapore - New York flight operated by Singapore Airlines, and it passes a few miles close to the North Pole. (see here for proof).

Interesting, but does this work for flights in the Southern Hemisphere too? Let us take a flight from Sao Paulo (Brazil) to Sydney (Australia).



Woo... the flight passes over Antarctica!!

Update (11th Feb 2011): So the lesson here is that if you have a flight that flies between two cities that lie in the same hemisphere, then the flight route is plotted as a great sphere route (assuming the weather is fine along the route. Otherwise, there would be deviations). Note the text in bold - lie in the same hemisphere. Why should the cities lie in the same hemisphere? Do flights travelling between cities across the Equator not have to travel via great circle routes? Yes they do have to travel along great circle routes, but that would roughly approximate the route you would draw on a paper map.

Nope, I shall put up my finger and accept that I was wrong in that last paragraph. I had assumed that flights that cross the Equator would more or less follow the straight line you drew between the two cities on a flat Earth. I guess I made this assumption on the fact that the route between Doha and Sao Paulo is like this:



which is erm... roughly a straight line..

Unhappily, just this example is not enough to argue that trans-equatorial flights do not fly on great circle routes, or to argue that their routes are roughly equivalent to straight lines. One example is enough - London to Sydney. I expected the route to be somewhat like this:



But in reality the route turns out to be this:



Why is this so? Again, the route I expected to see is because my mind still thinks of the world as a flat paper map. But of course the Earth is not flat, which means that the route you would get is the second one. Here is how the route would look if we had rightly visualized the Earth as a sphere in our minds:




So the lesson here is to think of the Earth as a sphere when mapping flight routes between two points, wherever those two points may be and whatever the distance between them!!

(All flight routes generated by the excellent flight route mapping website, Great Circle Mapper).

UPDATE (16th Dec 2012): Another proof of this is FlightRadar24, a website that shows flights travelling across the globe in realtime. You can see for yourselves the routes flights take.

Thursday, April 15, 2010

Code

I have been coding professionally for the past 5 years, and coding small projects at home, but only in the last year have I realized the benefits of having a public repository of my code. Having heard a lot about jQuery, Struts 2 and Ruby and having wanted to learn them, I started a small Minesweeper project on the side to learn these technologies. I also hosted the app on Google Code.

The app is hosted here. I won't say I am very great at coding (though I am following various ways to improve) and hence praise and criticism of my code is welcome.

Right now, it uses Struts 2 and jQuery. I have not yet started on the Ruby/RoR part. Hopefully, that day should come soon...

UPDATE (20th Aug 2012): The Java app is feature complete long ago (sometime in 2010 itself). Work continues on the Ruby app along with my other side projects, apart from official work and life.

Tuesday, November 17, 2009

About integer overflows...

One fine day, when I was browsing StackOverflow as usual, I came across this particular question. The gist of the question was this:
A person in an interview asked me how I would generate all possible integer values in Java.
Some people, including me, thought it was a simple question. All you have to do is this, right?
  for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
    System.out.println(i);
  }
(I confess I did not readily think of using the constants Integer.MIN_VALUE and Integer.MAX_VALUE. In my mind, the first program that hit me used the actual values of Integer.MIN_VALUE and Integer.MAX_VALUE. But reading through some of the comments to the question, I quickly realized I could use them.)

Simple right?

Wrong, as I found out later.

It turns out the program will run fine until the variable, i, equals Integer.MAX_VALUE. At that point, the System.out.println() will print the value of i which is Integer.MAX_VALUE and then control exits the current iteration of the for loop. Now i is incremented. What will the value of i now be? I expected it to be Integer.MAX_VALUE + 1. But no, its Integer.MIN_VALUE!! Since Integer.MIN_VALUE is less than Integer.MAX_VALUE, the conditional expression passes.

The outcome, sweetie, is that it's an infinite for loop.

You can test this out for yourself by executing the above program. but wait.. surely you are not going to wait for the program to run through all values from Integer.MIN_VALUE till Integer.MAX_VALUE? That's 4294967295 numbers!! When will you program finish executing? Instead you can try out this simple program:
int i = Integer.MAX_VALUE;
System.out.println((i + 1) == Integer.MIN_VALUE);
Executing it would print "true".

So to answer the interview question, the correct code to print all values that an int can store is:
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
  System.out.println(i); 
}
System.out.println(Integer.MAX_VALUE);

The bits deep under it all...

"But, but", I thought, "how can incrementing a variable that holds Integer.MAX_VALUE result in Integer.MIN_VALUE?"

To understand why this occurs, we must dive deep into the world of bits and bytes. Java defines an int data type as something that can hold upto 32 bits. Thus, the lowest value that it can hold is given by Integer.MIN_VALUE, which is actually -2147483648, which in binary is represented as 1000 0000 0000 0000 0000 0000 0000 0000. (You don't have to struggle a lot to get the binary representation of a number. Java provides you the Integer.toBinaryString(int) method. Another way to get the binary representation is to open Calculator in Windows, type in the number and click on 'Bin' radio button to get the binary representation.)

  • In case you have forgotten, in Java, of the 32 bits for an int, the left most bit (aka the higher order bit) indicates the sign, with 0 being positive and 1 being negative. That is why in the previous value, the higher order bit is 1. So basically Java uses only 31 bits to store the number.
  • "If that is the case", you ask, "how come the other digits are all 0? If all digits are 0 in binary, then shouldn't the value be 0 in decimal rather than -214 whatever? Are you doing something wrong?" Nope. Java stores values in two's complement form. In case this two's complement thing is new to you, please read all about it here before going ahead with this blog post.


Similarly, the highest value an int can hold is 2147483647, which in binary is 0111 1111 1111 1111 1111 1111 1111 1111. Notice something about the higher order bit?

Now that we have established the basics, let's go back to our original question - when you increment Integer.MAX_VALUE, why does it revert back to Integer.MIN_VALUE? Let's do the arithmetic and see what we get...

Addend: 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Addend: 1

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

The result of adding 1 to Integer.MAX_VALUE is 1000 0000 0000 0000 0000 0000 0000 0000, which is the value we previously got for Integer.MIN_VALUE!!.

The same reason is why we get Integer.MAX_VALUE when we decrement Integer.MIN_VALUE.

Minuend: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Subtrahend: 1

0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

This is the case with other languages that have the concept of datatypes. Let's take up C, which has datatypes just like Java. In C, the maximum value of an int is given by INT_MAX, defined in limits.h. Here's a program below that stores the value of INT_MAX in a variable, and tries to increment that value.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main() {
  int max = INT_MAX; 
  printf("Max int value: %d\n", max);
  max++;
  printf("Now value is %d\n", max);
  printf("Min int value: %d\n", INT_MIN);
  printf("Are they both equal?: %d\n", (max == INT_MIN));
  return 0;
}
When you execute this program, you would find that initially max holds the value 2147483647. However, when you do max++, the value of max immediately becomes -2147483648.

Thus, this 'problem' exists in C too!! In fact, I would go so far to say that this problem exists in most programming languages. This problem exists because we have reached the limit of what the language can store for that data type. To store numbers beyond that limit, the language will have to recognize bits beyond that limit as bits that represent the numberical value, which it doesn't do. As an example, consider the case where we increment Integer.MAX_VALUE by 1 in the Java code seen above. Integer.MAX_VALUE already has 31 '1' bits and its 32nd bit (the higher order bit) is 0. When we increment, the 31 '1' bits become '0' bits and the 32nd bit becomes '1'. But Java and C do not recognize the new value of the higher order bit as one that represents the new incremented value. Instead, they use it for the sign - thus taking only the 31 '0' bits as the binary representation of the incremented value, which is Integer.MIN_VALUE!!

What if we want the language to recognize those higher bits as part of the numeric value representation? We would have to use datatypes that store numbers using more number of bits. An example is long, which stores values using 64 bits. Using long, the solution we have posted above becomes:
for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
  System.out.println(i);
}
Since a long is 64 bits, integer values will very easily fit into it, and hence the solution can be provided without any extra printing of Integer.MAX_VALUE. But even in that case, you do have a limit beyond which the value resets to the lowest number that can be stored by the datatype. In case of long, because it stores numbers using 64 bits, the highest value that it can store is 9223372036854775807.

"Ok," you say, "just for the purposes of making our understanding concrete, let us assume that a language has a 32-bit integer datatype that stores only positive values. In such a case, there is no need for the sign bit - all values of that type are positive anyway. Would it then be possible to increment a variable that holds a value of 2147483647 and still get the right answer?"

Actually, C does have such a datatype - it's called unsigned int. And yes, you can go beyond INT_MAX. Check out this program:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main() {
  unsigned int value = INT_MAX;
  printf("value is: %u\n", value);
  value++;
  printf("incremented value is: %u\n", value);
  return 0;
}
When you increment, the value of value is 2147483648.

So that was what it was all about... when you have a language that supports datatypes, and when you use a datatype, remember that when you reach the limit of the datatype and increment the value, it will result in the lowest value that can be stored by the datatype. Depending upon your work, you might never face this situation in the real-world - it might come up only in interview questions - but still, it pays to learn this and keep this in a corner of your mind. I have been referring to this phenomeonon by using the word, 'problem' all this while, but it actually does have a name - Integer overflow.

P.S.: I am not sure if there are any strongly typed languages that handle this overflow by themselves instead of leaving it to the developer like Java and C/C++ do. If you do know of any, please do mention them in the comments!!

Tuesday, October 27, 2009

Test Post - Ignore

I have been meaning to post an entry for quite some time, which I did last week. However, it had some unexpected errors that made the entry unreadable, which you would know by now if you were following my blog.

I have deleted the post, but that didn't remove the post from my RSS feed. My apologies to everyone...

That said, this is a test post for me to find out what went wrong, and how to rectify it. I will be making a lot more changes to this post as I am in the process of finding out what went wrong. So you can coolly ignore this post. Move on, there's nothing here.

First:
for (int i = 0; i < 10; i++) {
    System.out.println("hi");
}


Second: Yes yet another...
Pattern pattern = Pattern.compile("[^LMR]", Pattern.CASE_INSENSITIVE);

Tuesday, June 02, 2009

Teaching Dad computers

On that particular day, I was starting for office. I had my bath, and walked into my room to choose my dress for the day.

Now our computer is in my room, and at that point, Dad was using it, transferring photos from his camcorder. While I was choosing my dress for the day, my dad remarked that though he had transferred the photos to the computer, he was not able to view them and called for my help.

Still choosing my dresses, I asked him whether he had done every step correctly. He insisted he had. I asked him to open the folder he had specified as the destination folder. He already had it open and showed it to me. Sure enough, the new pictures didn't seem to be there.

I scrolled down the window and found that the images were added to the folder, but Windows had not sorted the view after addition. I pointed this out to my dad, saying that the files were shown at the bottom of the view - they had been transferred, but Windows did not do a sort and that was the reason he did not see the files where he expected them to be.

"But it usually arranges everything in the specified sort order!!", he insisted.

"Maybe you should refresh", I said.

"How do I refresh?", he asked.

Now I have explained how to do a refresh many times to my dad, but he being he, asked this question again.

"Press F5", I said, and walked over to the wardrobe to continue my dress-selection-process.

"Not working", came the voice of dad.

"It will work, dad!!" After all the files are already there; all it has to do is refresh - how can it not work?

"No, it doesn't!!"

I walked over to the comp, and ask him to press F5 again. This time, I keenly watched what he was actually pressing. He pressed the 'F' key and the 'I' key. What I mentioned as "F5" fell on his ears as "FI".

"No dad!! Press F5!!"

"That's what I am doing!!"

"No dad!! Press F5!!", I said, this time emphasizing the "5" part.

"Oh ok, F5!!" he said, and pressed the 'F' key and the '5' key.

"No dad!! Press the F5 key at the top!!", I said, and for good measure, point out the key.

"Oh this one!"

He presses the key, and this time, the files are displayed all fine.