How to add dots and shorten a string

March 6th, 2010 by admin

While working on the back-end Calcatraz management system, I came a cross a situation where I wanted to display strings, but if they were too long I wanted to truncate them and add three dots to the end to show that this had occurred.

I first got on Google and looked for a solution. The best (as in most brief) solution I found could be distilled down to this:

(strlen($str)>10)?substr_replace($str,'...',10):$str;

It’s a bit clumsy, and contains the variable name three times, so would become quite long if the variable name was itself long. It would probably be best wrapped in a function to keep things clean, even if only used once or twice. I decided to try and do better. My first attempt was:

(strlen($str)>10)?substr($str,0,10).'...':'';
It’s shorter and only contains the variable name two times. However, it’s still not great. If it was inlined in code it is difficult to spot where it starts and finishes, so again wrapping it in a function call would probably be the best way to go.
I then realised I could achieve the same thing  with a single call to preg_replace(), like so:

preg_replace('/(.{10}).*/', '\\1...', $str);

This is shorter still, only uses the variable name once and is a single function call making it easier to spot the start and end. It’s not perfectly descriptive, but the second argument in particular does hint at it’s function. I’d be happy using this inline if it was only to be used a couple of times (and the surrounding code was otherwise quite straightforward).

Another Quick Tip: inline divs in IE

February 7th, 2010 by admin

In Firefox, it is easy to create an inline div (i.e. a div which adjusts its width to fit its contents). You just do this:

div#elemid { display: inline-block; }

However, it doesn’t work in IE. It took me a while to figure out how to get it working, so here’s the solution:

div#elemid { display: inline-block; *display: inline; zoom: 1; }

It works for the latest versions of IE, Firefox and Chrome (and possibly others – I haven’t tested yet).

Hopefully that’ll save someone some time.

A Quick Tip: Webpage Simplification

February 7th, 2010 by admin

If your web pages have a large number of nested div and table tags you may end up wondering whether they are all really necessary, and whether you might not be able to get by with less. While you could run through your code and assess each one individually and decide if it can be removed, there is a quicker, easier way to approach the problem. Simply add the following right at the end of your CSS definitions:

table { border: 1px solid red; }
div { border: 1px solid green; }

This will draw a border round each div and table on your page and let you visually see which are really necessary. It also works better than looking at each table / div in turn as often each seems necessary; it is only when you look at the big picture that you see that two or more can be combined.

As an illustration, here are the before and after screenshots when I applied this to the Calcatraz homepage. The excess tables / divs can be seen in the before shot (click on the image to see it full size). Notice how I’ve been able to two of them in the after shot, leading to shorter, cleaner html, with more of the presentation being handled in CSS where it should be.

Before:

The Calcatraz Homepage - Before

After:

The Calcatraz Homepage - After

Getting GTD to Stick #1: Offline or Online System?

February 7th, 2010 by admin

I’m trying to implement a Getting Things Done (GTD) system which works for me and which I can stick at on an ongoing basis. I’ve tried various set-ups in the past but constantly find them becoming derailed and eventually abandoned. In the process, however, I’ve seen enough to know it is something I want to get working more permanently. I’m making a push at the moment to get a proper system that works for me and that I continue to use. I’ll keep my progress posted on this site.

Online or Offline GTD Implementation?

The first issue is (as I see it) the big one. The main reason GTD hasn’t worked for me to-date has been that I’ve never found the right balance between online and offline. Previous systems have either been almost entirely computer-based and then failed because I spend most of my time away from the computer / my @computer list is the largest and I need all my online time for clearing it. Or they’ve been largely offline (i.e. in a notebook or organiser) and have failed as they are too bulky to carry around or are too inflexible to use. The offline systems are further affected by the fact that much of my offline time is not in contexts suitable for use of the system.

It seems to me that my ideal system will have to be somewhat of a mix between online and offline. It will also need to be workable with inconsistent and limited time in each context.

