More Than Coding

Because machines still need humans

How to write software that is ready for the world

The conventional wisdom in software development has always been that internationalization (i18n) is a very expensive and time-consuming effort, and that it’s always better to target just one language first, adding support for more languages later, when the market demands it. Because of that perception, multilingual support is not often considered during the early days of new software projects, and many products end up being constructed in such a way that makes localizing them more difficult than it should be.

In fact, writing software that can easily be localized at a later stage isn’t terribly hard, as long as you start with the end in mind. Use the following techniques to greatly minimize the amount of work required when you eventually take your software product global.

Maintain user-visible strings separately

By far the most important (and most often ignored) guideline in i18n preparation is to ensure that all user-visible strings are separated from the code that uses them.

The typical approach used to achieve this separation is to store the product’s textual content in resource files for that platform or language. For example, Java programmers should maintain their displayable strings inside ResourceBundles.

Text in applications should never be structurally tied to the application’s logic. User-visible strings should always be modifiable without breaking application flow or other functionality.

Interestingly, this task is becoming less and less important for web applications, thanks to innovations in technology that can automatically extract text content from web-delivered software, send those strings to humans for translation, and even deliver the finished localized content online – all without requiring a single change be made to the original source application. This approach can significantly reduce the effort and time required to take a web application global.

Expect user-visible strings to grow or shrink

English phrases may double in size when translated to other languages, and with other target languages they may also shrink by a sizable amount. It is crucial that product code and graphical interface components must not depend on the length of user-visible strings remaining the same.

This obviously presents a challenge when presenting graphical representations of text to the user, but there are plenty of ways to do that correctly.

Keep images free of embedded text

For everything except company or product logos, images that contain text rendered directly within them should be avoided, because it is more difficult to have that text content translated. Instead of having someone quickly translate the contents of a text file, graphic designers would have to be hired to convert the images and put the translated text on them too, one language at a time.

Plan for different calendar, time, phone and currency systems

Developers writing code should always remember that other countries:

Build a checklist into your existing review process that watches for these kinds of issues in code to prevent any “hard wiring” that will limit your software’s eventual global usage.

Always use established, globally-focused standards when storing data. For example, use E.164 for phone numbers, ISO-8601 for timestamps, ISO 639.2 for languages, ISO 3166 for countries and the Olson database for time zones.

Avoid ASCII, use Unicode

In the past, engineers building software for English-only markets felt safe to do tricks in their code that only worked when the encoding in use was always ASCII. For example, the flip of a single bit of an ASCII-encoded alphabetical character switches it between lowercase and uppercase. However, the world’s needs have long since moved beyond what ASCII provides and has now embraced Unicode as the correct way to encode text data and support international characters.

Even though Unicode is somewhat compatible with ASCII, the best way to avoid string encoding issues is to:

  • never assume that characters are encoded in ASCII
  • never assume that that one byte equals one character
  • always use Unicode-capable types and libraries

Thankfully, some of the most popular programming languages like Java, C# and Objective-C have native Unicode support in their string types. Using them can make dealing with international characters a trivial effort.

Even if an application supports Unicode throughout, it will likely store data in a database, and a bad database schema can easily ruin all of the good work done in the code to make it compatible with international character sets. For example, in a SQL Server database, user-visible strings should be stored within nvarchar types, and in MySQL it would be best to use utf8mb4.

For more information on Unicode, this introductory article from Joel “On Software” Spolsky is a good introduction.

Don’t assume that text always flows from left to right

The most common difference in text layout that may be encountered is a right-to-left flow, such as that used in Arabic and Hebrew.

bbc-arabic

In a web application, simply changing the CSS direction property across your entire system would weed out most major layout issues that would be encountered with a future translation into a right-to-left language.

It is also possible to have text flow from top-to-bottom as well, although that’s far less common.

Keep all user-visible language plain and simple

When application messages get localized for other markets, the job of the translators will be much easier if the language used is plain and simple.

Language that is highly technical and reads like technical jargon will not translate well. Prefer common phrases and terms to niche or less frequently used ones.

Test for basic multilingual support

Good developers instinctively write automated tests for product features that they build. The addition of a few more tests to a product verification suite that verify that the product supports international characters would be a hugely valuable task, and not much effort to create.

