Tuesday, June 12, 2012

Testing your code, pretend you are an end user

What is one of the best ways to test your code? Pretend you are an end user. Run it like you bought it instead of like you are testing it.

Near the end of this release I add export to CSV for the scheduler. People want all sorts of reports so why not let them export the data and do whatever they fancy in Excel? Works like a charm. I was doing some other testing and though "Hey, I will just export the data so I can sort it and see it in Excel to fix this bug!". Whammo, I hit a bug right away in the Export dialog.

I just wanted to export the appointment ID, start time and duration so I deleted all the other fields in the list box but then I could not add any back. The list box was reporting a selected index of 4 (the original count of items in the list) even though there were no items in the list. I changed the code to ask the backing data model for the row count so I could insert at the proper place and one bug fixed.

Next I wanted to sort the exported data. The problem is recurring appointments exported with the start date of the recurrence not the data of the grid which means they sorted in front of non-recurring appointments. When I export data I want the date to be the same for all appointments and just for the time to change. I fixed that issue too in the fixes branch and trunk.

Here I am using the software like an end user and finding bugs. Most developers are afraid to test like an end user. We are scared of finding bugs. We tend to test in a little vacuum, testing small bits of code in very isolated conditions. No user runs your program like that. They dive in and hit every menu item and button trying to make it do what they want. They multi-select, drag and drop, double click, press disabled controls and have all sorts of fun. You need to do that too. Beat on your program like it owes you money.

For the days leading up the release I just ran the software and found a number of usability issues. Why can I set default cell width for open / closed business hours but not overall row height? Why is the pivot set per view and not just once for grid? Either you like Time as a row or a column and don't want that to change if you change the other axis to Category, Provider or Facility. Yes it annoyed the technical writer that I changed this late in the game but the code and writing took us an hour and this is something that would annoy the user every day. It annoyed me after playing with the program for an hour.

You can't depend on your QA staff to be an end user. A lot of the time they are running through regression testing scripts following a very narrow path through your code. They don't mind finding bugs so they will beat on things in odd ways but it is still a view with blinders on. Those test tend to skip over usability and look at functionality. Yes, you can follow these 10 steps to get from Y to Z but why are there 10 steps? Can we do it in 5? Export was two layers deep in a menu but is something that many will use everyday to print out a reminder call list. I put it as a button on the main toolbar. Once I did that I made a note to make the toolbar layout configurable so those who don't use that button don't need to see it. I plan on implementing that in the next release.

It is so easy to just keep adding features figuring that will make clients happy but remember they are still using the existing features on a daily basis and those should be easy to use with as few steps as possible. I save off the settings they used the last time the exported data. Who wants to reconfigure that everyday? Maybe you do three types of exports. I allow you save as many named export as you want. Where do you write the file? I default to the user home directory. What if you give that export definition to another person? They don't have a directory called c:\users\john.doe so I write out {home.dir} instead of c:\users\john.doe and do replacement text when you load the export definition. Don't annoy your users, computers are there to eliminate steps and avoid the mundane.

Allow multiple ways to do things. Some people are mouse / menu folks and others use hot keys. If you use hot keys use them all over otherwise heavy keyboard users will be annoyed. Some like toolbars and will use tooltips to see what they do if the icon is not obvious. Others are text oriented and want to find what they want in the menu. Menus need to be logically laid out with descriptive text. I hate a menu that has "Preferences", "Options" and "Tools" - those words mean the same thing to me and I always pick the wrong one when I want to change a setting. Microsoft I am looking at you here with nearly every Office application. Use you tech writing team or someone you consider to be a wordsmith to help here.

Take the time to nurture your application. Don't just keep throwing more stuff at it watching it bloat up. Consolidate smaller dialogs when possible. No one likes to bring up 10 dialogs to get their initial preferences in place or to have to remember where to find some obscure setting.

You want them to be able to quick find and use every feature you have. Why waste time coding it if no ones knows it is there?

Thursday, June 7, 2012

Sync one minute Java timer to the current time

I am working on a patient scheduler and I need to draw a line across the screen indicating the current time. Helps them not create appointments in the past. We also have a clock on screen via the Jide status bar. It was driving me crazy that the line moved down or across screen but not in sync with clock. That means the line might move at the 20 second mark of the clock all depending on when you started up the program. Turns out it was adding one line of code to get them within one second of being in sync which made me happy.

timer = new Timer(60000, this);
// Force initial delay to sync within a second of current clock
Calendar cal = Calendar.getInstance();
timer.setInitialDelay((60 - cal.get(Calendar.SECOND)) * 1000);
timer.setRepeats(true);
timer.start();

It is the one line of code setting the initial delay that solves the problem. After that the timer triggers every 60 seconds and away we go. Just makes things look so much cleaner.

Sunday, June 3, 2012

Programming then and now


Is programming getting harder? I am not sure if the actual art of programming is getting harder but user expectations are growing so quickly it is much harder for a single programmer to keep up with all areas of expertise.