Some ideas I have which I’d like to try implementing:

  • Having lists stored / in the most appropriate format for where they’ll actually be used. For example computer actions should be stored in a text, excel, or similar file on my laptop / usb key, while errand actions should be stored in a lightweight notepad or similar that I can carry with me anywhere.
  • A central offline store for projects which is used to farm actions out to the appropriate lists. I’m thinking about having a large notebook which acts as the processing phase of GTD exclusively – inboxes will get summarised into there in terms of the projects / actions they inspire. Then the projects can be extracted to a list somewhere and the actions farmed to the distributed lists as and when appropriate. This processing setup would also let me make good use of the relatively large amount of time I have where I’m able to work on my own stuff but don’t have computer access (which was the Achilles’ heal of my attempted online systems).
  • I may make that central processing notepad small enough to be portable if needed (I’m thinking legal pad / moleskine…).

Mixed Online / Offline GTD System

So I’m going to give the mixed online / offline system a go. It’ll take more work to set up and get going, but hopefully it will let me tailor individual parts of the system to more neatly integrate with my situation.

To kick it off, I’m going to begin with the following:

  • A medium-sized notepad (large enough not to feel restrictive, small enough to be portable if needed). This will be used as a funnel into which all inboxes are emptied and processed. It will contain a series of entries, each a single line identifying a project and the next action on that project. These will be scored off as I farm them out to the various lists.
  • A pocket-sized diary for calendar items
  • A pocket-sized notepad for entering @errand / @anywhere tasks.
  • A medium-sized notepad for @home tasks
  • A text file for @computer tasks (stored on my usb key)
  • A medium-sized notepad for project / someday maybe lists

Note that I already have reasonable systems in place for initial capture – that’s something I do to a decent enough standard for the time being.

During offline time I will process inboxes into the processing pad. Then as appropriate I’ll move items onto the distributed lists when I’m in the appropriate context to do so.

Next Actions

I could go elaborate endlessly on the details, but I’ll save that for later. Today I’ll focus on two things:

  1. Getting hold of the various notepads, etc.,
  2. Making a start on processing some of my inboxes into the processing pad,
  3. Doing any two minute actions which show up during that time.

Defining Website Value

January 30th, 2010 by admin

Recently I attempted to define in as objective a way as possible how much value my online calculator is providing to its users. The idea is to come up with an equation which gives me a ’score’ of how much value has been provided to users. With this, it will then be possible to optimise the site to provide as much value as possible. For instance, when considering two possible improvements I can use the equation to estimate the likely increase in value. That then lets me know which one to go ahead with (the one likely to be of most value to the users).

At the end of this post are the notes I made while trying to figure it out. They’re probably not of any use to anyone, but I though I’d share them. Before that, though, I want to outline the process I went though as hopefully this will be a bit more useful.

Step 1: Identify the main source of value you provide

The first thing I did was to figure out what user actions provide the main source of value. For me, since my site is a calculator, this was clear. Value is provided when a user enters a calculation and receives an answer. There are other potential sources of value (e.g. someone may find some value in one of my blog posts). But I want to focus on the calculations as my main value proposition. I may include other sources of value later, but now I’ll focus on just the one.
Step 2: Identify possible outcomes for the value action

When a user takes the value giving action (e.g. performing a calculation), one of several things can happen. Specifically, value can be delivered or not. In my case I found there were four possible outcomes when a visitor was on the main calculation page:

  • No calculation performed
  • Calculation answered correctly
  • Calculation answered incorrectly
  • Calculation not answered

I initially didn’t include the ‘No calculation performed’ outcome, but then added it in as I realised that a user incurs a time cost in visiting the calculation page and thus if they don’t perform a calculation then the value provided is actually negative (i.e. it cost them and they gained nothing).

Step 3: Identify time costs

Each of these actions incurs a time cost to the user. Like the ‘No calculation performed’ case, all four outcomes incur the cost of the user first visiting the site (though this cost is actually shared among all calculations the user performs in that visit).

The  other three also incur the time cost involved in typing in the calculation. This is then followed by the time cost in waiting for a response. Hopefully all these costs should be minimal, but it would be wrong to ignore them.

By analysing web logs, etc, it should be possible to get exact values for this time cost in most cases. The only thing that can’t be exactly pinpointed is the time it takes for the user to find the site as this may include, e.g. searching on a different site such as Google.

Step 4: Identify the user-derived benefit and costs

Assuming the user takes the action required to produce the value, three things can happen. Either the user gets the value they were after, they don’t get the value, or they get a wrong answer which may actually cost them (in that they may act on incorrect information).