For example, imagine a web application that allows people to book concert tickets. Let’s assume that a test already exists that verifies that a fake user called “John Doe” can book a seat at a show and verify that his name shows up correctly on the ticket that he receives after paying. Adding a similar test that changes the user’s name to “John- Doe-批” and verifies that those same characters show up on the ticket received after paying would verify that the application supports international characters all the way through the application and the database. This simple technique (sometimes termed “pseudo-internationalization“) allows developers to verify that their applications support the transmission and storage of international strings but without having to do a full professional translation of the product, or without the developers having to be fluent in a foreign language.

Automated tests can go even further. Tests can be built to verify that right-to-left fields operate correctly, or that international plurals are supported without having to rework the basis of the product’s code.

Embrace the global opportunity

Developing software in such a way that it can be ready for a global release is not as difficult as it may seem, or as it once might have been. By following these simple guidelines and doing a little bit of work up front, you can create software products that can later be made available to a much larger market than you might first address, making your product, and its usefulness, have far greater reach as a result.

What Your Resume Says About Your Programming Skills

If you’re looking to get a new programming job, there is a very important fact to know about hiring managers. Since they are very busy and receive lots of resumes for open positions, they will build a mental profile of a candidate’s skills by scanning their resume in just a few seconds. Much like when you meet someone in person, first impressions count.

Hiring managers hone their speedy scanning skills through years of experience on the job. Knowing how they interpret your resume’s content is often the difference between moving to that crucial phone screen stage and being ignored. Here are a few hints about what messages your resume is sending to potential new employers about your programming skills.

Typos

If you haven’t bothered to run an automated spellchecker over your resume, you won’t be expected to take care when writing code on a daily basis. Typos on a resume are typically viewed as a sign of laziness and disinterest, and can easily lead to them being dropped right into the employer’s trashcan.

Experienced technical hiring managers will quickly evaluate the precision with which a programmer uses language in their resume, and they will extend that impression to the candidate’s programming skills. When the hiring manager sees your typos, they have unpleasant visions of the many bugs you would create in their applications.

Excessive Length

Engineering candidates frequently send resumes that are more than 10 pages long, describing in complete and exhaustive detail every single project the candidate ever worked on. There will be a careful mention of the exact compiler version used on a 3-month contract for IBM back in 1994, along with cryptic company-specific project names like “EDT/BTS” that would only make sense to a handful of people on the planet.

The immediate thought that jumps to mind for the hiring manager upon receiving such tomes? That the candidate probably never revisits existing code to refactor it. The idea of editing a complex routine to break it up into simpler constituent parts for better maintainability and readability is apparently not something that they naturally want to do. After all, they’ve been adding to their resume’s content for years without revisiting it, so why would anyone expect them to do the same with their code? Also, excessive length can also imply that the candidate has a problem prioritizing. In today’s world, where engineers frequently have to juggle numerous projects, prioritization skills are necessary.

Acronym Overload

Technical acronyms are understandably commonplace in software engineering. However, when a quick visual scan of a resume makes a manager feel like they are swimming in alphabet soup, they often build an image of the candidate as being someone who only knows tools and frameworks and has little ability to design software at an architectural level. On the other hand, if the position being filled needs someone who can quickly create “mash-up” prototypes using a diverse set of existing frameworks and tools, having an acronym-heavy resume might be exactly what the employer is looking for.

Lack of Creativity

If an employer were looking for an engineer to build a sexy new web UI, a boring, unimaginative resume created using a Microsoft Word template would be the last thing they’d want to see. Using a dull, expected resume format usually indicates a lack of visual creativity and curiosity, and the employer will often question the candidate’s ability to build aesthetically pleasing web interfaces.

Granted, plenty of engineers whose expertise is in building services that don’t contain graphical interfaces (such as server-side libraries or SDKs) have resumes that don’t push any creative boundaries, and could easily make fine candidates for positions responsible for working in those kinds of areas. However, a decent eye for design is becoming increasingly important for many engineering positions.

Complex Language

Resumes filled with pompous, overly complex language can be a sign of a programmer who prefers to look smart rather than communicate effectively. While this kind of candidate may have written some very dense code that works, nobody on their team probably understands it, and everyone is afraid to touch it in case they break it.

Programmers who have recently left a long stint in academia to enter private industry often produce resumes full of lofty language. In those cases, it’s probably a symptom of them having to write peer-reviewed papers for years rather than a desire of theirs to show off how many grandiose words they know. Still, an overly verbose, high-register writing style can be a red flag that the candidate may not naturally write code that is simple for others to understand.

Job Jumping

