Every user query is a puzzle

The user didn’t really mean to give you a level 5 puzzle to solve. But that’s what it is. Every time the user asks you to help him solve a software related problem, he’s giving you a puzzle.

Sometimes, it’s a level 1 puzzle, where you don’t even need to fire up your code editor to glance through the code to answer, or give more than a few seconds to think through. Sometimes, you have to really push for lots of hints, like clarifying the user’s query, ask for screenshots (even if sometimes they aren’t enough…), and dig through code archives.

I got a level 1.5-ish puzzle lately… The user said he couldn’t use the delete button. I fired up the application, selected a record, and indeed the delete button was disabled. On a whim, I double-clicked. The details of the selected record came up, and the delete button was enabled.

I have never seen or used that particular section of the application before. The user on the other hand, was supposed to be familiar with the application. Perhaps I’m more willing to try out typing randomly or aimlessly clicking the mouse on an application screen. I certainly typed enough asdf’s…

So, have you encountered any high level puzzles? Share in the comments.

Brain dead

I can’t think. I can’t focus. My thoughts are scattered, flying around of their own volition, out of my reach, out of my control.

I believe this is what people call “burnt out”.

For the past couple of months, I’ve been coding for, or working on, a few projects. I was either the sole developer, or a major contributor to the project. Their deadlines had been either back-to-back or overlapping. And this unhealthy schedule stays for the next couple of months.

I may be a Polymer, but I am only one.

There had been a few instances in the past where projects bunch up together. It was tough, but I weathered through. This time, it took its toll on me. I’ve never been out of the Zone for so long.

All my usual remedies failed. Reading. Hanging out with friends. Listening to upbeat music while working (but I already do that on a regular basis). Tea. Playing video games. Exercise. Coffee (mocha. I can’t withstand the strength of “normal” coffee…). Going for walks.

I was about to attempt unfettered hedonistic pleasures when I remembered I could take a break. Ok, it was more like “Take a day off!”, “Stop working!” and “Fight for Freedom!”. Ok, maybe not the last one…

I heeded those subtle hints, and took a day off here, a day off there. The Chinese New Year, which was just over, lengthened a weekend. So many people were taking days off too. Hint: don’t take the same days off as the other people if you can help it. Take those days when they’re back in office. This way, you get more done because you don’t get interrupted.

Stop interrupting me!

This episode was seriously difficult to recover from.

It came back, surprising me with its arrival. My coding groove. There were no announcements, no hints. One day I was down in the slumps, the next I was able to think cogently for a few hours straight. That gave me enough time to sift through the requirements, because much of programming isn’t really writing the code. It’s thinking.

I’m still feeling terrible, but at least I’m able to get the projects moving faster now. All the tricks for getting my energy back failed abysmally. In the end, my mind and body provided the best solution.

It was time. I just needed to rest. Sometimes, the fastest way is to stop.

Random Quote – Program X not social networking site

Today, my users got into a tangle. All of them got into a database deadlock.

Now my users have this habit of opening multiple windows so as to “appear busy”. Granted, my application wasn’t designed and programmed with many concurrent users in mind. Still, if more than 2 of them happen to access the same table, or heaven forbid, performing an update or delete operation on that table, the database throws up its hands in defeat and promptly denies further access. This includes other users accessing other tables.

So I did an sp_who (it’s a Sybase database) and found out the perpetrators. Then I wrote an email telling those who were doing non-critical tasks (and not still performing database transactions) to get the heck out of my database and log out of the application. And not return until half an hour later. Nicely coached in diplomatic language of course.

One of them asked if another colleague could continue, since that person was still performing a transaction. I said “Of course.” I also added something in the email that I thought was interesting (on hindsight):

Program X is not a social networking site. Log in, do your thing and log out.

Yes, I was a bit peeved and slightly mischievous at the time.

A typical month work load

Climber by Bettina Ritter
[image by Bettina Ritter]

I don’t really have a typical work day. It doesn’t mean I have an exciting job. It just means I can’t tell you what I’ll be doing the next day, because I don’t know for sure what I’ll be doing. What I can tell you is what I do in a typical month, generally speaking. There’s a point to all this, and I’ll start with…

From 8:30 am till 6 pm

Those are my work hours. Except Friday. On Fridays, I get to go off at 5:30 pm. My current job title is IT Analyst, changed from Systems Analyst. And if you think that’s vague, you’re right. My job scope is quite varied. Basically, my contractual terms require me to “do whatever the boss tells you to do”.

The current company I’m working for isn’t a software company. I just work in the IT department. What it means is, programming isn’t as highly regarded as I want, as what I read about in those programming blogs and sites. It kinda sucks, but it keeps me fed.

Let me tell you about the tools I use at work. I’m the “online guy”, which means any user interface related development comes to me. I use Visual Studio 2003 (C# and VB.NET) for all the web applications, console programs and a few software tools I create to help me. I also use Visual Studio 2005 for one particular application, with a graphical user interface. It’s too tedious to explain why I use both versions. It’s enough to know that I do.

I also use PowerBuilder for some Windows applications. It’s really, really painful to work with PowerBuilder code. I tell myself it’s the previous programmer’s skill that’s to blame, not the language, but I frequently fail. Tracing and debugging PowerBuilder code takes a lot of work for me. I really hate PowerBuilder… I think this calls for a separate rant article.

I’ve been asked to investigate C and C++ code on Unix machines too. So yes, I understand make files, shell scripts and cron jobs. I even know how to use the vi editor! I used to telnet to the Unix machines with TerraTerm, which is now abandoned for a more secure client application. Can’t remember the name because I rarely use it, because I rarely need to telnet.

Database admin, server admin and LAN admin

Despite the fact that I’m completely ignorant of SQL and databases in my formal education, I’m thrust full force into it at work. I’ve worked with the Oracle, SQL Server and Sybase databases, know most of the nuances between them on SQL syntax, and understand how to use stored procedures. I handle them all.

I am also completely in charge of a few Windows servers and the SQL Server databases running on them. Server maintenance, backup schedule and tapes, security patches, SSL certificates, IIS configuration, server performance.

Then I’ve got to know about the opening of ports for security purposes, who to notify when there are application or server changes. I need to know ping and tracert and ipconfig and other network related stuff.

All of that maintenance and administration is on top of my development work.

I don’t need to connect to Oracle databases now, but I used to do so with TOAD. There’s a limit to the number of licenses, so I wrote my own database connector program. It only does retrieval of data, basically the select statement, but it’s enough for current tasks. The Oracle databases belong to another team, and they’ve only needed me to help out rarely.

I use the Enterprise Manager and Query Analyzer for the SQL Servers. They’re great tools, and they come with the database installation, which is cool. There’s also another tool that has saved me many times. It’s the DTS, Data Transformation Services. I’ve used it to transfer data interchangeably between Oracle, SQL Server, Sybase and get this, Excel. Users take to Excel much better, so I need to use their form of “database”.

Designers, comparers and reflectors

I’m also a web designer. I suck at it, but I’ve been lucky enough to muddle through, and my users and their customers think my user interface looks awesome. I use Paint.NET (and sometimes the inbuilt Windows Paint program) for my image editing tasks. Plus I’ve got some colour tricks up my sleeve.

Some time ago, I had to verify some old code by another programmer. He can’t remember what he changed, and I obviously don’t know what could possibly be changed. I needed help! Fortunately, I found CSDiff. It allows you to compare two files (or even folders) and lists down differences between them. Much better than checking line after line of code by inspection.

And if you do .NET work, you must get the Reflector by Lutz Roeder, which had been taken over by Red Gate Software. It allows you to get back code from compiled .NET DLLs and programs. The result might not be the prettiest code, but with sufficient talent and patience, you can get something out of it.

I’ve used it on my own code and other team members’ code to check for disparity. Sometimes, you forget which version you’ve compiled that code into… Sometimes, it’s for self study, to understand what others have done.

The phone calls. Oh the phone calls.

My phone rings a lot. There are over 10 people in my immediate vicinity. I can tell you that, if you add up all the phone calls all of them ever receive in a month, it would still be less than what I alone receive in that same month.

Remember I told you I’m the “online guy”? That means a lot of users know me, and I don’t know all of them. Since they usually interact with the application interface, any problem is routed to me. Whether it’s data inconsistency, business logic query, application error or failure, all of them come to me. I’m a one-man helpdesk I tell ya.

It was so bad that sometimes, I’ve had to solve and handle user queries for entire days on end. Due to the nature of my work, the start and end of the month are particularly busy for my team. The number of times my phone rings goes through the roof. Maintaining decent phone etiquette starts to be a strain…

Wait, there’s something missing…

Where’s the source control software I’m supposed to be using? Well, I’m the source control. My team is very small in size. Company directives dictate we send work to our offshore colleagues. I think those (typically recent graduate) colleagues have some problems of their own, let alone set up a source control system that works across geographic boundaries.

I’ve not been with development teams at other IT departments, but I think we would totally fail at the Joel Test. Totally.

Despite these circumstances, I still manage to do development work, sometimes with surprising and outstanding results. I believe good task management is crucial to my balancing act. Which brings me to…

Holistic approach to programming

If you’re working at a software company, or on something focused on software and programming, I envy you. I really do. You’d probably get to talk with other programmers on interesting topics. Your work is really appreciated, because it goes to the bottom line.

I might not be programming exclusively, but I get to see the bigger picture. I get to liaise with people from sales, marketing and customer service. I get to talk with upper management and even the actual customers. I get to see the kinds of products and services offered, and how it’s implemented and supported by software.

Programming is kind of … an elite thing. When I was studying C programming in university, I was surprised that many of my fellow students struggled with it. I took to it like a fish in water. After a while, I realised that most people cannot grasp the thinking required in programming, even if they opted to study it themselves.

So I’m going to state this. Many people are not going to understand how great that piece of code you’ve written. Many people think software can make their lives easier, but fail to realise that not everyone can write good software.

This is where all your other skills come in. You have to sell what you’re doing to other people. Convince them that it’s useful, that it’s awesome, that it’s relevant, that what you do and what you propose is important.

Sell your ideas. Market your ideas. Your software is more useful if you see it from a bigger-picture point of view, from other people’s point of view. That requires you to understand other concepts. Concepts that aren’t related to programming at all. And you synthesise them together to make your code better.

And that, is my point.

When even screenshots fail

My best weapon for handling user queries is the screenshot.

User: Hey Vincent, I’ve got an error when doing X.
Me: Send me a screenshot.

User: Hi Vincent, sorry to disturb you. The application Y doesn’t work.
Me: Send me a screenshot.

User: Dear Sir, I cannot log in to application Z. Please advise.
Me: Send me a screenshot.

I’ve been fortunate in that I don’t have to educate my users on how to create a screenshot. Imagine the conversation with me describing where the PrintScreen button is…

User: Uh, how do I send you a screenshot?
Me: Just do a PrintScreen.
User: How do I do a PrintScreen?
Me: Just press the PrintScreen button.
User: What PrintScreen button?
Me: It’s a button on the top right corner of your keyboard, beside the Scroll Lock button.
User: Ok, I’ve pressed the PrintScreen button. Now what?
Me: Now send me the screenshot.
User: How do I do that?

I’d probably slam the phone down and throw it halfway across the hall.

PDFs, Word documents and bitmap files

Anyway, even with the absence of the kind of inane conversation above, I still receive some interesting emails. I might receive an email with a PDF file. I open the PDF file and lo and behold, there’s a screenshot inside, all shiny and black and white and kinda fuzzy and grainy due to the warping from the PDF writing software.

Yes, there are users who are more adept at creating PDFs than Word documents.

Then there are screenshots where the user diligently took a capture of the screen. With the actual error obscured by another window.

Then there are the emails with a file size of 2 megabytes. Think bitmap file attachments with a resolution of 1024 by 768 pixels.

Then there are the clever users who took a screenshot, and to compress the file size, they dumped the contents into a Word document. Word automatically compresses the bitmap. I can’t blame them for not knowing how to use an image editor, even one as simple as Windows Paint. Didn’t get any fancy meta-screenshots, though I’ve gotten a screenshot in a PowerPoint file before.

Then there are the ultra-clever users who know how to take a screenshot, use an image editor to crop it, and *exclaim* save it as JPG or PNG. Even then there are problems. Let me first show you this:

Yellow screen of death

If you’re familiar with ASP.NET, that’s everybody’s favourite error screen. It has useful data such as the general error message, the line of code where the error occurred and the stack trace. The stack trace contains information such as what events were triggered so you know for example, which button was clicked.

Now I have this web application with a loading screen, played out with an animated GIF image. And when there’s an error, something like this shows up:

ASP.NET error with Now Loading

I’m terrible at drawing stick figures… It’s supposed to be a stick figure searching for files in a file cabinet, and throwing any useless files behind him.

Well, my user sent me that. Most of the useful information was below the screen. So I asked her to scroll down so I could see them.

Me: Can you scroll down and resend the screenshot?
User: How to scroll down?
Me: Just use the scrollbar and scroll down.
User: What scrollbar?

That’s the compressed version of a few emails back and forth. I didn’t quite throw my phone across the hall, but I did take a deep breath and drink some water.

Then I took her screenshot and added some comments in it.

ASP.NET error screen with comments

I accompanied that modified screenshot with more comments in my email. I can’t remember what I typed, so here’s the closest version:

Hi,

I’m sure the man throwing files all over the place is all very nice, but I can’t see the actual error below him. Please scroll down so I can see more of the error message.

Regards,
Vincent

Sometimes, you’re not just debugging code. You’re debugging human behaviour.

How to prioritise your tasks

I follow just one simple rule. This rule comes from the culmination of 3 job changes, more than 5 years of experience in programming, administration, technical assistance and interactions with users and peers. And it goes something like this:

Given similar levels of urgency, first do that task which has the most number of people irritating you.

Feel free to substitute “irritating” with “bothering”, “unhappy with” or “angry with”.

What a young king taught me

Garion was a nice young man, raised as a peasant boy in a farm. He’s polite and modest, had a good sense of what’s right and had great friends. He’s also destined to be the king of an island, protected by powerful friends, and guardian of a precious orb. (find out more from the Belgariad series by David Eddings).

I’m going to skip the part about how he grew from just a simple peasant boy to overlord of the western seas. Now, as a king, he knew it would be very hard to get feedback from his people. Just his title alone scares the living daylights out of the lords and ladies, let alone his people.

So what he did was to have a confidant who’s among his people. I wouldn’t call the confidant a spy, and even if you think it is, I’d advise you not to say it to Garion’s face. He could do a lot of damage even if he’s only mildly irritated.

So, this confidant was a glass blower in town. Every once in a while, Garion would make some excuse about needing to buy some glass ware and go meet this glass blower. Then he’d talk with the glass blower and get some idea of what his people were doing or saying. This way, he’d be able to improve the situation. Coming from a peasant background, Garion really didn’t know how to run a kingdom, so he desperately needed feedback on how his laws and actions affected the common folks.

So, there’s this one time where the glass blower mentioned about a particular tax law which made taxes too high for the commoners and too low for the lords. The people were complaining, but no one dared say anything, even though Garion had repeatedly shown his kindness and fairness.

Garion told the glass blower he’d change the tax law in favour of the commoners immediately. The glass blower was surprised, so he asked his king what’s the reasoning behind it.

“It’s actually based on a selfish motivation.” said Garion. “How many people are affected by the high taxes?”

“About five hundred or so.” replied the glass blower.

“Well then, I’d rather have 5 people hating me than 500.”

How does this apply to me?

Let me give you an example. Suppose you have on your task list, in the following order:

  • Development work
  • An email query that you know is going to take an indefinite but probably long time to check
  • A simple data patching that’s an update statement which takes less than half an hour, including verification

Even though development work came first, you have to put it aside because the other 2 are more urgent. Now, you are already half way through the email query, finally understanding what the user was trying to ask in the first place. Then the data patching request comes in.

This is how I see it. Either way, you’re going to have the user who sent the email query, and the user requesting the data patch waiting for you. There are 2 people “unhappy with” you already. Even though the email query came first, and is slightly more urgent and important than the other one, you should complete the data patching first.

Your goal is to have as few people waiting for you to complete whatever they’re asking for. Can you imagine having 10 people waiting for you? You could have completed 9 very fast requests and have only 1 breathing down your neck. Whatever that long task is, that user is going to wait a long time anyway.

The side effect is that you’re perceived as super efficient by 9 people. 10, if that last user understands the length of time needed for his request. Everyone is happy, and at the end of the day, you still completed 10 requests. The trick is in gauging the urgency level.

Anything involving customers (and thus revenue and thus bottom lines) are top priority. Your users (other than direct customers) are next. Users such as sales personnel, customer support officers, marketing personnel and managers.

And you know what? Development takes the last priority. I’m like an all-in-one, so I handle a lot. Luckily, I’ve taken these constant opportunities-to-learn into my project estimations.

Getting burnt out from an overwhelming number of tasks is not fun. People breathing down your neck is not fun. So how do you prioritise your tasks?

Are you conscientious

My friend is thorough in his analysis and coding. Once, he remarked that he thought about solving a work problem while driving home. While bathing. Just before closing his eyes to sleep.

You could call him obsessive, a workaholic. Actually he isn’t. He arrives on time and leaves maybe half an hour after the official work hours.

He did it beyond the requirements of a paycheck. He cared about the work. Yet he’s not passionate about programming. At least not as much as I am anyway.

He did it because he’s conscientious. Because he’s responsible. Because he cares about the people he works with. And so when the situation requires it, he puts in a little extra effort to make his program better, more robust.

Are you conscientious in your work? Do you choose the right way, or the easy way?

Forced to mingle

There was a recent company event. It was organised for the IT departments. It’s usually referred to as a dinner-and-dance or D & D (not to be confused with Dungeons and Dragons). We usually just do the first D (the dinner, not the dungeons). Everyone seems too tired at the end to do the second D.

My colleagues in my department are close-knit. There aren’t many of us anyway. So we assumed we’d be put together in the same table.

When we arrived at the event, we found that we’d been separated. 2 of us in that table, 3 of us in this table, and another 3 in another table. We were a bit miffed of course.

It’s not so much that we were separated. It’s that we were seated with people we don’t know. We were forced to mingle with people from other departments and teams. There’s nothing wrong with mingling. We just weren’t prepared to mingle.

So we went into the event room, sat down at our respective tables and started making small talk with the people at our own tables. Well, at least I made small talk with the person next to me.

Then something happened. People started changing seats. People found out where their friends were seated and a mass migration happened swiftly and quietly. It was kind of fun. So together with the 2 “known” colleagues from my table, we changed tables. The “new” table has *shock* everyone from our known clique!

I don’t know what the organisers had in mind when they rearranged everyone’s seating plans at the last minute. From what I knew, we were in the same table originally. It just shows how humans can behave when forced along some rule or restriction. Given a chance, we will find a way to rectify the situation.

So here’s a question for you to think about. When you design and write an application, do you force your users to be in an uncomfortable situation? Maybe a button that doesn’t make sense, but they have to click on it anyway. Maybe the flow of entering information doesn’t make sense, but they follow your flow because they have no choice.

Fear of the security panel

Digital access by Eva Serrabassa @iStockphoto

Software security is a big thing. You have to be aware of it from day one, and your code must be designed with security in mind. There are no coding details here. Instead, you are going to learn the mentality behind coding for security, and a lesson in human behaviour. And it starts with a story…

The ride up

It’s a typical morning to work. I arrived at the office lobby at 2nd floor. The 1st floor is actually the car park. We can discuss this architectural mystery some other time.

Sometimes, I’m alone, which was cool, because that meant I could take the lift all the way up to the 6th floor where I work. Otherwise, there would be people exiting at the 3rd, and the 4th, and the 5th, and ooohhh, finally, my floor.

Now there are 2 lifts. I timed it, and my experiments told me that squeezing into the 1st available lift to go up to the 6th floor where everyone was in, was slower than taking the next lift that I could take all the way up.

Anyway, on the rare occasion where I find myself caught in a full elevator, I noticed a peculiar behaviour. Now I’m not saying everyone’s like this. It’s just something that’s frequent enough that I took note of it.

First, I need you to visualise the inside of the lift. The doors, which open and close on both sides of the lift, is in the centre of the lift entrance. To either side of the lift are the lift floor buttons. Every single floor has its button, plus the obligatory open, close and “come help save me” alarm buttons.

“Tell me about the weird behaviour already!” you exclaim. Ok, ok…

Some people would stroll straight to the back of the lift, even though they’re the first in. I mean the nice thing to do would be to go to the button panel and hold the lift open while the rest of us are trooping in, right?

Now here’s the even more peculiar behaviour. Some people, even though they’re right next to the button panel, don’t lift their finger to hold the door open at all. Sure, there’s another person at the other panel too. Then that person exits the lift at 3rd floor. No finger lifting. And while people are exiting too, the lift doors close. I had to rush in and take over at the button panel in one instance.

The long walk to the security panel

There’s a reason why I just used a couple of hundred words describing my lift ride. Those very people who don’t lift their fingers to help hold the doors open? On the 6th floor, suddenly, they’re filled with gentlemanly virtue or immense courtesy, and their fingers flew up to press the “open” button. Why?

So that they weren’t the first ones out. Which meant they wouldn’t be the first one to reach the security panel. Which meant they wouldn’t have to whip out their security passes and authenticate themselves, and get the office doors open, and heaven forbid, let the rest of us in as well.

Let me give you a floor plan of the journey from the lift to the office security panel.
Office entrance

These people would hold the doors open and let everyone out of the lift. They’d stroll normally at the same (or preferably slower) speed than the other people. Someone had to open the office doors. This way, they’re the least likely to have to authenticate themselves.

I believe they are legitimate staff working in the office. I believe they have legitimate security passes for authentication. I also believe they’re basically nice people. So why do they behave in such a manner? My conclusion is that they’re plain lazy.

The authentication process is really quite simple. Sure, the security panel can be faulty, and the security pass doesn’t work sometimes. We have this ongoing joke where if your security pass doesn’t work, the company probably fired you. *smile*

But is taking out the security pass for authentication that bothersome?

“What if those people aren’t at the lift button panels?” you ask. “What if they’re stuck at the front of the lift? What then?”.

Aha, here’s the really ingenious part. Please refer to the office floor plan above. See that visitor couch to the left? They would stroll, ever so slowly towards the visitor couch (or the fire escape), letting whoever was behind them to overtake them and thus reach the security panel first.

And after someone else authenticated successfully, and the doors were unlocked, what do they do? They just waited for the authenticator to open the doors as well. During the authentication process, these ingrates couldn’t go to the doors and open them the moment it’s unlocked. They needed someone to authenticate, unlock the doors and open the doors for them too.

Conclusion

Most of the people working on my floor are developers. Except for the administrative staff (only 2), and the team leaders and managers, the rest are all working directly in software related roles. Programmers, systems analysts, consultants.

If these people can’t even be bothered to authenticate themselves at the office doors, what are they doing about software security in the programs they write? Do they implement security or do they just talk about it?

Chinese Lunar New Year office decoration

In a couple of weeks, the Chinese Lunar New Year will arrive. The exact date is on the 7 February (Thursday), and the 7th and 8th are public holidays in Singapore.

It’s a ritual. Once past their due, our unofficial office decorator will take down the Christmas decorations, and replace them with the Chinese New Year decorations. She even has a system for rotating decorations…

So along our partition walls, we have
Welcome spring
The four Chinese characters are (from the left), “welcome spring receive blessing” literally. Feel free to replace “blessing” with “fortune”. The last character is a bit ambiguous in meaning. In this context, it just means something good.

Then we have
Fortune god
It’s a traditional thing to have the typical picture of a boy and girl around somewhere in decorations. I’ll have to go look it up why… The two sets of 7 characters, one on each side, is a bit harder to translate. The rough translation for the left set is “lots of good fortune, happy every year”. It can also be “great fortune, prosperous every year”. Chinese characters pack a lot of meaning into one word… The right set translates to “God of fortune descend (arrive), meet (have) good fortune”.

The ceiling wasn’t a problem for hanging Christmas decorations, so this is a cinch.
Hanging fish decor
Those 3 characters literally translates to “year year have”, or “every year have”. Have what? That fish under the three characters? In Chinese, “fish” sounds identical to “abundance” (or “extra” to be exact). So that decoration signifies abundance in every year. In the past, when people were poor, this used to mean abundance in food, particularly rice, the main staple. Now it just means anything you consider to be good, like money or fortune.

And where the Christmas tree used to stand, the brightly and auspiciously coloured vase took its place.
Auspicious flower vase
The two orangey things are Mandarin orange displays. During the New Year period, we Chinese exchange Mandarin oranges (real ones) with each other. Why? Well, in Cantonese, Mandarin oranges sound exactly like “gold”. So we exchange “gold” with each other. More to the point, we give “gold” to another, and receive “gold” from another.

I know the phonetic similarities stretches meanings a bit, but Chinese are like that… *smile*