Let’s set the way back machine to the land of terminals. Your user got a color choice of white, green or orange and maybe they could toggle the foreground and background colors. Basic operation was CRUD – Create, Review, Update and Delete. You picked from a menu and acted on one item at a time. Screens appeared and you typed in data probably in all uppercase. Everything was done in 80x25 all text. If you needed more room you added another entry screen.

Next up we tapped into the PC as a smart terminal. That gave us more colors. Everybody stuck with 80x25 for a bit but some ventured out to 80x50. You could color menu items; required items could have a label in red etc. Still looked like a terminal in general.

The GUI came into play. Everyone tried to make each dialog box look like a terminal window at first. Then things started to change. You could have a list box of data and scroll through it. Not everything had to fit the physical screen. Not only did you have colors but you had images. The mouse drove things but most still used it just to click on buttons or to quickly get to a certain control on the form. Next tooltips, right button mouse menus and lots of custom controls started to appear. People also went nuts with fonts doing bold, italic, 20pt, etc. to make things nearly unreadable. Various mouse clicks came into play. Double click to add from this list box to that one. Drag and drop within an app became required and users started to demand drag and drop between apps. The clipboard was a cool place to put things to save on typing.

Once people got used to the GUI they wanted it to do everything for them and if one program did it they expected all programs to do it. I want spell checking anyplace I can type words. Drag and drop should always work. I can copy anything I want to the clipboard. If you want a patient name here I better be able to create it right here by bringing up the patient create dialog. When I search on something I should not just have to scroll through a huge list but I want to start typing and have it narrow down my selection. What you only narrow by things that start with what I type? I need it to find the text anywhere within the data! I want to export all my data, wait expect for that column. Why don’t you remember the last thing I did every time I come into this dialog box? I want to import an image and have it automatically do OCR and pull out the text. Hey, all I did was reorder fields on this form and now the OCR is doing it all wrong! How come I can’t see my contacts here? What about my web browser favorites?

Our current platform is the smart phone and tablet. Now they expect to hardly type anything. It is a data consumption device. But they want to display the data in a very pretty manner with all sorts of swiping gestures that should be natural. What happens on single tap, double tap, swipe left or swipe up? The screen is back to tiny, really back to the 80x25 days in a lot of cases. But the screen can be bigger. A tablet is a PC screen again so just porting the smart phone version annoys that group of folks. Touch screen devices have cameras and people want to use them. Just when we were elated with tons of RAM to store everything so they can search on it willy nilly we have been told you barely have any memory to play with again.
When you write a program you might have to do four versions of it.

#1 A full blow PC app with every bell and whistle allowing you to manage all the data with ease. Might need to run on a Mac too.

#2 Slightly trimmed down Web version available under every browser under every OS for data access on the go.

#3 Smart phone version that has access to all the data, is super pretty, supports the camera, speech to text and all sorts of touch processing

#4 A tablet version that does everything the smartphone does also supports shrinking / expanding sub-screens so you can not only see where you are but where you were. Still fit all of this into as tight as memory as you can.

As you can see a single programmer has to know and do a lot more than ever. Where once everything was text now there are text and graphics. May the user could hit a predefined function key but now you have a master menu item, right mouse button menu item, accelerator keystroke, mouse swipe and finger swipe to access each event. You must support data in as many formats as possible for Drag and Drop, export and “hey someone deal with this” such as tapping on a web or email link. You need to interact with other programs and their data that may or may not be on the device.

It seems similar to the games industry. At one time a single developer or maybe two could write a game it now takes a team. Now you have sound, graphics, core game engine and menu system folks. We are seeing a similar need for UI specialist, data export folks, core OS interaction and many others.
On my current projects I have worn every hat in the list. I wrote both the iOS and Android versions. I did all the graphics and designed all the screens and touch interactions. I wrote a custom control for a menu system that appears when you tap on certain items and did all the DBA work creating 25 tables under SQLLite on each device. I am at a very small company so this is pretty much expected. At my previous job I had a User Experience team to handle the screen layouts and all the graphics. I had a design team to decide on how things in general should work. If I had a question about how something should look or operate I pretty much knew who could answer that question.

For the main Java application we wanted to add export functionality. By the time I was done with that it was over 1,000 lines of code that I wrote in a just two days. Why so much code? The export part was easy, just take the data and write to disk in CVS format. But that is not what a user wants. They need to pick every field they want exported, the name of the file, should I append the date of the data to the file name, where should the required appointment ID go, how to write out multiple lines for multiple associated physicians. What if they export different data for different needs? I allow you to name your format and save as many named formats as you like. I need to load / save this to the server. Then we needed permissions for creating named filters but if you don’t have that permission you need to be able to do ad hoc exports and save that locally and not on the server. It is all up and running but there was a ton to do and think about. We want to release on Monday so I had to get it all coded up and ready for QA to give it a solid once over. This is what you do working for small company on a monthly basis.