Candidates who have a history of jumping from position to position every year ring the alarm bells for many employers – they are the last people a company would expect to think about the readability and maintainability of their code. They will be considered as the kind of engineer that gets excited about working on new challenges but gets easily bored when asked to work on fixing bugs in existing features. Engineers quickly develop expertise in niche areas in any company, so having people leave after a short initial investment is not only costly for the employer, but can be detrimental to overall team morale.

A job jumper might be wonderful for a position that needs someone to build features quickly with the intention of handing their work off to a dedicated maintenance team, or as someone who can migrate from project to project, but they would probably need to be paired with others to oversee their work and ensure that their code is good enough to be allowed to go into production for years into the future. After all, the chances that they’ll still be in the same company when changes need to be made to their work are pretty slim.

What You Can Do

Your resume is a window into your programming skills and your personality. Make a special effort to overhaul yours to be viewed as a more desirable candidate to potential employers. For example, if you’re worried about your writing skills, have a professional proofreader check your resume for typos or stylistic mistakes.

If you are friends with a technical hiring manager, ask if they’ll help you by having them spend just a couple of minutes scanning your resume and then telling you what kind of programmer you appear to be, and in what kind of roles they believe you would fit. You might be surprised at the feedback, but at least you’ll be able to take some action to change how you appear to potential employers in order to make sure you increase your chances of not only getting a job, but of earning a position that is truly a great fit.

Understanding Software Engineering Job Titles

The world of professional software engineering is full of titles and grades. Employers use job titles as a means to help them build new teams with the right mix of talent, attract the right caliber of candidates when hiring, create attractive career paths and assist with compensation planning. However, many companies assign titles differently, making their systems difficult to understand, especially for younger engineers.

Sometimes employers will be very precise and define an engineering career track that might look like this:

Title

Experience Required

Responsibility

Sphere of Influence

Associate Engineer / Junior Engineer / Intern 0 years Bug fixes, minor feature Self
Software Engineer 1-4 years Features Team
Senior Engineer 4-8 years Modules Development Group
Principal Engineer 8-12 years Product, Architecture Company
Fellow 12+ years Products, Technical Strategy Industry

This model is most often used by companies with large and well-established engineering teams.

Other employers use grades that sound more like movie sequels than job titles:

  • Software Engineer I
  • Software Engineer II
  • Software Engineer III
  • Software Engineer IV
  • Software Engineer V

It probably won’t come as a surprise that the above bureaucratic-sounding titles are very similar to the definitions used by the US Department of Labor.

While it’s less common, some companies even drop the concept of job title progression completely and have everyone be just a plain old “Software Engineer,” regardless of their experience or talent. This can work wonders by preventing the formation of ivory towers and by empowering younger engineers to participate at the same level as their older peers. However it can be more difficult to implement because it goes against most people’s traditional (or even cultural) expectations, and it can cause unease for those engineers who strongly equate title changes with career advancement.

Given that there’s no standard structure for engineer progression, a Principal Engineer moving to a new company could be offered the less impressive-sounding title of Software Engineer, even though they may be taking on far more responsibility and increasing their sphere of influence.

Mature engineers tend to focus more on the opportunities and challenges available in a new position than they do about what they’ll be putting on their LinkedIn Profile. They know that any technical hiring manager worth their salt understands that every company uses different scales, and those managers won’t blindly assume that the candidate had been demoted mid-career if they see a title progression that looks somewhat backwards. They correctly focus on the engineer themselves and their innate talents, not on the details of their old business cards.

Should you worry about changing your title when making a move from one company to the next? No, you shouldn’t. At the end of the day, hiring managers for engineering positions are far more concerned about your technical chops than your title. Understanding your responsibilities and sphere of influence will be things that come out in the job interview. So, if you’re on the hunt for a new position, look for companies with a solid business model with a healthy and functioning team that will be taking on interesting challenges. Put minimal emphasis on the title you’ll bear once you work there, and focus more on how the position will allow you to develop your skills and knowledge. Those are the most valuable assets prized by any engineer, and by the managers who hire them.

UX, Then Architecture, Then Tools

Imagine you are building your dream house. Would you trust a general contractor who talks like this?

First, we’re going to pick out the material for the kitchen counter and the glass for the windows. Let’s just guess the amounts of each to buy for now.

Then we’ve got to buy some of that new concrete everyone’s been talking about. I suppose a truckload will do it for now, but we could always order more later. I just can’t wait to try it out!

