Tuesday, September 28, 2010

Hackers are Heroes?

Today I came across an interesting article by Gary Hamel on Facebook Generation vs. the Fortune 500. He talks about the "Generation F" and their expectations from the workplace, as well as unique skillsets and working styles they bring to the table. Read the entire article on Opensource.com

Saturday, September 18, 2010

Lessons of Comic Books make better UIs

As someone who grew up with comic books and viewed them as some kind of a "secret pleasure", it took me a while to come around to the fact that narrative and visual devices used in sequential art not only apply to the digital media, but can in fact be a driver for better, more immersive User Experiences. With the proliferation of SmartPhones and iPads we have more digitally literate people then ever, and that will only keep increasing.

Somewhat shortsightedly, the main concern of comic book companies has been how to get their print comics on the web, gettomg a second source of revenue for the same basic product (recycled story and art, minus printing, so it's essentially cost-free the second time around).

But why not consider tweaking that product and above everything the delivery model so that the user truly has a different experience, and not just a digital copy of the printed page? Think about it. Comic books were developed on the premise that you want to pack action and essentially bring drawing one step closer to animation. Yet animation and digital comic books have essentially evolved in separate directions, even though the very format of sequential art lends itself to presenting different types of content in different frames. And the technology can handle it now. What it does require is an investment in bringing the "envelope" to the next level, and while it's admittedly more involved than just copy/paste from the print medium, it allows the user to substitute the tactile experiences they're losing in transfer from print to digital (interaction with paper, un-evenness of page due to printing, owning a physical comic book, etc.) they can potentially replace not just with widgets, but with a truly improved and altered user experience.

What's interesting here though, and brings it outside of the world of comic book geeks sitting in dark basements is that the same lessons apply to just about any other vertical. No, it's not just a case of the Geek and the Suit sailing off in opposite directions and meeting each other again half-way across the world. While it's a fact that the comic book properties have flooded the mainsteream in the recent years, there is no reason not to believe that the spike will drop at some point. But for intents and purposes of strictly improving user experiences in any vertical or type of content, the true driver is the fact that today's user has come to expect and prefer information to be delivered in a manner that strikingly resembles, well, a comic book page. We multitask everything. We look at a few things at once. We prefer it that way.

In recently working on User Interface screens for CABEM's upcoming update to our Livia_vLab application it really hit me that this is exactly what we're trying to do. Even though the narrative is not necessarily sequential, everything else applies. User experience design was always about organizing and displaying information in a manner that is engaging, logical and well organized. Comic books do the same. If anything, being free of having to follow a completely linear narrative, the layout becomes even more engaging. It's not a book, it's a command module. And it's not just about storytelling anymore, it's about project management, organization, collaboration, archiving, and every way you find yourself working and looking at information every day.

Wednesday, September 15, 2010

Ten Strikes

A number of web sites block logins after just three failed attempts. Every site wants a different login and password, so sometimes it can take more than three tries to remember which password to use. The paper "Ten strikes and you're out": Increasing the number of login attempts can improve password usability takes a step toward quantifying the costs this policy. They find that increasing the number of allowed attempts to 10 could potentially eliminate 47% of password reset requests.

Wednesday, September 1, 2010

Pipes for Windows?

Today I had to get a list of files out of a zip file and append them into an Excel formatted spreadsheet. As a long time Unix user and being someone unfamiliar with Windows, the easiest way I could think of in under a minute is to use zipinfo and sed and sort to build a CSV file and then paste it into the Excel spreadsheet. It's pretty simple, just:
zipinfo -1 foo.zip | sed -e 's/.*\///' | sort -n -t_ -k2 > foo.csv
(The parameters to sort say to sort by the second field, delimited by '_' characters, which I need to do for this problem).

All very easy on -- from the Unix/Linux shell. The system that will ultimately use these files runs Windows. Is there any quick and dirty way to do this kind of throw-away scripting on Windows?

I have used Cygwin before, and could install it, but it always takes several hours to install, which seems like an awful lot of work to avoid a few file transfers. Of course, I could do the entire process manually under Windows, copying and pasting filenames from Windows Explorer. However, I have about 15 of these files which would make it pretty time consuming.

At the other extreme, I could probably write a .NET program in a few hours, but I have few enough files that copying and pasting from the CSV file is faster just typing a simple command line (though with .NET stuffing data directly into the spreadsheet becomes pretty easy).

So how would you handle this on Windows? Is there something similar to Unix pipes that lets you quickly handle one-off tasks like this?

Monday, August 30, 2010

MySQL Discussion at BGLUG

I went to the Bluegrass Linux User's Group (BGLUG) meeting last Saturday and saw an interesting talk about MySQL by Eddie Pauley. He covered the basics as well as some practical experience in scaling up to larger sites for his employer twinspires.com.

I would like to encourage anyone in the area with an interest in Linux or Unix to attend a meeting. They are typically held the third Saturday of the month at the Eagle Creek branch of the Lexington Public Library, though locations some times vary, so check the BGLUG website for times, topics, and locations. You can also chat with the group on freenode.net channel #bglug.

Sunday, August 8, 2010

Web-App Authentication in a Multi-Domain Active Directory Environment

CABEM has a customer who uses Active Directory internally to authenticate users. A web application we wrote for them ties into their Active Directory setup using LDAP to authenticate internal users to the application, using their email as a login name.

The adLDAP PHP class makes that pretty easy, we just look for the user name matching the email address, then authenticate as that user. They have recently switched to a setup with multiple sub-domains, requiring the application to authenticate across the sub-domains. I found very little on using adLDAP or LDAP in general to authenticate in a multi-domain environment, so I'll document some of what I found here.

Within a single domain, any domain server can answer a query because they synchronize information with each other. The reason for using sub-domains is because the link between the sub-domains is assumed to be too slow to keep domain controllers in sync. Only information in Active Directory's Global Catalog are shared across domains.

Our client has configured Active Directory to put all their internal users into the Global Catalog. That way a user visiting a remote site will be able to log in to any windows machine. The login may take a little longer, but travel to a remote site are uncommon. To reduce the amount of information that needs to be shared between sites, not all user attributes are made global.

The first problem we ran into is that email addresses were not being made global. As a result email lookup failed outside the user's home domain. The straightforward way to fix the problem is to mark the email address as a global attribute.

The other issue is more subtle. The adLDAP library authenticates users by trying to bind to the server as the user. Active Directory expects the user name to be either an LDAP Distinguished Name or a User Principal Name. The distinguished name explicitly calls out information about the user. A typical name would be something like "OU=users, OU=accounting, cn=Bob Smith, dc=carolina, dc= example, dc=com" identifying a user named Bob who works in accounting at the Carolina office of example.com. The DN's are pretty cumbersome, and likely to change if Bob ever moves to a different location.

The User Principal Name can be formed by concatenating the user's Active Directory name to an '@' followed by the DNS domain name of his or her home domain server. In this case it would probably look something like "BSmith@carolina.example.com". Though, this looks like an email address, it is not necessarily. The company we are working with uses a convention that would make Bob's email address be "bob.smith@example.com".

Active Directory generally does not allow anonymous access, for security reasons. Since a single connection with adLDAP might deal with several users, adLDAP conveniently stores the sub-domain name in its account_suffix attribute. However, the account used to get Active Directory listings only exists in one sub-domain and the adLDAP::authenticate method binds as both users within the same method call.

The solution is to set account_suffix to the empty string and pass the full User Principal Name rather than just the SAM Account Name to adLDAP::authenticate. Not using the account suffix really is not any more work. The code calling adLDAP just needs to as for userprincipalname rather than samaccountname.

As is often the case, once you know what to do it's easy. It's figuring out what to do that is difficult.

Sunday, July 18, 2010

Objects vs. Arrays in PHP

Traditionally, an array is a data structure storing values indexed by an integer. What PHP calls an array is really an ordered map, a data structure that maps a key to a value with some notion of how keys should be ordered when iterating through the map. Keys can be either integers or strings, and values can be any PHP type.

The obvious uses for arrays are when you need to store data indexed either by a number or by a key. The ordered map semantics of PHP arrays also allows them to be used to build arbitrary data structures fairly easily. The array keys are like field names and array values are values. New fields can be added at run time, simply by assigning a value to a new key representing the new field name.

This is a wimpy form of object oriented programming (OOP) -- by convention the methods that operate on an array pseudo-objects can be kept in one file, perhaps along with comments that describe which keys could be present. This wimpy OOP saves us the trouble of creating a new class, but relies on convention and extra documentation for clarity.

I have seen quite a bit of code that does this, so it appears to be a common idiom, probably left over from PHP4. PHP5 provides better object oriented support, so when should programmers use an array, and when should they declare a new object?

When To Use Arrays

The built-in array functions in PHP make it easy to use PHP arrays to implement the same functionality as a number of common data structures like queues, stacks, lists, etc. Most of these data structures are similar enough to arrays that it is best to take advantage of all of the built-in array functions, rather than trying to re-implement all that functionality with objects.

Sometimes, it is pretty clear when an array is called for. If you want a variable number of items, indexed numerically, that begs for an array. For example, if to write an RSS feed reader that gets all the articles from a group of sites within the last 3 days, the list of sites and the articles returned would make make sense to store in arrays. Or, to store definitions for words, it would make sense to use an array with the words as keys and the definitions as values. For example,

[sourcecode language="php"]
$words = array(
'doe' => 'a deer, a female deer',
'ray' => 'a drop of golden sun'
);
[/sourcecode]

Retrieving the definition of 'doe' is as simple as $words['doe'].

Things get a little less clear cut when dealing with more complicated data. In the word definitions example, you might also want to store pronunciation, and etymological information. The straightforward incremental change is to make each array value be an array with all of the properties you care about. For example,
[sourcecode language="php"]
$words = array(
'doe' => array('definition' => 'a deer, a female deer'
'pronunciation' => 'do̅'),
'ray' => array('definition' => 'a drop of golden sun',
'pronunciation' => 'rey')
);
[/sourcecode]

Is a common way to handle the issue. As more attributes of a word are needed, they can be added to the array describing each word.

In a language like C or C++ this would typically be done with structs. Passing around data like this in arrays has advantages and disadvantages. The advantage is that you can crank out code pretty quickly because you do not have to design an actual interface -- just put in all the stuff you want for now, and if you have to change it, just add or remove fields later.

Using arrays in this case does have several drawbacks, though. First, there is no easy way to check the type of the array to make sure the right array are gets passed to the right place. Passing a variable to the wrong parameter type to a function or method is a fairly common error to make. If words were defined as objects, the PHP interpreter would catch the error and warn you about it. Any time the interpreter can tell you the precise line of code that has a bug, that is a big time saver.

The second problem is that not thinking about how code will interface usually results in interfaces that are sloppy and inconsistent. In cases like this, it is fairly common that some arrays values are initialized and some are not, so the code ends up having to check for every attribute before it can be sure it is there. Often there will be a set of functions that operate on these word arrays. Putting those functions in an object with a word word makes more sense. Sometimes sets of attributes are mutually exclusive depending on the value of another attribute. This is an excellent time to take advantage of inheritance.

When To Use Objects

The above example can be recoded using objects like this:
[sourcecode language="php"]
class word {
public $definition;
public $pronunciation;
public function __construct($pronunciation, $definition) {
$this->definition = $definition;
$this->pronunciation = $pronunciation;
}

$words = array('doe' => new word('do̅', 'a deer, a female deer'),
'ray' => new word('rey', 'a drop of golden sun')
);
[/sourcecode]

Though this example is about twice as many lines, the more arrays of words you create, the smaller the overhead is. We don't have any word operations defined here, but as they are used more and more, some are likely to crop up.

An advantage of the object-based approach is that PHP can check the type of an object passed as a parameter, when passing a single word, whereas all arrays look the same to it. If you want to make sure an array someone passed is valid you have to explicitly check it, which is more work for the programmer. Unfortunately, PHP does not provide an easy way to require a function be passed an array of a particular object.

Conclusion

If you want a list of items or a hash table or dictionary, then arrays make perfect sense. There are lots of array operations that make operating on arrays fast and easy, so there is no reason to avoid them when they are a logic fit.

When data has well defined attributes and operations an object makes more sense. PHP can provide type checking, implementation can be hidden behind interfaces, operations can be coupled with data, inheritance can simplify implementation, and all that other good object oriented stuff.