Wednesday, January 28, 2009

Are you a Textual Minimalist or a Preacher of the Word

Choose a side


Of course the answer to almost every dichotomy is to find a solution in the middle which is a compromise. Whether you subscribe to the progress of history as Thesis, Antithesis, Synthesis like Hegel and his cronies or whether you believe society is a wave which only appears to make progess and never moves, the reality is that we need to make choices between opposites.

Continuing off a previous post regarding building user expectations, one area which needs further examining is the use of signs as replacements for text. Or rather replacing the sinage of letters with signs which are more readily digested and understood.

Linguistic researched has already shown that words are better representations of signs than their individual letters. There are two phenomenon which represent this. One test concluded that participants can more quickly identifiy whole words than individual letters, and that you can remove vowels from words in a context and still interprete the meaning with very little loss in terms of speed. This is why yo ucan review an article you have written and miss the same misspellings over and over again. Although you think you are viewling and reading each letter and each word, your brain is filling in gaps in order to speed processing.

Ok enough background. What good is this?

Please shut up


Well I am a Textual Minimalist. I would prefer to have simpler signs to designate meaning rather than text. However, in my company alot of people seem to balk at this and prefer to have alot of text. Like over-analysis/under-construction in the design phase, over textualization can often run into the same issues.

First over textualization wastes time be deciding the correct verbage to use. It has to be clear to the user not only in relation to the application but also to previous examples or text. If the text is being added in design mode, it is without context with regards to the application. But, once added to an application over textualization lives in two contexts, one that is the application into which it is inserted, the other which is the everday language we use to communicate.Since the specialized nature of business applications requires verbage which differs from our everyday usage, using alot of text on the screen often requires some sort of jargon interpreter.

A solution to reducing this complexity is to use sing simple signs and color codings. And as in the previous post regarding building expectations, these signs should be conventions regarding first the application, and secondly the business processes. The more abstract the signs are the more likely the user will be able to assign the sign with the action or functionality of the application without using textual interpreters. The business process sets the ocntext fo the application, and the application sets the context for the signs and texts which it contains. This is why building expectations though clear business rules is important for application development. Trying to create verbage in the application to backfill in business logic will almost always yield high resistance to application implementation.

The Difference


I think it is time for an example. Suppose we have two grids, one utilizing text, the other an image.


While functionally the same (clicking either the image or the button), these two cells do not necessarily convey the same message. Using my company as an example, we never delete data. I am not sure why, that is just 'the way it is'. Rows marked as 'deleted' are seldom used for reporting and once marked as such are even less likely to ever again make an appearance. But the point isn't what we do with the data, it is how the user feels as they interact with the application. We need to remember that although developers interact with data, end users interact with applications. Very few have the conceptual framework of data management. One row in a grid is one row in a grid even though the underlying structures may represent several tables and an aggregation of hundreds of rows.

The phenomenon


What happens when you click the image is more closely associated to that image than when you click on the button (whose text and column read 'Delete'). I will say this as fact. The text on the button says 'Delete' but in fact the data is not getting deleted. Would it be better to say "Make data eternally invisible?" Surely this is not an option. Having only the image present reduces the confusion and complexity since it merely indicates a 'going awayness' of the row. The user realizes that after clicking the button the row is irretrievable. Whether or not the data is actually deleted or just hidden is not of concern to the user for their real world usability. In a rare application that is does matter, signs can be used to signify the difference in other ways. In those cases, it would probably be even more problemmatic to have one button that says 'Delete' and one that says 'Hide', compounded even more if there is no 'Unhide' option.

But I have something really really important to tell you right now about this very important thing here onthe screen


Sometimes over textualization can actually inhibit workflow in addition to adding conceptual complexity. The most insidious form of over textualization is the modal popup when used for validation or informational purposes as opposed to stoppping workflow to indicate an error or the need to take corrective actions. How many times during work can I have a box popup that gives me information that I do not really need. And what is in the box? Text.

One symptom of over textualization is not only the sheer volume text, but rather the forcing of this text on the user. Instead of having popups, modal ones at that, disrupt the workflow of a user, or having gigantic panels taking up real estate with instrucitons consider the following:

Validation errors handled with highlighted violators. Empty textboxes can become color shaded. Invalid values can either have text added next to the offender inline with the entry point or submit point or the form can surface a tool tip.

Tooltips are a very useful tool as long as they don't fall prey to over textualization. Tooltips should not be used in place of training documents. If your application has so many tooltips that the user is afraid to stop their mouse, then your application needs to design and usuability re-working.

Informational issues concerning instructions can be put into a helpfile if need be (i.e. 'How to fill out this form'). Better yet, help icons can be surfaced in the place of a modal popup. If the user feels the need to see the information, they can choose to click on the icon of continue working.

The worst for last


Let me give you an example of how the use of over textualization has been abused at my company.

We have a very simple gridlike application for entering Time worked for the week. For Thanksgiving break, they automatically enter the time for you and nicely shade the box indicating that the values cannot be changed for that cost code for those days. All very nice. However, when I tried to enter time for Thanksgiving day, a modal popup well..popped up telling me basically that there was already some time entered for the thanksgiving day vacation and if I needed to change any of the values other than those for that day I could or I could keep the hours I added to Thanksgiving day. Bascially, the message told me to keep on going, don't mind me. It was the worse kind of over textualization, not only did it disupt my workflow (several times actually since the code that triggered the popup kept on triggering somehow), but it also did not give me any real information. It did not say that what I was doing was incorrect. It did not provide a better way of doing anything. It was basically a squirrel that just ran infront of my car forcing me to put the brakes on.

Nothing is wrong with words as long as they are meaningful. And you can quote me on that. Just don't quote me in your next applications.

You might be a corporate coder if...

you'd rather code than play in the snow.*


*(This assumes you are stuck in the office working on work)

Tuesday, January 27, 2009

Linq Madness

Dim query = From cm In db.case_masters _
Where cm.start_date > Now.AddMonths(-36) _
And cm.case_type_code = 1 _
Group Join cr In db.case_relationships On cr.case_code Equals cm.case_code And cr.client_code Equals cm.client_code _
Into bpGroup = Group _
From bp In bpGroup.DefaultIfEmpty() _
Group Join cr In db.case_relationships On cr.case_code Equals cm.case_code And cr.client_code Equals cm.client_code _
Into cmGroup = Group _
From cp In cmGroup.DefaultIfEmpty() _
Join co In db.case_offices On cm.case_code Equals co.case_code And cm.client_code Equals co.client_code _
Where bp.relationship_id = "BV" _
And cp.relationship_id = "CM" _
And co.office_type = 1 _
And cm.case_type_code = 1 _
And cm.client_code = basis_client_code _
Select cm.case_name, billing_region = db.fnOfficeHierarchy_GetEntityNameByApp(office_code, "RG", "DEF"), _
billing_partner = bp.employee.first_name + ", " + bp.employee.last_name, _
billing_partner_home_office = bp.employee.employee_offices.Where(Function(d) d.office_type = 4).First.office.office_name, _
case_manager = cp.employee.first_name + ", " + cp.employee.last_name, _
industry = cm.gxc_case_terms.Where(Function(d) d.relationship_strength = 0.8 And d.gxc_term.term_type_code = 6).First.gxc_term.term, _
industry_practice_area = cm.gxc_case_terms.Where(Function(d) d.relationship_strength = 0.8).First.gxc_term.industry_hierarchies.First.practice_area, _
capability = cm.gxc_case_terms.Where(Function(d) d.relationship_strength = 0.8 And d.gxc_term.term_type_code = 4).First.gxc_term.term, _
capability_practice_area = cm.gxc_case_terms.Where(Function(d) d.relationship_strength = 0.8).First.gxc_term.capability_hierarchies.First.practice_area, _
peg_client = IIf(cm.class_code = "S", True, False), _
portfolio_client = IIf(cm.case_private_equity_portfolios.Count = 0, False, True)

Linq: Projecting Query into New Object VB.Net

Sometimes it is useful to create a new object from data not stored in relational format in your database. In these cases, you can create a custom class and project linq to sql properties into it.

Here we have created an OrderDetail class (not shown) and projected into it properties from our linq to sql query. This will return a type of IQueryable(Of OrderDetail)

Dim query = from p in product _
join o in orders on p.product_id equals o.product_id _
select new OrderDetail with {
.ProductName = p.name,_
.Quantity = o.qty}

Building user expectations vs managins user experience

I see this over and over again with the applications I build. Each project, while professing to be different from last time, inevitably falls into the same old pattern of development. One area which falls victim to this more than anything is standardization.

For the most part our applications get data and display data. In those rare occassions where data is actually manipulated, it is most often done in some sort of grid format. And while my peers may grumble at the humble excel like structures, it is a format which is reasonably familar to the average user.

Sit an average worker in front of excel and they can do something with it. It isn't rocket surgery. Word and Excel manage to thrive because as functionality is added over time, the core product remains the same. Buttons, behavior and layout remain virtually untouched in the majority of functionality facing a user. Microsoft has done an amazing job building user expectations. When the next version of Word or Excel comes out, I will jump right into it creating pivot tables and writing long-winded diatribes.

This is boring. But this is how we ultimately get things done. Less time is spent learning relearning and training and more time working.

But there is another counter trend which appears from time to time, especdially at our company. Doing things in the same way is no longer acceptable. In each project a tiny group of business product owners and even smaller group of developers decide how THIS project should behave and how THIS grid should act. The 'THISNESS' of the project acts blindly towards previous projects as well as typical usability conventions. Why is this?

One potent motivator is the need for people to feel as though they are involved in the project. Everytime someone opens the application and the first cell of the grid is red, they can smile and say "I pushed for that". Whenever columns are read-only for no apparent reason, someone can point proudly to the fact that users are being saved time by not wasting valuable writing time. When it then becomes impossible to enter a cell because upon entrance the current cell becomes the cell to the right, well thank the Lord because the user does not have to even enter a cell to try to type in it.

Overanalysis is the second motivator in the example seen above. It is like a snake in the middle of your path. You carefully walk by the snake. It doesn't move. You feel the need to be certain, so you go back and prod it with a stick. You get bit. The problem is that someone already told you the snake was alive and indeed very poisonous.

Analysis is not bad. But the focus of the anlysis should be clear. There is a big difference when analyzing "What should be done vs How to do it". Often more time spent on detailing out the objective of the application will decrease the time spent figuring out how to do it. There is a big difference in thinking regarding the following two sentences:

"We need a way to highlight vacation times greater than one week"
AND
"We need to highlight vacation time greater than one week with a red underline"

One way of thinking is generic and adaptable. The other is much more rigid. In addition there are far more assumptions made in the second statment. Why red? Will the user know what a red underline means? Alot of time can be spent over analyzing such issues while more important business objectives fall to the wayside. This is even more true if there are no standards across development. And this is still only in the planning phase.

Strangely placed buttons, wierd acting grids and the like aim to manage user expectations. Development teams (including process owners) often see this as a way to save time and create something unique. However, people work much faster if they have new tools which imitate existing tools. Imagine if everytime you typed in a certain application, the letter C came out as a P. But with another application C came out as N. I could almost guarentee there would be no good reason for doing this, but it is not out of the realm of the impossible. Far greater assumptions have been made while developing applications.

Business applications should strive to build user expectations by building on standard behavior and presentation as well as standard business processes. Product owners should review existing applications when modeling future ones. Similar naming conventions, color coding and language goes a long way towards productivity and can cut down on development time by reusing code and cutting out the need to cumbersome help files to document not only how this works, but even to a less visible degree, how this applicaiton works as opposed to another internally developed application.

But I am just one man...well it is time to get back to my grid, which has readonly columns without indication, blinking, twirling and other useless features. Don't worry, it will save your data...well some of it....well eventually.

Linq Select Subquery

Dim db as new DataBaseDataContext

Dim query = from p in db.products _
select .category_name = (from c in db.category where p.category_id = p.category_id select c.category_name).first

Friday, January 9, 2009

Morality, Aesthetics and Denormalization (pt1. Moving towards an ethics of denormalization)

A Computer Problem


So I had this problem. I have a list of names (B). From this list of names I need to produce another list of names (N). Both B and N have data attached to them. B always exists, N's existence relies on B's existence.

We can picture the list of B as as the lowercase alphabet and the list of N as single digits (0-9)

Both B and N contain additional data.
N is created from B but it is not static.
For example, we can create a relation between B and N several ways.
One B can be made into several N (d-->2 && d-->3)
Many B can be made into one N (a,q,c-->1)

In addition at any point in time the relation NB can change. What was once (a,q,c-->1) is now (a,q-->1). In this case, 'c' is removed from N and is no longer relevant in the relation.

The purpose of this relation BN is to ultimately get data about this relation. So BN is only relevant once data (W) has been gathered on BN. W as a set of data includes datetime information about BN as well as a series of questions about BN. W is a context in which something can be said about BN.

The first pass at creating this structure was a standard march towards Normalization. We already have B, we can create N. Now we need a table which maps B to N. So far so good. But oops, we forgot about the point in timeness. We could create a history table with an audit trail, or create date range fields on the mappings and create new mappings whe needed. Since the relation BN could change at any time and we need to track BN, the relation BN is also immutable. This would be alot of work to normalize and maintain in an application.
Let us digress just a bit...

A Moral Issue


In the above example, B represent a morality. It is unchanging. What is B has always been B and is unable and unaffected by its relation to N. The data tied to B underlies many programs. It is a sort of primary key across applications. It is either B or not B. (using the references above 'a' is 'a' or not 'a') That is all it can be. N on the other hand represents something completely different.

N by itself has no meaning. It is a fleeting event, a concept, an idea. It is an aesthetic component. It is totally arbitrary. There is no value judgement placed on N. For this manner N can actually contain 'a' and not 'a'

Here is where the car is going....
B is 'Thou shall not kill'
N is the death of some man

Viewed in this manner the relation BN which takes place within the context of W (or in fact IS THE CONTEXT of W). W itself is the ascribing of meaning B to an event N. If we picture two scenarios using B and N above we can see how the this works.

SCENARIO A: A man walks down the street and is robbed and killed by a complete stranger.

SCENARIO B: A man walks down the street and is robbed and stabbed by a complete stranger. In the course of the struggle, the victim overpowers his assailent and kills him.

In both of these cases B and N is the same. One shouldn't kill (or murder) and in each scenario someone dies. However, in the relation between the underlying morality and the event, we end up with a relation BN. The judgement we make on that relation is W. W is valid only for that point in time in which the relation BN exists. To fully flush this out is beyond the scope of this post. Of course there are questions as to the completeness of facts and other intangibles. W becomes history which then can inform and shape morality but remains something completely different.

Extending W beyond the BN relationship


It is important to understand the BNW relationship in both a computing and noncomputing environment. From the computing environment, we could store every BN we needed to within a defined set of lists, assign each one an id and totally normalize the data. We could be insane and create millions of two column tables. However, if the relations are never used, then we have created alot of noise with no return or value. This is made worse still if we had to then account for new BN relations. W allows us to create a context in which to gather data.

In terms of W, is it important to note that while W may represent a context, it ONLY represents a context. W informs us about an event (N) taking place against a set of pre-defined rules (B). W cannot inform us about another W. If we need to reanalyze W, we do so by converting W into an N. Our new knowledge becomes the context (W) which we can say something about. But, since B is contained in each and every W, B can be influenced in light of W at the occurrence of N. The opposite cannot be true since the N which is contained within W is never the same N. For even though it may appear to be the same, viewing it as such is a matter of convenience. Trying to say something about every instance of N through W results in the naturalistic fallacy. And I think that is a good place to stop.

What makes a corporate coder?

This will be a growing list.

      Shows up to work

      Codes for N hours a day

      Thinks company events rock

      Thinks free pizza is better than profit sharing

New inspiration

I grabbed the title of this blog from a presentation by Zed Shaw hosted at http://www.vimeo.com/2723800.