After putting the beams in place we should decide how many floors the house should have. And right at the end we should decide what style the house will be. Sometime before you move in we should get planning permission, and I’ll probably contact an architect for some drawings after you’ve settled in.

It sounds ludicrous because there’s a well-established method for building houses, and it’s based on common sense. You start with a vision, get a set of plans, pour a foundation, build the framework, fill in the internal stuff, and finally finish all the little details.

Putting any step out of order would cause complete chaos. Finishing the walls before the electrical would mean you’d have to punch holes in all your walls in order to run wires around the house. Cleaning it before it is completely finished would be a wasted effort given the amount of dust builders cause while they work.

However many coders build their systems backwards. They become enamored with the latest whizz-bang framework or charmed by the reportedly speedy performance of the newest database. And they lead their thinking with those choices as they build new features, whether those technologies are appropriate or not.

More importantly, using a technology-first design typically means that the user experience (UX) will be left until last. And if you put your users last in your order of priorities, it will unfortunately be very evident in your system’s lack of usability.

UX First

The first order of business in application design is deciding what its users will experience. This should be a high-level vision sketched out on paper or in simple digital mockups, and it should express the flow of the system from the user’s perspective.

It doesn’t matter if you’re building a web application for senior citizens or a system-level tool for serious computing nerds. The UX must be designed first.

Type of System

Your First Thought Should NOT Be…

Your First Thought SHOULD Be…

Online music player “I’m going to design the database schema!” “Let’s design the UX”
Social media plugin “Let me start hacking around with some online social media APIs!” “Let’s design the UX”
Multiplayer Game “SuperFastDB is apparently really scalable, I’ll start testing it today!” “Let’s design the UX”
Virus Checker “I’ve been dying to write a new virus scanning algorithm, so I’m jumping right into that!” “Let’s design the UX”
GPS Device “I’m going to research the latest in OLED technology right away!” “Let’s design the UX”

Then Comes The Architecture

Once the UX has been designed and the vision of the system has been defined, an architecture should be laid out to make sure that the code that eventually gets written will actually meet the needs of the users. The choices made in the UX design radically shape and inform a system’s architecture.

A good UX design will cater for less obvious things that might be part of the overall user experience. A well-written specification might include requirements such as “the overall load time for page loads must be less than 200 msec” because the designers know the consequences of slow page load speeds. It might also call for close-to-zero downtime, so the architecture might end up requiring a multi-datacenter deployment.

Last But Not Least, The Tools

Now it’s finally playtime! Once the UX has been defined and the architecture has been laid out, the process of picking the right technologies, frameworks and libraries can begin. The crucial point is that now the tools are being chosen with the UX and architecture in mind, so any tool that doesn’t fulfill the needs of either can be quickly disregarded.

This Does Not Mean “Waterfall”

If you think that this design sequence requires an outdated Waterfall-like approach to accommodate it, think again! This is completely appropriate for Agile development. The implementation of a whole new product, an epic or even a single user story should follow the UX -> architecture -> tools sequence. When beginning the development of a product or epic, spikes should be used to design the UX and the architecture. And individual user stories should include enough details for the engineer to know what the UX for that story should be once it is fully implemented, and the engineer should also estimate enough points to cater for architectural planning to be done once work on that story begins.

Tools are great fun to research and to experiment with. Programmers love discovering new ones and finding “The Next Big Thing” in the framework jungle, and having lots of tools at your disposal is wonderful when the time comes to build a system that satisfies the UX and the architecture. Just don’t begin the entire design process with them. So remember: UX first, then architecture, then tools.

3 Signs of Narcissistic UI Design

User Interface (UI) and User Experience (UX) design is hard, no doubt about it. Sadly, many software applications appear to have been built by narcissists, because they seem to assume that:

  • We enjoy being constantly interrupted by them
  • We love to repeatedly try out every feature available they have, including things we will never need
  • We believe it’s worth spending hours re-wiring our brains to deal with their unconventional design choices

How do you know if your application is just as vain? Here are 3 signs of design narcissism:

1. Being Too Noisy

Imagine you hired a babysitter who called you every few minutes during your night out to say:

“Hey, everything is OK! I’m still here and everything is fine! I’ll be calling back every 2 minutes whether you want me to or not! Bye!”

Nobody in their right mind would be happy with that kind of nuisance, but many software applications behave similarly. We somehow convince ourselves that it’s normal, and we put up with it. We even let it cause us some major embarrassment.