In the case that the right answer is provided, we know that the user has received some value. While we don’t know how much there is one assumption we can make – it should be greater than the cost the time cost the user expected to incur. Otherwise the user wouldn’t have take the action (assuming rationality). We can figure out the expected time cost in a way similar to the actual time cost calculated in step 3. This just involves estimated averages across all sites (such as average site response time) rather than using data specific to my site. I also made an assumption that a user would expect a return of at least 10% greater than the time invested to make it worthwhile.

In the case that the calculator returns no answer (where I haven’t yet implemented the calculation asked), then the user gets no benefit, but also no real cost other than the time invested.

The final case is that the user gets given the wrong answer. This could potentially be have a large cost to the user if they act on the incorrect information. While hard to quantify, one assumption I felt confident making is that a rational user would cap their potential losses in relation to their potential gain. For this I assumed that the user would cap losses at, at most, 1o times their potential gain.

Step 5: Write out value expressions for each outcome

We now have enough information to write out expressions for each outcome, in terms of the total actual time cost (which I called ‘alpha’ for no good reason), and the user’s gain if the answer is correct, which I called G. These came out to be:
  • No calculation performed: -alpha/2
  • Calculation answered correctly: G – alpha
  • Calculation answered incorrectly: -10*G – alpha
  • Calculation not answered: -alpha

Step 6: Derive a lower-bound on each expression solely in terms of the gain

We know alpha is the actual time cost the user incurs. This is related to a lower-bound on the gain, G, by the user’s expected time cost (call it alpha_e). With a bit of work (see the notes below for details), we can rewrite the value expressions so that they are expressed in terms of the lower-bound on G. So essentially, we have value expressions written solely in terms of (a lower-bound on) G.

Without getting into to much detail, we can basically total up the value provided to a user when they perform a set of calculations. This will give us a value score for that set in terms of G. While we don’t know what G actually is, it doesn’t matter – as we will be using the value calculation simply to compare one set of calculations to another (separated in time, by user, by calculator version, etc.) we can just drop G entirely.

Conclusion

Now we have an expression for the lower-bound on the value provided by any set of calculations and resulting outcomes. While not perfect (an exact score would be better than a lower-bound), I think it might be the best that can be done without figuring out what user’s are actually doing with their calculation results (and I think that’s their own business). It will still be very useful to be able to compare the lower-bounds as these are likely to be reasonably well correlated with the actual values. Also as the aim is to increase value over time we can be fairly confident that this is occurring if we can see that the lower-bound on the value is increasing over time.

My Rambling Notes (or Stop Here and Don’t Read On)

The main aim is to provide value to users. In order to do so with the greatest impact / least effort, it is necessary to optimise the value provided. In particular, potential projects should be prioritised based on the value they are expected to deliver. However, value is one of those difficult to define things, which makes an objective assessment of the value delivered by projects difficult. Nonetheless, I think it is worth trying to get as good an approximation as possible.

For the time being I’m restricting the value calculation to the core calculation service. There are four basic outcomes which can occur when someone interacts with main calculator page:

  • No calculation performed
  • Calculation answered correctly
  • Calculation answered incorrectly
  • Calculation not answered

If it is possible to assign a reasonable measure of user value to each item, then it will be possible to combine them into a reasonable total measure of the value provided by the calculator in a given time period, per user, etc.

In general, there will be a fixed time cost involved in performing any calculation (regardless of the result). For the time being, call this alpha. The cost when no calculation is performed will be somewhat less than this. At a rough estimate it will be alpha / 2.

Should a calculation be performed correctly there will be some gain G for the user.

If a calculation is not answered, then this gain G will not be realised. However, should the calculation be incorrectly answered, not only will the gain not be realised, but the user may be significantly affected (e.g. by entering into a bad financial transaction based on the incorrect result). While we can’t say exactly what magnitude of loss this might be, it seems reasonable to expect that any rational user would cap their potential losses at 10 times the possible gain. At the very least, at that risks beyond that level, they could be expected to verify the calculation results with other sources. So the maximum loss can, I think, be taken to be -10*G.

Combining these we can get value expressions for each of the possible outcomes:

  • No calculation performed: -alpha/2
  • Calculation answered correctly: G – alpha
  • Calculation answered incorrectly: -10*G – alpha
  • Calculation not answered: -alpha

This will be more useful if we can express it in a single quantity. To do so we need to look at the relationship between alpha and G.

