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?
Tuesday, June 12, 2012
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();
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.
Subscribe to:
Posts (Atom)