Applications with a singular purpose (for example, automatic backup programs) have historically been built by developers who felt they had to repeatedly show the value of that one feature to you. So every time they successfully performed their only important task, they would notify you. They would scream over emails and dialog boxes: “Hey I just backed up your files for the 3,716th straight hour!” That’s the narcissistic approach, and it assumes that the user wants to hear that noise on a regular basis.

And of course, no customer wants to hear it. There’s no value in telling users that nothing is wrong and that the application is working just fine. Instead, they want to hear about things that are not typical. They want to be told about events that require immediate attention.

For example:

Application Please Interrupt Me If…
Don’t Interrupt Me If…
Outlook I have an upcoming meeting There are new emails in my Inbox
Skype Someone is calling me One of my contacts has a birthday
Anti-Virus A virus was detected A routine scan was started
Web Browser I’m browsing a phishing site I can upgrade to a new version
Music Player Never, I’ll notice if the music stops Ever

DropBox is an application that is not narcissistic. It knows not to bother me, and I love that about it. It sits very quietly in my Mac’s status bar, its tiny logo remaining unobtrusive and its noise levels almost at zero.  When I save a file to my DropBox folder, it quite happily synchronizes it without requiring any clicks, acknowledgments or action on my part. When it’s finished, it doesn’t presume that I am waiting with bated breath for the final confirmation of success, so it stays quiet. If I really need some reassurance that it is healthy then I can make the choice to look for the “green tick” on the icon.

Microsoft has also been doing better with reducing interruptions recently. Their latest versions of Office have drastically reduced the number of annoying “informational” message boxes shown to the user, but they still have a few more to go.

A user’s attention should be considered valuable, and any software that tries to grab more of their brain’s time than it deserves will likely be quickly uninstalled.

2. Being Too Helpful

It’s impossible for every single feature in an application to also be the most important one for the user to select. However, most software gives every feature similar amounts of real estate on your screen, regardless of their relative importance. A good example of this is in Microsoft Excel’s toolbar (click the image to enlarge):

Excel Toolbar

It’s basically a “Where’s Waldo?” of features. Since I’m not a financial professional, I never use most of these features. It always takes me far too long to find the “Σ” symbol to sum up data, and that’s because it’s right next to icons for completely unrelated things like Copy, Paste and Undo.

The importance of different features changes over time for each user. Wouldn’t it be nice if an application were smart enough to hide icons from you if you hadn’t used them in a few months? I’d also love to see an application react to the way I use its features. For example, I always use keyboard commands to Copy and Paste, so I would love if my applications would automatically realize that and would just make those wasted icons disappear and give more room to the things I’m working on.

Many developers try to meet everyone’s needs partially but end up meeting no one’s completely. Users are usually faced with the results of design-by-committee interfaces that never seem to meet the needs of each individual. It’s like trying to order a meal at a restaurant that has far too many things on its menu from a waiter who never stops offering suggestions. Time and time again, customers must adapt to the application’s need to offer them every possible option all the time, when all they want is the same dinner they ordered the last twenty times. If you take all users across your install base, chances are every feature is used by someone. But that shouldn’t mean that every user needs to see every feature.

So, before any more Paperclip Assistants are conceived, let’s make sure the software world knows that their customers just want to get their work done, not to have vast numbers of irrelevant features presented to them on a never-ending basis.

3. Being Too Different

Narcissistic software developers will regularly assume that users will be happy to use an application that completely disregards UI design conventions and interaction guidelines. This is usually done to make an application really “stand out,” but in reality the developer’s vanity often makes their application unusable.

There are plenty of examples of terrible user interfaces to be found. One thing they all share is a complete disregard for consistency with established standards. Making a user re-learn how to perform basic operations would normally be a recipe for the application’s total failure in the marketplace, but some lucky products lack any competition, leaving the user no alternative. For example, most of the peripheral hardware devices that I’ve purchased over the years (sound cards, printers, etc) came with proprietary software that look like they were designed as an April Fool’s prank (click the image to enlarge):

overclocker

Developers should have the humility to respect established UI and UX standards unless they can truly show significant value by breaking the mold. But be prepared for an initial backlash if you don’t manage that change well enough.

So, to every software developer out there: remember, if there’s anyone who has a right to be a narcissist when it comes to UI design, it’s not you, but rather the user.

Follow

Get every new post delivered to your Inbox.

Join 35 other followers

%d bloggers like this: