lmi
[Top][All Lists]

## Re: [lmi] InputSequence questions

 From: Greg Chicares Subject: Re: [lmi] InputSequence questions Date: Wed, 24 Mar 2010 17:03:17 +0000 User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

On 2010-03-24 13:48Z, Vaclav Slavik wrote:
>
> On Tue, 2010-03-23 at 21:22 +0000, Greg Chicares wrote:
>>
>> > e_number_of_years  - "for N years", is this end_mode only?
>>
>> No--I'd omit the word "for", which suggests that this is a right-hand
>> endpoint;
>
> That's because I had trouble seeing how it could meaningfully be used
> for the left-hand point; that's clear now.
>
>> this just quantifies an endpoint. AFAICS these have the
>> same meaning in the example above (issue age 45, retirement age 65):
>>   1000 [5,retirement); 123 address@hidden, @72); 0 address@hidden, maturity)
>>   1000 [#5,retirement); 123 [#5, @72); 0 address@hidden, maturity)
>> A number without '#' means a duration--the number of full years
>> elapsed since inception. A number with '#' means the number of full
>> years elapsed since the beginning of the preceding interval.
>
> (I think this should have been "the end of the preceding interval". And

Yes: not the beginning, but the end. With the convention that
duration zero (the issue date) is the "beginning" of a preceding
interval that fails to exist.

Let's see if I can state it more clearly. We'll start by defining an
endpoint to be the beginning or end of an interval. (Already some
readers think my quest for clarity has become hopeless because 'end'
is overloaded and there's no such thing as a 'beginpoint'; but you're
a mathematician, so....) Now we take the origin, duration zero, as the
first endpoint; then we walk through the intervals, following the arrow
of time forward (which IIRC is required to be left to right in the
'sequence' text) and marking every new endpoint as we encounter it.
Whenever we see "#N", we look back at the last endpoint we had marked,
then mark a new endpoint N years after that last-preceding endpoint.

If we see just "N" in a context where it must designate an endpoint,
then we mark a new endpoint N years after the origin. Thus, the
difference between "N" and "#N" is only the frame of reference.

> for use in the left endpoint only; for right-hand one it means "since
> the left-hand endpoint". So "from the previous endpoint"?)

Yes, that's what I was trying to say.

> What do you think about the following UI? It's based on these
> assumptions:
>
> (a) any sequence (but not necessarily its textual representation) is
>     continuous and covers the entire [inception,maturity) domain

True. I interpret "continuous" and "covers" as meaning that the
intervals constitute a partition of the domain, in this sense:
http://en.wikipedia.org/wiki/Partition_of_a_set
Thus, they're
- non-overlapping
- non-empty
- collectively exhaustive
- mutually exclusive

I got stuck on "non-empty", but worked through it as follows.
Certainly no interval of negative measure can be permitted,
but what about zero measure?

Even if we normally wouldn't create an empty interval, is it
possible for one to sneak in implicitly?
issue age 45
retirement age 65
123 [0, retirement); 0 [retirement, maturity)
Suppose we enter that sequence in a "census" (what a '.cns' file
represents) as the "case default" (what the magnifying glass icon
with three stick figures represents), and then add a cell with
issue age 65 and retirement age 65 (both the same age). Perhaps
the *realized* sequence ought to degrade gracefully into the
*equivalent* of
0 [0, maturity)
which could be well-defined as meaning nothing. It's not vitally
important, because the original sequence must be invalid for
issue age 66+ anyway.

But today we forbid it--the steps above elicit this diagnostic:

Interval [ 0, 0 ) is improper: it ends before it begins.
Current token ';' at position 20.

and AFAIK no one has ever complained about that.

It may seem reasonable to guess that I must have substituted
0 [0, maturity)
for
123 [0, retirement); 0 [retirement, maturity)
to get the messagebox quoted above, but I did not. Diagnostics are
expressed in terms of the "mathematical" interval thought-model which
InputSequence::mathematical_representation()
represents. This entry:
123,#0;0
would give exactly the same "Interval [ 0, 0 ) is improper"
diagnostic even though the entered string contains no '['.

I had to study the phrase "it ends before it begins" carefully
to convince myself that it's true: [0, 0) has no measure because
it cannot exist (because it would have to include and also exclude
the origin). In our integer domain, the least possible measure of
a proper interval is one.

So, yes, it is obvious [0] that intervals must be non-empty.

> (b) it's natural to express the intervals as [a,b); so let that be
>     the only way they are shown to the user in this UI

Amen. Lest anyone misunderstand, we wouldn't show the symbols
'[' and ')' like this:
amount      interval
1000     [0, 20)
0     [20, maturity)
Instead, we'd show something like this:
amount   from     to
1000      0      20
0     20   maturity
[but see below: to[N] == from[1+N] here, so the redundancy can
be eliminated...or retained for clarity...]

> (c) the number of intervals is small, ~6 even for complicated
>     expressions, and almost always <10 or so

Oh. I hadn't thought of that. But maybe it's okay to limit the GUI
to a "reasonable" number of rows.

Someone may indeed (albeit rarely) enter a 100-term sequence like this:
1000000; 1001000; 1002000; ... 1099000
(issue age may be as low as zero, and maturity age 100 or even higher).
But to what heroic lengths should we go to accommodate that? I'm
assuming that this is a pop-up dialog, and scrollable dialogs always
feel wrong. OTOH, if the dialog contains a grid control instead of
many discrete controls, then a scrollable grid might be okay.

I think the answer is dictated by how awful the GUI would become
without a limit. It's not worth radically redesigning the GUI in
order to obtain a different answer.

> You commented on both (a) and (b) in affirmative above and I assume (c)
> based on the examples I've seen so far; if anything, I suspect they are
> more complicated than the real usage is.

I think something like the
1000000; 1001000; 1002000; ... 1099000
example above actually has been observed in userland.

> You suggest in #104480 to use value, from-duration, to-duration columns.
> I'd get rid of the from-duration one and only show the data like this:
>
>
>       Value  |  When
>
>     [     ]     [-----------------------]   [-Remove]
>     [     ]     [-----------------------]   [-Remove]
>     ...
>     [     ]     until maturity

Oh, yes, that's clearly better. [but see (far) below]

There's an implicit "When" before the first row, which would always
be the time origin. It's appropriate to leave that out of the GUI.

Instead of the word "When" we might use "Until" (though that's an
implementation detail that can be postponed). Then the second column
in the last row could just say "maturity". (I think the plain text
with "maturity" above is written with no '[]' to indicate a static
control, which seems exactly right.)

> Note that this isn't a grid, but grid-like layout of regular dialog
> controls. I think this is pretty common in email clients for setting up
> filters, for example. The "Value" column would contain text controls,
> wxChoices or wxComboBoxes (for entering number-of-keyword [*])

Both "Value" and "When" could be either numeric or text; but all
text would be picked from an enumerative set, and no free-form
text would ever be needed.

> To repeat your earlier example:
>
>   1000 [5,retirement); 123 address@hidden, @72); 0
>
> which normalized according to (a)+(b) is
>
>      0 in [ 0,  5)  *** implicitly zero
>   1000 in [ 5, 20)
>      0 in [20, 25)  *** implicitly zero
>    123 in [25, 27)
>      0 in [27, 55)
>
> this would look like this:
>
>
>       Value  |  When
>
>     [    0]     [until year      ] [5     ]      [-Remove]
>     [ 1000]     [until retirement]               [-Remove]
>     [    0]     [until age       ] [70    ]      [-Remove]
>     [  123]     [until age       ] [72    ]      [-Remove]
>     [    0]     until maturity

Perfect. (IMO, that is; other opinions are welcome, but really
must be expressed soon.) If we change "When" to "Until", then
it becomes simpler still because "until" need not be repeated.

We have something a little different today on the "Solve" tab:
Value  |  Year  |  Age
where "Year" and "Age" are locked so that their difference is
always the issue age. If we expressed intervals' endpoints only
as year or age, it might be nice to show an extra column. But
we have "#N", and someday we might add 'calendar year' and
'inforce duration', and...um...yuck. No, the simple array
you sketched above is the right thing to do.

I don't know what text we'd use for "#N". "Years hence"?
We can figure that out later.

> Noteworthy properties of this design:
>
> * It reads as text. Hopefully it's clear that it begins at the beginning
>   and that every line continues where the previous one ended. We can --
>   and probably should -- add "and then" static text after every row
>   (before [-Remove]) to emphasize this, if the read-only "until
>   maturity" is not enough of a hint.

We can decide that later, but I might even omit the "and then".
It might help first-time users, but would be a distraction for
everyone else, so I'd feel comfortable steering first-timers to
a user manual.

If we had the resources of microsoft, we could detect whether
the user has ever tried this feature, and pop up an animated
paper-clip guy to offer help. (Maybe we could fix msvc, too.)
Given the resources we have, I think it's appropriate to remove
every nonessential feature and rely on the user manual for
instruction. Illustration systems are designed for expert use.

> * In the first part of "When", you choose duration_mode; then, if it
>   makes sense for it, a numeric entry field appears.

This number ought to be validated interactively.

To see what we do elsewhere, try this:
File | New | Illustration
"Payments" tab
enter "-1" in the "Dumpin" field
Now try to change focus by tabbing or clicking, or try hitting OK.

> * There's the problem with "until" that you mentioned yourself; it's not
>   clear whether the interval is closed or open. I hope that this can be
>   fixed by better wording alone (any ideas?). If not, the "When" header
>   may spell it out ("Until when (not including the endpoint)").

We'll restrict the GUI to '[)' intervals. Then "until" is always suitable.

> * [-Remove] and [+Add] buttons make it easy to do big changes without
>   making a mess of the UI. It's still possible to clean the sequence
>   completely easily (4 clicks in the same place in the above example).
>   [+Add] adds a new row to the end of editable rows, i.e. just above
>   the last line, "until maturity".

One could imagine an extra "Remove all" button, but that's unnecessary,
and we want to avoid anything that's unnecessary. As you say, four clicks
will do it; or go back the the input sequence's single textcontrol and
delete its contents.

I wonder whether anyone will want an "add in the middle" function that
would subdivide an interval. That might be nice to have in rare cases,
but:
- requiring a whole sequence to be retyped isn't all that harsh; and
- subdivision gets complicated, especially when we disallow intervals
of measure zero.

Perhaps a little graphic like this would help:
|----|-----------|-----------------------|
0    5          10                      28
if [0, maturity) is of length 28 and there are interval endpoints at
interior points 5 and 10. That's just a stray idea.

> * The ability to enter invalid data (overlapping intervals, incomplete
>   sequences) is much reduced.

Simpler is better. Less is more.

> * For completeness, here's the list of "When" phrases needed (modulo
>   Greg's justified critique of the phrasing):
>
>      "until retirement"
>              (no text field)
>      "until year %i"
>      "until age %i"
>              (numeric text field)
>      "for the next %i years"
>              (I'd much prefer phrasing that doesn't require putting
>              text input field in the middle of the phrase here, for
>              obvious reasons)

I interpret '%' as meaning that the numeric column would be enabled
(and not that the numeric value would be inserted at the '%' as for
printf()).

I'm thinking
retirement
year
age
years hence
where the last one needs more thought...
years hereafter
years thence
years further
further years
# years
We can work it out.

>   Note that "until maturity" is not needed, it's always the implicit
>   last row.

Exactly. Just as "from 0" is the starting point implicit in a
nonexistent zeroth row.

> A variation of the same could include from-duration too, as read-only
> text repeated from previous row, to improve understanding:
>
>
>     [    0]  from inception   [until year      ] [5     ]
>     [ 1000]  from year 5      [until retirement]
>
>
> What do you think?

That's a hard choice. The alternative introduces redundancy, which
has a cost; but it might increase clarity. I'll say again that our
customer is the expert user, who already has a mental model of what
an illustration system is supposed to do and only wants a simple
"cheat sheet" mapping that model to lmi. No mapping is so perfectly
intuitive as to be understood without explanation. What will delight
them is a simple, reasonable mapping that they can get at a glance
with a modicum of initial effort, and that once learnt gives them
the power and flexibility to get their work done.

I'm growing to like this alternative. The begin-points are filled
in automatically, of course, and they're written into read-only
static controls. Each row can be understood in isolation as well
as in context; for instance, this single row:
>     [ 1000]  from year 5      [until retirement]
maps to a single thought.

> [*] It would be useful to know the different value types that can be
>     used with this control, with corresponding controls in current GUI.

The asterisk refers to:

> The "Value" column would contain text controls,
> wxChoices or wxComboBoxes (for entering number-of-keyword [*])

Declared in 'input_seq_helpers.hpp':
std::map<std::string, std::string, std::less<std::string> > dbo_map();
std::map<std::string, std::string, std::less<std::string> > mode_map();
std::map<std::string, std::string, std::less<std::string> > sastrategy_map();
std::map<std::string, std::string, std::less<std::string> > pmtstrategy_map();
and implemented in 'input_seq_helpers.cpp'. For example, "death benefit option"
is a "term of art" for which these values are conceivable:
m["a"  ] = "A"  ;
m["b"  ] = "B"  ;
m["rop"] = "ROP";
Please use the values in the first column, e.g. lowercase "rop",
because that's what input sequences use.

In a particular context, not all conceivable values are necessarily
allowable; 'input_harmonization.cpp' already takes care of that,
I think. For example [slightly simplified]:
DeathBenefitOptionFromRetirement.allow(mce_rop,
database_->Query(DB_AllowDBO3));
so if you're using a wxItemContainer, this line
if(datum->is_allowed(j))
in MvcController::ConditionallyEnableItems() dynamically populates
the control with the values allowed in the current context.

---------

[0] "it is obvious that"

http://math.bu.edu/people/jeffs/joke.html
| A professor was notorious for leaving complicated demonstrations to
| the students, with no more than a remark that "It is obvious that..."
| One day a student interrupted. "Professor, is it really obvious that
| the second line follows from the first?" The professor looked at the
| board, wrinkled his brow, paced about the room for a few minutes, then,
| triumphantly said, "Why yes, it is obvious."

reply via email to