2017년 7월 28일 금요일

Ordered Search and Lookup


Abe Getzler
Sep 2016

Purpose
This doc shows how to present a sorted lookup table to a user in ten step wide (customizable) zooms, for logarithmic speed lookups.  The original data used for this sample was taken from a two way translation app, so a choice of translation table is offered at app startup.  The two languages I will call French and Shinimare (I haven’t heard from the table author what the second language is called, so I am guessing here.)


Sample screens



This is a pretty simple screen layout.  A List Picker chooses which conversion table to load, by user-friendly name.  A second List Picker presents the table’s first column at successive zoom levels until the lowest detail level where a single element is chosen and its translation (column 2) is shown in the label.  Notice in this sample that half our ranges have only a single item in them.


Designer



Besides the two List Pickers and the Label, I have two File components, one for the friendly directory of translation files, and another for the actual translation file.  Both files are in csv table format.  A Notifier is included,to show the Progress Dialog during the slow tale load process and reassure the user that his app has not gone dead during the file load.

Screen1.Initialize


At startup time, we need to load the directory of translation tables.

Lists.csv


French to Shinimare,db2.csv
Shinimare to French,db2inv.csv


Column 1 contains the friendly name, and column 2 contains the file name to be loaded (independent of path).


When File_Lists.GotText
When the very small lists.csv file arrives, it is loaded into global fileMap as a table, then the first column is split out into the global fileTitles, for presentation in the first List Picker.


First
This is for convenience, to keep my blocks small and simple.


When lpkFile.AfterPicking
After a translation file is chosen, we build a file name from ‘//’ (for Media File access) and the lookup result in our newly loaded global fileMap.  We initiate the file read using the FileData control, and announce what we are doing, in a Notifier Show Progress Dialog, the lpkFile.Text , and in the lpkView Text.


When FileData GotText
This section receives the huge text from loading a translation table.  Some people like to send their text directly into a csv to table block for simplicity.  Because I am not sure my input table is robustly formatted, and because I have to make a second pass through it to load just column 1 into another list, I am attempting to do this in one pass.  Feel free to change this if you can get it to run faster.


When we are finished loading, we should have two important global variables loaded:

⦁ Pairs contains the complete table (selected word, its translation) and
⦁ Words contains the contents of column 1 of the table Pairs, for use in a List Picker.


After the global lookup table is loaded, the Progress Dialog can be dismissed.


The global Stack is initialized with the furthest possible zoom out of our pairs table, from line 1 to the last line.  The SectionName value procedure is used to build a text string expressing the range, as First Word [...] Last Word. The List Picker lpkView Elements are loaded from the Stack.


sectionNamesectionName.png
This routine receives two parameters, fromLine and toLine, specifying the starting and ending line numbers in the lookup table pairs, looks up the words at those two locations, and expresses the range as those two words separated by a fixed string “[...]”, which will be used later to split the two values after selection.  The separator had better be unique, and not in the lookup table, or it will mess up the split.


If the range only has one line in it, then just the one line from words is returned.


when lpkView AfterPicking
when lpkView AfterPicking.png
The List Picker lpkView does the work of presenting search range options to the user and zooming in on each successive Selection he makes.


Two local variables, from and to, are loaded with the line numbers in the pairs table holding the front and back parts of the Selection, splitting the Selection at the “[...]” string.  This reverse the effect of the sectionname procedure.


If from equals to, we have zoomed in all the way down to a single word.  We show the word and the translation result on the screen.


Otherwise, we have to apply Divide and Conquer to the selected range, dividing it up into smaller ranges to be presented at the top (location 1) of our Stack.  This is like branching out from a branch to smaller branches, so I call the smaller branches leaves.


From
From.png
To
To.png
The From and To value procedures take a sectionName selection string and try to split it at the separator string ([...]).  A list of one or two items results.  The first (From) or second (To) item is looked up in the words list, and its position is returned.  The max function is used for bulletproofing so we don’t fall off an end of a list.


Leaves
leaves.png
This procedure returns a list of sectionNames to be added to the Stack and presented to the user as he zooms in from his current step.  The from and to  parameters define the starting range to be divided into subranges.  (The stack parameter is defunct, oops).


A local value step is calculated by dividing the length of the current range (to-front) by our zoom factor, from global maxChoices (currently 7, change it to 10 for faster wider zoom, for example.)
We avoid fractional line numbers.
For each n from to down to from by step (at least 1), we add to our result the sectionName of the range (n-step) to n


The resulting leaves are inserted at the front of our Stack, and presented to the user in the list  picker lstView, which is re-opened for convenience.


The old section names at the bottom of the Stack are there to act as bread crumbs, to allow the user to back out of an undesired selection.


Stack
Stack.png
Source code


Sample file
sample file.png


More Projects

댓글 없음:

댓글 쓰기