Projects – the things I do
Articles – things I recommend or wrote myself
Personal – more about me
Recent changes – what’s new on this page
Some time ago a bold gentleman by the name of “anon” edited the What sucks page on the Hatta’s main wiki, and added a strange line in there:
This is a very silly way of making a feature request – I have no idea what that is supposed to mean. I just can’t imagine a way that “encryption” of any sort could be added to an open wiki like Hatta and be useful in any way. So I made it a link to a feature request on the bug tracker with a question about what it is supposed to mean.
As could be expected, this was a typical “ask and run” feature request. The guy just added his first vague thought to a list and never ever came back. I will give him some more time and close the ticket as “wontfix”, removing his comment from the page. No problem, if you don’t care about your feature requests, why should I?
But the silliness doesn’t end here. Now the Bitbucket is getting pestered about introducing “encryption”. First there was a question on the IRC channel, but nobody managed to answer within the 2-minute attention span of the asker. Now on the mailing list. They guy got a detailed answer about how the Bitbucket infrastructure is secured against code theft, but he keeps on insisting on adding encryption somehow somewhere, not understanding that it is not going to change anything. As it usually happens, his ignorance is coupled with stubbornness and hostility. Sigh.
So I’m writing this post mostly to vent. I don’t think that it will help any of the people I mentioned (or maybe it’s a single person?), because it’s too long for a 2-minute attention span, but perhaps it will clear some matters about web applications.
In short, a web application runs (mostly) on the server, under complete control of the system administrators who have access to that server. If that application needs access to any data (for example to display the contents of your wiki, or contents of your repository), it needs to read that data on the server. That in turn means that if the data is encrypted, the application needs to decrypt it on the server. Anybody who has root privileges on that server also has access to the decrypted data through many means. It doesn’t help if you provide the decryption key every time you use the application, and it doesn’t save it anywhere. It can be modified by the attacker to save it, for example. Or to save the decrypted data. Or the decrypted data can be taken from the application’s memory. Or from different levels of caches. Whatever the application does to obtain the key and decrypt the data, the attacker can do exactly the same thing, if he is determined enough. Once you have a malicious person with root privileges or physical access to the machine, it’s a lost fight. That’s why they do so much to not let that happen.
Then again, if you believe that the source code that you have written in the last month or so is so innovative, revolutionary and precious that there are people willing to go through all the trouble with breaking into that server just to get it – and at the same time you don’t understand the basics of how encryption works – then you need professional help. But don’t seek it on the Internet, you are not going to get it there.
A list of ten most stupid things you can do with my password to your website or other service:
I’m playing with junk.
This is really fun. All you need is an old modem, two broken cellphones, old mouse (the kind with a ball inside) and a button battery and you can make a light-chasing “Herbie” robot. Really!
LM386-something. This is the amplifier that we will need.That’s presumably all (I’m still playing with that stuff, looking for a good battery).
I recently gave a talk on the Google Summer of Code Mentor Summit about usability, in particular about so called Cognitive Dimensions. Then I thought that I might actually write about it in some more detail. You see, Cognitive Dimensions (or some variation of them) may be very useful for programmers or web developers who are forced to make their user interface decisions on the fly without a help from an expert and/or usability testing. They let you foresee the consequences of the decisions, at least to some degree, and pick the alternatives that have a good chance of being more usable.
Since the dimensions don’t really have any formal unit or scale, you cannot really use them to evaluate the usability of interfaces. All you can do is taking two possible solutions and telling which one is “better” in certain dimensions. If in addition to that you can somehow imagine which dimensions are more important for you at that particular place, you can pick the solution that suits you better.
Ok, enough, here come the Cognitive Dimensions (of Notation):
This is the distance between the smallest little detail that your user interface supports, and the largest general thing in it. The shorter that distance, that is, the smaller the difference between the detailed and the general things in your application, the better. If the users have to manage little details and at the same time keep an eye on the overall structure, they will get tired quickly.
You should pick the level of abstraction most adequate for the task and stick with it as closely as possible. You may even want to structure the workflow in such a way that it is divided into tasks with different levels of abstraction but narrow scale of abstraction in each of them – but beware, because it will affect the other dimensions.
Usually the elements and controls of your user interface represent something – they map to some real or virtual objects and terms. Closeness of mapping tells how closely they resemble what they map to. The resemblance need not me visual – in fact, it’s in the ways that are important for your particular application that they should be similar. In the very simplest approach, this tells how far are the things you are manipulating from their controls – but it’s not just limited to that.
The canonical example of a bad mapping, beloved by all usability experts, are the valves and burners on a kitchen stove: the burners are aligned into a square, but the valves are usually aligned linearly. It’s very easy to open the wrong valve – because the mapping it and the thing it operates – the burner – is not very close.
We all know that consistency is good, but how to measure it? We can say that two features are implemented in consistent (with each other) way if by learning to use one of them you have already learned to use the other – it just works the same, or similar, way. Your interface should be internally consistent – all the elements should be consistent with each other where possible – but it should also be consistent with the operating system it runs on, other applications the user may be using or have used in the past, etc.
How dense is the information you are showing? How much of it fits on the screen or a page? How much of it is actually necessary – can you remove any irrelevant information, or show it in a way that is easier to understand? You should generally favor terse notation over sparse one – the fewer the users need to look at, the better, as long as it lets them get the job done.
What errors and mistake can the user make when using your interface? Could any of those be avoided or somehow made harder to make? You can try using some Poka-yoke techniques.
Are those errors fatal? Can you do something to make them non-fatal? Maybe an undo function or some sort of sanitizing the input?
How early are the mistakes detected and reported? Maybe you could notify the user earlier and save him some time before he goes on building upon bad a foundation?
Some operations are hard for humans and are much better performed by machines. Your interface shouldn’t force users to perform hard operations, such as: calculating, remembering things, counting, searching and locating, inventing names or passwords, repeating, aligning things, etc.
Note: human short-term memory can hold a limited number of items – usually from 4 to 10, depending on how concentrated you are and such. If you interrupt one thing and ask the users to do something else, and you do it several times, they will forget what they were doing in the first place – or will need some time and effort to recall that. Remember about that and try not to nest tasks within each other, even if it makes sense from the programming point of view.
Dependencies between elements of your interface, or objects they manipulate, should be as obvious as possible. When manipulating something also affects other things, the way they change should be preferably visible, or at least indicated in some way. Don’t make the users constantly switch between screens just to tune something exactly how they want it.
This is a clever trick to check how well your display reflects the important aspects of your application. Just put two instances of your application, with different data in each, next to each other. Can you tell at a glance that the data is different? Can you tell what is exactly different? Can you tell what operations you need to make on one instance to get it to the state of the other?
Premature commitment is when you ask your users for some data that they don’t have yet, they are not sure about yet or that may change in the near future – and you insist that they input it here and now. Even worse, you may make it hard to change it later. This is bad. Try to avoid “trap doors” in your user interface – always let the users change their minds and correct their mistakes. Also, make sure that it’s cheap – don’t make them reboot their computer just because they have chosen the wrong option, or restart filling a registration form because they have picked a user name that is already in use by someone else.
Provide immediate feedback on user’s input. Display partial results, and show how the user inputs affects them. If some data is missing use some default values. This way the users are in control, can learn faster and can notice their errors earlier. If displaying the results is expensive, display a lower quality preview that just shows the important details. If the input is not finished (for example, the user is typing code and didn’t finish it yet, so there is a syntax error), at least display something – even if it may be wrong.
Make sure that it is obvious what each element of your interface is for. Make buttons look like buttons, links look like links, decorations look like irrelevant fluff (or get rid of them entirely), etc. Make sure you don’t use the same thing to mean two different things – even if it’s aesthetically pleasing. The users should be able to tell what they can do with interface elements and what will happen then. Follow well established traditions and “intuitive” meanings (beware! they change from culture to culture).
Allow the users to put more information than is strictly necessary. Let them leave comments and notes for themselves and for other users. Variable names and comments in code, margin notes in books, syntax highlighting in text editors, text formatting in blog posts – even such a simple thing as ignoring multiple spaces and newlines in data files – it all helps the users to add helpful things you didn’t think about. Humans don’t like rigid environments, so leave some wiggle room for them.
This is basically how hard it is to change something in your application once it is done. Generally the easier it is, the better. High viscosity often happens when the operations you provide are on a lower abstraction level than the operations the users want to perform – like a text editor that allows inserting and removing spaces, but not indenting and unindenting whole blocks of code. The difficulty may come from a number of different sources:
Knock-On viscosity happens when there are many interdependent elements, and changing one requires you to change others and this change may in turn require further changes, etc. You may need to rethink your presentation or provide operations that adjust the dependent elements too.
Repetition viscosity is similar in that it requires many changes, but this time it’s the same change repeated all over. Following the DRY (Don’t Repeat Yourself) principle helps here.
Scope viscosity happens when adding or removing something suddenly requires you to use a completely different representation. For example, you started your drawing too close to an edge and made it too big, and now you need a larger sheet of paper – but of course that requires you to redo or copy the picture somehow. This sometimes happens when you have a “simple” and “advanced” mode.
Are all the elements and information that users need visible? How easy they are to find? How hard it is to access them? Are they presented in a convenient and understandable way? Are they obscured by other elements at the moment when users need them?
Are important things more prominent than irrelevant details? Things may be hidden not just because they are obscured or not displayed, but also because hey are lost in a sea of information.
Since about a year I’m playing a tinwhistle, or maybe should I say I’m learning to play tinwhistle, even though there is hardly any progress recently. I’ve chosen tinwhistle as my first musical instrument because of three reasons:
If you always wanted to learn to play some instrument, and you don’t have a piano or guitar gathering dust on the attic, tinwhistle is a great choice for beginners – go get one right now and start playing. You even avoid all the difficult music theory related to chords – just simple plain melody.
Unfortunately, after a short while you start noticing the downsides of a tinwhistle:
There is, however, a musical instrument similar to the tinwhistle, but without those downsides. It’s slightly more expensive (again, there are insanely expensive ones too) and much harder to get (forget about finding it in any small or medium-sized music shop), it is also slightly harder to pick up. Well, it’s extremely easy to pick up if you already know the tinwhistle. On the plus side:
If you play a tinwhistle and enjoy it, you may want to also try an ocarina. There is however a number of differences you must remember. First of all, ocarina is not really a single instrument (well, there are many kinds of whistles too, but they are all pretty similar, with the same fingering, etc.) – there are four major kinds you may encounter:
Another difference between the ocarinas and the tinwhistles is in how the tabs are written. In tabs for tinwhistle you use numbers telling how many holes to cover – so 6 is the lowest note you can play, and 0 is the highest (not counting the second and third octave). For some unknown reason ocarinas use a reverse notation: 1 is the lowest note, and 7 is the highest (in the same octave). To convert from one to the other, just subtract the numbers from 7.
Of course there are lots of differences in tuning of particular instruments, in various advanced techniques you use (although cutting, tapping and rolling are there for both), etc. – I will leave all that for you to discover.