There is a quantity related to alpha which will be useful to us. This is the time cost the user expects to pay, assuming a reasonably responsive system. Depending on the performance of our system, alpha may be greater or smaller than this. We’ll call this quantity alpha_e.

A rational user would not carry out actions which did not at least repay the expected initial investment plus a bit of ‘profit’ to make it worthwhile and absorb associated risks. Thus we can expect G to have a lower-bound of perhaps 1.1 * alpha_e.

That’s a bit better, but still not quite there. We can get the rest of the way by looking at what exactly alpha and alpha_e are. These, as noted above, are the time cost of performing a calculation and the expected time cost of performing one on an averagely responsive system respectively. They have the same formula:

time_to_input_calc + time_to_perform_calc + time_to_reach_calculator / num_calcs_per_user

The only difference is that alpha_e represents the user’s expectation of these values while alpha represents the actual values.

We can assign approximate values to these for alpha_e. Something like this, perhaps:

alpha_e = time_to_input_calc_e + time_to_perform_calc_e + time_to_reach_calculator_e / num_calcs_per_user_e

= 10 + 3 + 10 / 5

= 15 seconds

This gives a lower-bound on G of 16.5 seconds.

Now, we can perform a similar calculation for alpha. I don’t know exactly, but the result will probably be something similar. Assuming for the time being that it is, we can then say that G >= 1.1 * alpha. We could easily adjust the multiplicative factor should analysis of the data show that alpha and alpha_e show that they differ.

But is relating alpha to a lower-bound on G any use? It’s not precise, but it gives a possible approach.

Totalling up the value for a set of calculations (based on the expressions above) we will get something in terms of G and alpha, e.g.

value = a * G – b * alpha

If we can get an upper-bound on b * alpha in terms of G, then we’ll get a lower-bound on the value in terms of G:

Setting G = 1.1 * alpha, we get our upper-bound on b * alpha:

b * alpha < (b / 1.1) * G

This gives us a lower-bound on the value provided as:

value >= (a – (b / 1.1)) * G

So that is our lower-bound on the value provided to the user by a set of calculations. The a and b variables can easily be calculated by totalling the values of G and alpha for each calculation in the set. The 1.1 factor can be assumed constant (or calculated from the actual data observed). And G is essentially irrelevant to us. As all value calculations will contain a multiple of G, we can simply drop it – it contains no useful information.

So we have, pulling everything together, finally:

value >= (a – (b / c))

where

a = answered_correctly – 10 * answered_incorrectly

b = 0.5 * no_calculation + answered_correctly + answered_incorrectly + not_answered

c = 1.1 * 15 / (time_to_input_calc + time_to_perform_calc + time_to_reach_calculator / num_calcs_per_user)

While not an exact measure, (which wouldn’t really be feasible), it does give us a lower-bound on the value provided (given the assumptions made above). This is almost as useful as we can now operate with this as our measure in value and strive for a constantly increasing lower-bound on the value provided. While the actual value may be somewhere higher than this, improvements in the lower-bound will almost certainly result in the actual value provided being increased (if not perfectly correlated, this should at least happen on average over time).

Note that there are no units – this doesn’t matter as the primary use of this value is to compare two sets of calculations, or options, to determine the relative value provided to the user.

Technorati Claim

January 25th, 2010 by admin

9W7P7Z6N4RQE

Calcatraz, the Fast Online Calculator

January 23rd, 2010 by admin

Recently a number of changes I made to the calculator have been causing a bit of a performance hit. To counteract that I’ve been through and made a few simple changes:

  • Removed some external file includes which were no longer needed
  • Implemented better caching to prevent unnecessary re-requests
  • Modified the core to minimise the amount of work being performed in the most-frequently used code.

The last of these required some profiling to be performed. For this I used webgrind for PHP (which requires xdebug to be installed, which I did on my local testing environment). While this set-up was a bit fiddly to get going, it was worth it as it let me pinpoint exactly where performance was being the most affected. As a result I was able to cut calculation time down from 2.5 to around 0.5 seconds on average. The result is faster page loads every time.

The year ahead for Calcatraz

January 11th, 2010 by admin

Happy new year, everyone! 2009 was a very exciting year for me. The idea for an online calculator  has been kicking around my head for a few years, getting progressively refined. As of March 2009 I began work on turning it into more than an idea. The first few months were spent progressively refining the core algorithms until I had it working in the way I had imagined. A basic user interface was then added and I put the calculator onto a live site in August 2009. As Calcatraz was little more than a prototype at this stage, I avoided doing any big promotional launch. Instead I have been working steadily since then to improve the site.

One of the main improvements made was to significantly improve the user interface. I noticed that users appeared to be getting confused by the sudden jump from the neat front page to a much more cluttered calculation result page. To resolve this I consolidated the two into a single page which acts as both the front page and the calculation result page, removing much of the clutter in the process. The result was an immediate increase in the number of users successfully performing calculations.

In addition, I also extended the range of core calculations performed from some basic calculations to a range of scientific calculations. To this added the ability to perform many unit conversions and, more recently, currency conversions. Another new feature with which I’m particularly happy is the display of full calculation workings.

2010

Moving on, I have many improvements planned for 2010.

I have already taken a number of steps behind the scenes to increase the amount of time I have free to spend on Calcatraz development, which should see an increase in the rate of improvement.

The focus for the start of the year is going to be on the continued improvement of calculation results. As well as improving on current answers, I’m looking to continue to expand the depth and range of calculations performed. This will involve further additions to the core, unit conversion and currency conversion modules. Additionally, several new modules will be added extending the types of calculations Calcatraz can perform.

A number of enhancements to the core algorithms are planned. These enhancements will increase automation within the development process, freeing up time for development in other areas. They are also expected to enhance the quality of calculation results.

I’m also looking to improve documentation and provide a much easier and more comprehensive set of help guides. While Calcatraz is intended to answer any calculation posed to it, it will be useful at this early stage in its development to assist users in finding the right way to express their calculation. It should also serve as a useful range of examples to illustrate what can be done.

Of particular importance is the value provided to users. I will be actively attempting to measure the levels of value provided and make use of opportunities to increase that value. Hopefully, in doing so I can tailor the calculator more accurately to the needs of the user.

I expect 2010 to bring about a significant maturing of Calcatraz as an online calculator. Perhaps I will plan a ‘launch’ towards the end of the year. Alternatively I may just continue on the path of continual improvement and allow the quality of the calculator to speak for itself.

I hope you have a happy new year, and continue to enjoy my ever improving calculator.

List of Online Calculators

November 14th, 2009 by admin

I’ve decided to compile a list of web-based calculators to better help me understand the online calculator market. I hope also that it will help everyone find the best calculator for their needs. I aim to make it as comprehensive and unbiased as possible. I’ll be adding to it as time goes by, but if you have a suggestion, please let me know. Here goes:

General Calculators

This section lists calculators which offer general calculation capabilities. These allow you to simply type any calculation into a free-form text box which they then try to answer.

Calcatraz – My free online calculator offering scientific, unit and currency calculations. Shows workings and a history of previous calculations.

CalculateForFree multiple functions – A calculator script with many functions. This calculator includes different measures conversion, rule of three, temperature conversion and other formulas.

Google calculator – Google will provide answers to calculations entered into the main search box.

Instacalc - The fast, easy shareable online calculator.

Wolfram|alpha – A computational knowledge engine. Enter a query and it uses its built-in algorithms and a growing collection of data to compute the answer.

Task-Specific Calculators

This section is for calculators which provide one specific function (e.g. scientific calculator, tax calculator, etc).

CalculateForFree -Free calculators for home, work and school. The main page offers a basic calculator with links to a wide range of specific calculators including travel, poker odds and global warming calculators.

Calculator.com – Another site with a number of specific calculators, including mortgage, math, loan, finance, scientific, health & sports calculators.

Calculator.net – Claiming to be the richest collection of free online calculators, it offers a large number of specific calculators including mortgage and loan calculators and a number sequence calculator.

Math.com – A collection of specific calculators including trigonometry, probability and finance calculators.

Well that’s it! If you know of a web-based calculator which isn’t on this list, please let me know.

The fast, easy and shareable online calculator.

The qualities of a great web application

November 8th, 2009 by admin
The qualities of a great web application
I aim to make Calcatraz into a great web application. To do so effectively it is important to understand the qualities a great web application exhibits. So what are they? Here are a few things I have thought of:
1. Punctual
A web application should be quick: quick to load, quick to respond to user input, etc. However, I don’t think that calling the required quality ’speed’ would be entirely accurate. There are instances when things can be too fast – an error message not displayed for long enough, for example. In general, events should happen at the appropriate time. If the user does not need a time lag, then there should not be one. I think the correct word is ‘punctual’ – the app should do things at, rather than before or after, the right time.
2. Minimal
A web application should be minimal. Not in the sense of leaving out important features, but more in the sense of containing no unnecessary parts. Anything which does not perform a necessary function should usually be removed. Where several parts perform similar functions they should be generated by the same code.
3. Magical
There is a quote ‘any sufficiently advanced technology will be indistinguishable from magic’. I think this applies to great web apps. Components of the application should be worked on and crafted to such an extent that it is no longer possible for the user to readily comprehend the underlying process.
4. Intuitive
Use of the application should be easy. Even complex parts of the application should be straight-forward to use without prior knowledge. This requires not just simplicity, but an understanding of human psychology. By understanding the mind and it’s quirks, an experience can be tailored to it.
5. Unlimited
A great web app will be unlimited in the sense that users do not hit upon limits while making use of it. That doesn’t mean the app can do anything in the world, but it does mean that it can do anything in its domain. This requires general mechanisms for extending the application upon its lines of functionality. An example is Google Analytics, while it doesn’t capture everything you need to know about your app, it can be readily extended to do so.
6. Responsive
An application should be the product of user feedback. While it should not necessarily address every bit of feedback (as good for one user may be bad for another), it should be shaped and moulded into the form and function which delivers the most value to the most users. It should continue to evolve over time with changing needs.
7. Predictive
As well as just responding to user requirements, a great application will predicted future requirements. New functionality will appear before a user realises they need it. Only genuinely useful improvements will be made – those that enhance and improve the user’s experience.
8. Avaliable
The application will be on-hand wherever the user requires it. It should be unobtrusive, but always available and easily invoked.

I aim to make Calcatraz into a great web application. To do so effectively it is important to understand the qualities a great web application exhibits. So what are they? Here are a few things I have thought of:

Punctual

A web application should be quick: quick to load, quick to respond to user input, etc. However, I don’t think that calling the required quality ’speed’ would be entirely accurate. There are instances when things can be too fast – an error message not displayed for long enough, for example. In general, events should happen at the appropriate time. If the user does not need a time lag, then there should not be one. I think the correct word is ‘punctual’ – the app should do things at, rather than before or after, the right time.

Example: Not an web app as such, but Google Chrome is exemplary in this area – compare it to Firefox or IE to see the difference.

Minimal

A web application should be minimal. Not in the sense of leaving out important features, but more in the sense of containing no unnecessary parts. Anything which does not perform a necessary function should usually be removed. Where several parts perform similar functions they should be generated by the same code.

Example: The 37 Signals guys do this really well. See BaseCamp for instance.

Magical

There is a quote ‘any sufficiently advanced technology will be indistinguishable from magic’. I think this applies to great web apps. Components of the application should be worked on and crafted to such an extent that it is no longer possible for the user to readily comprehend the underlying process. Alternatively it should be surprising – as in it offers something obvious but that no one even conceived as being possible.

Example: PHPAnywhere – coding is suddenly mobile.

Intuitive

Use of the application should be easy. Even complex parts of the application should be straight-forward to use without prior knowledge. This requires not just simplicity, but an understanding of human psychology. By understanding the mind and it’s quirks, an experience can be tailored to it.

Unlimited

A great web app will be unlimited in the sense that users do not hit upon limits while making use of it. That doesn’t mean the app can do anything in the world, but it does mean that it can do anything in its domain. This requires general mechanisms for extending the application upon its lines of functionality. An example is Google Analytics, while it doesn’t capture everything you need to know about your app, it can be readily extended to do so.

Example: Twitter – while the app is incredibly simple in itself, it is being put to an incredibly wide range of uses.

Responsive

An application should be the product of user feedback. While it should not necessarily address every bit of feedback (as good for one user may be bad for another), it should be shaped and moulded into the form and function which delivers the most value to the most users. It should continue to evolve over time with changing needs.

Predictive

As well as just responding to user requirements, a great application will predicted future requirements. New functionality will appear before a user realises they need it. Only genuinely useful improvements will be made – those that enhance and improve the user’s experience.

Available

The application will be on-hand wherever the user requires it. It should be unobtrusive, but always available and easily invoked.