David Ness |
Mind / Matter |
By David Ness
Thursday, December 7, 2000Data Base
For reasons that are too boring and complex to go into, I keep my phone/address data in a format that is (indirectly) compatible with a large number of different systems that I regularly use that need to have this information. This format consists of lines that are of the form `Label: Value', where items are separated from one another by `---------' lines used as a separator. The first item in the data base is a dummy, and contains all possible item labels. All of the real items in the data base only have the labels needed for each particular item (i.e. if an item doesn't have an `address', we simply leave out the address related labels).
The worst of the programs that process this data is clearly, in my experience, Microsoft Outlook, so the format chosen works particularly nicely with that system. Various perl and other programs re-map the data into forms appropriate for all of the uses. All of the other programs are much easier to manage, so handling the data in a form for these programs is an easy task compared to Outlook.
Data kept in the form given here is easy to manage, I generally create new entries and modify old entries with any old ASCII editor that happens to be available.
Downloading
The code, as written, assumes the phone list is in C:\PHONE.LNG, Each piece of this code refers to this file only in one place, so it would be easy to put it elsewhere. The code is designed to be called from a command line in a DOS window under any version of Windows that I know. I would imagine that it also would work under Linux, but I haven't tested that yet. There are three files that need to be downloaded, the `test' data base, the J code and the K code. Due to obscurities with how files are passed (I can't do FTP from my site), these files have to be `browsed' and saved under appropriate names in appropriate places. Given that there are only three files (the test data + 2 code snippets), I hope this isn't an arduous task. As an alternative, and depending on your browser, the appropriate information could be snipped from the file that is downloaded to produce the display you are now reading.
Executing
Both of the programs expect to be called in essentially the same way. To execute the J code, open a DOS box and execute `J JCODE Name' (where JCODE is the name of the J program). Similarly, to execute the K code, execute K KCODE Name.
Disclaimer
As will be clear from looking at the code, I am not a good J or K programmer. What is interesting to me, however, is that I can program in both J and K and get useful things done, without being a good programmer. That's consoling news for those of us who aren't profoundly good at this stuff.
Accessing the Data
Rather than boring anyone with my real phone list, I make available a very small data base that can be used to test the programs and experiment with the software.
Comparisons
All of the code runs sufficiently fast that it doesn't seem to me to be worth trying to do any timing comparisons. I was somewhat surprised I found coding in K to be easier, for this problem, than with J. I have substantially more experience with J, so I expected it to be the other way.
Code Commentary
I now present the J and K code that was used to solve this problem.
It is not obvious how much we should assume the reader knows about J and K in this note. What is obvious, however, is that there is no particular amount of discussion that will be right for everyone.
In addition, some lines are too long to be displayed as a single line. Here I have broken them at a blank and then indented the continuation on the next line with five extra spaces of indentation. I hope that this will not cause confusion.
J Code
The J code is reasonably daunting. And being forced to break lines for display purposes doesn't help much. But perhaps with a few words, the general drift can be understood.
The a array gets a copy of the input file, with the EOF and CR trimmed (if they were present), and then the lines are boxed, and the separator lines are replaced with lines that look like
End: Endso that they will conform to the format of all of the rest of the lines in the file. Once this is done we create tab to contain all of the values of the name fields. This information is then used to re-code all of the items in the data base to convert the text values in the name field into index values.
NB. <$Load Phone DB - Ver DN-1A(2) - [HRU-WHEP]$> NB. called by JPHONE.BAT containing: NB. `e:\j406\j.exe e:\j406\user\dnn\phone.ijs %*' Toss =: 26 13{a. NB. characters to throw away s =: ' '"_ NB. space and separator constants c =: ': '"_ NB. load the phone db, toss EOF/CR and cut into lines a =: ([: (< ;. _2) (] (#~) ([: -. (Toss"_ (e.~) ])))) 1!:1 <'c:\phone.lng' NB. find the lines that are separators and replace them with `End: End' v =: (# i.@#) > ([: +./ '-----'"_ E. ]) each a a =: (<'End: End') v}a NB. build thd data base and a list of column titles tab =: 0{|:(>:0{v){.db =: (1&}.) each"0 >(sl=:(c E. s,],c) (<;._2)(s,(],c))) each a NB. replace labels with index numbers db =: |: (<"0 (tab i. 0{|:db)) 0} |: dbThis pretty much takes care of the set-up. Then there are some functions that are useful.
NB. `r n' displays the nth entry r =: 3 : '>,,.sl each a{~([ (+i.) -~)/ 1 0 + (y. + 0 1){_1,v' NB. `l n' gives item number that contains line n l =: 3 : '0{(# i.@#) (_1}.y.>_1,v) *. y. <: v' NB. get the (last) command argument cmd =: >_1{< ;. _2 (11!:0 'qcmdline'),' ' NB. `sh n' is a lot like `r n', but I think it's prettier sh =: 3 : 0 xx =: >0{zz =: |:(1&}.) each r y. (<>(-+/*./ \|.' '=|:xx)|. each <"1 xx),.<>1{zz ) NB. `fn text' yields the column of data named `text' fn =: 3 : 0 tt =: ~. > l each <"0 xx =: (# i.@#) (tab i.0{"1 db (1{"1 xx{db) tt} (#v)$<'' ) NB. build a base of what we want to display Data =: |:>fn each ('Last Name'; 'First Name';'Home Phone';'Business Phone') NB. find the items that have elements that match the argument m =: 3 : '~.>l each (# i.@#)> +/ each y.&E. each a' NB. display it ((0,m cmd){Data) 1!:2 (2) This creates a program which can act to display the given information from the data base.
K Code
The K code is even more terse.
/ <$Load Phone DB - Ver DN-1A(3) - [GKR-UHKM]$> / Called from PHONE.BAT with `k phone %*' c:_i / save command args a:0:"phone.lng" / get the data base v:a _sm\: "----------*" / find lines that end entries a[v]:(#v:&v)#,"End: End" / make them `End: End' / `r n' dumps nth entry r:{ x:,/x; a[b+!v[x[0]]-b:1+(-1,v)[x[0]]]} / `l n' finds entry # that contains line n l:{-1 # &(x>-1 _ -1,v)&x<1 _ v,1+#a} / prepare to cut up lines cl: 0,/: cp ,' 2 + cp: a _ss \ ": " db: (+cl _' a)[0 2;] / cut them and toss `: ' tab: db[0;!v[0]] / get keys from 1st item db[0;]: tab ?/: db[0;] / `key' the items / fn["Field Name"] crates a `column' of that particular field fn: { p: &db[0;] = (tab ?/: ,x)[0]; h: (#v)#,""; h[,/l'p]: db[1;p]; h} / pickup the fields of interest in this example Data: fn'("Last Name";"First Name"; "Home Phone";"Business Phone") / find the items that match command arg, doing a `nub' in the process m: & (!#v) _in\: ,/ l'&a _sm\: "*",c[0],"*" / display them `show $ +(-15;-15;-15;-15) $/: +Data[;0,m]This highlights both the differences and the similarities of J and K.
Sample Data
This is only a `shadow' of the real data base, but it is enough to test the concepts and the code that has been presented.
Title: Title First Name: First Name Middle Name: Middle Name Last Name: Last Name Suffix: Suffix Company: Company Department: Department Job Title: Job Title Business Street: Business Street Business Street 2: Business Street 2 Business Street 3: Business Street 3 Business City: Business City Business State: Business State Business Postal Code: Business Postal Code Business Country: Business Country Home Street: Home Street Home Street 2: Home Street 2 Home Street 3: Home Street 3 Home City: Home City Home State: Home State Home Postal Code: Home Postal Code Home Country: Home Country Other Street: Other Street Other Street 2: Other Street 2 Other Street 3: Other Street 3 Other City: Other City Other State: Other State Other Postal Code: Other Postal Code Other Country: Other Country Assistant's Phone: Assistant's Phone Business Fax: Business Fax Business Phone: Business Phone Business Phone 2: Business Phone 2 Callback: Callback Car Phone: Car Phone Company Main Phone: Company Main Phone Home Fax: Home Fax Home Phone: Home Phone Home Phone 2: Home Phone 2 ISDN: ISDN Mobile Phone: Mobile Phone Other Fax: Other Fax Other Phone: Other Phone Pager: Pager Primary Phone: Primary Phone Radio Phone: Radio Phone TTY/TDD Phone: TTY/TDD Phone Telex: Telex Account: Account Anniversary: Anniversary Assistant's Name: Assistant's Name Billing Information: Billing Information Birthday: Birthday Categories: Categories Children: Children Directory Server: Directory Server E-mail Address: E-mail Address E-mail Display Name: E-mail Display Name E-mail 2 Address: E-mail 2 Address E-mail 2 Display Name: E-mail 2 Display Name E-mail 3 Address: E-mail 3 Address E-mail 3 Display Name: E-mail 3 Display Name Gender: Gender Government ID Number: Government ID Number Hobby: Hobby Initials: Initials Internet Free Busy: Internet Free Busy Keywords: Keywords Language: Language Location: Location Manager's Name: Manager's Name Mileage: Mileage Notes: Notes Office Location: Office Location Organizational ID Number: Organizational ID Number PO Box: PO Box Priority: Priority Private: Private Profession: Profession Referred By: Referred By Sensitivity: Sensitivity Spouse: Spouse User 1: User 1 User 2: User 2 User 3: User 3 User 4: User 4 Web Page: Web Page ----------- Last Name: Zabar's Business Street: 2245 Broadway (at 80th St) Business City: New York Business State: NY Business Postal Code: 10024 Business Country: USA Business Phone: 212/496-1234 Business Phone 2: 800/697-6301 Business Fax: 212/580-4477 Web Page: www.zabars.com User 1: Zabars ----------- Last Name: Cedar Inn Business Street: 6th and Main Business City: Starbuck Business State: MN Business Country: USA Business Phone: 320/239-4300 User 1: Cedar ----------- First Name: Alexander Last Name: Pushkin Business Street: 1234 Harvard Yard Mail Center Business City: Cambridge Business State: MA Business Postal Code: 02138-7501 Business Country: USA Business Phone: 555/121-1212 User 1: Alexander -------------- First Name: Nancy Last Name: Everfast Business Street: Brown Systems Inc. Business Street 2: 1212 Chattanooga Business City: Mountain View Business State: CA Business Postal Code: 94040 Business Country: USA Business Phone: 800/555-1212 User 1: Brown ----------- First Name: Carol Last Name: Edgeworth Home Street: 211 W 49st St. Home Street 2: #4 Home City: New York Home State: NY Home Postal Code: 10023 Home Country: USA Home Phone: 555/112-2121 Business Phone: 555/312-1234 User 1: Edgeworth ----------- First Name: Irene Spouse: Paul Last Name: Pushkin Home Street: 101 Valley View Drive Home City: Tampa Home State: FL Home Postal Code: 33606--1111 Home Country: USA Home Phone: 555/123-2222 User 1: Irene E-mail Address: ppush@tampabay.rr.com -----------David Ness' summary of work can be found at http://mywebpages.comcast.net/dness
Some feeling for J and K may result from looking how a simple problem is coded.