spock

Loading Mike's stuff ...

Mike's NoteBook

Copyright (c) 2016-2022, M. P. Trivedi. All rights reserved.
QuickLinks old Notes
Latest Script Hdr
Latest Style Hdr
Show Edited Divs

Two moody poems chosen by ...
Show Tooltip Dialog

List of test pages:



Show the Console...
This txt is in teeny font

Right-click menu-> test

Edit
Update
Close
(fwd)
Output
Items

Stack Group 1 Content

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

The following grid shows the multiple editing capabilities built into dojox/grid/DataGrid.

Results2
Results3

Stack Group 2 Content in Editor

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Anil Agarval Venture Finance ->


zero



"Smithers, the monkeys are messing with the compiler again"

"I'll take care of it, Sir."
Mr. Burns


Photochrome Prints from the Lib. of Cong. [ca. 1890-1910]
Bombay. Pydownee Street
Bombay. Girgaum Road
(Rights Advisory: No known restrictions on publication.)


This is a test



Tag cloud:

Toggle
Output:
http://www.imdb.com/chart/top (checked upto #70)

http://www.imdb.com/title/tt0301357/?ref_=nv_sr_1 https://images-na.ssl-images-amazon.com/images/M/MV5BMTI0MTg4NzI3M15BMl5BanBnXkFtZTcwOTE0MTUyMQ@@._V1_UY268_CR1,0,182,268_AL_.jpg Good Bye Lenin! (2003) (https://en.wikipedia.org/wiki/Ostalgie) nostalgia for aspects of life in East Germany. Woman goes into coma just before the wall fall; when she wakes up her kids keep up a facade that the Soviet era still reigns.
[[NEED TO READ REVIEWS OF THESE BEFORE INCL. THEM]] Crime, Mystery http://www.imdb.com/title/tt0051201/ https://images-na.ssl-images-amazon.com/images/M/MV5BMTc0MjgyNTUyNF5BMl5BanBnXkFtZTcwNDQzMDg0Nw@@._V1_UX182_CR0,0,182,268_AL_.jpg (1957) | Agatha Christie | Marlene Dietrich | A veteran British barrister must defend his client in a murder trial that has surprise after surprise.
http://www.imdb.com/title/tt0364569/ https://images-na.ssl-images-amazon.com/images/M/MV5BMTI3NTQyMzU5M15BMl5BanBnXkFtZTcwMTM2MjgyMQ@@._V1_UX182_CR0,0,182,268_AL_.jpg 2003 s. Korean | After being kidnapped and imprisoned for fifteen years, Oh Dae-Su is released, only to find that he must find his captor in five days.
http://www.imdb.com/title/tt0405094/ https://images-na.ssl-images-amazon.com/images/M/MV5BNDUzNjYwNDYyNl5BMl5BanBnXkFtZTcwNjU3ODQ0MQ@@._V1_UX182_CR0,0,182,268_AL_.jpg The Lives of Others (2006) In 1984 East Berlin, an agent of the secret police, conducting surveillance on a writer and his lover, finds himself becoming increasingly absorbed by their lives.
http://www.imdb.com/title/tt0317248/ https://images-na.ssl-images-amazon.com/images/M/MV5BMjA4ODQ3ODkzNV5BMl5BanBnXkFtZTYwOTc4NDI3._V1_UX182_CR0,0,182,268_AL_.jpg (2002)Two boys growing up in a violent neighborhood of Rio de Janeiro take different paths: one becomes a photographer, the other a drug dealer.
http://www.imdb.com/title/tt0114369/ https://images-na.ssl-images-amazon.com/images/M/MV5BMTQwNTU3MTE4NF5BMl5BanBnXkFtZTcwOTgxNDM2Mg@@._V1_UX182_CR0,0,182,268_AL_.jpg Se7en (1995) Two detectives, a rookie and a veteran, hunt a serial killer who uses the seven deadly sins as his modus operandi.
Crime, Mystery http://www.imdb.com/title/tt0114814/ https://images-na.ssl-images-amazon.com/images/M/MV5BMzI1MjI5MDQyOV5BMl5BanBnXkFtZTcwNzE4Mjg3NA@@._V1_UX182_CR0,0,182,268_AL_.jpg A sole survivor tells of the twisty events leading up to a horrific gun battle on a boat, which begin when five criminals meet at a seemingly random police lineup. Sci-Fi http://www.imdb.com/title/tt0816692/ https://images-na.ssl-images-amazon.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_UX182_CR0,0,182,268_AL_.jpg Interstellar (2014) |Matthew McConaughey, Anne Hathaway, Jessica Chastain |A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival. pOSS ALREADY IN DB.: http://www.imdb.com/title/tt0407887/ https://images-na.ssl-images-amazon.com/images/M/MV5BMTI1MTY2OTIxNV5BMl5BanBnXkFtZTYwNjQ4NjY3._V1_UX182_CR0,0,182,268_AL_.jpg An undercover cop and a mole in the police attempt to identify each other while infiltrating an Irish gang in South Boston. Scorsese DiCaprio, Matt Damon, Jack Nicholson http://www.imdb.com/title/tt2582802/ https://images-na.ssl-images-amazon.com/images/M/MV5BMTU4OTQ3MDUyMV5BMl5BanBnXkFtZTgwOTA2MjU0MjE@._V1_SX214_AL_.jpg 2014 (Philippines) A promising young drummer enrolls at a cut-throat music conservatory where his dreams of greatness are mentored by an instructor who will stop at nothing to realize a student's potential. http://www.imdb.com/title/tt0043014/ https://images-na.ssl-images-amazon.com/images/M/MV5BMTc3NDYzODAwNV5BMl5BanBnXkFtZTgwODg1MTczMTE@._V1_UX182_CR0,0,182,268_AL_.jpg (1950) A hack screenwriter writes a screenplay for a former silent-film star who has faded into Hollywood obscurity. dIR: Billy Wilder
[Please select tags:]

Notes:(last updated 2016.12.07)

NoteBook
  1. Add Org module based off treeGrid
  2. Add AdminMode on/off w/pwd triggered by acc expand/coll < > hide toolbar buttons(fwdStack) if off
  3. Need 2nd dlgBox size (larger) for, eg, LinerNotes
  4. IF mBox has text larger ~len, put "..." clickable into mAlert/mDlgBox
  5. Add "reading" to rec accordian; move stuff from misc/Other
Film
MOVIE UPDATES CONTINUED @ NatlBoardAwards http://www.notcoming.com/
Midnight Eye - Visions of Japanese cinema
Bottom of this page has links to desi Film Awd winners : https://en.wikipedia.org/wiki/Shyamchi_Aai_(film)
https://www.criterion.com/explore/149-yakuza
https://www.criterion.com/explore/19-samurai-cinema
20160930mpt yakuza.txt Liner Notes:

Film sections to add:
Historical (Bios of Napoleon/Monet/etc.) Music - Live shows/concerts Theater
-Categ & good liner notes (thoughtful/th~provoking articles) for Maigret Movies - Woody Allen - Spike Lee - - Wimsey, Astaire, Hitchcock, Tarantino, Mel Brooks
Spl Interest Categories: Literary / Art etc. (about, incl. biopix)
New root categ for Spotlight? If using dojo:query; do so with a sep section for LinerNotes as well (They can have keywords too)
Notes on SELECTION: There has to be a system (V imp.) otherwise results in inequity

20161206mpt bookmarks update 2pm
Shell w/treeGrid & Layout
dojo.Observable
20161206mpt test tree Shell 8pm (Using dojo.tree to represent store data; with put/etc., dynamically updating dojo.tree widget using dojo.Observable (ObjectStoreModel)

20161204mpt dojox.grid.TreeGrid Model-based test
Shell w/code for Iterating thro an Object Store
Le Monde Editorial (w comments)
20161110mpt shell w/dataStore stuff
20161109mpt error chk fn
20161010mpt validation testing shell
Tab Builder
20161007mpt 2pm dojo testing shell w/layout & *working* UI domConstruct for tags

WORKING GIST
20160924mpt final update WORKING GIST need to fix timestamp (instd of 9 we're getting 8), fixed elsewhere

Dojo PageBuilder.html SHELL for URLRdr 9/12
//--URLRdr_v1.092--upd 9/12/2016-------------------- ->


Not as Spaniards, but as traitors, thieves, and murderers...a NewYorker visits St.Augustine, FL
Travels through Switz... pursuing, like the swallow, the inconstant summer of delight and beauty which invests this visible world (the Shelleys)

Last stable bootcrap Launcher (8/15/16 or thereabouts)


(for later?)
(srch results for idler) http://tinyurl.com/jy5vb79
* insert col-sm & col-md tags
* preview/test in handheld brosers online
lookup public todo app w/export data fmt outlk

Left to add:
Blogs: Man~ AND -anglophile =epicurean -single malt avail =alfresco sm frndly opts

Fan pgs for: -Wharton -rafa/tgr -astaire -chilpprs -jB/crnrShp - sufi/bulleh/rumi -suchet -fry/laurie

wadala/gangsterCulture -mann/spa

TI trading rms -eco -re/au
-Green rm, bw/off -FOB/AB blogroll -Lit/Iowa Wrkshp -LP availabil in BOM -AmazonLists -rsch chp compl Vinyl setup
How to find tlr, pique/tech/den

Frette is supposedly a good choice for linens and robes.

- Tom Ford has belts with a "T" for a buckle Men's
Mohan's custom tailoring


http://www.gentlemansgazette.com/
http://putthison.com/
http://dappered.com/
http://offthecuffdc.com/

Seward Trunk Co. Embossed Steel 31" Oversize wheeled locker
http://www.distributorcentral.com/websites/MercuryLuggage/item_information.cfm? SupplierItemGUID=71851D65 -5A6C-43FD-834E- C62D9FB6B482&

Rhino Trunk & Case
http://www.rhinotrunkandcase.com/products-capabilities/rhino-travel-wardrobe-trunks/
https://amishhandcrafted.com/content/maple-steamer-trunk


Men's Nike Free RN Distance
Men's SAUCONY KINVARA 7


Film Section

TV Mini-Series (72-75) | ~10 episodes | Ian Carmichael
TV Mini-Series (72-75) | ~10 episodes | Edward Petherbridge...more calm, solemn and had a stiff upper lip, subtly downplaying many of the character's eccentricities.
(1977) John Cleese | The grandson of the world's first and foremost consulting detective and his bumbling, bionic sidekick attempt to catch the only living descendant of Professor Moriarty.
(2001-2) 27 episodes | Highly rated A&E Series
Ed McBain's 87th Precinct: 3 movies | Lightning, Ice, Heatwave (1995-7)
film
(1962) Matthau is a syndicate mobster angry @ streak winner Dean Martin who's being set up.
film
(1963) Gangster Matthau is mad when movie w/his stripper girlfriend bombs; producer/writer run away to "island of love".
film
(1963) Paris | Hepburn, Cary Grant | Mathhau is a cop | film is in pub. dom; can watch it @ wikipedia
film
(1965) A biochemist suffers memory lapses, finds bad guys after him, and has no idea why. Gregory Peck, Matthau as investigator.
film
(1966) Matthau plays shyster lawyer | Dir. Bill Wilder (Irma la D)
film
(1968) farce abt the adventures of its naive heroine. Brando, Richard Burton, Coburn, Matthau, Ringo Starr Many cameos incl. Sugar Ray Robinson.
film
(1969) a strong-willed matchmaker(Streisand) travels to Yonkers, to find a match for "well-known unmarried half-a-millionaire".
film
(1969) Matthau breaks relationship lying that he is married. Also has Ingrid Bergman, Goldie Hawn
film
unsuccessful, now considered cult classic. (1971) playboy Matthau has 6 wks to find a rich bride & repay loan, or forfeit all property to uncle
film
(1972) Matthau plays a confirmed bachelor w/ eccentric habits. *s Carol Burnett,
film
(1973) In San Fran, Matthau investigates when a busload of passengers are gunned down & killed.
film
(1973) Matthau, a former stunt pilot, holds up bank in sleepy NM town.
film
(1974) group of criminals takes passengers hostage inside a NYC Subway car for ransom.
film
(1974) Lemmon is reporter @ Chicago paper & Matthau is ruthless editor | dir by Billy Wilder (Irm la d)
film
(1978) Similar to 'Plaza Suite', based on play by Neil Simon. Visitors from London/Philly/Chicago.
film
(1980) Matthau is a renegade CIA agent abt to expose the cia/kgb
film
(1981) Matthau is hitman stuck in hotel w/Lemmon who wants to kill himself.| dir by Billy Wilder (Irm la d)
film
(1983) in NY, Matthau's gas station is accidentally blown up by Robin WIlliams "unconventional humour" people thot the two didn't gel tog.
film
(1996) 2 old fogies meet in NYC Central Park. Film adaptation based on tony-awd winning play
film
(1997) the pair are dance hosts on a cruise ship trying to seduce heiresses.
film
(1998) a sequel, d'you believe it?
film
(1959) 2 musicians who dress in drag in order to escape from mafia gangsters | dir. Billy Wilder (Irma la D)
film
(1960) Lemmon's Upper WestSide apt is used by 4 mngrs for trysts | dir. Billy Wilder (Irma la D)
film
(1972) Lemmon's dad dies in Naples but not alone (w/mistress) bodies disappear, etc. | dir. Billy Wilder (Irma la D)
film
(1965) Has to be a FREAKING good movie (plus, look at the date) | Basil Fawlty claims to have seen it six times,
film
(1960) Ocean's 11 is a heist film centered on a series of Vegas casino robberies
film
(1962) remake of Gunga Din set in the American West. Last film to feature all 5 due to Sinatra's falling out with Lawford.
film
(1964 ) the film transplants the Robin Hood legend to a 1930s Chicago gangster setting
film
(1947) (Frank Sinatra and Peter Lawford)
film
(1956) a gambling rancher (Dailey) discovers that all he has to do to win at roulette is take hold of ballerina Charisse's hand
film
(1958) a troubled Army veteran and author who returns to his Ill. town after 16 yr, to the chagrin of his wealthy, social-climbing brother.
film
(1959) Charles Bronson, Steve McQueen, Sinatra/Lawford fighting the Japanese in Burma in World War II despite a lack of support from their commanders
film
(1963) based on the play of the same name by Neil Simon.
film
(1963) exiled American in Rome, rescues a young Sicilian outlaw, from the police & turns him into Johnny Cool.| Telly Savalas, Sammy Davis, Jr.
film
(1963) thug Charles Bronson & a cameo by the Three Stooges
film
(1965) a businessman's wife who ends up divorced by mistake and then married to his best friend by an even bigger mistake
film
(1966) story of a self-destructive jazz musician (Sammy Davis) Also features Louis Armstrong, Mel Torme & Frank Sinatra
film
(1966) comedy/satire abt a love-triangle made more complex by an Indian maiden & a Comanche raiding party
film
(1968) At a nightclub in Swinging London, a dying Asian girl sets off plot to overthrow the British govt
film
(1970) Salt & Peppar redux
film
(2012) Western dir Quentin Tarantino,
film
(2012) criminal syndicates use contracted killers called "loopers" to kill victims sent through time travel.
film
(2012) based on 96 murder of 80yr-old millionaire in TX by her 39yr-old companion.
film
(2012) cops & bloods in LA police procedural
film
(2012) skateboarding subculture movie in LA
film
(2013) Sandra Bullock % George Clooney are stranded in space
film
(2013) American war film (Afghanistan) based on true-life act.
film
(2013) crime drama Hugh Jackman
film
(2013) Emma Thompson as author (Mary Poppins) and Tom Hanks as Walt Disney
film
(2013) Ben Stiller / life at Life magazine
film
(2013) biographical black comedy crime film directed by Martin Scorsese
film
(2013) based on the life story of the Wing Chun grandmaster Ip Man
film
(2013) crime prison drama
film
(2013) crime drama NY motorcycle stuntman working in a traveling act for state fairs.
film
(2014) mob movie based in 1981 New York
film
(2014) satirical black comedy-drama film dir by Alejandro G. Innarritu.
film
(2014) tank crews in Nazi Germany
film
(2014) psychological thriller Ben Afflek's wife is missing
film
(2014) Alan Turing, who decrypted German intelligence codes during World War II. Cumberbatch
film
(2014) thief shoots live footage of accidents/crimes in LA, selling content to news channel
film
(2014) husband is believed to have prioritized his own escape frm avalanche over safety of family.
film
(2014) current life in small-town N. Russia nr Finland
film
(2013) British prison with some of the country's most violent criminals
film
2013 thriller film funded via crowdfunding
film
2014 spy thriller - chechnya, germany, le carre
film
(2014) BioPic won a few awards
film
(2013) S Korean-Czech science fiction thriller film based on French graphic novel.
film
Cafe Society (2016)Bronx native moves to Hollywood, where he falls in love with the secretary of his powerful uncle, an agent to the stars. After returning to New York, he is swept up in the vibrant world of high society nightclub life.
film
Irrational Man (2015) tormented philosophy professor finds a will to live when he commits an existential act.
film
Magic in the Moonlight (2014)A romantic comedy about an Englishman brought in to help unmask a possible swindle. Personal and professional complications ensue.
film
Midnight in Paris (2011)While on a trip to Paris with his fiance's family, a nostalgic screenwriter finds himself mysteriously going back to the 1920s everyday at midnight.
film
The Curse of the Jade Scorpion (2001)An insurance investigator and an efficency expert who hate each other are both hypnotized by a crooked hypnotist with a jade scorpion into stealing jewels.
film
Small Time Crooks (2000)A loser of a crook and his wife strike it rich when a botched bank job's cover business becomes a spectacular success.
film
Sweet and Lowdown (1999) 1930s, jazz guitarist idolizes Django Reinhardt, faces gangsters, falls in love w/a mute woman.
film
Mighty Aphrodite (1995) When he discovers his adopted son is a genius, a New York sportswriter seeks out the boy's birth mother: a ditzy porn star and prostitute.
film
Bullets Over Broadway (1994) In New York in 1928, a struggling playwright is forced to cast a mobster's talentless girlfriend in his latest drama in order to get it produced.
film
Manhattan Murder Mystery (1993) Woody Allen, Diane Keaton
film
Shadows and Fog (1991) Woody Allen, Mia Farrow With a serial strangler on the loose, a bookkeeper wanders around town searching for the vigilante group intent on catching the killer.
film
Crimes and Misdemeanors (1989) An ophthalmologist's mistress threatens to reveal their affair to his wife, while a married documentary filmmaker is infatuated by another woman.
film
The Purple Rose of Cairo (1985) In New Jersey in 1935, a movie character walks off the screen and into the real world.
film
Broadway Danny Rose (1984) In his attempts to reconcile a lounge singer with his mistress, a hapless talent agent is mistaken as her lover by a jealous gangster.
film
Manhattan (1979) life of a divorced television writer dating a teenage girl is further complicated when he falls in love with his best friend's mistress.
film
Love and Death (1975)In czarist Russia, a neurotic soldier and his distant cousin formulate a plot to assassinate Napoleon.
film
Bananas (1971) When a bumbling New Yorker is dumped by his activist girlfriend, he travels to a tiny Latin American nation and becomes involved in its latest rebellion.
film
Pussycat, Pussycat, I Love You (1970)An American playwright living in Rome consults a quack psychiatrist to combat his fears of balding and save his failing marriage.
film
Take the Money and Run (1969)The life and times of Virgil Starkwell, inept bank robber.
film
What's New Pussycat (1965) Peter Sellers, Peter O'TooleA playboy who refuses to give up his hedonistic lifestyle to settle down and marry his true love seeks help from a demented psychoanalyst who is having romantic problems of his own.
film
Jaanisaar (2015)(from Muzaffar Ali, dir of Umrao Jaan) courtesan from Avadh, and a prince brought up in England, set in 1877...introduces Janaab Nazeer Akbarabadi, known Urdu poems for both Ali/Krishna
film
Lakhon Ki Baat (1984) Sanjeev Kumar, Farooq Shaikh. Photographer & pals decide to sue.
film
Ab Ayega Mazaa (1984) Farooq Shaikh.
film
Uddhar (1986) Farooq Shaikh, Supriya Pathak
film
Anjuman (1986) music by Khayyam, dir Muzaffar Ali |Shabana Azmi, Farooq Shaikh, R Hattangadi Set in Lucknow, it deals with exploitation of women and problems of local "chikan" embroidery workers. three songs by Shabana Azmi.
film
Ek Pal (1986) Farooq Shaikh, Shabana Azmi, Naseeruddin Shah,
film
Dir Muzaffar Ali. Farooq Shaikh, Smita Patil. Lucknowite re-locates to Bombay. Has "Seene Mein Jalan...Toofaan"
film
(2010) Farooq Shaikh. thriller based on a real-life incident of a woman who hit a man, drove home & parked the car w/the man wedged halfway thro' the windshield.
film
Detective Byomkesh Bakshy! (2015)Dir Dibakar Banerjee The origin story of famous Bengali sleuth created by Saradindu Bandopadhyay.
film
Khosla Ka Ghosla! (2006)Dir Dibakar Banerjee Delhi based retired man tries to get his land back from a swindler.
film
Titli (2014) a violent car-jacking brotherhood in Delhi
film
Talvar (2015) An experienced investigator confronts several conflicting theories about the perpetrators of a violent double homicide.
film
Nikaah (1982) Salma Agha
film
(2014)Helen Mirren, Om Puri. The Kadam family leaves India for France where they open a restaurant across from a Michelin-starred eatery.
film
36 Ghante (1974) Raaj Kumar, Sunil Dutt Three jailed convicts break out of prison and take over the household of Editor Ashok Rai.
film
Baaz (1953) Guru Dutt, Johnny Walker2 desi girls fight back in Portuguese-ruled Malabar region in India
film
Mr. & Mrs. '55 (1955) Guru Dutt, Madhubala naive heiress forced into 'marriage of convenience' w/unemployed cartoonist
film
12 O'Clock (1958) Guru Dutt, Waheeda Rehman (!) Maya is found dead in the first class compartment at a railway terminus in Bombay
film
Chaudvin Ka chand (1961) Guru Dutt, Waheeda Rehman (!) love triangle in Lucknow
film
Sahib Bibi Aur Ghulam (1962) Guru Dutt, Waheeda Rehman (!)servant Bhootnath gets close to the wife of his employer, and narrates her story. Has "Bhanwara Bada Naadaan".
film
Bharosa (1963) Guru Dutt, Mehmood
film
Suhagan (1964) Guru Dutt, affair between a professor and a student
film
Sanjh Aur Savera (1964) Guru Dutt, Dir. Hr Mukherjee
film
Maigret tend un piage (1958) Gabin
film
Maigret et l'affaire Saint-Fiacre (1959) Gabin
film
Maigret voit rouge (1963) Gabin
film
Maigret(TV series|54 episodes|91-05)...Certes, le grain de l'image a vieilli, les lumieres ou la musique ne sont pas toujours extraordinaires, mais cette ambiance est unique.
film
Maigret Sets a Trap (2016) TV Movie Rowan Atkinson (reviewer) ...The scenery, photography, costumes, props and direction were beautiful and the movie was 100% traditional 'Noir' in every popular sense of the film world. The shadows and lighting, cars, streets, the brown... (lots of brown!), even the smoking and the hats... all Film Noir! (another rev) ...Atkinson's calm and soft-speaking portrayal is the first proper portrayal of Maigret I've ever seen (all the others were a bit too flashy for my taste).
film
Maigret's Dead Man (2016) TV Movie Rowan Atkinson
film
Maigret(TV series|53 episodes|59-63) Rupert Davies (review)...captured mood and style of Simenon's books ...captured the atmosphere of Simenon's Paris perfectly with its Citroen Tractions, cobbled streets and bistros. ...Half the UK population flocked home to see it each week.
film
Les enquites du commissaire Maigret (TV Series|88 episodes|67-90) ...has to be good; prod. while Simenon was alive.
film
Maigret (1988) Richard Harris's version; if likeable they made a TV series w/him too
film
S Korean, (1989)The title itself is a koan. "... better than any previous film of this type."
film
2009 (Japan) Dogen Zenji
film
S Korean, Spring, Summer, Fall, Winter... and Spring (2003)
film
set in Ladakh, Himalayas
film
Milarepa (2006) Photographed in the stunning Lahaul-Spiti region of Northern India
film
(2005) Document. A journey exploring the practices of Chinese hermits living in the Zhongnan Mountains.
film
"...a clever little Indie about the American zen experience" (Comedy)
film
The Sea That Thinks (2000) comme "The Mind's Eye"
film
Documentary: Rinpoche (2011) stars Ginsberg
film
Document.: 1998 (Switzerland) Steps of mindfulness
film
Cave in the Snow (2002) 52min | Documentary | Australia
film
Around the World in 80 Gardens: China and Japan | Documentary 2008
film
(1958) Released from prison, a gangster (Michitaro Mizushima) retrieves diamonds sought by fellow yakuza.
film
(1960) A prison truck is assaulted and the two convicts inside are murdered.
film
(1960)Two reporters of divergent morals investigate a drug ring, delving deeper into the underworld in the process.
film
(1960)young rebel Juro has to deal with an environment of crime and prostitution
film
(1961)A Hell of a Guy | Muteppo-daisho (original title)
film
(1961) The Man with the Hollow-Tip Bullets | Sandanju no otoko (original title)
film
Detective Bureau 2-3: Go to Hell Bastards (1963) Kutabare akuta-domo - Tantei jimusho 23 (original title)
film
Youth of the Beast (1963) Yaja no seishun (original title)
film
Akutaro (1963) The Bastard
film
Nikutai no mon (1964)Gate of Flesh
film
Irezumi ichidai (1965) Tattooed Life
film
Tokyo nagaremono (1966) Tokyo Drifter
film
J Shishido,(1967)
film
(2001) Pisutoru opera (original title)
film
(1985)... possibly the ne plus ultra of Seijun Suzuki provocations, and must be seen to be believed... Made entirely in Japan, and with dodgy English-language acting by both the Japanese and American performers, it's an explosion of color and anachronistic costumes and hairstyles, with Kimura's set design repurposing a Japanese amusement park to approximate the West Coast of the United States.
film
Kanta mushuku (1963)
film
Water (2005), India in 1938, movie follows Fire(1996) & Earth(1998). Deepa Mehta/Anurag Kashyap
film
(2006) based upon J. Lahiri's bk / Mira Nair
film
2008 British drama film
film
2009 science fiction thriller aliens in '82 Jo'burg
film
1996 Wes Anderson | Owen & Luke Wilson
film
1998 Wes Anderson | Bill Murray
film
2001 Wes Anderson | Gene Hackman Ben Stiller
film
2004 Wes Anderson | Owen Wilson hunt for shark
film
2007 Wes Anderson | Owen Wilson train voyage across India
film
(1962)
film
(1966) Believing himself to be a suspect for embezzlement in British India, a man must testify against non-violent freedom-fighters.
film
Biwi Aur Makan (1966) 4 guys come to Bombay & 2 of 'em dress in drag to get accomodation
film
(1971) Bombay, Hanging gardens etc.
film
(1972)family has a reputation of not having any cook last long
film
Sabse Bada Sukh (1972) Village born Lalloo re-locates to Bombay
film
(1973) Delhi, Calcutta
film
(1975)new husband plays a practical joke on wife's family
film
Alaap (1977)
film
Chaitali (1975) Dharmendra, based on novel of the same name by famed Bengali writer Ashapoorna Devi
film
1976 - Keshto
film
(1980)
film
Naukri (1978)A.K. Hangal Rajesh Khanna Raj Kapoor
film
(1979) Hangal, Keshto, bachchan
film
(1981) Amol Palekar, Swaroop Sampat, Utpal Dutt |
film
Achha Bura (1983) Amjad Khan, Ranjeet, Raj Babbar
film
(1983) Farooq Shaikh, Deepti Naval, Utpal Dutt |
film
(1998)
film
(2007) flooding the Reich w/fake notes
film
(2007) bio-Piaf
film
set in Communist Romania ~ final yrs of Ceau?escu era
film
Spy movie set in Hong Kong in 1938 and in Shanghai in 1942
film
2007 Turkish-German drama
film
2007 French film French slang for "trashy novel fr. train station"
film
Viennese ex-con & Ukrainian prostitute - bank robbery.
film
a 2008 Iranian movie man works @ ostrich farm; fired when an ostrich escapes
film
2008 Turkish film Istanbul
film
2009 black-and-white German-language drama the roots of evil
film
2009 French prison drama-crime film: the Corsicans vs the Muslims.
film
2009 German comedy film re: Greek tavern in Hamburg
film
cop-shooters in '88 Melbourne, Austr.
film
2009 British drama film / 15yr old in an East London council estate
film
2010 pol thriller film directed by Roman Polanski.
film
explores ennui among Hollywood stars / Chateau Marmont / S. coppola
film
3 generations of middle-class Taiwanese family in Taipei.
film
Hong Kong in 1962, v. highly rated movie
food
Hyeol-eui-noo (2005) Blood Rain | Dae-seung Kim
film
(1974) A Delhi-based woman in a steady relationship gets an old Mumbai flame back in her life.
film
(1975) "established Amol Palekar as having an uncommon comic talent for playing mousy characters..."
film
(1976) Bombay Zarina Wahab
film
(1977) Smita Patil, Dina Pathak, Naseeruddin Shah |Girish Karnad (screenplay)
film
(1977) taxi-driver Tun Tun, Mehmood Jr.
film
(1977) Bombay
film
(1978) Panchgani Keshto Mukherjee, Asrani, Iftekhar
film
Jeena Yahan (1979) Shabana Azmi, Dina Pathak
film
(1980) Utpal Dutt, Shabana Azmi, Girish Karnad
film
(1980) Rajesh Khanna, Rakhee Gulzar, Rekha |
film
(1981)Plot No. 5
film
(1981) Director: Hrishikesh Mukherjee | Swaroop Sampat, Utpal Dutt |
film
(1982) Sanjeev Kumar, A.K. Hangal, Deepti Naval|
film
(1983) |
film
(1982) Hrishikesh Mukherjee | Amol Palekar, Parveen Babi, Farooq Shaikh |
film
Pyaasi Aankhen (1983) | Shabana Azmi, Amol Palekar, Waheeda Rehman
film
Tarang (1984) |Smita Patil, Shreeram Lagoo, Girish Karnad, Om Puri
film
(1984) |Director: Hrishikesh Mukherjee
film
(1985) | murder mystery on set
film
(1985) | astrologer
film
(1986) | 10th Road, Juhu, Bombay Utpal Dutt
film
Mr. X (1987) | Tom Alter, Shabana Azmi, Amjad Khan
film
Galate Samsara (1977) Kannada comedy of a married man who develops an affair with a cabaret dancer
film
Bairavi (1978) Tamil when he "became a superstar" (35 ft cut-out poster etc.)
film
Thorn and flower (1978) Tamil widely considered best perf. of his career
film
Ninaithale Inikkum (1979) Sweet Memories - Kamalahassan; Singapore, young love
film
Moondru Mugam - Three Faces (1982) Tamil triple roles Alex, Arun and John
film
Thalapathi (Commander) 1991 Tamil Mani Ratnam/ Mammootty/ based on the friendship betw Karna/Duryodhana
film
Baashha 1995 Tamil - R is rickshaw-driver w/gangster past
film
Thenmavin Kombath (At the top of Sweet Mango Tree) 1994 Malayalam madly successful in Japan (dubbed into Japanese, as Mutu: Odoru Maharaja in 98)
film
Sivaji 2007 - programmer returns to India
film
Kabali 2016 Tamil gang war uuuuge!!
film
Lord Jim (1965) O'Toole
film
Elena et les hommes 1956 fin-de-siecle France Jean Renoir| Comedy
film
1988 man spouts talking boil| cult-hit Comedy
film
1945 Rex Harrison as a novelist | film ver of Coward's theater hit | Comedy
film
1986 semi-autobiographical cult favorite Two unemployed actors | Comedy
film
1949 Jacques Tati
film
1958 Jacques Tati
film
1967 Jacques Tati
film
1971 Jacques Tati
film
Analyze That (2002)
film
Meet the Fockers (2004)
film
Little Fockers (2010)
film
Starred Up
film
The Last King of Scotland (2006) re:Idi Amin
film
The Departed (2006) directed by Martin Scorsese
film
Letters from Iwo Jima (2006) directed by Clint Eastwood
film
The History Boys (2006), adapted from play which won 05 Olivier/ 06 Tony Awards
film
Sweeney Todd (2007), Johnny Depp as The Demon Barber of Fleet Street
film
Into the Wild (2007) drama survival film-Sean Penn(dir) - 1996 non-fiction bk of same name.
film
The Bourne Ultimatum (2007) Matt Damon
film
The Assassination of Jesse James... 2007 revisionist Western film
film
Starting Out in the Evening(2007)aging author approached by Brown U grad student.
film
Starred Up (buzz abt. impossible-to-decipher accents in this movie)
film
2008
film
2008
film
aging professional wrestler befriends stripper etc.
film
2008 crime drama film abt 2 working-class women who smuggle immigrants frm Canada to US
film
The Rise of Genghis Khan
film
2009 60s london
film
2008 war film about an Iraq War Explosive Ordinance Disposal team
film
2009 German-American war film written/dir by Quentin Tarantino
film
2009 highly rated rom-com (@ end he meets 'Autumn') :-(
film
2009 Mandela, rugby - Eastwood
film
2009 film
film
2010
film
2010 the founding of Facebook
film
2010 boxing film
film
2010 science fiction heist thriller film
film
2010 'neo-noir' thriller dir Scorsese
film
2008 black comedy (Coen bros, O brother...)
film
2010 Revisionist Western (Coen bros /Spielberg)
film
'50s Hollywood (Coen bros)
film
2011 neo-noir crime thriller
film
2011 Swedish-American psychological thriller
film
50s Texas; v. highly rated
film
initial stages of the financial crisis of 2007-08, "easily the best Wall Street movie ever made"
film
The Expendables (2010)
film
The Expendables 3 (2014)
film
The Expendables 2 (2012)
film
Hero (2002)
film
House of Flying Daggers (2005)
film
Fearless (2006)
film
The Peacock Spring (1996)
film
Cosmopolitan (2003)
film
Hiding Divya (2006)
film
The Papdits (2006)
film
Partition (2007)
film< /a>
Jadoo (2013)
film
Delhi Belly (2011)
film
East Is East (1999)
film
Bombay Boys (1998)
film
Brahmin Bulls (2013)
film
The Man Who Would Be King (1975)
film
Manika, une vie plus tard (1989)
film
Outsourced (2006)
film
Loins of Punjab Presents (2007)
film
Bhaag Milkha Bhaag (2013)
film
Nina's Heavenly Delights (2006)
film
Cotton Mary (1999) Directors: Ismail Merchant, Madhur Jaffrey
film
Bombay Talkie
film
Shakespeare-Wallah (1965)
film
The Guru (1969)
film
The Wild Party (1975)
film
Autobiography of a Princess (1975)
film
Roseland (1977)
film</ a>
Hullabaloo Over Georgie and Bonnie's Pictures (1978)
film
The Europeans (1979)
film
Quartet (1981)
film
The Bostonians (1984)
film
The Perfect Murder (1988)
film
Mr. & Mrs. Bridge (1990)
film
The Ballad of the Sad Cafe (1991)
film
Jefferson in Paris (1995)
film
Surviving Picasso (1996)
film
Side Streets (1998)
film
The Golden Bowl (2000)
film
Merci Dr Rey! (2002)
film
The White Countess (2005)
film</ a>
Chungking Express (1994)
film
Floating Weeds (1959)
film
Persona (1966) | Bergman
film
Charade (1963) Cary Grant/Hepburn review
film
Hour of the Wolf (1968)
film
The Exterminating Angel (1962) Bunuel
film
Daredevil in the Castle (1961) Mifune
film
Man Against Man (1960)
film
The Gambling Samurai (1960)
film
The Hidden Fortress (1958)
film
Ankokugai no kaoyaku (1959)
film
The Lower Depths (1957) Gorky (play), Kurosawa
film
The Blue Angel (1930) Dietrich
film
Shanghai Express (1932)
film
The Devil Is a Woman (1935)
film
Gosford Park (2001)
film
Peter's Friends (1992)
film
A Bit of Fry and Laurie (1987- 1995) many episodes remain to be seen
film
Alfresco (1983-1984)
film
The Proprietor (1996)
film
The Lower Depths (1936) Gabin | Renoir
film
Toni (1935) | Renoir
film
Night at the Crossroads (1932)
film
The Last Metro (1980)
film
Shoot the Pianist (1960)
film
Greed in the Sun (1964)
film"
Pierrot le Fou (1965)
film
Andha Naal (1954) first film noir in Tamil, no songs/dance/stunts
film
Weekend (1967) | Godard
film
Three Colors: Blue (1993)
film
Three Colors: Red (1994)
film
Three Colors: White (1994)
film
Les Biches (1968)
film
Les Cousins (1959)
film
Leda (1959) Director: Claude Chabrol
film
Just Before Nightfall (1971)
film
Last Year at Marienbad (1961)
film
Umrao Jaan (1981)
film
Masoom (1983)
film
Permission (1987)
film
Khamoshi (1970)
film
Albert Pinto Ko Gussa Kyon Ata Hai (1980)
film
Bazaar (1982)
film
The Morning Breeze (1995)
film
Mohan Joshi Hazir Ho! (1984)
film
Gaman (1978)
film
Josh (2013)
film
Riyaasat Mein (1994)
film
Foyle's War (2002- 2015)
film
Agatha Christie: Poirot (Many episodes remain to be seen)
film
Inspector Morse (Many episodes remain to be seen)
film
Inspector Lewis (2006 TV Series)
film
Miss Fisher's Murder Mysteries (2012 TV Series)
film
Partners in Crime(1992)
film
Maigret Sets a Trap (2016 TV Movie)
film
Zatoichi Meets Yojimbo (1970)
film
Zatoichi Meets the One-Armed Swordsman (1971)
film
Zatoichi in Desperation (1972)
film
Samaritan Zatoichi (1968)
film
Zatoichi's Cane-sword (1967)
film
2005 Filmfare_Critics_Award_for_Best_Film- Yuva - Mani Ratnam
film
Dev (2004)
film
Shootout at Wadala (2013) The first-ever registered encounter by the Mumbai Police, which took place on November 1, 1982. Based on a true story.
film
2013 Filmfare_Critics_Award_for_Best_Film - Gangs of Wasseypur - Anurag Kashyap
film
Once Upon a Time in Mumbai (2010) A smuggler rises to power in in 1970s Mumbai, a younger gangster seeks to overthrow him, and a police officer is caught in the middle.
film
Once Upon a Time in Mumbai Dobaara! (2013)
film
Dhoom 3- 2013
film
Chennai Express - 2013 about a man's journey from Mumbai to Rameswaram, and what happens along the way after he falls in love with the daughter of a local don.
film
Bajirao Mastani 2015 Indian epic historical romance film directed by Sanjay Leela Bhansali
film
Agantuk (1991) The Stranger(Saty. Ray, Utpal Dutt) Comedy
film
Aranyer Din Ratri - Days/Nights in the Forest (1970) S. Ray | Calcutta city slickers head out into wilderness
film
Xagoroloi Bohudoor (Sea v. far) 1995 award winning Assamese boatman loses biz when govt builds bridge
film
(1953) Marathi
film
Kathapurushan (1996) awd-winning film abt char initially a Gandhian eventually a Marxist
film
(The Red Door) 1997 Bengali Kolkotta dentist reflects on his life vs his drivers, lal door's from his childhood a ala Orwell.
film
1999 Malayalee award-winning film re: Kathak dancer plays Arjun upp-class audience girl falls for him & they have child but he finds she loved the stage Arjun not the real person.
film
Dhoom 3- 2013 Aamir Khan, Katrina Kaif, Abhishek Bachchan
film
Maqbool (2003) Irrfan Khan, Naseeruddin Shah(Dir Anurag Kashyap) 'Macbeth' in Mumbai underworld
film
Garam Masala (2006) Comedy
film
Jodhaa Akbar (2008) (Hritik Rosh/Aishw) great Mughal emperor, Akbar, and a Rajput princess, Jodha
film
Mumbai Meri Jaan (2008) follows several interconnected stories re:'06 train bombings
film
Oye Lucky! Lucky Oye! (2009) based on true story of Lucky Singh, charismatic conman frm Delhi
film
3 Idiots (2009) College days in Delhi's Eng. College
film
Firaaq (2010) Muslims in Gujarat after riots
film
Dabangg (2010) A corrupt police officer (later 2 sequels)
film
Zindagi Na Milegi Dobara (2011) Hrithik Roshan, Farhan Akhtar, Abhay Deol decide to turn their fantasy vacation into reality
film
Rowdy Rathore (2012) (Sanjay Leela Bhansali) A con man uncovers a deadly secret and must save ppl from the mob (Dir. Prabhu Deva; became one of the highest-grossing Indian films)
film
Ankhon Dekhi (2015) Comedy, drama "out of the box"
film
Gabbar is Back (2015) (Sanjay Leela Bhansali) Gabbar Singh Rajput (Akshay Kumar) creates his own vigilante military network
film
Visaaranai (2015) (Dir Anurag Kashyap) Labourers tortured by police to confess to a theft they have not committed.
film
Ae Dil Hai Mushkil (2017) Karan Johar, 'slick actors/locations'
film
Padmaavat (2018) (Sanjay Leela Bhansali) Set in medieval Rajasthan
film
Hindi Medium (2018) Irrfan Khan, couple from Chandni Chowk aspire to give their daughter the best education
film
Gully Boy (2019) lives of street rappers in Mumbai; Zoya Akhtar
film
Aparajito (1956) Satyajit Ray a boy leaves home to study in Calcutta
film
Garm Hava (1974) Balraj Sahni, A.K. Hangal partition: considered 'a v influential film'
film
Nishant (1975) Dir. Shyam Benegal Girish Karnad, Shabana Azmi, Naseeruddin Shah village Zamindars
film
Manthan (1976) Smita Patil, Girish Karnad, Naseeruddin Shah: setup of milk co-op
film
Junoon (1979) Dir. Shyam Benegal circa 1857 Indian Nawab desires to wed a young Anglo-Indian woman Shashi Kapoor, Naseeruddin
film
Sadgati (1981) Dir. Satyajit Ray premchand's story re: Untouchable shoemender Om Puri
film
Bhavni Bhavai (1981) Dir. Ketan Mehta atrocities on lower caste ppl
film
Utsav (1984) Dir. Karnad; Rekha, Kharbanda, Amjad Khan 200 BC courtesan Vasantsena
film
Mohan Joshi Haazir Ho! (1984) Dir. Saeed Akhtar Mirza Dina Pathak, old couple sue landlord of collapsing apt
film
Holi (1985) Dir. Ketan Mehta Naseeruddin S, Om Puri, hostel life
film
Pestonjee (1988) Nas. Shah, Shab. Azmi, Mumbai Parsee community in the '50s and 60s
film
Hero Hiralal (1988) Dir. Ketan Mehta Naseeruddin S, rickshaw driver is a hero
film
Salim Langde Pe Mat Ro (1989) unemployed youth aspires to big crime but mends his ways
film
Kamla Ki Maut (1989) Dir.Basu Chatterjee Pankaj Kapur, Irrfan
film
Suraj Ka Satvan Ghoda (1992) '1 of Shyam Benegal's most abstract films ever'... stories of meeting three women in diff life stages. Also known for its subversive take on the "Devdas" syndrome
film
Patang (1993) Dir. Goutam Ghose S Azmi, Om Puri life of people in illegal slums in Bihar
film
Padma Nadir Majhi (Bengali, 1993) Dir. Goutam Ghose pre-partition man wants to establish utopia in Padma delta (Bangladesh)
film
Maya (1993) Dir. Ketan Mehta based on "Madame Bovary"
film
Droh Kaal (1994) Dir. Govind Nihalani Om Puri, Naseeruddin Shah Undercover cops infiltrate a terrorist organisation (tr. Times of Treason)
film
Yatra (2006) Dir. Goutam Ghose Rekha, N Patekar, D Naval Writer meets filmMaker & discuss prostitute
film
Dharm (2007) Pankaj Kapur, Supriya Pathak a priest's wife brings home an orphan boy. Shot in Varanasi.
film
Rang Rasiya (2008) Dir. Ketan Mehta biopic 19th century Indian painter Raja Ravi Varma
film
Kaalbela (2009) Dir. Goutam Ghose Naxalite movement in 70s Calcutta
film
Raahgir (2019) Dir. Goutam Ghose encounters between poverty-stricken travellers

"Beat" Takeshi liner notes:


* Brother FilmFour, 18, 109 mins, 2000; Pounds 19.99 (DVD) ***


The first American co-production for the cult Japanese auteur "Beat" Takeshi Kitano. Brother, shot mostly in the States and delivered mainly in English, could be the biggest launchpad yet for a director and actor who remains almost unknown in Britain, despite being a megastar at home. This is a gangster film like no other, in which the violence never seems gratuitous or glamorised because of the dreamlike surrealism of the camerawork, and the wit and creativity of writing and performance. As a performer, Kitano manages to convey total menace with an acting style so minimal that by the end you almost forget that he's barely finished a sentence. Includes a 48-minute documentary on the film-maker, and cast and crew interviews.


More wondrous sights are on display in Hana-Bi, the most thoughtful film yet from the Japanese cult director Takeshi Kitano. The title means Fireworks, though the hyphen pointedly splits up the title into the Japanese words for flower and fire. Flower and fire, beauty and violence: key ingredients in Kitano's world, where gangster bloodshed is regularly interrupted by lyrical interludes, often set by the sea (as in Sonatine). The current film refines his style to the nth degree; dialogue is so sparse that you might almost be watching a silent film, and the elliptical editing whisks us, at times disconcertingly, between different points in time.
Kitano's characters have never been chatterboxes, but detective Nisi (Kitano himself, under his acting name Beat Takeshi) scales a new peak of silence. His wife is diagnosed with a terminal illness. His colleague Horibe is shot during a stakeout, and becomes confined to a wheelchair. Feelings hidden under dark glasses and tight lips, Nisi leaves the force and robs a bank to finance, among other things, a last trip with his wife and the supply of art materials to Horibe, who has taken up painting. But a blunt rehearsal of the plot can give no indication of the film's visual power.
This is Kitano's most personal work. He himself escaped death four years ago in a bike accident, and he is the painter of Horibe's artwork, bizarre amalgams of flowers and animals. The director's oblique manner needs an audience on the ball; but Kitano can make the most taciturn gaze speak volumes, and as the jigsaw builds there is never a doubt about the emotional force of this meditative tale of flowers and fire, of life and beauty in the face of death.


To anyone unfamiliar with the Japanese director and media star Takeshi Kitano, his film Sonatine may be something of a mystery. One minute, bullets fly and bodies fall with sudden, icy brutality, as bands of gangsters fight for supremacy in Okinawa. The next, those persons still left alive lark around with guns, seaweed and a soft-drink can on a beautiful beach, under a piercing blue sky.
Whatever the mood, the leading character Murakawa, played by the director under his acting nickname ``Beat" Takeshi, adopts a frozen face that suggests a huge existential death wish. Is this a yakuza thriller, an art movie divertissement, or what?
Essentially, what Takeshi has done is to yoke together two separate styles pursued in the three previous films since this extraordinary character actor, stand-up comic and television personality took up directing in 1989. The idyll by the beach recalls the tender, poetic simplicity of the mesmerising A Scene at the Sea. The quirky brand of bloodshed harks back to Violent Cop and Boiling Point, films whose casual violence can churn even an experienced stomach.
The result is a bizarre and awkward hybrid; for Western tastes, sensitivity and violence make strange bedfellows. But Takeshi's strong visual eye and elliptical manner (he serves, importantly, as his own editor) always keep our eyes glued to the screen. Sonatine takes you by surprise sometimes pleasantly, sometimes not: a valuable asset in a world dominated by Identikit films.

(2005 London Film Festival)


BLOOD AND BONES Beat Takeshi gives one of his most powerful performances in this portrait of a brutal businessman and his family.


Meanwhile, non-animation Japanese directors are breathing new life into tired Hollywood genres. Violent Cop was shown in Britain on limited release last month to much excitement. Its handsome director and star, ``Beat" Takeshi, was seen by reviewers as ``the next international cult figure" and as ``Japan's answer to Clint Eastwood". The film is certainly as violent as its title suggests, but, unlike the recent Hollywood police movies, you are kept in suspense rather than in a state of deja vu.
From 2011 The Daily Beast: In 2009, Tadamasa Goto, the former Yamaguchi-gumi (Japan's largest crime group) gang boss, wrote extensively in his autobiography, Habakarinagara, of his connections to Japan's entertainment industry, and justifies the attack his members made on a famous Japanese film director, Juzo Itami, who dared to depict the yakuza unfavorably in his dark comedy The Gentle Art of Japanese Extortion. Kitano's last film, Outrage is the most accurate portrayal of the modern Yakuza ever. The film is a diatribe against them, showing how the traditional yakuza that upheld some primitive code of honor end up being betrayed or killed. The ones that survive are those who are ruthless, backstabbing businessmen - Goldman Sachs with guns. If you want to understand the modern yakuza, Outrage is a fantastic introductory course...
Folio
Bomber Jacket Tyler Folio
Jotting Index cards
Custom Index NoteCards
pen
Lincoln Vintage Metalsmith Tornado Rollerball Pen
pen
Aurora Gemstone Rollerball Pen
pen
Waterford Pallas Rollerball Pen
pen
Parker Sonnet Cisele Rollerball Pen
pen
Faber-Castell e-Motion Pure Black Rollerball Pen
pen
ACME Rhapsody Rollerball Pen
pen
Single-Sheet Cutters


Article: Some words about Khayaal

some
Indian classical music on EP/LP

LP+EP+Ghulam+Ali+ghazal+Akhtar
https://pediaview.com/openpedia/Indian_classical_music

201608140319mpt Yahoo Search result for urdu+ghazal+ghulam+ali+ghalib


http://www.avsforum.com/
http://www.klipsch.com/
http://www.polkaudio.com/
http://definitivetechnology.com/
http://www.martinlogan.com/
https://www.cambridgeaudio.com/
http://www.bang- olufsen.com/da/collection/speakers/beolab-20
http://www.jbl.com/loudspeakers/STUDIO +L890.html?dwvar_STUDIO%20L890_color=Black#start=1
http://www.paradigm.com/products- current/type=tower/model=prestige-95f/page=overview
http://kef.com/html/us/index.html
http://www.bowers- wilkins.com/Speakers/Home_Audio/600_Series/683.html
http://www.bostonacoustics.com/
Sony Home Cinema Projector - VPL- HW40ES
http://www.amazon.com/Koss-PortaPro- Headphones-with-Case/dp/B00001P4ZH/ref=sr_1_1?s=electronics&ie=UTF8&qid=1464305449&sr=1-1&keywords=Koss+PortaPro+Headphones+with+Case
Stereophile
http://www.theabsolutesound.com/
http://www.soundandvision.com/
Radeon
Sennheiser over-the-ear wireless Headphones
http://www.tomshardware.com/s/pc+4k/
ASUS Sound Card Essence STX II
Srch for "Essence ASUS headphone movie 2016" tinyurl.com/zrtpnn2

http://www.dansdata.com/spkvshead.htm
(forum) http://www.head-fi.org/
https://www.headphone.com/collections/top-10-headphones/audiophile
(srch results for headphones) http://tinyurl.com/mpt-headphones






























Some words about Khyal

Perhaps the most popular of contemporary Hindustani vocal styles is the idiom known as "khyal." The word literally means "imagination," and the khyal form demands improvisational flexibility as well as careful attention to nuances of intonation, phrasing and rhythm. Paradoxically, it is less known to audiences in the West, who have learned to enjoy Indian instrumental music unhesitatingly -- and have even begun to absorb the intricacies of Dhrupad vocals. Music stores in India offer a wide selection of Khyal recordings, and performances are well attended.

Khyal is several hundred years old. Originating in the courts of the Moghul emperors as a less rigid alternative to the Dhrupad style, it has evolved into a remarkably flexible form that allows an artist's individuality considerable rein -- while remaining within the steady, inexorable flow of Indian tradition. Even within the past five decades the form has undergone metamorphoses, and the tradition of innovation continues. An artist is expected to develop an individual style (albeit one that is demonstrably connected to the tradition), and those performers who restrict themselves to mere imitation of their preceptors or of other famous musical personalities are firmly criticized for a lack of imagination.

Khyal texts draw freely from Hindu and Muslim poetic traditions, and are usually romantic or devotional -- or a combination of the two. Generally composed in the archaic Hindi dialect known as Brij Bhasha, khyal songs are also found in languages like Bhojpuri, Punjabi, Urdu, Rajasthani, Marathi and (occasionally) Sanskrit. Many songs have unclear wordings, and in some cases the texts have become completely garbled through multiple generations of oral transmission. However, the primary focus in a khyal performance is less on the textual or lyrical content of a song than on abstract musical values. Audiences respond with delight to nuances of ornamentation, to complex rhythmic improvisation, to intricate melodic patterns or to a vocalist's superb intonation.

Performances of khyal often start with a song in a very slow rhythmic cycle, perhaps of 10, 12, 14 or 16 beats; often the pulse is so slow that each beat is further subdivided -- for instance, a 12-beat cycle becoming one of 48. Each beat of the rhythm is marked by a specific stroke or combination of strokes on the tabla drums; by listening to their sound a singer can keep his or her place in improvisation. The tonal material of the raga gradually moves from a restricted melodic range to an extensive gamut; from a slow and relaxed pace to a quicker one. Improvisation is punctuated by the first few words of the song, which become a familiar melody leading up to the first beat of the rhythmic cycle. All extemporized melodic or rhythmic variations aim for this beat, and the gradual building of tension as it approaches is one of Hindustani music's great delights. Eventually the singer switches to a faster song in the same raga, displaying his or her virtuosity and command over the material. Some of the time a "tarana" is used to conclude -- these pieces are rhythmic in focus, and make use of nonsense syllables; they are thus in a sense analogous to scat singing in Jazz.

Fortunately, the music of great khyal singers (the proper generic noun is "khyaliya") is widely available on cassette, CD and lp. The following are some of the most highly regarded singers of this century; most are dead, but their music is easily obtainable, and their voices ring out with extraordinary conviction and passion. Other artists, like Bhimsen Joshi and Kishori Amonkar, are still performing and recording actively.

  • Kesarbai Kerkar
  • Hirabai Barodekar
  • Faiyaaz Khan
  • Bade Ghulam Ali Khan
  • Mallikarjan Mansur
  • Abdul Karim Khan
  • Amir Khan
  • Mogubai Kurdikar
  • Nazakat and Salamat Ali
  • Bhimsen Joshi
  • Kishori Amonkar

Contemporary performers include many musicians of great skill; some are regarded as "up-and-coming," while others are relatively senior performers who have only recently begun to attract critical attention. These include:

  • Rashid Khan
  • Padma Talwalkar
  • Malini Rajurkar
  • Ulhas Kashalkar
  • Dinkar Kaikini
  • Rajan and Sajan Mishra
  • Ashwini Bhide Deshpande
  • Arati Ankalikar-Tikekar
  • Veena Sahasrabuddhe
Warren Senders <WARVIJ@AOL.COM>

To Todd McComb's Indian Music menu.
20 years of free stock data on Finnhub

[[legacy]] blcked srch res: http://www.tinyurl.com/hvvf5lr http://www.ft.com/global-economy
http://www.economist.com/
https://www.bloomberg.com

http://tulipsandbears.com/
http://www.itulip.com/
http://www.shadowstats.com/
http://www.gold-eagle.com
http://www.kitco.com
https:\\www.forbes.com\2002\02\28\0228dynasties.html
http://www.mansionglobal.com/newyork
Rental studios under 2k

Studios for about $200/day - http://manhattan.marmaranyc.com/studio/
Brown harris (also has rentals)
HDFC income-restr. apts on zillow.
trulia has both for sale & for rent

Decent real-est site w/lots of articles
Curbed: nyc real estate
Tips and things for living better in small spaces
(site below has WishList saved under email id)
http://www.furniturelandsouth.com/
http://www.hickoryfurniture.com/Furniture-Jonathan-Charles-Tables/ItemBrowser.aspx?action=attributes&ItemType=Furniture&Brand=Jonathan%20Charles&Type=Tables&TrailIndex=1
http://s3.amazonaws.com/images2.eprevue.net/p4dbimg/513/images/217%20jessicamcclintock%20cover.pdf
chair
Leather- Barrel-Chair
chair
Miles Talbott Living Room Chair
chair
Tufted Leather Chair by Reflections
chair
Lexington Living Room Cardiff Chair
chair
Thomasville Vienna Chair
chair
Lincoln- Tufted-Chair
chair
Kenneth Chair
chair
George III Wing Chair
chair
George III Tufted Wing Chair
chair
Chandler Chair
chair
Michael Amini Knightsbridge Charterhse Leather Chair
chair
Michael Amini Chair and a Half
chair
Francesco Molon Leather Wing Chair
chest
Small Marcelle Chest
chest
Floral painted chest
sm chest
Chaddock- Petite-Camille-Small-Chest
mirror
Chatelet Floor Mirror
mirror
Furniture Rhapsody Floor
Cabinet
Black Gold Drinks Cabinet
Cabinet
Black Chinoiserie Drinks Cabinet
bar/cabinet
Chaddock- Prince-Bar-TV-Cabinet
bar/cabinet
Guildmaster Provence Drink Cabinet
Table
Mahogany Drum Table
sm table
Walnut Eglomise Side Table
side table
Rope Twist Round side table
eglomise
Lapis Blue Eglomise With Mahogan
tables
Jonathan Charles Tables
armoire
Artitalia Group Armoire
armoire
Francesco Molon 2 dr armoire
credenza
Artitalia Group Credenza
credenza
Artitalia Group Credenza in Oak
bed
Hooker furniture vintage king poster bed
bench
Guildmaster Heritage Caned Bench

Note: This design can also be used for a bench swing (custom)
chest
Karges Furniture Georgian Chest
desk
Four Hands Large desk
desk
Hooker Furniture Kendrick jr exec desk
desk
Hooker Furniture la maison Writing desk
desk
Hooker Furniture Sanctuary 60" Writing Desk
desk
Lorts Three Drawer Writing Desk
desk
Theodore Alexander Chippendale's Signature Writing Desk
chest

Manhattan Mini Storage www.manhattanministorage.com
Makespace https://makespace.com/nyc/
Box Butler http://www.yelp.com/biz/box-butler- new-york
OR dump stuff in Edison/Philly (cheaper + less crowded + less hassles)

NOTE: MOST MANHATTAN SITES DON'T HAVE TRUE 24X7 ACCESS, ONLY DAYTIME ACCESS. ALSO, IF THEY DELIVER THERE MIGHT BE DELAYS etc.

JAN. 22, 2013 Gotham Mini Storage

Prices range from $39 a month for a 64- cubic-foot locker reached by a stepladder, to $2,000 for a garage- size space. In contrast, a similar 64-cubic-foot space at Manhattan Mini Storage this week was $57 a month, with a year lease, at most locations. Prices started at $70 a month, for a slightly larger space, at Tuck-It-Away, which is based in Upper Manhattan.

2016:Gotham Mini Storage Locker Promotion Rent a storage locker for $79/month at Gotham Mini Storage and save 50% for the first three months.

There are about 30 self-storage facilities in Manhattan. Manhattan Mini Storage, which has been in business since the 1970s, owns 17 of those properties. (NYT 08:) A 10-by-10-by-8-foot space runs about $300 a month. manhattanministorage.com. Spaces start at 4 by 4 by 5 feet, and one of the most popular is a closet that size with a hanging rod and shelves, "so people can store out-of-season clothing,"" he said. The monthly cost is $45. The company provides a key card for access to the building and elevator, and the customer provides a lock.

CubeSmart ... enjoy a range of new services, like a courier that can shuttle boxes to tenants' homes its employees can sign for packages, which is important for tenants who run their businesses out of their storage areas and who make up about 30 percent of CubeSmart's tenants

Tuck-It-Away, one of the oldest operators in the city, owns 14 facilities with a total of about one million square feet of space.

''Most people rent twice as much space as they really need,'' said Edward Troianello, the president of the Self-Service Storage Association of New York. So calculate carefully and conservatively. According to Mr, Troianello, a three-piece bedroom set, plus the boxed contents of a bedroom closet, can fit into a 5-by-5-by-8-foot storage room

(NYT 14:)start-ups like MakeSpace charge roughly $220 a month for 36 square feet of space at an offsite warehouse.


https://www.publicstorage.com/storage-search- landing.aspx?location=edison+nj
Storage Units Off Old Post Road in Edison, NJ --
SMALL 5' x 5'
*Climate Controlled
*Inside unit/1st Floor 1 Left $69/mo.
Online Special* $74 In-store


(Note: These work in lib browser)
Some girl who moved from Minn to NYC - http://101baddesidates.blogspot.com/
Amardeep Singh (dated site but lotsa links) = http://www.lehigh.edu/~amsp/2005/04/desi-weekend-indian-bloggers-bob- nyc.html
SruTHI's decorating website - http://theeastcoastdesi.blogspot.com/
SAJA Form desi spotting - http://www.sajaforum.org/desi_spotting/
Professional Indian Associations (net-ip, tie, etc.)
Valley desi site

Bhel, chaat, etc @ Murrah Hill & Village http://www.desi-galli.com/
Nisha's Desi Street Food Site LOTS of info - http://indianstreetfoodie.com/

punjabi forum (chk out jokes)- http://www.desicomments.com/desi/janmashtami/
Daandiyaa TOO! host events all over, website only works in IE -> www.desiparty.com

502 error?! "http://nycpunjabigal.blog.com/"
Desi Blog srch Multipg results:

The new stuff to watch

Brokenwood Mysteries: Series 4


Neill Rea (Actor)
Filmed amid the beautiful landscape of New Zealand's North Island,
these four feature-length mysteries show that murder can haunt even the most idyllic locations.


from an AMZN review:

The last three years have taken a dreadful toll on my favorite British policemen:
   "Foyle's War" ended in 2015 after eight seasons.
   "New Tricks" ended in 2015 after twelve seasons.
   "Inspector Lewis" ended in 2016 after nine seasons.
   "DCI Banks" ended in 2017 after five seasons.
   "George Gently" will end in 2017 after eight seasons.
(we may come to look back on the last ten years as the Golden Age of British Police on Television.)

The one bright spot is "Endeavour".
This prequel to "Inspector Morse" is still going strong in it's fourth season.
A fifth season has been announced for 2018.
"Endeavour" debuted in 2013, but was set in 1965, when Constable Endeavour Morse joined the Oxford City Police.
Promoted to Sergeant Morse in 1969.
If it's still on the air ten years from now, we will see the return of "Inspector Morse".
If it's still on the air eighteen years from now, we will see the return of Sergeant Robbie Lewis.

WHY YOU SHOULD WATCH ENDEAVOUR ON BLU-RAY OR DVD, NOT PBS:
I always knew Masterpiece Mystery broadcasts on PBS were edited, but was I was surprised to learn exactly how much was cut.


Wallander



Kenneth Branagh returns to his remarkable Emmy and Golden Globe-nominated role
as the soul-searching Swedish cop in Wallander III, with three gripping new Kurt Wallander
cases based on the character created by bestselling novelist and father of the
Nordic noir craze, Henning Mankell.


Worricker



2013
Page Eight, Turks & Caicos, and Salting the Battlefield form The Worricker Trilogy
three gripping films that follow the exploits of Worricker
from MI5 headquarters in London to exile on a Caribbean island to life on the run
with his former lover and fellow agent Margot Tyrrell.
The all-star cast includes Oscar winner Christopher Walken.


Arthur & George



2015
Martin Clunes (Doc Martin) stars as Sir Arthur Conan Doyle, the creator of
Sherlock Holmes, in a real-life case that inspired the great author to put
down his pen and turn detective.
Co-starring Art Malik
Inspired by a true case, Arthur & George is adapted from Julian Barnes's
acclaimed novel of the same name


List of Masterpiece Mystery! episodes
List of Masterpiece Contemporary episodes
List of Masterpiece Theatre episodes
    Season 32 (2002-03)
    Almost a Woman
    Daniel Deronda
    The Forsyte Saga
    Foyle's War
    The Hound of the Baskervilles
    The Jury
    Me & Mrs. Jones
    My Uncle Silas II
    White Teeth
List of Masterpiece Classic episodes
(2008 onwards)


An introduction to light classical thumri dadra and other styles


The History and the Origin of the with Special Reference to Gharanasand Styles Thumri with Special Reference to Gharanasand Styles.


Thumri
  • Originated in Eastern Uttar Pradesh, mainly in Lucknow & Benares, around the 18th century.
  • A romantic & erotic style of singing; also called “the lyric of Indian classical music”.
  • Compositions are mostly on love, separation, and devotion.
  • Distinct feature: Erotic subject matter portrayed picturesquely from the various episodes of the lives of Lord Krishna & Radha.
  • Lyrics are typically in Brij Bhasha and are usually romantic & religious.
  • A Thumri is usually performed as the last item of a Khayal concert.
  • Three main gharanas of thumri — Benaras, Lucknow, and Patiala.
  • Begum Akhtar is one of the most popular singers of the thumri style.



Kathak uses ‘Thumris’ (expression-based numbers like ‘Padams’ and ‘Javalis’ of Bharatanatyam) to tell stories – stories of love, anger, separation, heroes and heroines. Thumri originated from the term ‘Thumakna’ which refers to rhythmic movement and stylized gait. These semi-classical compositions combined melody and rhythm with a couple of lines of text/ poetry, which was more colloquial. Some Thumris reflected Shringara rasa (the amorous flavour of love and romance) and some, ‘Bhakti’ (devotion).


While the early Kathakars and forest dwellers told the stories of the divine (early Gupta period 4th century CE), the traditional compositions also explored love and beauty with Shyam/ Krishna as the hero of the story.... ...ater, rulers like Nawab Wajid Ali Shah went on to write Thumris, set them to music, and also danced to various Thumris, where he played the role of Krishna. The others like Pia Rangeelay, explored the aspect of love through Thumris, where the subjects were the lover and his beloved, and not specifically Gods as heroes of the Thumris, as it used to be in the traditional compositions. Much later, during the British rule, when Indian classical dance was considered nautch, the presentation of the Nayika became more sensuous and enticing, the style of singing more provocative, and thus a lighter version of the Thumris emerged.
(from namasteswitzerland)


(from a film review: Girija- A Life Time in Music)
Produced by Madhu Chandra and Sudha Datta and directed by Debapriya Adhikary, Samanwaya Sarkar and Sankalp Meshram; with a running time of over 2 hours, Girija- A Life time in Music is a labour of love that takes us into the world of Padma Bhushan , Girija Devi- one of the finest contemporary Hindustani vocalists of our times. In the film, a student of Girija Devi recalls an incident- of how one day Appa ji, as Girija Devi is lovingly referred to by her students and younger members of the music fraternity, was sitting in the verandah and suddenly called out to her. It was drizzling outside, she recalls and Appaji asked her to extend her arm and feel the rain drops. “Feel it,” she told her-“this is the jhir jhir barse sawan ras bundiya that we sing about. Feel how softly the drops fall. Now if you take a big taan while singing of rain that would mean musladhaar baarish (heavy rain), so the taans need to be soft and delicate when you speak about jhir jhir rains.” This one scene gave me goosebumps. As did many other… The documentary is such a wonderful attempt to introduce music lovers to the living legend (who...) rose to become the epitome of grace in the world of Hindustani music and earned the title of Queen of Thumris.


(below snipped from good short essay here)
The Banarasi style draws from poetry in Hindi, Braj and Avadhi to source suitable insertions, while Lucknowi thumri sources insertions from Urdu poetry alone.
While Lucknowi thumri shows marked influence of Kathak, ghazal and tappa, the Banarasi variety seems more inclined towards adapting melodies from the folk repertoire of kajri, chaiti and jhoomar. Lucknowi thumri illustrates the impact of the courtly culture of the Nawabs of Avadh, while Banarasi thumri uses with elements from folk culture...
Some of the most famous thumri artists are – Badi Motibai, Rasoolan Bai, Siddheshwari Devi, Savita Devi, Girija Devi, Gauhar Jan, Shobha Gurtu, Begum Akhtar, Prabha Atre, Pandit Channulal Mishra, Naina Devi, Purnima Choudhuri, Shubha Mudgal, Abdul Karim Khan, Nazakat-Salamat Ali Khan, Barkat Ali Khan, Bade Ghulam Ali Khan. Among these stars Shobha Gurtu is the brightest and is called “the thumri queen”.


https://www.quora.com/What-are-some-of-the-best-thumris has links to YouTube incl SAIGAL Babul Mora


The Hori Thumris are most often based on the romance of Krishna and Radha. They talk about their play and pranks with colors during Holi. an excellent, in-depth essay on Hori Thumris w/links to many YouTube entries


All Episodes of In our Time
Episodes classified by the Dewey Dec. Sys
A few selections (only chkd upto about #500)

http://www.songlyrics.com/
Great American Songbook

Billboard #1 hits over the years
Grammy-nominated or not, No. 1 hits over the years
(APnews: By MESFIN FEKADU)
NEW YORK (AP) The exclusion of The Weeknds Blinding Lights at the 2021 Grammy Awards shocked many, but hes in good company: Princes When Doves Cry never scored a nomination either.
Heres a look at every Billboard No. 1 hit of the year since 1958, Grammy-nominated or not.
NOTE: Songs with an asterisk represent tracks that earned a Grammy nomination; songs with two asterisks won a Grammy.
2020: The Weeknd, Blinding Lights
2019: Lil Nas X featuring Billy Ray Cyrus, Old Town Road (asterisk)(asterisk)
2018: Drake, Gods Plan (asterisk)(asterisk)
2017: Ed Sheeran, Shape of You (asterisk)(asterisk)
2016: Justin Bieber, Love Yourself (asterisk)
2015: Mark Ronson featuring Bruno Mars, Uptown Funk (asterisk)(asterisk)
2014: Pharrell Williams, Happy (asterisk)(asterisk)
2013: Macklemore & Ryan Lewis featuring Wanz, Thrift Shop (asterisk)(asterisk)
2012: Gotye featuring Kimbra, Somebody That I Used to Know (asterisk)(asterisk)
2011: Adele, Rolling In the Deep (asterisk)(asterisk)
2010: Kesha, Tik Tok
2009: Black Eyed Peas, Boom Boom Pow (asterisk)(asterisk)
2008: Flo Rida featuring T-Pain, Get Low (asterisk)
2007: Beyonc, Irreplaceable (asterisk)
2006: Daniel Powter, Bad Day (asterisk)
2005: Mariah Carey, We Belong Together (asterisk)(asterisk)
2004: Usher featuring Lil Jon and Ludacris, Yeah! (asterisk)(asterisk)
2003: 50 Cent, In Da Club (asterisk)
2002: Nickelback, How You Remind Me (asterisk)
2001: Lifehouse, Hanging by a Moment
2000: Faith Hill, Breathe (asterisk)(asterisk)
1999: Cher, Believe (asterisk)(asterisk)
1998: Next, Too Close
1997: Elton John Candle In the Wind 1997 (asterisk)(asterisk)
1996: Los del Ro, Macarena (Bayside Boys Mix)
1995: Coolio, Gangstas Paradise (asterisk)(asterisk)
1994: Ace of Base, The Sign (asterisk)
1993: Whitney Houston, I Will Always Love You(asterisk)(asterisk)
1992: Boyz II Men, End of the Road (asterisk)(asterisk)
1991: Bryan Adams, (Everything I Do) I Do It for You (asterisk)(asterisk)
1990: Wilson Phillips, Hold On (asterisk)
1989: Chicago, Look Away
1988: George Michael, Faith
1987: The Bangles, Walk Like an Egyptian
1986: Dionne Warwick & Friends, Thats What Friends Are For (asterisk)(asterisk)
1985: Wham!, Careless Whisper
1984: Prince, When Doves Cry
1983: The Police, Every Breath You Take (asterisk)(asterisk)
1982: Olivia Newton-John, Physical (asterisk)
1981: Kim Carnes, Bette Davis Eyes (asterisk)(asterisk)
1980: Blondie, Call Me (asterisk)
1979: The Knack, My Sharona (asterisk)
1978: Andy Gibb, Shadow Dancing
1977: Rod Stewart, Tonights the Night (Gonna Be Alright)
1976: Wings, Silly Love Songs
1975: Captain & Tennille, Love Will Keep Us Together (asterisk)(asterisk)
1974: Barbra Streisand, The Way We Were (asterisk)(asterisk)
1973: Tony Orlando and Dawn, Tie a Yellow Ribbon Round the Ole Oak Tree (asterisk)
1972: Roberta Flack, The First Time Ever I Saw Your Face (asterisk)(asterisk)
1971: Three Dog Night, Joy to the World (asterisk)
1970: Simon & Garfunkel, Bridge Over Troubled Water (asterisk)(asterisk)
1969: The Archies, Sugar, Sugar
1968: The Beatles, Hey Jude (asterisk)
1967: Lulu, To Sir with Love
1966: SSgt. Barry Sadler, Ballad of the Green Berets
1965: Sam the Sham & the Pharaohs, Wooly Bully (asterisk)
1964: The Beatles, I Want to Hold Your Hand (asterisk)
1963: Jimmy Gilmer and the Fireballs, Sugar Shack
1962: Acker Bilk, Stranger on the Shore (asterisk)
1961: Bobby Lewis, Tossin and Turnin
1960: Percy Faith, Theme from A Summer Place (asterisk)(asterisk)
1959: Johnny Horton, The Battle of New Orleans (asterisk)(asterisk)
1958: Domenico Modugno, Nel Blu Dipinto di Blu (Volare) (asterisk)(asterisk)



Stephen Holden writes for the NYT covering the Cabaret/Standards Scene (Gershwin/Berlin/Porter/Broadway)

Show Calendars @ some NYC venues
http://metropolitanroom.com/enhancedCalendar.cfm
https://54below.com/calendar/?month=December+2016
https://www.rosewoodhotels.com/en/the-carlyle-new-york/location/things-to-do/events-at-the-carlyle
http://www.birdlandjazz.com/calendar/
http://www.jazz.org/calendar-full.php
http://americansongbook.org/
"NYC's 3 major cabaret supper clubs - Cafe Carlyle, the Oak Room (Algonquin) & Feinstein's @ Loews Regency - are attached to hotels.
Other downtown Cabaret venues listed in a NYT "Cabaret for a steal" article by Erik Piepenburg:
the 70-seat cabaret theater @ the Duplex in the West Village cover is $20 w 2 drink min.
100-seat place @ Laurie Beechman Theater in Clinton
Don't Tell Mama, W 46th St.
the Metropolitan Rm
Le Poisson RougeJoe's PubCast Party @ Birdland
Kazuo Ishiguro "writes fanciful, mildly surreal lyrics to (Jim) Tomlinson's (saxophonist) music..."
...latter-day answer to Gilberto & Stan Getz (!!)

Harmonica stuff

Harmonica Notes: Understanding the holes for playing songs

If you play any blow hole on a standard key of C 10-hole diatonic harmonica will the pitch be higher or lower?
If you dont know the answer to this trick question, you may have trouble playing songs forever.
Lets figure it out together.
First, blow into hole number 1 and follow that by drawing into hole number 1. Which is higher? The draw note is higher. Right? Check for yourself and youll see this is correct.
Now blow into hole number two, then draw. Again the draw note is higher.
So from these two examples you might conclude that the draw notes are higher than the blow notes, but, if so, you would only be partly correct.
Now try blowing into 10 and then drawing into 10. Hopefully your ear can tell you this is different. Which note is higher in pitch?
The blow note is the higher pitch than the draw note. Somewhere on the harp, the pattern goes from the draw notes being higher to the blow notes being higher. Where does that happen?
Blow draw into 3, then 4, then 5, then 6, then 7! The switch happens between holes 6 and 7. From holes 1 through 6 the blow notes are lower than the draw notes. From holes 7 through 10, it reverses. The blow notes are higher than the draw notes.
Because of this, most harmonica players call holes 1 through 6 the low end of the harp and holes 7 through 10 the high end of the harp. Many players get confused when exploring the high notes.
They know something is different, but they cannot put it into words. Because of this, many harmonica players do not continue exploring the high notes (and they feel intimidated to play songs on the higher notes).
Have the courage to explore the high notes and, the more you do it, the easier it will be for you to include all the notes on the harmonica to play the songs you love.
Playing the major scale is a great way to feel the shift.
Play these notes to go up the major scale:
Do Re Mi Fa So La Ti Do
4 -4 5 -5 6 -6 -7 7
And play the same notes in reverse to go down the major scale.

Practice this a bit and this initially confusing aspect of harmonica will soon become second nature to you.
(Article by: Michael Rubin)




Wild Thing (Hendrix)

5 4 -5 -5 5 -4 4
Wild Thing you make my heart sing

-5 -5 6 4 4 4 3
You make everything groovy

-4 4
Wild Thing (spoken)"Wild thing I think I love you"

3 6 6 b6 6 -5 5 4
But I wanna know for sure

(spoken)"come on and hold me tight I love you"

(instamental break)
6 6 5 6 5 6 5 6 5 6 5 5 6 -6 6 5 6 -6
-6 6 5 6 5 6 5 6 -6 -6 -7 -7 -6 6 -6 6 5
-7 -6 6 -6 6 5 -7 -6 6 -6 6 5 -7 -6 6 5 -7
-6 6 5 5 6 6 5 6 5 5 5 6 -6

REPEAT THE FIRST PARTOF THE SONG

AND END WITH THIS
-5 -5 -5 -5 5 4
C`m`on c`m`on Wild Thing

(harmonica riff) Billy joel's piano man

456 456- 456 456- 456 345- 345 345- 345
45 456- 45 456- 45

Yeh shaam mastani (Kishore Kumar)
ye shaam mastaani, mada_hosh kiye jaaye


6  4     -4 4-6  6   6 6  4  
 4 -4  -4  5


mujhe Dor koii khii.nche, terii ooor liye jaaye


5 5   56 -6  6 -9  6  -9-9 5   5-95-4
6


<ye shaam ...>


duur rahatii hai tuu, mere paas aatii nahii.n


-6  -9   6   -6   6    4 4  -6
   -9 6   -6 6


hoTho.n pe tere, kabhii pyaas aatii nahii.n


4 -6 -96 -6 6   4 4    -6     -9 6  
-6 6


aisaa lage, jaise ki tuu, ha.Nske zahar koii piye jaaye


-7 -6   6 -9   -6  6  -9  5 -4  -4
   -4  -4 -9  -9 -44 67 -55



Chala jaata huun (Kishore Kumar)

PLAY with a fast tempo


chalaa jaataa huuN, kisii kii dhun mein


555 66 55 7 -5-5


dhaDakate dil ke, taraane liye


555 566 5 7 -4 -7 7


milan kii mastii, bharii aaNkhon mein


77 -7 -6 -6 -7 -7 -6 6 66


hazaaron sapane, suhaane liye ho..oo


7 7 -7 -6 -6 -6 -7 -7 -6 6 6 6 -55


ye mastii ke, nazaaren hain, to aise mein


6 6 6 65 6 6 6 6 -55 6 6 6 6 5-4


sambhalanaa kaisaa merii qasam


-7 -7 -7 -7 7 7 6 -7 -6 6


tuu laharaatii, Dagariyaa ho, to phir kyuN naa


6 6 6 6 6 5 6 6 6 6 6-55 6 6 6 6 5-4


chaluuN mein bahakaa bahakaa re


-7 -7 -7 7 7 7 -7 -7 -7 7


mere jeevan mein, ye shaam aaii hai


7 7 -7 -6 -6 -7 -7 -6 6 6


muhabbat vaale, zamaane liye ho..oo


7 7 -7 -6 -6 -7 -7 -6 6 6 6 -55



Yeh dosti

yeh dosti 


5~ -4~44 3~


hum nahi todenge


3 -66~  5-454~


todenge dum magar


55-5~ 6 -5 5 -4~


tera sath na chhodenge


-4-4 555~ -444~


 


teri jeet meri jeet


666 -6-6-6


teri haar meri haar


666 -6-6-6


sun aey mere yaar


6~6~ -56 -55~


tera gum mera gum


666 -6-6-6


meri jaan teri jaan


666 -6-6-6


aesa apna pyar


6~6~ -56 -55~


 


jaan pe bhi khelenge


55 -56 -55 -4


tere liye le lenge


-4-4 5 -5 555~


sab se dushmani


555~ -444~


yeh dosti hum nahi todenge


Aane wala pal

aane wala pal


4 -4 5 -6-6~ -7


jane wala hai


-7 -6 5 -4 5~


ho sake to isme


5 -5 6 -5 5 -4~


zindagi bita do


-4 5 -5 5 -4 4


pal jo ye jane wala hai


-4 4 5 -4 -5 5 6 -5 5


ik bar waqt se


444 -3 -4 -3 4~


lamha gira koi


555 -4 6 -4 5


wahan dastaan mili


666 6 -6 7 -6 -5


lamha kahin nahi


-6-6-6 6-6-7-6 6~


thoda sa hansa ke


5 -5 6 -5 5 -4~


thoda sa rula ke


-4 5 -5 5 -4 4~


pal ye bhi jane wala hai


-4 4 5 -4 -5 5 6 -5 5


Maniyaro

.. ,
.
,
, ,
, .


..
,
, . .


..
,
, .


..
,
, .


.. ,
,
, ,
, .


.. ,
,
, ,
, .


..
, ,
, ,
, . .


Buddhism
Ten Bulls or Ten Ox Herding Pictures:
https://en.wikipedia.org/wiki/Ten_Bulls
http://philosophy.lander.edu/oriental/reader/reader/x5038.html

Shikantaza
Five Ranks
Subitism
Kensh
Satori
Three Mysterious Gates
Four ways of knowing
Sesshin
Zazenkai
Ango
Rinzai school
https://blogs.baruch.cuny.edu/asianamericanhistorynyc/

Discounted stuff:

WallSt to RedHook ferry free wkends
Free (pay what you want) museums: Met, NatHist, Frick
only remaining disc store
Woodbury commons mall, 1 hr upstate
Public pools
free kayak sess/Hudson
free wifi
pod (39th, 51st) $95+
theJane (railway sleeperCar inspired) $85+
'stylish' timesSq $150+, 230-rm
Rooftop bars #1#2#3

somewhat interesting:
https://batteryrooftopgarden.org
http://www.bikeblognyc.com/ & page/2/ etc.


NY Post

VICE
NY Daily News
Why We Love to Loathe Manhattan's UES...
AM NY
ABC7 NY
CBS NY
Those People (2016) - Rotten Tomatoes
westsidewords
Airbnb but lotsa gd photos
http://untappedcities.com/
(blocked)humansofnewyork
(blocked)WestSideRag (seems gd)
(blocked)The Upper Far East - The Rumpus.net
life in the apple (blocked)
http://gothamist.com
Anglophile's guide to New York
Gotham Gazette Manhattan blogs, lists
Terry Teachout
NYT CITY ROOM rdr's stories
NY rooms to let stories






Europan Cafe - 11 Reviews - Cafes - Upper West Side - New ...
Vegan NYC Tour
ny.eater
Yelp rev


srch results for manhattan veggie places: http://tinyurl.com/z9bh8qq

- 252 Manhattan veggie restaurants at http://www.vegguide.org/region/5
(but v. few rated well, lots of cafes & raw/vegan stuff) top choices have been listed below.
Hummus Kitchen - 768 9th Avenue 212-333- 3009
Gd rev from NYT, also has falafel
Soy and Sake Village
47 7th Avenue South 212-255-2848 http://www.soyandsake.com
Japanese Vegetarian cafe West Village specializing in Japanese food, but also carrying Chinese, Malaysian, and American soul food. owned by the same people as Red Bamboo / VP2, so the menu includes many well-known Red Bamboo items like chicken Parmesan, soy chops, and other soul food dishes utilizing soy meats. Other menu items include: numerous mockmeat sandwiches, curries, salads, noodle dishes, bento boxes and sushi. Lunch specials are about $7-9 include both sushi and soul food options.
Hangawi 12 E 32nd Street
Vegan Korean dining in a tranquil space "posh". Zagat rated as top Korean and top vegetarian.
Lunch specials are WAY cheaper than dinner ($10 vs. $25),

Beyond Sushi 229 E 14th St betw 2nd & 3rd Ave Union Square vegetarian sushi shop
Executive Chef Guy Vaknin is a Hell's Kitchen finalist. He serves all vegetarian sushi made from fruits and vegetables topped with customized sauces. Spicy Mango Roll - black rice, avocado, mango, cucumber and spicy veggie topping with toasted cayenne sauce.
Kyotofu Upper West Side 705 Ninth Avenue
Upscale, modern Japanese food with an emphasis on tofu
Souen Organic Ramen East Village Betw 1st & 2nd Ave 326 E 6th St Small organic ramen noodle shop
From the owners of Souen comes this tiny organic ramen noodle shop. The seitan dumplings are vegan but make sure to ask questions about the ingredients of the different broths available.
Maoz Vegetarian Restaurant 38 Union Sq E International Falafel Chain
falafel sandwiches, salads, and fries. After you get your sandwich, there's a large selection of self-serve toppings - pickles, cucumber salad, roasted cauliflower, dairy and vegan coleslaws, carrots, baby eggplants dyed in beet juice (really), olives, several fresh hot sauces, and much more. The trick is they don't leave very much spare room in your sandwich, so you can't really load up on the condiments. The first Maoz branch was opened in 1991 in Amsterdam, Holland
KAJITSU it's Michelin-starred Midtown E 125 E39th St betw Park & Lex Aves
A tasting menu here runs $95, with the option of an additional $59 sake pairing;
you can also opt for the less extravagant $55 menu, with a $45 sake pairing.
Shojin cuisine refers to a type of vegetarian cooking that originates in Zen Buddhism.
Even though it does not use meat or fish, shojin is regarded as the foundation of all Japanese cuisine, especially kaiseki, the Japanese version of haute cuisine. In its present form kaiseki is a multi-course meal in which fresh, seasonal ingredients are prepared in ways that enhance the flavor of each component, with the finished dishes beautifully arranged on plates. All of these characteristics come from shojin cuisine, which is still prepared in Buddhist temples throughout Japan.

Peacefood Cafe 460 Amsterdam Ave betw82nd and 83rd Streets on UWside
The roasted Japanese pumpkin sandwiches ($9.75) are served on spelt bread and come stuffed with pumpkin pulp, cashew cheese, walnuts and onions; the Shangai-style dumplings ($8.50) are packed with chives, mushrooms, marinated tofu and vegetarian protein, and the chickpea fries ($8.50) are thick mashed legume slices fired up with piquant Indian spicethere are also vegan cheeseburgers on tap at Peacefood's downtown spot. Don't skip out on dessert here, since the raw key lime pie ($7.50) will blow your mind, almond brazil nut crust and all. (limes shortage coming up).
In addition to expanding service to anyone and everyone (in Midtown East) Jul2016, David Chang's delivery-only Momofuku restaurant Ando also introduced a new vegetarian sandwich and a meat-less side: Veg Banh Mi s/w ($10), Kimchi salad $4
Charrua 131 Essex Street, New York, NY 10002 (212) 677-5838 (S of Houston)
the vegetarian chivito, called the el cheto, a "signature Uruguayan sandwich" filled with portobello mushrooms and mozzarella, plus carrots, caramelized onions, and chimichurri, and served with a handful of thick, hot fries.
Renovations are now complete at Tribeca stalwart Pakistan Tea House. The inexpensive restaurant was purchased by the owners of Baluchi's last year, who decided to close the shop for some renovations in January. The space now has a few new details including large wooden tables, and chrome panelling on part of the wall but the overall layout remains the same. Tribeca Citizen notes that the restaurant is now serving a limited menu, which includes vegetarian and meat combo plates for $8 to $10. According to the specials board, samosas are two-for-a-dollar.
Cinnamon Snail at The Pennsy
World famous vegan food truck turned permanent vendor in this spacious food hall above Penn Station. Every vegan's dream

Founded by renowned Chef, Guy Vaknin, and his wife, Tali, Beyond Sushi offers an assortment of distinctive sushi rolls and other nutritional staples at their three outposts in Manhattan.
Chef Guy and his culinary team fuses unconventional pairings of fruit and vegetables with whole grains to create sushi rolls. Hand pressed juices; reason. prices, online ordering/deliv.
UNION SQUARE 646-861-2889 229 E. 14th St. (Between 2nd & 3rd Ave)
MIDTOWN WEST 646-964-5097 62 W 56th St. (Between 5th & 6th Ave)
CHELSEA MARKET 212-929-2889 75 9th Avenue (Between 15th & 16th St)

Cinnamon Snail Penn Plaza, Southwest corner of 33rd St. and 7th Ave
"voted the top food truck in America", four- time Vendy Award winner the Cinnamon Snail finally shares the recipes for its beloved street-side meals. Here you'll find Fresh Fig Pancakes for breakfast, Chimichurri Tempeh Empanadas for a snack, Thai Barbecue Seitan Ribs for a meal, and, of course, Snail classics like Vanilla-Bourbon Creme Brulee Donuts for dessert.
Blossom du Jour (212) 229-2595 Vegan, Juice Bars & Smoothies 5 locations:
CHELSEA 259 West 23rd Street (between 7th & 8th Ave.)
HELL'S KITCHEN 617 9th Avenue (between 43rd & 44th St.)
UNION SQUARE 15 East 13th Street (between 5th & University)
UWS 81ST 449 Amsterdam Avenue (between 81st & 82nd St.)
COLUMBUS CIRCLE in the subway statione 1000S 8th Ave, #21
For over a decade, Terry's Gourmet Deli on Chelsea's 6th Avenue has dispensed some of the city's best Trinidadian rotis. The vegetarian (potatoes and chickpeas only) weighed in at a whopping 1 pound, 10 ounces; was 6 inches long, and cost $8. I'm not sure how one person could finish it. You can ask the roti maker for any amount of pepper sauce to be put inside, and I usually go for three plastic teaspoonfuls. 575 6th Ave, (212) 206-0170.

Nix (Michelin-starred chef John Fraser)
Vegetables are finally getting their due in New York, as evidenced by new all-vegetarian restaurant Nix. The food is complemented by a strong drinks program at this NYU-area restaurant in a modern space.
(Brdway & 11th, just north of the Village) 72 University Pl New York, NY 10003 (212) 498-9393
presently open for dinner only. http://www.nixny.com/
"When my vegetarian friends ask for dining advice I send them to American spots like Hearth, for hen of the woods mushrooms and gnocchi, or to to nouveau-Indian spots like Babu Ji for their bright yellow Punjabi curries. I send them to creative pizza spots like Roberta's and Pasquale Jones, to Semilla for vegetable-heavy tastings, to Del Posto for their vegan tasting menu. Some of the most celebrated vegetable dishes right now are served at "regular" restaurants: the grain bowls, the avocado toasts, the brown butter and squash carpaccios.
Superiority Burger made the veggie burger just as much an object of desire among the city's culinary cognoscenti as a trendy lamb burger. Now, the menus at Momofuku restaurants read "vegetarian options available on request."

famed Avenue B deli Sunny and Annie's - vegetarian sandwich - had not just pesto, grilled mozzarella, fresh goat cheese, spinach, seaweed, and avocado, but also ~three~ pieces of bread, making it the first non-meat double decker I've ever seen.
new fast-casual Asian restaurant @ 122 Ludlow Street Zing's Awesome Rice: menu will include six types of "seared rice," Yes, the fried rice is awesome, and it comes attractively plated with two domed scoops on either end of a long plate, with sriracha squirted in the middle in the shape of a heart or a leaf. But is it worth $11.99 to $13.99 for a modest serving, so that a full meal with app and beverage will run you $20 or $25? That's for you to decide. The rice is loaded with umami, has diced vegetables in it, and offers as a main ingredient a choice of tofu. For an extra dollar or two you can pick a more exotic form of rice, including a black rice with a particularly nutty flavor. Beverages run to beer and infused sake.
(5/16) Philadelphia-based chef Michael Solmonov and restaurateur Steve Cook officially kicked open the doors to the Chelsea Market outpost of their hit hummus restaurant, Dizengoff, this morning. A key member of the Dizengoff Philly team moved to New York for the opening of this new counter: executive chef Emily Seaman. Dizengoff will always serve fresh hummus, and pita baked in a taboon, but the toppings and combinations will change often. Solomonov tells Eater: "Emily really changes the menu all the time. She gets everything from the market, basically, and transforms it into Israeli-esque dishes." Solomonov notes that the avocado with peanut harissa on the opening menu is "not something that you'd ever find in Israel, but it really tastes fantastic." The hummus meals are $10 to $13, and the salatim are $3 each. for the moment, Dizengoff NYC is serving salads, hummus, pita, and drinks.
<<resp to above, a reviewer sez:>>I thought that the hummus at Dizengoff was excellent - probably the best in Manhattan along with Baraca on 38th Street, and amongst the best in the entire City in league with places like Olympic Pita and Mabat in Brooklyn, or Grill Point in Queens. (they don't have falafel for some reason)

Freud
The brunch menu at chef Eduard Frauneder's new Greenwich Village Austrian restaurant has a vegetarian breakfast sandwich with cauliflower, egg, Tumbleweed cheese, and onions on a roll. Baked eggs are also on the menu. For sweet options, Frauneder is offering pancakes with rhubarb, and French toast served with walnuts and smoked maple syrup.
506 Laguardia Pl New York, NY 10012 (212) 777- 0327 (just N of Houston below the Village)
Stuff to eat @ the Columbus Circle's Turnstyle Food Court (access via an outdoor elevator at 59th Street and 8th Ave)
2. Tex-Mex Slice at The Pizza * Uber-cheesy, with a slightly thicker than usual crust dotted with serious jalapenos and black-olive slices, and irrationally finished with squiggle of honey, the Tex-Mex slice verges on wonderful. But they should hand out wet-naps due to stickiness. $3.50
3. Key Lime Tart at Georgia & Aliou's * Topped with a fresh raspberry and a few slivers of lemon zest, the yellow pastry looks like a beach scene if you squint your eyes. It's every bit as tart and rich as you hoped, made for nibbling rather than biting. $5.50
5. Smoked Egg Salad Sandwich at Ellary's Greens * Vegetarians take note: The smoked egg salad sandwich at Ellary's Greens delivers much the same barbecue power as a slice of smoked brisket, with chopped kale adding to the textural terrain. $8
6. Avellino Focaccia Sandwich at Casa Toscana * The house-baked focaccia (sometimes known as pizza bianca) is thin and slightly crisp, and on it is piled mozzarella, cherry tomatoes, and fresh basil, making for a simple and delicious sandwich, the way they do it in Italy. $9

Agern
Agern is the new restaurant from Noma co- founder Claus Meyer and chef Gunnar Gaslason. It is located within Grand Central Station, right next to the Nordic food court that Meyer recently opened. The focus is primarily on Nordic cooking using local American ingredients. There are two tasting menus available * the vegetarian "Field and Forest" ($120) and the meat and fish heavy "Land and Sea" ($145) * as well as a la carte options. Both tasting menus span seven courses, along with a selection of amuse-bouches. (Prices are inclusive of service.)
89 E 42nd St New York, NY 10017 (646) 568- 4018

Salvation Burger - rustic joint in the Pod 51 hotel
Chefs across New York are fostering a vegetarian burger renaissance, and the version April Bloomfield serves at Salvation Burger, her newest restaurant, ranks near the top of the citywide hierarchy. Her kitchen mashes together golden beets, carrots, carrot juice, French lentils, mushrooms, sticky rice, and sweet potato vermicelli. This is all laced with enough warming garam masala to power a geothermal turbine, grilled over wood, and then anointed with cooling yogurt, shredded lettuce, and sweet tomato confit.<<writer goes on to pan this place bigtime, also v. exp (~30 burger) Desi spots:

Founded in 1975 with a name certain to popularize the cuisine to a wider audience, Curry in a Hurry was one of the original anchors of Curry Hill. The international food store Kalustyan's was another. 119 Lexington Ave, (212) 683-0900.
Dating to 1996, the amazing Vatan still offers a single enormous vegetarian meal, reflecting an era when the westernmost state of Gujarat provided many of the city's Indian immigrants. The price of the meal is fixed at $32, and includes approximately 25 dishes organized into four courses. It's also all-you-can-eat. 409 3rd Ave, (212) 689-5666.
<<just a reg. thaali, avoid>>

Bombay Masala (148 W 49th St #2, 212-302-8150) this Times Square standard, successor to Ceylon India Inn, which occupied the space as late as 1968, has a $12.95 lunch buffet considered a good deal.

Vegetarian Ham Banh Mi * Vietnamese baguette sandwiches present such a chorus of powerful flavors (pickled veggies, cilantro, jalapenos, doctored mayo) that it's hard to imagine that lack of real meat would make much of a difference. But there's something wonderful about the fake ham used in this banh mi * greasy, salty, and gelatinous that actually boosts the flavor of this excellent sandwich. Find it at: Banh Mi Place, 824 Washington Ave, Brooklyn,



http://www.dominoguru.com/page.xsp? id=index.html

LinkedIn - Xpages stuff (incl presentations) & Notes stuff
http://xpages.info/XPagesHome.nsf/Home.xsp
https://xomino.com/
http://xpages.tv/
XPages CheatSheet Demo App(Tips & Tricks)
XPages mobile development
notesin9
LACK of notes developers
IBM Connect13 - Meet the Java Application Server You Already Own
ibm Connect 2016 review
IBM Syndicated feeds (Tons o'links)
IBM Connect Sessions & Lotusphere Slides
(esp check earlier xpages stuff, eg::
BP308 The Journey to Becoming a Social Application Developer (2014)

http://www.idonotes.com/IdoNotes/IdoConnect2013.nsf/archive?openview&title=Domino&type=cat&cat=null&tag=Domino
https://developer.ibm.com/connect2cloud/
How to create your own Domino XPages Server in the IBM SmartCloud
IBM Notes and Domino Application Development wiki
IBM Domino biz partner solutions

XPages links:

JSF Tutorials
JSF Tuts from Core Servlets
http://openntf.org/
http://dojotoolkit.org/
Whats_New in 8.52 for XPages
Client Side JS Libraries in XPages
http://www- 10.lotus.com/ldd/ddwiki.nsf/dx/Master_Table_of_Contents_for_XPages_Extensibility_APIs_Developer_Guide IBM XSP & js API ref
CSS & Themes for XPgs
IBM OneUI Theme

https://dojotoolkit.org
OpenNTF java Xpages snippets
A demo application, implemented in the XPages runtime, with a Domino NoSQL database, for Java HttpServlets and front-end development practices
build & deploy a simple, Java-based XPages appl on yr own laptop
Some dude (Medhu?) copied mChart!
Create a local JSON Server for testing (v.gd!)
Notes/Domino blogs/personal sites:
Mat Newman
Notes Speak
Cool 1-pg Notes resume from this guy.
Domino Gavin

Java Cloud IDEs:

http://www.koding.com/features
... once you've finalized your app, you'll want to deploy it on a cloud-based service that lets you host apps long term, preferably one with a free hosting option like Heroku.
(looks ok)Free java cloud IDE : https://codetasty.com
also seems good -> https://codeanywhere.com/signup
http://www.koding.com/


Compile & exec Java (Hydr.)
CodeChef
jDoodle

Bunk from the SauceLabs people

compile.net v gd except for http permissions

ideOne nice but complains on long output

Browxy nice but complains on long output

Chinese compiler only, no IDE

CodEnvy supposedly gd but requires sign-in & reg

Free Java EE, JSF 2.0, Ajax, Android, jQuery, & GWT Tutorials

Servlet Hosting (outdated?!):

gwtproject


ISPs
These days it seems there are servlet engines for nearly every web server, and now we're seeing servlets commonly offered as core value-add for Internet Service Providers (ISPs) and Web Hosting companies.
The megacorp ISPs and Hosting companies still don't offer servlets, though, probably because it's not something Joe Consumer cares about. Also because to host servlets effectively and efficiently requires a bit of expertise. That makes finding a good servlet provider somewhat challenging.
On this page we try to help you on that endeavor by keeping track of all the ISPs that are known to host servlets. For each ISP we provide location and contact information, a short summary, and user reviews. The reviews should help you find out how the ISP you're looking at compares to others in terms of features, reliability, support, and overall score. Feel free to add one of your own.





URLRdr v1_9 updated 9/10/2016 & some srch results generated.
URLRdr v1_82 updated 08/16/2016 & some & some srch results generated by it.
URLRdr v1_7 (w/timeStamp module) updated 08/08/2016 & lotsa srch results generated by it.
URLRdr v1_6 (working GistLink & TinyLink) updated 07/18/2016
URLRdr v1_5 (no soup, no apache includes)
Code for jSoup + escaped JSON string version of URLRdr v1_4.java

//---------------------------------------------------------
FOR TUT POINT SHELL:
http://www.tutorialspoint.com/unix/unix-environment.htm

To set the value of PS1 (PROMPT)
so that it shows the USERNAME & working directory, issue the command -

PS1="[\u@\h \w]\$"

The prompt will show username, machine's name (hostname), and the working directory.

echo $PATH (to see path env)
echo $TERM (to see path terminal)

mvn --version (shows maven version, which IS installed on tutpoint)

*SOLVED!
first :
find / -name "jsoup*.*"
that listed 2 locations for the jars; incl
/usr/share/java/jsoup/jsoup.jar
/usr/share/maven/lib/jsoup_jsoup.jar

to update env var syntax is:
export CLASSPATH= $CLASSPATH:/usr/share/java/jsoup/jsoup.jar

//Before running, will have to compile with jsoup jar:
//export CLASSPATH= $CLASSPATH:/usr/share/java/jsoup/jsoup.jar
//------------------------------------------------------------------------------
import java.net.*;
import java.io.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class URLRdr {

public static String getText(String url) throws IOException {

URL website = new URL(url);
String strBody = "";
Document doc = Jsoup.connect (url).get();
Elements bodyTxt = doc.select("body");

for (Element el : bodyTxt){
System.out.println("bodyTxt: "+el);
strBody = strBody + el.toString();
}
return strBody;
}

public static void main( String[] args ) throws IOException{

String[] thisIsAStringArray = {
"http://www.bing.com/search? q=aesthete+or+flaneur&go=Search&qs=ds&form=QBRE" , "http://www.bing.com/search?q=aesthete+or+flaneur&go=Search&qs=ds&first=11&FORM=PERE" , "http://www.bing.com/search?q=aesthete+or+flaneur&go=Search&qs=ds&first=21&FORM=PERE1" , "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&first=31&FORM=PERE2" };

String content = "";

for( int i = 0; i < thisIsAStringArray.length; i++) {
content=content + URLRdr.getText(thisIsAStringArray[i]);
}
System.out.println( content );

}

}
Code for String Array version of URLRdr v1_2.java

//---------------------------------------------------------
//URLRdr.java
import java.net.*;
import java.io.*;
public class URLRdr {
public static String getText(String url) throws Exception {
URL website = new URL(url);
URLConnection connection = website.openConnection();
BufferedReader in = new BufferedReader( new InputStreamReader( connection.getInputStream()));
StringBuilder response = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
return response.toString();
} public static void main(String[] args) throws Exception { //String content = URLRdr.getText(args [0]);
//System.out.println(content);
//String[] thisIsAStringArray = {"Apple", "Banana", "Orange"};
String[] thisIsAStringArray = { "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&form=QBRE" , "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&first=11&FORM=PERE" , "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&first=21&FORM=PERE1" , "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&first=31&FORM=PERE2" };
String content = "";
for( int i = 0;
i < thisIsAStringArray.length;
i++) { content=content + URLRdr.getText(thisIsAStringArray[i]);
} System.out.println( content );
} }
Sample output from GitHub

//---------------------------------------------------------
//URLRdr.java (for tutorialspoint.com)
import java.net.*;
import java.io.*;
public class URLRdr {
public static String getText(String url) throws Exception {
URL website = new URL(url);
URLConnection connection = website.openConnection();
BufferedReader in = new BufferedReader( new InputStreamReader( connection.getInputStream()));
StringBuilder response = new StringBuilder(); String inputLine; while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
return response.toString();
}
public static void main(String[] args) throws Exception {
String content = URLRdr.getText(args [0]);
System.out.println(content);
}
}
//---------------------------------------------------------
//java URLRdr "https://www.yahoo.com/? p=dnr" >
HelloWorld.java
//then refresh the project to see HelloWorld.java which's auto added to Project

Search param. notes: To get 30 result on single page, pass below parameter:
For bing use count=30 - http://www.bing.com/search?q=test&count=30
For yahoo use n=30 - https://search.yahoo.com/search? p=test&n=30
For google use num=30
- https://www.google.com/search?q=test&num=30

 String[] 

srchUrlArray = {
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=11&pstart=2", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=21&pstart=3", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=31&pstart=4", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=41&pstart=5", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=51&pstart=6", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=61&pstart=7", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=71&pstart=8", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=81&pstart=9", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=91&pstart=10", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=101&pstart=11", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=111&pstart=12", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=121&pstart=13", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=131&pstart=14", 
    "https://search.yahoo.com/search?p=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016%26n%3D100%26sort%3Dnew&xargs=0&psqn=2&b=141&pstart=15", 
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=11&FORM=PERE" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=21&FORM=PERE1" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=31&FORM=PERE2" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=41&FORM=PERE3" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=51&FORM=PERE4" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=61&FORM=PERE5" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=71&FORM=PERE6" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=81&FORM=PERE7" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=91&FORM=PERE8" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=101&FORM=PERE9" ,
    "http://www.bing.com/search?q=domino+xpages+java+jobs+contract+-pizza+-delivery+-driver

+2016&go=Search&qs=ds&first=111&FORM=PERE10" 
    };

OTHER JAVA-RELATED READING


some general reading from Dec '20 reddit etc. Java Development on Windows - Request for Ideas/Enhancements : java
What are some great Java libraries I'm probably not using but I should? : java
Java Microservices: A Practical Guide : java
Humblebundle Java Programming Books Bundle : java
Why backend using java is not popular in startups? : java
How to write a (toy) JVM : java
Memory Leaks in Java: A Cautionary Tale and Gentle Introduction to Preventing Memory Errors : java
Modern Web Development in Java - The (Never) Complete Guide : java
Should I get Clean Code? : java
The 25 greatest Java apps ever written : java
Principles to Handle Thousands of Connections in Java Using Netty : java
Why Java is better than C++ for high speed trading systems : java
Programming Languages
programming


Interesting libraries (many've been updated since last checked)

jimfs: An in-memory file system for Java 7+, poss updated since last use

Gulava allows you to write relational predicates in Java. You can write Prolog-style predicates and use them from normal Java code, seamlessly integrated with the magic of annotation processors.
(uses annotations to generate preds; class Goal accepts Objects & pred is blt frm that)

Reagera is a minimal implementation of a predictable state container in Java, inspired by Elm and Redux.

GitHub - Vedenin/useful-java-links: A list of useful Java frameworks, libraries, software and hello worlds examples

GitHub - iluwatar/java-design-patterns: Design patterns implemented in Java

GitHub - TheAlgorithms/Java: All Algorithms implemented in Java

GitHub - looly/hutool: A set of tools that keep Java sweet.

GitHub - redisson/redisson: Redisson - Redis Java client with features of In-Memory Data Grid. Over 50 Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Publish / Subscribe, Bloom filter, Spring Cache, Tomcat, Scheduler, JCache API, Hibernate, MyBatis, RPC, local cache ...

GitHub - mybatis/mybatis-3: MyBatis SQL mapper framework for Java

GitHub - oracle/graal: GraalVM: Run Programs Faster Anywhere

GitHub - realm/realm-java: Realm is a mobile database: a replacement for SQLite & ORMs

GitHub - rzwitserloot/lombok: Very spicy additions to the Java programming language.

GitHub - redis/jedis: A blazingly small and sane redis java client

GitHub - java-decompiler/jd-gui: A standalone Java Decompiler GUI

GitHub - antlr/antlr4: ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files.

GitHub - ben-manes/caffeine: A high performance caching library for Java 8

GitHub - square/javapoet: A Java API for generating .java source files.

GitHub - facebook/buck: A fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.

GitHub - TooTallNate/Java-WebSocket: A barebones WebSocket client and server implementation written in 100% Java.

GitHub - dropwizard/metrics: Capturing JVM- and application-level metrics. So you know what's going on.

GitHub - spring-projects/spring-security: Spring Security

GitHub - scribejava/scribejava: Simple OAuth library for Java

GitHub - klehmann/domino-jna: Java project to access the IBM/HCL Domino C API using Java Native Access (JNA)



programming the "trillion dollar disaster" - Google Search
Is Object-Oriented Programming a Trillion Dollar Disaster? - Slashdot
Object-Oriented Programming The Trillion Dollar Disaster | Hacker News
Object-Oriented Programming The Trillion Dollar Disaster : haskell
Case against OOP is understated, not overstated
Is Object-Oriented Programming "Dangerous"? - DEV

Docker Tutorial: Play with Containers (Simple Examples)
  • RedHat OpenShift | AWS FreeTier | RackSpace hosting
    Outlook taskitem members/methods
    https://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._taskitem_members.aspx

    JSON

    http://www.json.org/
    http://www.jsoneditoronline.org/
    http://jsonlint.com/
    CouchDB

    http://couchdb.apache.org/
    Apache CouchDB is open source database software that focuses on ease of use and having an architecture that "completely embraces the Web".[2] It has a document-oriented NoSQL database architecture and is implemented in the concurrency-oriented language Erlang; it uses JSON to store data, JavaScript as its query language using MapReduce, and HTTP for an API.[2]
    http://couchdb.apache.org/fauxton-visual-guide/index.html
    PDF

    Java github 2 pdf using itextpdf Lib
    JavaScript PDF gen lib uses PhantomJS


    VBA code snippet
    Selection.Find.Execute FindText:="http:", _Forward:=True, Wrap:=wdFindStop Selection.MoveLeft Unit:=wdCharacter, Count:=1 Selection.TypeParagraph Selection.TypeText Text:="
    " Selection.MoveRight Unit:=wdCharacter, Count:=15


    Office365

    Working/manipulating MSO Files via REST: (3 links)

    https://xomino.com/2016/08/01/reading-an-excel-file-from-onedrive-using-the-microsoft-graph- api/

    MSDN Office365 API Ref

    Accessing MS Files using the Graph API


  • Reading & Notes


    mongo-java-driver/driver-core/src/main/com/mongodb at master mongodb/mongo-java-driver GitHub
    BigTable Almost All You Need to Know | by Amulya Rattan Bhatia | The Startup | Medium
    Cloud Bigtable Client Libraries | Cloud Bigtable Documentation
    Adding a cache layer to Google Cloud databases (Bigtable + Memcached) | by Billy Jacobson | Google Cloud - Community | Medium
    Google Cloud makes it cheaper to run smaller workloads on Bigtable | TechCrunch
    Adding a cache layer to Google Cloud databases (Cloud Bigtable with Memcached)
    Azure Redis Cache and BigTable | G2
    Caching hbase/ google bigtable with SQLite : golang
    Unable to use Bigtable Query object as cache key Issue #5550 googleapis/google-cloud-java GitHub
    How we moved our Historical Stats from MySQL to Bigtable with zero downtime | Fastly
    How Cortex Is Evolving to Ingest 1 Trillion Samples a Day | Grafana Labs
    CS 261 Notes on Bigtable
    mongo-java-driver/driver-core/src/main/com/mongodb at master mongodb/mongo-java-driver GitHub
    BigTable Almost All You Need to Know | by Amulya Rattan Bhatia | The Startup | Medium
    Cloud Bigtable Client Libraries | Cloud Bigtable Documentation
    How Map and Reduce operations are actually carried out

    HN Thread: Burnt $72k testing Firebase and Cloud Run and almost went bankrupt


    I don't understand why developers use cloud for bootstrapping/side project. Digital Ocean is all you need $5 droplet + $15 Postgres or even better $7 dyno on Heroku.
    ...
    Heroku costs are pretty predicable, and you can easily set a maximum scalability threshold to their auto-scalable dynos, so that they will never cost you more than a predefined amount of money


    >>I'm just a student but I've spent about 10 hours trying to figure out why Azure >>has been charging me >$5/day for their "basic" database @5DTUs, 2gb max >>storage.
    Do you have geo-replication turned on? More regions will be an additional $5/month (plus bandwidth between regions) if you replicate. You can serve everything out of a single region but it is pretty easy to add others if you're not paying attention during initial setup.


    Yeah a friend of mine wanted a real cert, not letsencrypt (I don't understand how that is more real but ok), as a bit of a noob he clicked around on the AWS website and some days later had a bill op 1500 eur. They also nulled it. Still, this scares the hell out of me.


    ...we're in the process of switching from Digital Ocean to Hetzner for a project, that will increase infrastructure performance (roughly memory/cpu/storage) by 4x and decrease costs by 4x. And no driving to the colo center is neccessary, as it's their dedicated server, so their on-site engineers do the hardware replacement.


    ,,,writing as somebody who runs a big collection of bare-metal hypervisors for ISP infrastructure purposes... this post quite honestly just makes me smirk.
    I have truly lost track of the numerous instances, and number of people who would be better served by buying a $1200 test/development 1U dual socket server with a few fast SSDs in it, and putting it in colocation somewhere for a few hundred dollars a month. The costs would be absolutely fixed and known.

    On a tight budget? You don't even need to go as far as $1200, I see totally fine test/development environment suitable, Dell 1U servers on eBay right now for under $500 with 128GB of RAM.

    Or that would be better off purchasing a fixed-configuration virtual machine (typically running on xen or kvm underneath) that has a certain specific amount of CPU, RAM and storage resources allocated to it which cannot balloon. For a fixed bill per month like $65 or $85.


    >>Can anyone recommend a similar provider but for North America?
    https://oneprovider.com/dedicated-servers-in-north-america


    ...Always use a virtual card for this. This way you can tell in advance how much can be drawn max and the expiration date.
    ...Instead I use DigitalOcean where you have droplet limits that you can set, and the ability the pre-pay if you pay by PayPal, and never enter my bank card
    ...I use DigitalOcean and not GCP/AWS, personally and professionally, for the exact same reason: they provide a way to not give the company a "free for all" access to a bank acccount.
    ...I tried to signup with a gift card and it was rejected.
    I can attach a gift card to paypal and use it.


    Addenda 2.26
    mongoplayground.net (blocked @ careerF)
    https://www.humongous.io/app/playground
    https://github.com/ramnes/awesome-mongodb

    https://www.w3resource.com/mongodb-exercises/

    https://github.com/fakemongo/fongo
    Fongo is an in-memory java implementation of MongoDB. It intercepts calls to the standard mongo-java-driver for finds, updates, inserts, removes and other methods. The primary use is for lightweight unit testing where you don't want to spin up a mongod process.

    Capacity planning:...Additional capacity can be added with no application downtime, and you can optionally
    enable auto-scaling to respond automatically to spikes in usage.

    Ensuring that applications gracefully handle cluster failover through testing.

    "ALL indexes shd fit in memory"
    If your index doesnt fit in memory the slow down you will experience when querying on that index as pages are read from disk expired and then reread from disk will be dramatic.

    The goal for every performant database is to have all its regularily queried indexes to fit completely in RAM. To futher increase performance the most regularily queried records should fit in RAM as well.

    For a gaming application this means data associated with logged in users, for a banking application accounts that have transactions in the last thirty days etc. etc.

    ...from mongoDevBlog related to above, how to fit all idx es into RAM...
    In MongoDB Collections and Indexes both use the same underlying data structure. WiredTiger tables - these are BTrees (B+ ish trees) , essentially key-value stores arranged into pages(or blocks depending who you ask) - each page is 32KB in size or one entry whichever is larger (Up to 16MB for a single 16MB BSON document) - its then compressed when flushed to disk. In memory a collection page contains both the the on-disk version of the page as well as a list of changes to any document not yet reconciled to disk. An Index page contains the index keys and for each key (which may be the full key or prefix compressed) a pointer to the identity of the document it points to.

    When you access an index - MongoDB checks to see if the page is in cache - if not it reads it from the disk (going via the OS pagecache so it may be cached there) - index pages are not compressed on disk as they already have prefix compression.

    The upshot is that each index lookup may in cache (nice and fast) or not in which case , nothing to do with page faults - this is all explicitly tracked, it will require a disk read which will be 32KB and a seek at the very least - if you have readahead set appropriately it may be more than 32KB. If that happens to be in your OS page cache it will be quicker but it still needs some processing to put it in cache. The seek will take 1 IO operation at least so a 1000 IOPS disk, with random seeks in an index which is much larger than ram will be very much throttled by IO.

    You can look at the Read-Into-Cache metric using any of the MongoDB tooling (or look in db.serverStatus() and diff the entries) you can also observer the cache for collections and indexes using mongocacheview.js (https://github.com/johnlpage/MongoCacheView).

    In general - if your working set does not fit in ram, expect one to two orders of magnitude slower operations that hit those keys (queries, inserts, deletes, updates of indexed values) , consider (a) Adding RAM (b) Making indexes smaller Adding many IOPS - in that order.

    ...also...
    If you want to preheat (upload it into RAM) your indexes when mongod start you may use db.runCommand({"touch" : , "data" : true, "index" : true}). Accessing index entries that are not in memory is particularly inefficient, as it often causes two page faults. There is one fault to load the index entry into memory and then another to load the document into memory. When an index lookup causes a page fault its called a btree miss. MongoDB also tracks btree hits: when an index access does not have to go to disk (from MongoDB definitive guide). Alexey Smirnov Dec 31 '16 at 12:36

    >>$or query using more than 2 indexes takes forever Joris_SEBIRE
    Hello, I have a probleme with a mongo query that uses an $or like :
    {
    a: 1,
    b: 2,
    $or: [
    { c: 3 },
    { d: 4 },
    { e: 5 },
    { f: 6 }
    ]
    }
    i have every a_b_c, a_b_d, a_b_e and a_b_f indexes but that query takes more than 150 seconds.
    But, if i comment any 2 of the 4 items in my $or, the request takes 0.5 seconds
    Does mongo applie a limit of index used in an $or query ? or something i didnt get ?
    Thanks for your answer.

    Pavel_Duchovny MongoDB Employee
    Welcome to MongoDB community.
    The ways your indexes are built the engine tries to do an index intersection loading all indexes to memory and merging them.
    I think that for this query its best to use either all fields in one index or just index a,b
    Thanks,
    Pavel

    Sudhesh_Gnanasekaran
    Refer to this documentation that might be helpful for your use-case.
    https://docs.mongodb.com/manual/core/index-compound/
    ,...from above...MongoDB imposes a limit of 32 fields for any compound index.
    Compound indexes can support queries that match on multiple fields.
    ...Index fields are parsed in order; if a query omits a particular index prefix, it is unable to make use of any index fields that follow that prefix.

    ...The choice between creating compound indexes that support your queries or relying on index intersection depends on the specifics of your system. (see https://docs.mongodb.com/manual/core/index-intersection/#index-intersection-compound-indexes)

    MongoDB may use the same wildcard index for satisfying each independent argument of the query $or or aggregation $or operators.

    if you want the aggregation to use the index you need to perform either a $match or $sort stages in the beginning of the query.
    eg, db.collection.aggregate([{$match:{"Instance.field":"value"},
    {$unwind: "$Instance"},
    {$match:{"Instance.field":"value"}}])

    https://stackoverflow.com/questions/8607637/are-there-any-tools-to-estimate-index-size-in-mongodb
    mongodb query and index optimization.

    groupBy note:
    "$group does not order its output documents." See http://docs.mongodb.org/manual/reference/operator/aggregation/group/

    $limit limits the number of processed elements of an immediately preceding $sort operation, not only the number of elements passed to the next stage. See the note at http://docs.mongodb.org/manual/reference/operator/aggregation/limit/

    >>pagination on group data mongodb -

    in $group items you can't directly apply pagination, but below trick will be used ,
    step 1 - write aggregation on product table, and write groupBY
    step 2 - prdSkip for skipping , and limit for limiting data , pass it dynamically
    finally query looks like - params - limit , skip - for category pagination and prdSkip and PrdLimit for products pagination
    db.products.aggregate([
    { $group: { _id: '$prdCategoryId', products: { $push: '$$ROOT' } } },
    {
    $lookup: {
    from: 'categories',
    localField: '_id',
    foreignField: '_id',
    as: 'categoryProducts',
    },
    },
    {
    $replaceRoot: {
    newRoot: {
    $mergeObjects: [{ $arrayElemAt: ['$categoryProducts', 0] }, '$$ROOT'],
    },
    },
    },
    {
    $project: {
    // pagination for products
    products: {
    $slice: ['$products', prdSkip, prdLimit],
    },
    _id: 1,
    catName: 1,
    catDescription: 1,
    },
    },
    ])
    .limit(limit) // pagination for category
    .skip(skip);
    answered Oct 22 '20 at 6:50 Akshay Dhawle


    $replaceRoot (aggregation):
    https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/#new-replacement-doc

    Some Docs:

    Mongo api
    mongo github src
    Aggregates
    MongoIterable
    github src

    2.12: 14 gotchas for MongoDB

    2.10: mongo java cli snippets for multiGrps

    <>
    $bucket Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries.

    >>The example for $bucket uses push to create a "bucket" w/an aggregation
    containing an array of Docs; GroupedBy specific crit. @ https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/#pipe._S_bucket


    Use the $accumulator operator to execute your own JavaScript functions to implement behavior not supported by the MongoDB Query Language See also $function.


    MongoCollection myCollection = myDB.getCollection("myCollection");

    Map multiIdMap = new HashMap();
    multiIdMap.put("groupField1", "$groupField1");
    multiIdMap.put("groupField2", "$groupField2");

    Document groupFields = new Document(multiIdMap);
    AggregateIterable aggregate = myCollection.aggregate(Arrays.asList(
    Aggregates.group(groupFields,
    Accumulators.last("lastDate", "$dateCreated"),
    Accumulators.last("lastNumAvail", "$availableUnits")
    )
    ));


    Mongo aggregation in java: group with multiple fields

    MongoDatabase mongo = // initialize your connection;
    Document matches = new Document("$match",
    new Document("gi", new Document("$ne", null))
    .append("ci", Integer.parseInt(courseid)));

    Document firstGroup = new Document("$group",
    new Document("_id",
    new Document("ci", "$ci")
    .append("gi", "$gi")
    .append("gn", "$gn")
    .append("si", "$si"))
    .append("count", new Document("$sum", 1)));

    Document secondGroup = new Document("$group",
    new Document("_id",
    new Document("ci", "$_id.ci")
    .append("gi", "$_id.gi")
    .append("gn", "$_id.gn"))
    .append("ns", new Document("$sum", 1)));

    Document sort = new Document("$sort",
    new Document("_id.gi", 1));

    List pipeline = Arrays.asList(matches, firstGroup,
    secondGroup, sort);
    AggregateIterable cursor = mongo.getCollection("I1")
    .aggregate(pipeline);

    for(Document doc : cursor) { // do stuff with doc }


    Aggregation.group(Fields.fields()
    .and("field1")
    .and("field2"))
    .first("name")
    .`as`("name")
    .count().`as`("count")
    This will produce the following MDB query:

    { "$group" :
    { "_id" :
    { "field1" : "$field1", "field2" : "$field2"},
    "name" : { "$first" : "$name"},
    "count" : { "$sum" : 1}
    }


    Use $unwind to passBack docObs? see:
    final Aggregation aggregation = newAggregation(
    match(Criteria.where("key").is("KEYCODE001")),
    unwind("$values", true),
    unwind("$values.objects", true),
    match(Criteria.where("classId").is("CLASS_01")),
    project().and("$values.classId").as("classId").and("$values.objects").as("object"),
    group("classId", "objects").push("$object").as("objects").first("$classId").as("_id"),
    project().and("$_id").as("classId").and("$objects").as("objects")
    );


    Aggregation.group(fields.toArray(new String[fields.size()])).first("birthdate").as("birthdate").first("category").as("category").sum("usage_history.total_usage").as("sumOfTotalUsage");


    2.12: Pagination in mongoDb Collections
    MPT note: IF NECC this approach can be used by
    - adding a new tmp Counter field *AFTER GROUPING*
    - finding the range#s as above; then getting the pg.

    SO post: When talking about pagination in MongoDB, it is easily to write this code:

    collection.find().skip(pageSize*(pageNum-1)).limit(pageSize);
    Above is the native solution supported by MongoDB, but this is not efficient if there are huge documents in the collection. Suppose you have 100M documents, and you want to get the data from the middle offset(50Mth). MongoDB has to build up the full dataset and walk from the beginning to the specified offset, this will be low performance. As your offset increases, the performance keeps degrade.

    The root cause is the skip() command which is not efficient and can not take big benifit from index.

    Below is another solution to improve performance on large data pagination:

    The typical usage scenario of pagination is that there is a table or list to show data of specified page, and also a 'Previous Page' & 'Next Page' button to load data of previous or next page.

    If you got the '_id' of the last document in current page, you can use find() instead of skip(). Use _id > currentPage_LastDocument._id as one of the criteria to find next page data. Here is pseudocode:

    //Page 1
    collection.find().limit(pageSize);
    //Get the _id of the last document in this page
    last_id = ...

    //Page 2
    users = collection.find({'_id': {$gt: last_id}}).limit(pageSize);
    //Update the last id with the _id of the last document in this page
    last_id = ...
    This will avoid MongoDB to walk through large data when using skip().

    edited Jun 4 '19 at 12:17
    SQB answered May 10 '18 at 6:47



    fs snip
    nice Memoize example
    https://github.com/mikhailshilkov/azure-functions-fsharp-examples Regexp (straight net api calls):
                let TestConnString = 
                    """"""
                Regex.Match(connectionString, "[dD]atabase=(?.*?);").Groups.["database"].Value
                


    SecureString
                For console.readPwd; look @ Security.SecureString;
                
    pump into Marshal.SecureStringToGlobalAllocUnicode
    then to Marshal.PtrToStringUni & finallly Marshal.ZeroFreeGlobalAllocUnicode
    match (Console.ReadKey true).KeyChar
    with | '\r' | '\n' -> Console.WriteLine () charList | chr -> Console.Write '*' readKey <| chr :: charList


    CSV parsing
    // An example of how you might manually parse a CSV file in F#.
     
    open System
    open System.IO
    Environment.CurrentDirectory <- __SOURCE_DIRECTORY__
     
    let file = @"..\..\data\FootballResults.csv"
    type Result =
        { Date : DateTime
          Home : string
          Away : string
          HomeGoals : int
          AwayGoals : int }
     
    let data =
        file
        |> File.ReadAllLines
        |> Seq.skip 1
        |> Seq.map(fun row ->
            let fields = row.Split ','
            { Date = DateTime.ParseExact(fields.[0], "MM/dd/yyyy", null)
              Home = fields.[1]
              Away = fields.[2]
              HomeGoals = int fields.[3]
              AwayGoals = int fields.[4] })
     
    data
    |> Seq.filter(fun row -> row.HomeGoals > row.AwayGoals)
    |> Seq.countBy(fun row -> row.Home)
    |> Seq.sortByDescending snd
    |> Seq.take 3
    


    List fold snippet from EventSourcing-DIY
    module List
     
        /// Map a Result producing function over a list to get a new Result
        /// ('a -> Result<'b>) -> 'a list -> Result<'b list>
        let traverseResult f list =
     
          // define the monadic functions
          let (>>=) x f = Result.bind f x
          let retn = Result.Ok
     
          // right fold over the list
          let initState = retn []
          let folder head tail =
              f head >>= (fun h ->
              tail >>= (fun t ->
              retn (h :: t) ))
     
          List.foldBack folder list initState
    


    fslang-suggestions: Allow Unicode symbols to be used as operators -> has a working workaround
    Unicode Symbol Table

    Fpish: Event.guard to run Async if race conditions
    Event.guard takes a lambda and an event, and returns that same event except it will run the lambda after subscribing so that you never 'miss' the event if the lambda may provoke it.

    Composing validations together to parse a csv file (no invalid inpt allowed via only valid types resulting.)

    (DSyme) Operators You Might Need to Know
    f1 >> f2 Function composition
    (expr1, expr2) ||> f Two-argument pipelining
    (expr1, expr2, expr3) |||> f Three-argument pipelining

    n..step..m Range with step (within a list or sequence or loop)

    let (|A|_|) arg = … Defining active patterns
    let (|A|B|) arg = … Defining active patterns

    <@ … @> Code quotation (expression tree)
    <@@ … @@> Code quotation (expression tree, untyped)

    Operators You Don't Need to Know
    !cell Dereference a mutable reference cell. Use cell.Value instead
    := Assign a mutable reference cell. Use "cell.Value <- expr" instead
    @ Append one list to another. Can normally use a computed list expression or List.append instead

    << Backward function composition, discouraged in favour of forward composition

    <| Back-piping, discouraged in favour of forward piping
    <|| Back-piping, discouraged in favour of forward piping
    <||| Back-piping, discouraged in favour of forward piping

    *?, +? … Nullable operators (these are used exceptionally rarely in LINQ queries, ignore these)

    Should I Define My Own Operators?
    Almost certainly not. See msft design guidelines


    Reflection on Nested Types in DU
    
        open System
    
        type OptModID = | OptModID of i_modNm: string
    
        type DocVersionModule = | DocVersionModule of OptModID * lastVerNum:int * hasPriorVers:bool with
            member this.desc() = 
             let (DocVersionModule(OptModID(modNm), lastVerNum, hasPriorVers)) = this
             "Optional Module: " + modNm + 
               match hasPriorVers with
               | true -> " has PriorVersions = true; lastVersionNumber: " + lastVerNum.ToString()
               | _ -> " doesn't have PriorVersions"
    
        let oldM = DocVersionModule( OptModID("ver 2") , 2, false)
    
        type CustomVer =
            | DocVersionModule of DocVersionModule
            | CustomVer of DocVersionModule * newFld:string
    
        let oldM2 = CustomVer.DocVersionModule(oldM)
        let newM = CustomVer(oldM, "newFld")
    
        let li:list<_> = [oldM2; newM]
    
        List.map(fun (x) -> 
                    match x with
                    | DocVersionModule m -> printfn "found old mod:%A " m
                    | _ -> printfn "found new mod:%A " x
    
                ) li |> ignore
    
    > typeof.GetNestedTypes()
    |> Seq.iter (fun t -> 
        let p = t.GetProperties() 
        let s = 
            p
            |> Array.map (fun p -> sprintf "%s: %s" p.Name p.PropertyType.Name) 
            |> String.concat "; "
        printfn "Nested type %s: %i Properties %s" t.Name p.Length s
    )
    

    Also, from quotations.fs (f# repo)
    
        let getUnionCaseInfoField(unionCase:UnionCaseInfo, index) =
            let fields = unionCase.GetFields()
            if index < 0 || index >= fields.Length then invalidArg "index" (SR.GetString(SR.QinvalidCaseIndex))
            fields.[index]
      


    Unlicense or cc0-1.0(no attrib) f# projects


    Github srch query
    Chessie.ErrorHandling (Railway-oriented programming)
    FSharpx.Extras has Reader/Writer/Async, Regexp stuff & some other stuff, gd examples
    FSharp.Quotations.Evaluator.Tools (contains 7tpl & expression stuff)
    fsprojects/FSharp.Compiler.CodeDom (has a CodeDom Visitor and compiler for ides
    REF: This contains a file 'waitUntilExists' func: https://github.com/microsoft/fsharplu/blob/master/FSharpLu/File.fs (use w = new System.IO.FileSystemWatcher(parentDir, fileName, IncludeSubdirectories = false, EnableRaisingEvents = true))
    REF: Azure Db locally stored (using LiteDb) entirely in f#, with emulator



    fsharplu: MIT License (displ lic on substantial reuse)
    /// State machine-based asynchronous agents
    /// ... supports fork/join, continuations
    namespace Microsoft.FSharpLu.Actor.StateMachine
    // This module implements a lightweight Http server using HttpListener.
    /// The purpose of the server is to enable inter-process communication
    module Microsoft.FSharpLu.HttpCommunication


    Steve W.
    raganwald
    Sergey Tihon's Blog (Chk past posts)
    fpish.net
    sturmnet.org
    ikriv.com
    From Eirik Tsarpalis' blog (more remains to be chkd)
    Practical Generic programming in f#
    F# and purity (note the comments)
    Encoding Higher-Kinded Types in F# (workaround)
    Reconciling Stacktraces with Computation Expressions

    FSharpX library contribs->

    Brian McNamara (msft)'s Blog: Graphing a subReddit using F# & DGML
    Matt Thornton's Monad Series
    https://geekeh.com/
    https://thinkbeforecoding.com/
    https://www.wtfsharp.net/hosts/stachu
    https://devonburriss.me/tag/fsharp/

    SO threads on F# (some selected; + more remain to chk)

    Some reading & links from fpish

    F# web data feed
    Should I use monads to carry the "context" of my program?
    Apparently, I don't understand pattern matching
    How-to Use FParSec for parsing simple text
    Type classes in F#
    How to convert C# windows form application to F# codes.. T_T heeellpp
    Decorating ASTs with line numbers
    ASP.NET and F# - Creating MVC web applications in F#


    Forums
  • Reddit
  • dZone
  • HackerNews
  • Lobster forums: tagged by dotnet haskell ml ruby wasm windows
  • codeGuru
  • codeProject
  • Bytes
  • dreamInCode
  • Lambda the ultimate
  • Some reading links (Aug 7 2021; mostly from codeproject.com)


    https://www.codeproject.com/Articles/246323/A-Coder-Interview-With-Sacha-Barber
    https://www.codeproject.com/Articles/767639/Fsharp-Generics
    https://www.codeproject.com/Articles/769819/Fsharp-Reflection
    https://www.codeproject.com/Articles/775751/Fsharp-Interop

    https://www.codeproject.com/Tips/125781/Reading-Zip-files-in-F
    **https://www.codeproject.com/Reference/315638/List-of-freely-available-programming-books
    https://www.codeproject.com/Articles/680100/Overview-of-the-NET-Framework
    https://www.codeproject.com/Articles/235221/Monadic-Parsing-in-Fsharp
    https://www.codeproject.com/Articles/241577/Embedded-scripting-using-Fsharp
    https://www.codeproject.com/Articles/95656/Using-a-DataRader-like-a-List-in-F
    https://www.codeproject.com/Articles/30999/ScriptEngine-User-Defined-Calculations-in-C-VB-JSc
    https://www.codeproject.com/Tips/137779/Optimize-references-in-closures-in-F
    https://www.codeproject.com/Articles/5301612/Using-an-Fsharp-DSL-to-generate-Csharp-code
    https://www.codeproject.com/Articles/5165750/How-I-Got-Started-with-Bolero

    https://www.codeproject.com/Articles/277701/A-Coder-Interview-With-Dan-Mohl

    http://blogs.tedneward.com/patterns/closurebasedstate-fsharp/
    ** https://www.openfsharp.org/ -> spkrs often have github links

    https://github.com/fsharp/fslang-suggestions/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc

    https://medium.com/hackernoon/reflecting-on-f-in-2017-5ac67fb138ff ->
    * Suave and Giraffe emerged as two dominant libraries to use when writing web services on .NET Core, with Freya as a brilliant alternative that everyone should try out as well.
    * Fable rapidly evolved from an interesting project with potential into an impressive and fully-fledged alternative for JavaScript in the browser, allowing you to write Full-Stack F# applications.


    New('21 May04) F# reading from HN
    I just sat in a Mathematical Planning seminar with a guy from Quicken Loans who uses F# in production at work (Matthew Crews). He is also an author behind the Flips F# library.

    A quick list of F# libs for real world, everyday uses:
    * Pulumi / Farmer - code as infrastructure
    * FAKE - build tool
    * Fable - javascript transpiler
    * Feliz - react elements
    * FSharp.Data - parsing csvs, html pages
    http.fs : A simple, functional HTTP client library for F#

    Note:
    Poss. reason behind the @MBIs trying to force 'earlier version' adoption ->
    ,,,(if you're targetting) Mono assemblies ... do lag .NET CLR in functionality, so you'll probably need to use an F# version a few minor releases earlier than the official one.
    (So if they want to steal/use code elsewhere (bastas prefer macs) they'd have to... )

    what i wish i knew when learning fsharp

    https://ericsink.com/entries/fsharp_chasm.html

    https://github.com/Kavignon/fsharp-companies

    F# using companies: Jet did, but they're now dead...or do they still live on inside of the greater Walmart (Labs?) organization? Their F# projects under github.com/jet are still active

    Quant finance: G-Research

    Q: Can anyone recommend a a project or two that is small enough for a newcomer to wrap their minds around, that also exemplifies what makes a high quality F# codebase?
    2021
    2017
    2016
    * Compositional IT has a lot of good blog posts on how they use F# to solve real world problems.
    * Kit Eason's Stylish F# is a good book.
    HN F# threads (only read one)


    Notes from Podcasts

    Rachel Reese (Jet)

    • 300+ microsvcs in F#
    • TypeProv.s with CSV files
    • Heavy Xamarin.Forms usage

    Bob Martin (Uncle Bob)

    • TopDnDev 4 mocks (sketch out top 1st instd of botm)
    • Lazy Lists
    • Assignment (rewrite w/o using); use rec
    • cleanCode (closure site)
    • koans + katas exist forAll SICP stuff

    Phil Carter (MSFT F# hd)

    • as part of dotNet eventually expect F# to native
    • FSIs provide: TypeDefs + API + doc
    • The compiler can be customized for use

    From Chris Rathman's site
    Function Abstraction Symbol Bird Combinator
    labc.a(bc) B Bluebird S(KS)K
    labcd.a(bcd) B1 Blackbird BBB
    labcde.a(bcde) B2 Bunting B(BBB)B
    labcd.a(b(cd)) B3 Becard B(BB)B
    labc.acb C Cardinal S(BBS)(KK)
    labcd.ab(cd) D Dove BB
    labcde.abc(de) D1 Dickcissel B(BB)
    labcde.a(bc)(de) D2 Dovekies BB(BB)
    labcde.ab(cde) E Eagle B(BBB)
    labcdefg.a(bcd)(efg) Ê Bald Eagle B(BBB)(B(BBB))
    labc.cba F Finch ETTET
    labcd.ad(bc) G Goldfinch BBC
    labc.abcb H Hummingbird BW(BC)
    la.a I Identity Bird (aka Idiot) SKK
    labcd.ab(adc) J Jay B(BC)(W(BC(B(BBB))))
    lab.a K Kestrel (True) K
    lab.a(bb) L Lark CBM
    la.aa M Mockingbird SII
    lab.ab(ab) M2 Double Mockingbird BM
    lab.b(ab) O Owl SI
    labc.b(ac) Q Queer Bird CB
    labc.a(cb) Q1 Quixotic Bird BCB
    labc.b(ca) Q2 Quizzical Bird C(BCB)
    labc.c(ab) Q3 Quirky Bird BT
    labc.c(ba) Q4 Quacky Bird F*B
    labc.bca R Robin BBT
    labc.ac(bc) S Starling S
    lab.ba T Thrush CI
    lab.b(aab) U Turing LO
    labc.cab V Vireo (aka Pairing) BCT
    lab.abb W Warbler C(BMR)
    lab.baa W1 Converse Warbler CW
    la.a(la) Y Why Bird (aka Sage Bird) SLL
    lab.ab I* Identity Bird Once Removed S(SK)
    labc.abcc W* Warbler Once Removed BW
    labcd.abdc C* Cardinal Once Removed BC
    labcd.acdb R* Robin Once Removed C*C*
    labcd.adcb F* Finch Once Removed BC*R*
    labcd.acbd V* Vireo Once Removed C*F*
    labc.abc I** Identity Bird Twice Removed  
    labcd.abcdd W** Warbler Twice Removed B(BW)
    labcde.abced C** Cardinal Twice Removed BC*
    labcde.abdec R** Robin Twice Removed BR*
    labcde.abedc F** Finch Twice Removed BF*
    labcde.abecd V** Vireo Twice Removed BV*
    lab.b KI Kite (False) KI
    l W Omega MM
    lab.bb KM Konstant Mocker KM
    lab.aa C(KM) Crossed Konstant Mocker C(KM)
    l Q Theta YO



    A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.
    inv. (1920)...Schnfinkel's system was essentially equivalent to a combinatory logic based upon the combinators
    B -- | B combinator - bluebird - Haskell ('.').
    bluebird :: (b -> c) -> (a -> b) -> a -> c
    bluebird = (.)
    ,
    C -- | C combinator - cardinal - Haskell 'flip'.
    cardinal :: (a -> b -> c) -> b -> a -> c
    cardinal = flip
    , I,
    K
    -- | K combinator - kestrel - Haskell 'const'.
    -- Corresponds to the encoding of @true@ in the lambda calculus.
    kestrel :: a -> b -> a
    kestrel = const
    , and
    S -- | S combinator - starling.
    -- Haskell: Applicative\'s @(\<*\>)@ on functions.
    -- Substitution.
    starling :: (a -> b -> c) -> (a -> b) -> a -> c
    starling f g x = f x (g x)
    , . Schonfinkel was able to show that the system could be reduced to just K and S (i.e., SKI calculus) and outlined a proof that a version of this system had the same power as predicate logic.
    His paper also showed that functions of two or more arguments could be replaced by functions taking a single argument (i.e., Currying)

    Haskell Aviary
         (more compl.) Bird list

    raganwald ... more @ his backup repo; addresses Ruby/js but v. useable ...
    (raganwald) Given fn; {do! (side-effect) (fn) (side-effect) } A combinator that takes a function and imposes some side effects before and after the function
    e.g.,
    Free memory (C) after using it (B) whenever we have allocated it (A)
    or
    open files/sockets (A), reading/writing (B), then closing them (C)
    or
    accessing mutexen (A), working therein (B), and leaving (C)
    A composition of Kestrel and Thrush gets the job done:
    K(Txy) = Kyx = y
    K(Txyz) = Kyxz = yz
    K(K(Txyz)) = K(Kyxz) = Kyz = y

    (raganwald) Kestrels for DSL
    HardDrive.new.capacity(150).external.speed(7200)
    Instead of:
    hd = HardDrive.new
    hd.capacity = 150
    hd.external = true
    hd.speed = 7200 OR instead of
    def fizz(arr)
         arr.pop
         arr.map! { |n| n * 2 }
    end
    We can write:

    def fizz(arr)
         arr.tap(&:pop).map! { |n| n * 2 }
    end
    also, (@ lst in Ruby) K:Object#dont is the Ruby-semantic equivalent of commenting out a method call, only it can be
    inserted inside of an existing expression, eg.
    JoinBetweenTwoModels.dont.create!(...) do |new_join|

    (raganwald) Using a 3-param-C as a fn generator
    The Cardinal is written Cxyz = xzy. In Ruby:
        cardinal.call(proc_over_proc).call(a_value).call(a_proc)
         => proc_over_proc.call(a_proc).call(a_value)
    This implies that proc_over_proc is a function that takes a function as its argument and returns a function; i.e., you want a cardinal when you would like to modify what a function does.

    (raganwald) Using the Quirky
    -- | Q3 combinator - quirky bird.
    quirky :: (a -> b) -> a -> (b -> c) -> c
    quirky f x g = g (f x) Bird

    The quirky bird is written Q3xyz = z(xy). In Ruby:
        quirky.call(value_proc).call(a_value).call(a_proc)
         => a_proc.call(value_proc.call(a_value))
    Like the cardinal, the quirky bird reverses the order of application. But where the cardinal modifies the function that is applied to a value, the quirky bird modifies the value itself.
    ie, Q addOne 2 squareFirst = 5

    Cont Monad School of Haskell:The Mother of all Monads (Dan Piponi)'s exc. intro; refers to his post
    per riptutorial.com; async in F# is a Continuation Monad; A coroutine Monad.
    from brian McNamara(msft)'s blog (catamorphisms series):
    
    type ContinuationBuilder() =
        member this.Return(x) = (fun k -> k x) 
        member this.ReturnFrom(x) = x 
        member this.Bind(m,f) = (fun k -> m (fun a -> f a k))
        member this.Delay(f) = f()
    let K = new ContinuationBuilder()
    
    This def isn't congruent to Haskell's (since they use the predefined m)
    ...(I) wrote CallCC at the representation level; I think this is maybe also the "traditional" approach for such monads...
    (see discussion on fpish)
    Some other definitions:

    Monad Transformers etc.
    (OCaml) Monad Transformers Lib w/links to further reading etc. & [[lots of stuff here]]
    also see for tranformers:
    • http://lambda.jimpryor.net/topics/week9_monad_transformers/
    • https://gist.github.com/naoto-ogawa/97fe0e1236f31aac9bbfd4a6c73a91b7
    • http://patryshev.com/books/Transformers.pdf (Haskell)


    manual Transformers ->
    let hoist (a: option): Async> = async {return a}
    let lift (a: Async): Async> = a |> Async.map Some
    


    https://github.com/ocaml-batteries-team/batteries-included/
    here's the batInterface.ml def of Monad:
    module type Monad = sig
      type 'a m
      val bind : 'a m -> ('a -> 'b m) -> 'b m
      val return: 'a -> 'a m
    end
    

    Here's how oCaml defines State (reversed) ->
    (
    Chattered/ocaml-monad) ln # 473
    module State(T : sig type s end) =
    struct
      include Make(struct
                    type 'a m = T.s -> (T.s * 'a)
                    let return x s  = (s, x)
                    let bind xf f s =
                      let s',x = xf s in
                      f x s'
                  end)
      let read s    = (s,s)
      let write x s = (x,())
      let run x s   = x s
      let eval x s  = snd (x s)
      let modify f  = bind read (fun s -> write (f s))
    end
    
    Also chk Chattered applicative

    Monad threads, mostly from fpish: Monad for Composing UI Elements
    continuation monad and call/cc
    A Few Questions about F# Workflows one two three four five six seven eight nine ten

    Links to OCaml reading on Monads 'Can monads help me my refactor code for an enhanced data structure?
    An intermediate abstraction between applicatives and monads
    [ANN] Monads - the missing monad transformers library
    Error handling with `ocaml-github`

    Threading/ IO monad vs threads: the case of web-app servers
    'Interfacing mutable operations within a functional core - program design'

    Wikipedia on Generalizations of monads:
    Arrows use additional structure to bring plain functions and monads under a single interface
    Monad transformers act on distinct monads to combine them modularly Alternatives for modeling computations:
    Effect systems are a different way to describe side effects as types
    Uniqueness types are a third approach to handling side-effects in functional languages (mpt: no gd.)




    Quotations snippet

    from the F# Repo:
    This has a fn traversing/using MANY quotPatterns -> Quotations debug
    Here are all the patterns (Line#2251) quotations.fs

    The three main things you should know about the quotations API (from Traversing and transforming F# quotations: A guided tour)
    • Quotations.Expr and Quotations.Patterns are each others dual: they are used for constructing and deconstructing Expr types respectively;
    • Quotations.ExprShape contains the workhorse of any quotations-using implementation: a zipper-like pattern for traversing and transforming any quotation in a straightforward way
    • Splicing is used to effectively and readably construct parameterized expressions as an alternative to Expr.Whatever calls.

    
    // tryFindOne to get an Option<'t> 
    let john = people.tryFindOne q fun person , person.Name = "John" @> 
    // findOne to get a single existing document 
    let firstAlbum = albums.findOne <@ fun album -> album.Id = 1 @> 
    // findMany to get many documents of seq<'t> that match the query 
    let popularAlbums = albums.findMany <@ fun album -> album.IsPopular @> 
    // using "not" function let unverifiedEmails = accounts.findMany <@ fun ace -> not acc.EmailVerified @> 
    // with comparison operators 
    let albumsWithManySongs = albums.findMany q fun album -> album.SongCount > 50 
    // composite operators 
    let popularAndHaveManySongs = albums.findMany q fun album -> album.IsPopular && album.SongCount 50 
    // full search with a customized predicate 
    let releasedThisYear = albums.fullSearch <@ fun album -> album.DateReleased @> (fun dateReleased -> dateReleased.Year = DateTime.Now.Year) 
    

    Dec'21 Task: @Rsch ex quot work for feeding string to cmp/eval
    This suffices -> (uniLicense; based on the old PowerPack)
    https://fsprojects.github.io/FSharp.Quotations.Evaluator/tutorial.html
    On-the-fly code generation
    You can generate lambdas and compile them dynamically:
    
    	let tupler = 
    	    let v = Var("x",typeof)
    	    let v = Expr.Lambda(v, Expr.NewTuple [Expr.Var v; Expr.Var v]) // codegen (fun x -> (x,x))
    	    v.CompileUntyped() :?> (int -> (int * int))
    
    	tupler 78  // (78, 78)
    


    I can't talk about Clojure since I have't used it, but I know a bit about DSLs in F#. F# provides two main language oriented programming features (which is what Don Syme likes to call them): code quotations and computation expressions.
    Code quotations are closer to what you would get with macros in a language like Lisp. They allow you to generate expressions programmatically which you can then execute. By using the ReflectedDefinition attribute on F# expressions you get access to their ASTs. See msdn for more details.
    Wrapping visitors with active patterns in F#

    (this is one of the guys bhd FSharpx)
    (using Visitors + a dsl-like (from scratch) evaluator for simple logicOps cn be extended...) See also Juliet Rosenthal's SO post mentioned.





    Point-free programming style in F#

    Tom P's ans to an SO qn inv lazy seq / point-free

    SO: Advantages and disadvantages of "point free" style (1st resp v gd., f# eg below)

    Brian Berns on point-free style

    let safeSqrt = Option.filter ((<=) 0.0) >> Option.map sqrt

    Eric T.'s Programming in the Point-Free Style

    let f = Option.map sqrt << Option.filter ((<=) 0.)

    ...Eventually you end up in point-free world, where foo|>bar|>baz and so on.


    .net5 PBE api
    CodeProj: emulating PBE under .net
    .net/Java interop AES w IV
    crypto in C & Java
    InterOp encr in Java/dotNet
    Translate PBE from Java to C
    A collection of common (interesting) cryptographic mistakes and learning resources.
    Representing SHA-256 Hashes As Avatars
    related: generate unique images from any text (above art also refers to github/goog using this methd)



    F# Compiler service examples
    (has both FSharpSyntaxTokenKind.Function & FSharpSyntaxTokenKind.Val)
    Tokenizing / Lexing src. code
    https://fsharp.github.io/FSharp.Compiler.Service/index.html
    Using Roslyn to parse the AST.
    fcs samples Tokenization example (uses & requires FSharp.Compiler.SourceCodeServices)
    fsprojects snippet which uses Fsharp.Formatting.CodeFormat.dll to tokenize F# source.
    Understand the .NET Compiler Platform SDK model

    MSFT Cosmo
    Froto (protoBuffs)
    Db app (Suave + Mongo)
    Falanx by jet.com (now wm)
    Code generation from Protobuf v3 schema (rather than types being injected as a type provider.)
    Mondocks: An alternative way to interact with MongoDB databases from F# that allows you to use mongo-idiomatic constructs

    oPlus Colors Lunapic (free online imgEditor w/effects etc.)
    HexColorTool

    Cobalt Blue is: hex -> #0047AB; decimal RGB -> rgb(0,71,171)
    Royal Blue is: hex -> #00275E (see: http://www.99colors.net/hex/00275E)
    rgba(0, 39, 94, 1); hsla(215, 100%, 18%, 1)

    Same color in lighter hues: #3365AA, #5E8ED1

    Related blues (lightest is #3):
    1. Air Force blue (Hex code #5E8ED1)
    2. Lime (Hex code #BFDAFF)
    3. Platinum (Hex code #E5F0FF)

    (Ancient) Forms example with somewhat unusual UI idioms (for us) Handler->
    
       Line# 320: let rec ComboSelectHandler (sender:obj) (e:EventArgs) =
       ... in
       let	_ = combo.SelectionChangeCommitted.AddHandler( new EventHandler(ComboSelectHandler) )  in
    		folderPanel.Controls.Add(combo)
    
    Props ->
    
        let labelStart = new Label()
        do labelStart.Anchor <- AnchorStyles.Bottom ||| AnchorStyles.Right
        do labelStart.Text <- "Start"
    
        do rangeTable.Controls.Add(labelStart)
    
    Menu->
    
        let memuMain = mainForm.Menu <- new MainMenu()
        let menuFile= mainForm.Menu.MenuItems.Add("&File")
        let miFileOpen = new MenuItem("&Open")
        let miFileExit = new MenuItem("&Exit")
        do menuFile.MenuItems.Add(miFileOpen) |> ignore
        do menuFile.MenuItems.Add(miFileExit) |> ignore
        do miFileOpen.Click.Add( fun _ -> ...
    

    WinForms snippet->
    
        open System
        open System.Windows.Forms
    
        [<EntryPoint>]
        [<STAThread>]
        let main argv =
            Application.EnableVisualStyles()
    //      Application.SetCompatibleTextRenderingDefault(false)
            let form = new Form(Width= 400, Height = 300, Visible = true, Text = "Hello World from F#!")
            form.TopMost <- true
            form.Click.Add (fun args-> printfn "the form was clicked")
            Application.Run(form)
            0
    


    WinForms Animation
    SO: How can I add moving effects to my controls in C#? ...I have a Panel In my C# form and I have a button. When I click on the Button the invisible Panel Shows. Instead of that I want the Panel to move in or slide in.
    Approach #1 A>>Window animation is a built-in feature for Windows. Here's a class that uses it:
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    public static class Util {
        public enum Effect { Roll, Slide, Center, Blend }
    
        public static void Animate(Control ctl, Effect effect, int msec, int angle) {
            int flags = effmap[(int)effect];
            if (ctl.Visible) { flags |= 0x10000; angle += 180; }
            else {
                if (ctl.TopLevelControl == ctl) flags |= 0x20000; 
                else if (effect == Effect.Blend) throw new ArgumentException();
            }
            flags |= dirmap[(angle % 360) / 45];
            bool ok = AnimateWindow(ctl.Handle, msec, flags);
            if (!ok) throw new Exception("Animation failed");
            ctl.Visible = !ctl.Visible;
        }
    
        private static int[] dirmap = { 1, 5, 4, 6, 2, 10, 8, 9 };
        private static int[] effmap = { 0, 0x40000, 0x10, 0x80000 };
    
        [DllImport("user32.dll")]
        private static extern bool AnimateWindow(IntPtr handle, int msec, int flags);
    }
    Sample usage:
    
        private void button2_Click(object sender, EventArgs e) {
            Util.Animate(button1, Util.Effect.Slide, 150, 180);
        }
    
    Hans Passant

    Q:Does this only work on contained controls, Hans?
    A:I tested it on contained controls. It should work on toplevel forms as well, however it is going hide the form on the first call since you'd have called Show() to display it. Replacing Show() so it animates the opening of the form is tricky, ask a question about it separately.
    Q:this works for sliding out a panel but how to slide in a panel.
    A:You can do it by changing fourth parameter in calling Util.Animate method which is movement angle, such as: Util.Animate(button1, Util.Effect.Slide, 150, 360);
    Approach #2 If you are using .NET 4 (if not replace Task with Thread), a function similar to this could be a start:
    
        private void slideToDestination(Control destination, Control control, int delay, Action onFinish){
            new Task(() =>{
                int directionX = destination.Left > control.Left ? 1 : -1;
                int directionY = destination.Bottom > control.Top ? 1 : -1;
    
                while (control.Left != destination.Left || control.Top != destination.Bottom){
                    try{
                        if (control.Left != destination.Left){
                            this.Invoke((Action)delegate(){
                                control.Left += directionX;
                            });
                        }
                        if (control.Top != destination.Bottom){
                            this.Invoke((Action)delegate(){
                                control.Top += directionY;
                            });
                        }
                        Thread.Sleep(delay);
                    }catch{
                        // form could be disposed
                        break;
                    }
                }
                if (onFinish != null) onFinish();
            }).Start();
        }
    Usage:
    slideToDestination(sender as Control, panel1, 10, () => MessageBox.Show("Done!"));
    slideToDestination(sender as Control, panel1, 0, null);
    
    As action you would send some boolean variable to set to true so that you know that the animation has finished or some code to run after it. Beware of deadlocks when calling with a null action. You could run two animations on the same control in two different directions with the same speed, and it will stay where it was forever and of course two animations simultaneusly can make the control go infinitely in some direction because the while will never finish :)
    Marino imi
    Approach #3
    SO: Sliding in Winforms form
    ...I'm making a form at the bottom of the screen and I want it to slide upwards...
    but the code just runs through and shows the end position without showing the form sliding in which is what I want. I've tried Refresh, DoEvents
    A>>Run the code in a background thread. Example:
    
            int destinationX = (Screen.PrimaryScreen.WorkingArea.Width / 2) - (this.Width / 2);
            int destinationY = Screen.PrimaryScreen.WorkingArea.Height - this.Height;
    
            Point newLocation = new Point(destinationX, destinationY + this.Height);
    
            new Thread(new ThreadStart(() =>{
                do{
                     // this line needs to be executed in the UI thread, hence we use Invoke
                    this.Invoke(new Action(() => { this.Location = newLocation; }));
    
                    newLocation = new Point(destinationX, newLocation.Y - 1);
                    Thread.Sleep(100);
                }
                while (newLocation != new Point(destinationX, destinationY));
            })).Start();
    

    WinForms & DataGridView stuff


    Main WinForms src
    dotNet WinForms.Design<.a> (the Drawing dir has BitmapEditor/ColorEditor/FontEditor etc.)

    Hierarchical GridView: original src (markrideout) and some related discussions/Q&A here and here

    Windows Forms Data Controls and Databinding FAQ (has 30+ Qns incl master-details)
    WinForms Property Browser


    Hierarchical/Tree DataGridViews codeProject: https://www.codeproject.com/Articles/28276/DataGridView-with-hierarchical-data-binding
    https://social.msdn.microsoft.com/Forums/windows/en-US/2a6d60d8-4ac8-4bc0-8627-bae6d8b782b0/vb-datagridview-grouping-expand-and-collapse-rows-help-needed
    https://social.msdn.microsoft.com/Forums/en-US/7905b1a3-dce9-4128-a7fb-9cb1facf8b44/collapsible-datagridview
    https://10tec.com/articles/treegridview-c-sharp-vb-net.aspx
    https://www.dotnetspider.com/forum/236162-Treeview-datagridview-Hierarchical-datagridview
    https://stackoverflow.com/questions/5378854/net-winforms-datagridview-any-way-to-nest
    http://www.windows-tech.info/3/c443f28d9afc6587.php
    https://social.msdn.microsoft.com/Forums/vstudio/en-US/da1b7fed-3577-4db9-a95d-b5993c4d18d5/how-to-make-colspan-in-datagridview-#:~:text=Be%20aware%20a%20datagridview%20is%20not%20a%20spreadsheet.,you%20can%20concatenate%20the%20data%20in%20an%20item%29

    colSpan for DataGridViews
    https://www.codeproject.com/articles/34037/datagridvewtextboxcell-with-span-behaviour
    https://stackoverflow.com/questions/17524739/c-sharp-datagridview-colspan
    https://stackoverflow.com/questions/6936417/colspan-gridview-rows
    https://social.msdn.microsoft.com/Forums/vstudio/en-US/da1b7fed-3577-4db9-a95d-b5993c4d18d5/how-to-make-colspan-in-datagridview-
    https://www.aspsnippets.com/Articles/Add-Colspan-ColumnSpan-to-GridView-in-ASPNet.aspx
    https://www.c-sharpcorner.com/forums/colspan-and-row-span-on-datagridview
    http://www.windows-tech.info/3/89ca73fd05c73500.php

    C# code snippets for DataGridView control ->

    Example setting various DataGridView col properties incl tooltips
    using System.Windows.Forms;
    using System;
    using System.Drawing;
     
    public class DataGridViewColumnDemo : Form{
        #region "set up form"
        public DataGridViewColumnDemo()    {
            InitializeComponent();
     
            AddButton(Button1, "Reset",
                new EventHandler(ResetToDisorder));
            AddButton(Button2, "Change Column 3 Header",
                new EventHandler(ChangeColumn3Header));
            AddButton(Button3, "Change Meatloaf Recipe",
                new EventHandler(ChangeMeatloafRecipe));
            AddAdditionalButtons();
     
            InitializeDataGridView();
        }
     
        DataGridView dataGridView;
        Button Button1 = new Button();
        Button Button2 = new Button();
        Button Button3 = new Button();
        Button Button4 = new Button();
        Button Button5 = new Button();
        Button Button6 = new Button();
        Button Button7 = new Button();
        Button Button8 = new Button();
        Button Button9 = new Button();
        Button Button10 = new Button();
        FlowLayoutPanel FlowLayoutPanel1 = new FlowLayoutPanel();
     
        private void InitializeComponent()    {
            FlowLayoutPanel1.Location = new Point(454, 0);
            FlowLayoutPanel1.AutoSize = true;
            FlowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
            FlowLayoutPanel1.Name = "flowlayoutpanel";
            ClientSize = new System.Drawing.Size(614, 360);
            Controls.Add(this.FlowLayoutPanel1);
            Text = this.GetType().Name;
            AutoSize = true;
        }
        #endregion
     
        #region "set up DataGridView"
     
        private string thirdColumnHeader = "Main Ingredients";
        private string boringMeatloaf = "ground beef";
        private string boringMeatloafRanking = "*";
        private bool boringRecipe;
        private bool shortMode;
     
        private void InitializeDataGridView()    {
            dataGridView = new System.Windows.Forms.DataGridView();
            Controls.Add(dataGridView);
            dataGridView.Size = new Size(300, 200);
     
            // Create an unbound DataGridView by declaring a
            // column count.
            dataGridView.ColumnCount = 4;
            AdjustDataGridViewSizing();
     
            // Set the column header style.
            DataGridViewCellStyle columnHeaderStyle =
                new DataGridViewCellStyle();
            columnHeaderStyle.BackColor = Color.Aqua;
            columnHeaderStyle.Font =
                new Font("Verdana", 10, FontStyle.Bold);
            dataGridView.ColumnHeadersDefaultCellStyle =
                columnHeaderStyle;
     
            // Set the column header names.
            dataGridView.Columns[0].Name = "Recipe";
            dataGridView.Columns[1].Name = "Category";
            dataGridView.Columns[2].Name = thirdColumnHeader;
            dataGridView.Columns[3].Name = "Rating";
     
            PostColumnCreation();
     
            // Populate the rows.
            string[] row1 = new string[]{"Meatloaf", 
                                            "Main Dish", boringMeatloaf, boringMeatloafRanking};
            string[] row2 = new string[]{"Key Lime Pie", 
                                            "Dessert", "lime juice, evaporated milk", "****"};
            string[] row3 = new string[]{"Orange-Salsa Pork Chops", 
                                            "Main Dish", "pork chops, salsa, orange juice", "****"};
            string[] row4 = new string[]{"Black Bean and Rice Salad", 
                                            "Salad", "black beans, brown rice", "****"};
            string[] row5 = new string[]{"Chocolate Cheesecake", 
                                            "Dessert", "cream cheese", "***"};
            string[] row6 = new string[]{"Black Bean Dip", "Appetizer",
                                            "black beans, sour cream", "***"};
            object[] rows = new object[] { row1, row2, row3, row4, row5, row6 };
     
            foreach (string[] rowArray in rows)        {
                dataGridView.Rows.Add(rowArray);
            }
     
            shortMode = false;
            boringRecipe = true;
        }
     
        private void AddButton(Button button, string buttonLabel, EventHandler handler)    {
            FlowLayoutPanel1.Controls.Add(button);
            button.TabIndex = FlowLayoutPanel1.Controls.Count;
            button.Text = buttonLabel;
            button.AutoSize = true;
            button.Click += handler;
        }
     
        private void ResetToDisorder(object sender, System.EventArgs e)    {
            Controls.Remove(dataGridView);
            dataGridView.Dispose();
            InitializeDataGridView();
        }
     
        private void ChangeColumn3Header(object sender,
            System.EventArgs e)    {
            Toggle(ref shortMode);
            if (shortMode)
            { dataGridView.Columns[2].HeaderText = "S"; }
            else
            { dataGridView.Columns[2].HeaderText = thirdColumnHeader; }
        }
     
        private static void Toggle(ref bool toggleThis)    {
            toggleThis = !toggleThis;
        }
     
        private void ChangeMeatloafRecipe(object sender,        System.EventArgs e)
        {
            Toggle(ref boringRecipe);
            if (boringRecipe)        {
                SetMeatloaf(boringMeatloaf, boringMeatloafRanking);
            }        else        {
                string greatMeatloafRecipe =
                    "1 lb. lean ground beef, " +
                    "1/2 cup bread crumbs, 1/4 cup ketchup," +
                    "1/3 tsp onion powder, " +
                    "1 clove of garlic, 1/2 pack onion soup mix " +
                    " dash of your favorite BBQ Sauce";
                SetMeatloaf(greatMeatloafRecipe, "***");
            }
        }
     
        private void SetMeatloaf(string recipe, string rating)    {
            dataGridView.Rows[0].Cells[2].Value = recipe;
            dataGridView.Rows[0].Cells[3].Value = rating;
        }
        #endregion
     
        #region "demonstration code"
        private void PostColumnCreation()    {
            AddContextLabel();
            AddCriteriaLabel();
            CustomizeCellsInThirdColumn();
            AddContextMenu();
            SetDefaultCellInFirstColumn();
            ToolTips();
     
            dataGridView.CellMouseEnter +=
                dataGridView_CellMouseEnter;
            dataGridView.AutoSizeColumnModeChanged +=
                dataGridView_AutoSizeColumnModeChanged;
        }
     
        private string criteriaLabel = "Column 3 sizing criteria: ";
        private void AddCriteriaLabel()    {
            AddLabelToPanelIfNotAlreadyThere(criteriaLabel,
                criteriaLabel +
                dataGridView.Columns[2].AutoSizeMode.ToString() +
                ".");
        }
     
        private void AddContextLabel()    {
            string labelName = "label";
            AddLabelToPanelIfNotAlreadyThere(labelName,
                "Use shortcut menu to change cell color.");
        }
     
        private void AddLabelToPanelIfNotAlreadyThere(
            string labelName, string labelText)    {
            Label label;
            if (FlowLayoutPanel1.Controls[labelName] == null)        {
                label = new Label();
                label.AutoSize = true;
                label.Name = labelName;
                label.BackColor = Color.Bisque;
                FlowLayoutPanel1.Controls.Add(label);
            }        else        {
                label = (Label)FlowLayoutPanel1.Controls[labelName];
            }
            label.Text = labelText;
        }
     
        private void CustomizeCellsInThirdColumn()    {
            int thirdColumn = 2;
            DataGridViewColumn column =
                dataGridView.Columns[thirdColumn];
            DataGridViewCell cell = new DataGridViewTextBoxCell();
     
            cell.Style.BackColor = Color.Wheat;
            column.CellTemplate = cell;
        }
     
        ToolStripMenuItem toolStripItem1 = new ToolStripMenuItem();
     
        private void AddContextMenu()    {
            toolStripItem1.Text = "Redden";
            toolStripItem1.Click += new EventHandler(toolStripItem1_Click);
            ContextMenuStrip strip = new ContextMenuStrip();
            foreach (DataGridViewColumn column in dataGridView.Columns)        {
                column.ContextMenuStrip = strip;
                column.ContextMenuStrip.Items.Add(toolStripItem1);
            }
        }
     
        private DataGridViewCellEventArgs mouseLocation;
     
        // Change the cell's color.
        private void toolStripItem1_Click(object sender, EventArgs args)    {
            dataGridView.Rows[mouseLocation.RowIndex]
                .Cells[mouseLocation.ColumnIndex].Style.BackColor
                = Color.Red;
        }
     
        // Deal with hovering over a cell.
        private void dataGridView_CellMouseEnter(object sender,
            DataGridViewCellEventArgs location)    {
            mouseLocation = location;
        }
     
        private void SetDefaultCellInFirstColumn()    {
            DataGridViewColumn firstColumn = dataGridView.Columns[0];
            DataGridViewCellStyle cellStyle =
                new DataGridViewCellStyle();
            cellStyle.BackColor = Color.Thistle;
            firstColumn.DefaultCellStyle = cellStyle;
        }
     
        private void ToolTips()    {
            DataGridViewColumn firstColumn = dataGridView.Columns[0];
            DataGridViewColumn thirdColumn = dataGridView.Columns[2];
            firstColumn.ToolTipText =
                "This column uses a default cell.";
            thirdColumn.ToolTipText =
                "This column uses a template cell." +
                " Style changes to one cell apply to all cells.";
        }
     
        private void AddAdditionalButtons()    {
            AddButton(Button4, "Set Minimum Width of Column Two",
                new EventHandler(Button4_Click));
            AddButton(Button5, "Set Width of Column One",
                new EventHandler(Button5_Click));
            AddButton(Button6, "Autosize Third Column",
                new EventHandler(Button6_Click));
            AddButton(Button7, "Add Thick Vertical Edge",
                new EventHandler(Button7_Click));
            AddButton(Button8, "Style and Number Columns",
                new EventHandler(Button8_Click));
            AddButton(Button9, "Change Column Header Text",
                new EventHandler(Button9_Click));
            AddButton(Button10, "Swap First and Last Columns",
                new EventHandler(Button10_Click));
        }
     
        private void AdjustDataGridViewSizing()    {
            dataGridView.ColumnHeadersHeightSizeMode = 
                DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        }
     
        //Set the minimum width.
        private void Button4_Click(object sender, System.EventArgs e)    {
            DataGridViewColumn column = dataGridView.Columns[1];
            column.MinimumWidth = 40;
        }
     
        // Set the width.
        private void Button5_Click(object sender, System.EventArgs e)    {
            DataGridViewColumn column = dataGridView.Columns[0];
            column.Width = 60;
        }
     
        // AutoSize the third column.
        private void Button6_Click(object sender, System.EventArgs e)    {
            DataGridViewColumn column = dataGridView.Columns[2];
            column.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
        }
     
        // Set the vertical edge.
        private void Button7_Click(object sender, System.EventArgs e)    {
            int thirdColumn = 2;
            DataGridViewColumn column =
                dataGridView.Columns[thirdColumn];
            column.DividerWidth = 10;
        }
     
        // Style and number columns.
        private void Button8_Click(object sender, EventArgs args)    {
            DataGridViewCellStyle style = new DataGridViewCellStyle();
            style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            style.ForeColor = Color.IndianRed;
            style.BackColor = Color.Ivory;
     
            foreach (DataGridViewColumn column in dataGridView.Columns)        {
                column.HeaderCell.Value = column.Index.ToString();
                column.HeaderCell.Style = style;
            }
        }
     
        // Change the text in the column header.
        private void Button9_Click(object sender, EventArgs args)    {
            foreach (DataGridViewColumn column in dataGridView.Columns)        {
                column.HeaderText = String.Concat("Column ",
                    column.Index.ToString());
            }
        }
     
        // Swap the last column with the first.
        private void Button10_Click(object sender, EventArgs args)    {
            DataGridViewColumnCollection columnCollection = dataGridView.Columns;
            DataGridViewColumn firstVisibleColumn =
                columnCollection.GetFirstColumn(DataGridViewElementStates.Visible);
            DataGridViewColumn lastVisibleColumn =
                columnCollection.GetLastColumn(
                    DataGridViewElementStates.Visible, DataGridViewElementStates.None);
            int firstColumn_sIndex = firstVisibleColumn.DisplayIndex;
            firstVisibleColumn.DisplayIndex = lastVisibleColumn.DisplayIndex;
            lastVisibleColumn.DisplayIndex = firstColumn_sIndex;
        }
     
        // Updated the criteria label.
        private void dataGridView_AutoSizeColumnModeChanged(object sender, DataGridViewAutoSizeColumnModeEventArgs args)    {
            args.Column.DataGridView.Parent.
                Controls["flowlayoutpanel"].Controls[criteriaLabel].
                Text = criteriaLabel
                + args.Column.AutoSizeMode.ToString();
        }
        #endregion
     
        [STAThreadAttribute()]
        public static void Main()    {
            Application.Run(new DataGridViewColumnDemo());
        }
    }
    

    Example for CellPainting
    In the following code example, you will paint all the cells in a ContactName column using the DataGridView control's color scheme. Each cell's text content is painted in Crimson, and an inset rectangle is drawn in the same color as the DataGridView control's GridColor property.
    private void dataGridView1_CellPainting(object sender,
    System.Windows.Forms.DataGridViewCellPaintingEventArgs e){
        if (this.dataGridView1.Columns["ContactName"].Index ==
            e.ColumnIndex && e.RowIndex >= 0)    {
            Rectangle newRect = new Rectangle(e.CellBounds.X + 1,
                e.CellBounds.Y + 1, e.CellBounds.Width - 4,
                e.CellBounds.Height - 4);
            using (
                Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
                backColorBrush = new SolidBrush(e.CellStyle.BackColor))        {
                using (Pen gridLinePen = new Pen(gridBrush))            {
                    // Erase the cell.
                    e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
     
                    // Draw the grid lines (only the right and bottom lines;
                    // DataGridView takes care of the others).
                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left,
                        e.CellBounds.Bottom - 1, e.CellBounds.Right - 1,
                        e.CellBounds.Bottom - 1);
                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
                        e.CellBounds.Top, e.CellBounds.Right - 1,
                        e.CellBounds.Bottom);
     
                    // Draw the inset highlight box.
                    e.Graphics.DrawRectangle(Pens.Blue, newRect);
     
                    // Draw the text content of the cell, ignoring alignment.
                    if (e.Value != null)                {
                        e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
                            Brushes.Crimson, e.CellBounds.X + 2,
                            e.CellBounds.Y + 2, StringFormat.GenericDefault);
                    }
                    e.Handled = true;
                }
            }
        }
    }
     
    

    MSFT Docs for Customizing the WinForms DataGridView
    • How to: Customize the Appearance of Cells in the Windows Forms DataGridView Control
    • How to: Customize the Appearance of Rows in the Windows Forms DataGridView Control
    • How to: Customize Cells and Columns in the Windows Forms DataGridView Control by Extending Their Behavior and Appearance
    • How to: Host Controls in Windows Forms DataGridView Cells


    winForms reading/links
    Winforms Desktop docs

    (many snippets incl: TableLayout, Drawing, GridStrip...
    The GridStrip control is a custom ToolStrip that arranges
    its ToolStripButton controls in a grid layout.)
    The repo also has wpf docs
    Enhancing Windows Forms Applications
    Overriding MenuStrip class's renderer to use custom colors (shd work for all ctrls)
    Custom Ttip to display img on hover
    Using 'flat style' -> ...It's enough to set FlatStyle = System.Windows.Forms.FlatStyle.Flat; then FlatAppearance.BorderSize = 0; no nd to override paint...
    ..."Flat" controls are long-deprecated. They have been drawn the same as 3D controls ever since the introduction of Visual Styles (Windows XP). The WinForms framework has to simulate it by owner-drawing. The result is ugly, and inconsistent with the standard platform UI. The best solution is to set all controls' FlatStyle property to System....
    ...removing hover backgrnd ->
    
        this.btnClose.FlatAppearance.BorderSize = 0;
        this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
    

    >>this.btnClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent;
    Using the Anchor & Dock Properties
    TableLayoutPanel with all childPanels' DockStyle=Fill (scroll dn to see img)
    Adding label to Panel w/o dockStyleFill automatically puts it topLeft.
    How to center a ctrl w/in a container?
    use TableLayoutPanel w/1row&1col; lbl w/Anchor=None will alw center it vert/horiz.
    Q:FlowLayoutPanel subPanels wont fill when resizing form, when the flowlayoutpanel gets bigger
    A:The FlowLayoutPanel implies a Column (determined by the widest object) and a Row (determined by the tallest object) when child controls are added. This model defines the flow behavior. When you anchor or dock a child Control, this Cell (Column, Row) is the virtual container where the anchors are applied to. You may want to use a standard Panel container or TableLayoutPanel.
    TableLayoutPanel auto-size behav:
    >>If you set AutoSize=true & controls w/SizeType=Percent; no row/col will be clipped
    TableLayoutPanel best practices
    >>'avoid nesting'
    Q:How to design a fluid layout? >>use one panel which docks to the left and another one which docks as "Full". This has the effect that the left part won't get wider but the right one does. This is a nifty solution for a complicated form with many controls in a fixed layout to the left and several growable grids or preview panes to the right.
    >>You could put Your controls into tableLayout, and set the Dock property to fill.
    ContainerControl.PerformAutoScale Method (System.Windows.Forms) Performs scaling of the container control ****and its children****.




    SAFE stack
    http://fsprojects.github.io/FSharp.Desktop.UI/
    https://github.com/microsoft/fsharplu
    https://github.com/Acadian-Ambulance/vinyl-ui
    https://github.com/AvaloniaCommunity/Avalonia.FuncUI

    Java PBE Crypto Spec

    The following table lists cipher algorithms available in the SunJCE provider.
    
    Algorithm Name				MODES		Paddings
    
    PBEWithMD5AndDES,			CBC		PKCS5Padding
    PBEWithMD5AndTripleDES Footnote 1,
    PBEWithSHA1AndDESede,
    PBEWithSHA1AndRC2_40,
    PBEWithSHA1AndRC2_128,
    PBEWithSHA1AndRC4_40,
    PBEWithSHA1AndRC4_128,
    PBEWithHmacSHA1AndAES_128,
    PBEWithHmacSHA224AndAES_128,
    PBEWithHmacSHA256AndAES_128,
    PBEWithHmacSHA384AndAES_128,
    PBEWithHmacSHA512AndAES_128,
    PBEWithHmacSHA1AndAES_256,
    PBEWithHmacSHA224AndAES_256,
    PBEWithHmacSHA256AndAES_256,
    PBEWithHmacSHA384AndAES_256,
    PBEWithHmacSHA512AndAES_256
    
    Footnote 1: PBEWithMD5AndTripleDES is a proprietary algorithm that has not been standardized.
    


    jdk8 pbe s2 test illustrating a proprietory cypher build: (PBEWithMD5AndTripleDESCipher ) http://hg.openjdk.java.net/jdk8/jdk8/jdk/raw-file/519f4c9ebf8d/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndTripleDESCipher.java

    frm 'Hacking Multifactor Authentication', Roger Grimes/Wiley (2019) MFA vendors: xl sheet: wiley.com/go/hackingmultifactor
    Open Source Intell: github.com/jivoi/awesome-osint
    Pwd Recovery Qns
    in 2008, Palin's YHOO act hacked in 45 min
    washingtontimes.com/news/2008/sep/19/hacker_wanted_to_derail_palin


    GOOG paper www.a51.nl/sites/default/files/pdf/43783.pdf
    - Some recov Qns can be guessed 1st try 20% of the time
    - 40% of users unable to recall their own answers
    - 16% answers found in soc media profiles
    Some (dated) refs from the paper above -> (need to chk)

    Secrets, Lies, and Account Recovery: Lessons from the Use of Personal Knowledge Questions at Google

    Mike Just. Designing and Evaluating Challenge-Question Systems. IEEE Security & Privacy Magazine, 2(5), 2004.

    [21] Mike Just and David Aspinall. Personal Choice and Challenge Questions: A Security and Usability Assessment. SOUPS 09: The 5th Symposium on Usable Privacy and Security, 2009.

    Rachael Pond, John Podd, Julie Bunnell, and Ron Henderson. Word Association Computer Passwords: The Effect of Formulation Techniques on Recall and Guessing Rates. Computers & Security, 2000.

    Ariel Rabkin. Personal knowledge questions for fallback authentication: Security questions in the era of Facebook. SOUPS 08: The 4th Symposium on Usable Privacy and Security, 2008

    Stuart Schechter, A. J. Bernheim Brush, and Serge Egelman. Its No Secret: Measuring the security and reliability of authentication via secret questions. 2009 IEEE Symposium on Security and Privacy, 2009.

    Moshe Zviran and William J. Haga. A Comparison of Password Techniques for Multilevel Authentication Mechanisms. Computer Journal, 36(3):227237, 1993.



    Hacked chk -> haveibeenpwned.com & sec.hpi.de/ilc/?
    ?? auth's employer ?? knowbe4.com/breached_password_test

    Biometrics
    Palm Vein Scan / Windows Hello
    newatlas/windows-10-palm-vein-scan/53344

    2014-15 China stole 5-6M fingerprints/sec clearance
    wikipedia.org/Office_of_Personnel_Management_data_breach (OPM)

    security.googleblog.com/2019/05/bew_research_how_effective_is_basic.html
    techcommunity.microsoft.com/t5/Azure-Active-Directory-Identity/Your-Pa-work-doesn-t-matter/ba-p/731984
    OpenPuff

    Demo: jsonp Dojo pull requests


    This page has been updated with a live JSONP pull list
    saucelab Emulator (mm) to test stuff on different browsers.
    TypeScript

    Notes on TypeScript to JS:


    I have an app whose code is written in TypeScript and that uses jQuery to attach functions to page events and it works pretty well; although, like you, I found it to obe a struggle to identify the magic formula to make it all work.
    My TS file starts with a reference to the jQuery type file:
    /// [reference path="../typings/globals/jQuery/index" /]
    then there's all of my app-specific code that I will omit here. Finally at the end, I have my jQuery code to hook everything up:>
    $(document).ready(function () { $("#answerRequest").click(function (e) { e.preventDefault(); let answer = chatty.ask($("#question").val()); $("#answer").val(answer); }); });
    That should all be pretty familiar. The chatty object is instantiated elsewhere.
    Now that I have my .ts file, I compile it with tsc, then I use browserify to turn the .js from the tsc output into JS that will run happily in the browser.
    In the HTML, I include a script tag that points to the output of the browserify step, and it works just as if I had written the whole thing in JS to begin with.

    Console output...


    NYC: The place that put US cheeses on the map
    "one of Manhattans premier cheese shops" in Chelsea Market
    Herbal Fruit Jams http://salliesgreatest.com
    Fairy Tale Brownies (brownies.com) [[Has a good-looking coll of blondies too.]]
    Blue Martini Companies -> Taubman Centers, Michigan CEO Mark Vasu (another link to someone Mitsu calls "Stinker Pinker")

    Online Pie Order Sources


    food
    Featured on Good Morning America and a National Pie Championship winner, the Michigan 4-Berry Pie is Achatz's signature dessert!
    food
    Chocolate Pecan. VOTED DC'S BEST PIE SEVEN YEARS RUNNING!
    food
    Sweet-n-salty Must check other choices; also has a "pie club" 6 month plan (cld be same as above site?)
    food
    MISSISSIPPI MUD PIE imported Belgian chocolate, brownie streusel and a chocolate glaze in a chocolate cookie crust. (Also has key lime etc.)
    food
    They have a HUGE selection
    food
    This is our famous pecan pie, but in a fudgy deep dish form. It's packed full of delicious, Southern pecan halves-a full 2 pounds of nuts.
    food
    Not overly sweet, this pie is a Two Fat Cats favorite. 7?/9? available

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.


    https://en.wikipedia.org/wiki/Le_Monde%27s_100_Books_of_the_Century

    https://gutenberg.org/ebooks/1056 (Martin Eden, Jack London)
    https://en.wikipedia.org/wiki/The_Strange_Case_of_Peter_the_Lett (Simenon's 1st Maigret)
    https://en.wikipedia.org/wiki/The_Resistible_Rise_of_Arturo_Ui (Brecht)
    https://en.wikipedia.org/wiki/%C3%89crits (Lacan)
    https://en.wikipedia.org/wiki/Manhattan_Transfer_(Dos Passos)
    https://en.wikipedia.org/wiki/The_General_of_the_Dead_Army_(Ismael Kadare)
    https://en.wikipedia.org/wiki/The_Notebooks_of_Malte_Laurids_Brigge (Rilke's only noveL)
    https://en.wikipedia.org/wiki/Tristes_Tropiques
    https://en.wikipedia.org/wiki/The_Tartar_Steppe
    https://en.wikipedia.org/wiki/Confusion_of_Feelings
    https://en.wikipedia.org/wiki/Bonjour_Tristesse
    https://en.wikipedia.org/wiki/The_Lost_Honour_of_Katharina_Blum
    The Association of Small Bombs By Karan Mahajan
    A finalist for the National Book Award, Mahajan's novel smart, devastating and unpredictable opens with a Kashmirian terrorist attack in a Delhi market, then follows the lives of those affected. This includes Deepa and Vikas Khurana, whose young sons were killed, and the boys' injured friend Mansoor, who grows up to flirt with a form of political terrorism himself. As the narrative suggests, nothing recovers from a bomb: not our humanity, not our politics, not even our faith.
    Review: http://www.nytimes.com/2016/03/20/books/review/the-association-of-small-bombs-by-karan-mahajan.html

    Dark Money: The Hidden History of the Billionaires Behind the Rise of the Radical RightBy Jane MayerIn 1980 Charles and David Koch decided they would spend vast amounts of their fortune to elect conservatives to all levels of government, and the world of American politics has never been the same. Mayer spent five years looking into the Koch brothers' activities, and the result is this thoroughly investigated, well-documented book. It cannot have been easy to uncover the workings of so secretive an operation, but Mayer has come as close to doing it as anyone is likely to anytime soon.
    Review: http://www.nytimes.com/2016/01/24/books/review/dark-money-by-jane-mayer.html


    UNREAD Reading


    20161107mpt reading SOME UNREAD

    READING

    S Korean films
    All's not quiet on the eastern front - Film
    Times, The (London, England) - October 1, 2005

    Author/Byline: Ian JohnsSection: FeaturesPage: London Film Festival 26Readability: >12 grade level (Lexile: 1440)

    South Korea is the newest pretender to the world-cinema throne, and it has the energy and diversity to back up its claim, finds Ian Johns
    Every ten years or so a new country seems to take the lead in ground-breaking cinema. After the Second World War it was the Italian neo-realists. In the 1960s it was the French New Wave. More recently, in the 1990s, China led the field before being edged out by Iran. Now South Korea has seized the baton with a group of eclectic, provocative film-makers producing a diverse range of work, a taste of which can be experienced in this year's festival.
    The films include Kim Dae-Seung's Blood Rain, in which an imperial investigator in the early 1800s is faced with a series of grisly murders on an island. It's a labyrinthine mystery, full of evocative period detail, involving a paper-mill-owning family, a reclusive young swordsman and sins of the past.
    Another mystery, Wang Cheol-Mean's Spying Cam, couldn't be more different as political and sexual barriers break down between two men as they tape themselves trapped in a motel room.

    A rising directors making an impact overseas is Park Chan-Wook. His festival film Sympathy for Lady Vengeance is a funny, violent story about a murderess pursuing a vendetta that should provide a slightly less daunting experience for mainstream audiences than his gruesome but gripping cult hit Oldboy. Just as the hero of that film was abducted and detained for 15 years without knowing the reason why, the heroine of Lady Vengeance serves 13 years in jail on false charges of kidnapping and infanticide.

    "I'm often misunderstood as a director of violence," Park has said, "but really I want to show how violence makes the perpetrator and the victim destroy themselves." And always wrapped up in his fascination with violence, vengeance and taboos is an interest in ethical questions.

    Park's high energy, provocative film-making reflects an erupting energy among Korean film-makers. Since South Korea's military dictatorship ended in 1992 with the election of a civilian president, there has been a breaking down of censorship barriers and a rapid growth in production, helped by a quota system that ensures a high proportion of screen time for local films.

    Park describes himself as part of "a generation thirsty for more cinematic expression and the richness and diversity of cinema". According to Anthony Leong, the author of Korean Cinema: The New Hong Kong, "Korean cinema is a melting pot of different types of film-making". He cites many of the film-makers now making an impact as being young, Western-educated and fans of Western, Hong Kong and Japanese cinema, as well as the French New Wave. "They take all these techniques, perspectives and genres and meld them into something unique."

    Kim Ki-Duk has a reputation as one of the bad boys of Korean cinema. His films include Samaritan Girl, a gritty tale of teen prostitution, Bad Guy, a sordid account of a pimp's brutal recruitment of a student, and the revenge yarn 3 Iron.

    Yet he also made Spring, Summer, Autumn, Winter...and Spring (2003), a quasi-Buddhist tale filled with serene natural imagery. It made less than $300,000 in Korea but became the most successful Korean film at the US box office, earning $2.3 million.

    Success abroad is becoming increasingly important for the Korean film industry, which has moved beyond domestic crowd-pleasers such as cop dramas and romantic comedies into darker thrillers, martial-arts adventures, reality-based war epics and distinctive auteur offerings. Even two of South Korea's biggest mainstream hits -Silmido (about a convict commando unit brutally trained in 1968 to kill the North Korean leader) and Taegukgi (two brothers pitted against each other during the Korean war) are tackling the country's troubled past.

    For Kim Dong-Ju, the head of the Seoul-based production and distribution company Show West, "Korea used to be an importing nation, now it will be an exporter". He is working with other Asian backers on such projects as Chen Kaige's The Promise, touted as "the Lord of the Rings of the East". "We are just a beginner," Kim says, "but we want to learn how to make movies like Hero and House of Flying Daggers."

    At the same time the French company MK2 has invested in two of Hong Sang-Soo's recent films, Woman is the Future of Man and Tale of Cinema. The latter, a London festival screening, is an intriguing blurring of fact and fiction as a struggling film-maker bumps into a film star outside a cinema after seeing a movie that was inspired by his life. For film-makers such as Hong, whose low-key, observant style has a relaxed charm reminiscent of Eric Rohmer, foreign backing is invaluable.

    It also means that first-time directors such as Lee Yoon-Ki can hope to carve out a career. His festival film This Charming Girl, shot entirely with a hand-held camera, is a gentle portrait of a shy post-office worker who summons up the courage to invite a regular customer to dinner but is stood up and later offered a lame excuse. We're left, like her, wondering whether to believe him or not.

    An indication of South Korea's passion for cinema was amply demonstrated in 1999 when a change to South Korea's film quota system was suggested. There were hunger strikes and boycotts of Hollywood films -100 film professionals even shaved their heads in protest. But while Kim acknowledges that the industry now boasts many committed, talented people, he doesn't see it as guaranteeing a rosy future: "We just need to try harder to make better films."

    * Blood Rain, Oct 28, NFT1 & Oct 31, Odeon West End 2; Spying Cam, Oct 21 & 24, ICA; Sympathy for Lady Vengeance, Oct 22, Odeon West End 2; Tale of Cinema Oct 30 & Nov 2, NFT1; This Charming Girl, Oct 28, NFT2, & 31, NFT1

    ASIA AT THE FESTIVAL:


    IF YOU WERE ME 2 Shorts by leading South Korean directors for the National Human Rights Commission.
    KEKEXILI: MOUNTAIN PATROL Inspired by the true story of a near-suicidal pursuit of poachers by game wardens in Tibet.
    SHANGHAI DREAMS Family saga of how factory workers relocated to remote areas in the 1960s tried to move back to the cities in the 1980s.
    STOLEN LIFE Poignant Chinese story of a college graduate who gets pregnant.


    Tokyo? Yo! - Japan

    Sunday Times, The (London, England) - January 2, 1994

    Author/Byline: Tom HineySection: FeaturesPage: 6/14Readability: >12 grade level (Lexile: 1410)

    Instead of imitating Western culture, the Japanese are now influencing it.

    There was a time when the one thing Britain didn't import from Japan was its culture. The electronics with which to create and replay our own sights and sounds were worth every yen, but there it stopped. With the exception of art house stalwarts and credit card hippies (Pounds 80-a-head Now and Zen dinners, Buddhism courses in South Ken), most of us presumed that Japanese culture was either a feeble imitation of the West (of which the karaoke machine was the frightening embodiment) or consisted of tea gardens and samurai.

    But no more. Watch out for manga cartoons demented full-length adult animation films and for cyberpunk movies, a sort of Dr Who for grown-ups. From the burgeoning of import mixes by Tokyo club DJs, to the staying power of Japanese designers and young novelists, Britain is waking up to the joys of Japanese pop culture.

    The Land of the Rising Street Cred has graduated from its bug-eyed crash course in Hollywood and Carnaby Street and is creating its own versions of the 1990s in ways both distinctly Japanese and yet with all the familiar idiom of a generation brought up on the Stones and Stanley Kubrick. Forget bullet trains and company anthems, this is the subversive imagination of a new, streetwise Japan.

    You could not get further from the salarymen cliches or chocolate box Wish You Were Here images of Japan than manga cartoons. These are an adult-rated, unashamed diet of what one reviewer described as ``violent sex and sexy violence" and now, as they say, available in your local video store.
    While manga has a long tradition in Japan originating in risque comic-books, the most successful of which were later filmed it has taken a generation of directors reared on Ridley Scott and David Cronenberg to take it out of crude samurai swashbuckling into the post-apocalyptic sophistication of Akira, Legend Of The Overfiend or Dominion-Tank Police. The action is gruesome, the plots generally baffling and some people here don't seem to be able to get enough.

    When the ICA in London, the flagship of art-houses, showed a selection of manga animes two years ago, under the billing A Celebration Of Japanese Animation, they were besieged by young manga freaks. Long tantalised by references in their computer magazines, they were desperate to see classics such as Akira, by Katsuhiro Otomo, about a boy turned by scientists into a monster, on the big screen. All box office records were broken as hordes of people who normally wouldn't go within spitting distance of a contemporary arts institute flocked to see Venus Wars, Fist Of The North Star, or Robot Carnival. Such was the interest that Island International, part of the record company, bought distribution rights and launched Manga Video. Each title so far has gone straight into the top 10 national video charts within weeks, displacing staple bestsellers, but soon afterwards disappearing a true manifestation of cult buying.

    Kenny Penman, who as the manager of the Forbidden Planet comic and video store in Edinburgh has witnessed the manga-raiders at work, says: ``It's a fanatical thing they know the release dates before we do, and always buy the video straight away. Manga is bringing out two a month now and they always sell about 12,000 in the first week."

    Shinya Tsukamoto's Tetsuo a black-and-white movie about a man who turns into, yes, a monster will not be shown properly in Britain until this spring, but is already regarded as the ultimate cyberpunk movie; what more likely nation than Japan to create such a gory and compulsive vision of techno-madness. Subtitles, which are always liable to damage a film's wide popularity, are badly needed in Tetsuo: it is like a demented, hour-long pop video, and if you think the violence is disturbing, wait until you hear the soundtrack.

    Japanese jazz funk has also been grabbing selected spotlights lately; Mo Wax is a new London record label concentrating on Tokyo club releases, whose compilation Jazz Hip Jazz (released last month) is genuinely ``available everywhere". According to Ashley Heath, of The Face magazine, groups such as UFO (United Future Organisation) are being taken ``very seriously" in British clubs; the birthplace of modern electronics has come into its own in the age of mixing and sampling. The chain-smoking, stubble-weary young Japanese DJs who are masterminding this surge are the epitome of scowling hip. The most sought-after soundtrack writer and musical polymath of our day is the seasoned Ryuichui Sakamoto (Last Emperor, Wild Palms), but it is Jap Jazz that has the music press excited. ``How much is a ticket to Tokyo?" finished one breathless review.

    Similarly with fashion few Londoners would continue spending Tokyo prices on Issey Miyake, Yohji Yamamoto or Rei Kawakubo if these designers were just novelty weirdos or expensive copycats. They're different enough to be fresh and controversial, but not so different as to be tedious, which is really all the fashion and music worlds ask of anybody.

    Even the trend value of Japanese lager, that apparently most self-generated of marketing whims, was not entirely arbitrary. These days we don't feel guilty about appreciating supermarket aesthetics, and when it comes to imaginative packaging you can't beat the Japs: if you thought Lucozade was inventive with its isotonic-in-a-bag, try a magnificent two-litre can of Sapporo (so outsize that it's got a metal handle) or the stationery departments at Muji or Sogo stores.

    British publishers are meanwhile busily hunting down the cult novel the Catcher In The Rye of downtown Tokyo. Contestants include most of Shusaku Endo's books, which always get rave reviews here. Endo is set for household naming after Martin Scorsese's planned adaptation of his classic novel, Silence. His novels portray a gritty and paranoid Tokyo, as do those of the excellent Haruki Murakami. Murakami's characters, in books such as A Wild Sheep Chase or The End Of The World and the Hard Boiled Wonderland, listen to the Stones, read Sherlock Holmes and hate offices. Far from this making him unpopular in Japan, he is the country's biggest selling writer, and Penguin reports healthy sales here. Faber and Faber has its money on Banana Yoshimoto, whose first novel, Kitchen, is about ``mothers, transsexuality, bereavement, kitchens, love and tragedy", and comes out in paperback later this month.

    So forget Yoko Ono, David Sylvian, Seven Samurai, misspelt Bowie sleeve notes and Dylan making a quick buck at Budokan. And certainly forget, as emblems of Japan, Nikon cameras, Nissan car factories, over-priced Impressionists, endurance game shows, and the nightmare that is karaoke. Pick up instead a copy of Super Play, a 50,000-circulation independent British computer games glossy, enjoy its fixation with Japanese snacks and toys and read its column from Tokyo, called Live From City Hell.

    Elsewhere, be tolerant of the occasional lapse in Japanese bicultural hipness, such as in Banana Yoshimoto's dedication of her novel to a Mr Jiro Yoshikawa, ``who introduced me to Mike Oldfield's wonderful piece of music". You can forgive a nation for being 10 years late with punk and 20 years late with ska, but to name a whole chapter of your first novel after Moonlight Shadow is pushing it.
    Never mind it won't seem to matter when you pick up the latest action-packed issue of Manga Mania magazine. Whatever happened to the computer dweeb?

    Jonathan Ross presents a programme on manga on BBC2 at 7.30pm on Friday;
    Akira is on BBC2 at 10.30pm on Saturday.
    Record: 986546909Copyright: (c) Times Newspapers Limited 1994, 2003










    Startup Stuff
    Startup Playbook
    Startup Reading/Links
    [/r/bestof] /u/divbase explains a lot of things he did wrong with his failed startup
    Bootstraping a SAAS
    Startup Pulse


    Job Search
    20161103mpt java job trends xpages srch results
    20161103mpt salary rate java freelance consultant 2016 Yahoo srch results
    20161103mpt salary rate java freelance consultant 2016 BING srch results
    Yahoo & Bing job srch (1 pg ea) "ibm domino jobs contract -pizza -delivery -driver&n=100&sort=new"
    Params for Job srch:
    =ibm+domino+jobs+java+contract+us+-canada+-uk +-administrator+-pizza+-delivery+-driver+n=100+sort=new


    Salary
    "Knowing a niche technology and/or industry, finding a company that needs to staff and going in as a self-employed contractor instead of an employee.
    I had friends making $200 an hour in 1999 because of this.
    I'd like to say they were working in Lotus at the time, but I don't really remember."
    https://news.ycombinator.com/item?id=5804798


    Japanese lit Unfortunately, most of these are either blocked or the server sends you somewhere else; but check on non-public pc later...
    Aozora Bunko, a e-txt lib (sim to gutenbrg)
    The Letters of Zen Master Hakuin Translated by Norman Waddell
    Univ of VA lib (many txtx)
    Hakuin: A chat on a boat in the evening
    The Lankavatara Sutra. A Mahayana Text trans. Suzuki; based upon the Sanskrit edition of Bunyu Nanjo (1923)


    blouin art info

    Corina Stanis (Duke): The Art of Distances (2018)
    essay on aeon: On Tact in Dark Times, 'masters of diplomacy & tact':
    Theodor Adorno, US exile: Minima Moralia ('51)
    Anne DuFourmantelle: Power of Gentleness: Meditations on the Risk of Living (2013)
    Pierre Zaoui: Discretion, or the Art of Disappearing (2013)

    Thomas Mann
    try to locate his essay Brother Hitler (esquire 39); ref: Nazism centered in cultural mvmts of fin de siecle era
    After WWI he wrote 'Confessions of a non-politcal man', ref: 'An authoritarian state is proper & becoming to Germans'
    from zauberBrg, which 'acutely diagnozed the malady afflicting central Europe': character Leo Naptha (a fanatical Jes. priest)
    'The mystery and precept of our age (1924) is not liberation and the development of the ego. What our age needs, what it demands, what it will create for itself; is - terror.'

    Soviet exiles in the US during the ColdWar era (ref Nabokov, cousin of Vlad, opera composer, on Shostakovich's 7th et al) - cia-backed cultural mouthpieces took the stance that 'without freedom art can't exist' etc., many voices incl Vlad Nab. put down all Soviet writers/musicians; refs from art:
    20th Century political art: Brecht, Neruda, Rivera
    "The highwater mark for Spanish lit. coincided w/ruthless religious autocracy": Velasquez, El Greco, Cervantes, Tomas Luis de Victoria.
    Soviets: Eisenstein, Meyerhold, Akhmatova.

    Tempo Rubato (it., stolen time) Singing technique by which a vocalist plays around with, but ultimately obeys, a song's timing.

    Robert's Rules of Order

    Apparently 'refernce' translations:
    Pushkin - Stanley Mitchell; Turgenev - Peter Carson


    http://www.metmuseum.org/

    https://www.theguardian.com/books/translation- tuesdays-by-asymptote-journal
    https://www.theguardian.com/books/biography? page=2
    https://www.theguardian.com/books/series/100- best-nonfiction-books-of-all- time
    http://www.lrb.co.uk/v28/n11/maya- jasanoff/before-and-after-said
    https://www.theguardian.com/books/2016/apr/05/john-aubrey-my-own-life-by-ruth-scurr- review-diary- rival-pepys
    https://www.theguardian.com/books/2016/apr/14/maggie-nelson-argonauts-intellectualism- having- baggage

    https://en.wikipedia.org/wiki/Rodrigues_Ottolengui (Proj gutenberg)

    http://aldaily.com/ ... the Internet's best index of articles on culture and ideas
    http://www.spiegel.de/international/
    http://www.pepysdiary.com/

    http://www.artnet.com/
    http://www.uppereast.com/articles


    http://www.theparisreview.org/



    https://www.scribd.com

    https://getd.libs.uga.edu/pdfs/harris_paget_w_200512_ma.pdf
    http://www.ft.com/cms/s/2/59590084-f59b-11e0- 94b1-00144feab49a.html

    http://www.thedandy.org/thedandy
    http://www.huckmagazine.com/art-and- culture/flaneurs/
    https://www.scribd.com/doc/316466247/Gleber- Art-of-Walking-Ch-4


    Early b.html w/working map

    Some Blocked searchlist sites:
    http://circumspections.tumblr.com/
    http://psychogeographicreview.com/baudelaire- benjamin-and-the-birth-of-the-flaneur/

    Yahoo multipg srch "Wall street forum technical Analysis economy"
    Google's Undocumented Finance API
    Against Nature: A Rebours by Huysmans

    The Lost Tools Of Learning By Dorothy Sayers
    https://en.wikipedia.org/wiki/Katapayadi_system
    https://en.wikipedia.org/wiki/Method_of_loci

    10 Athleic NYC items

    Loop the rez at night
    Decline using yr car or Uber, walk instead!
    Appreciate the facilities in midtown
    Enjoy a heavenly bliss out after a run
    Pick up some post-run energy with an espresso
    Hit the roads on your bike and ride
    Kiss the blues goodbye @ CBGB
    Catch some tree-time by going outdoors
    Rise above the smoke/smog and look down
    Shoot some pool everyday


    Maniyaro
    ..   ,
         .
        ,
     ,  ,
      ,   .
    
    ..    
         ,
     ,  . .
    
    ..    
         ,
     ,   .
    
    ..    
          ,
     ,   .
    
    ..     ,
         ,
     ,  ,
     ,   .
    
    ..    ,
          ,
     ,  ,
      ,   .
    
    ..   
      ,    ,
     ,  ,
     ,  . . 
    


    test Div One Content
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dapibus efficitur gravida. Curabitur semper dignissim posuere. In augue nisl, malesuada a tellus quis, sagittis fermentum arcu. Duis at sodales erat, non finibus orci. Phasellus in auctor justo, sed congue nisl. Nulla iaculis, purus id sollicitudin hendrerit, mi orci maximus dolor, a feugiat elit justo id magna. Nulla vestibulum ligula sed accumsan finibus. Phasellus ornare eros nisl, sit amet mattis libero vulputate in. Ut a blandit leo, a rhoncus velit. Aliquam sit amet dolor nisi. Duis lobortis mauris arcu, ut auctor massa venenatis id. Cras imperdiet nibh non purus vulputate, vel lobortis neque pretium. Ut vel gravida libero. Aliquam erat volutpat.
    Interdum et malesuada fames ac ante ipsum primis in faucibus. In hac habitasse platea dictumst. Suspendisse potenti. Nulla ut lacus vitae velit suscipit pulvinar in eu purus. Mauris dapibus nunc risus, ac tempor felis congue id. Integer nec placerat enim. Suspendisse lobortis fermentum ornare. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla at ligula eu mi molestie venenatis at eu ex. Nam feugiat aliquet massa, tincidunt iaculis nunc tincidunt eget. Etiam in iaculis leo. Etiam vulputate in est a aliquet. Proin fermentum felis cursus leo egestas elementum.
    Suspendisse in aliquam tortor, quis elementum neque. Donec ultrices purus sed est aliquam vulputate. Donec lobortis, mi sed dapibus auctor, nunc lorem feugiat dolor, ac aliquet sem orci at nisl. Aliquam tincidunt ante leo. Sed pulvinar elit nec mi mollis, eget laoreet erat cursus. Sed euismod in est ac feugiat. Ut ac neque sit amet tortor bibendum accumsan. Pellentesque sed fringilla ipsum. Fusce velit tortor, sagittis vel velit non, lacinia auctor purus. Donec commodo sed arcu eget ultricies. Proin feugiat dignissim hendrerit. Vestibulum efficitur tincidunt rhoncus. Pellentesque lobortis justo vitae nunc bibendum, nec consectetur leo tristique.
    Maecenas a eleifend ligula, ac finibus nibh. Quisque ullamcorper tortor pulvinar, pellentesque sapien sit amet, semper nunc. Praesent luctus erat in lacus efficitur, tincidunt laoreet ante suscipit. Nullam laoreet vestibulum sagittis. Suspendisse tristique, massa eget ultricies tincidunt, ipsum felis lobortis est, vitae interdum augue enim ut turpis. Quisque a augue nisi. Proin cursus ligula at pulvinar eleifend. Nunc sollicitudin ultrices mi eget varius. Etiam lectus risus, vulputate nec leo sed, ultrices gravida dolor. Donec ultricies sodales justo eu vehicula. Sed sit amet ultrices dolor. Nunc a congue sem.
    test Div Two Content
    1914 translation by H. Rackham
    "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"
    "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."
    Hi friends
    test Div Three Content

    Gist Output:

    Output here...



    John Milton, 1608 - 1674

    When I consider how my light is spent,
    Ere half my days in this dark world and wide,
    And that one talent which is death to hide
    Lodged with me useless, though my soul more bent

    To serve therewith my Maker, and present
    My true account, lest He returning chide;
    "Doth God exact day-labor, light denied?"
    I fondly ask. But Patience, to prevent

    That murmur, soon replies, "God doth not need
    Either man's work or His own gifts. Who best
    Bear His mild yoke, they serve Him best. His state
    Is kingly: thousands at His bidding speed,
    And post o'er land and ocean without rest;
    They also serve who only stand and wait."


    Acquainted with the Night, ROBERT FROST
    I have been one acquainted with the night.
    I have walked out in rain-and back in rain.
    I have outwalked the furthest city light.

    I have looked down the saddest city lane.
    I have passed by the watchman on his beat
    And dropped my eyes, unwilling to explain.

    I have stood still and stopped the sound of feet
    When far away an interrupted cry
    Came over houses from another street,

    But not to call me back or say good-bye;
    And further still at an unearthly height,
    One luminary clock against the sky

    Proclaimed the time was neither wrong nor right.
    I have been one acquainted with the night.


    //Before running, will have to compile with jsoup jar:
    //export CLASSPATH= $CLASSPATH:/usr/share/java/jsoup/jsoup.jar
    //------------------------------------------------------------------------------
    //Before running, will have to compile with jsoup & apache commons jars:
    //export CLASSPATH=$CLASSPATH:/usr/share/java/jsoup/jsoup.jar:
    //usr/share/java/apache-commons-lang3.jar
    //------------------------------------------------------------------------------
    import java.net.*;
    import java.io.*;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    import org.apache.commons.lang3.StringEscapeUtils;

    public class URLRdr {

    public static String getText(String url) throws IOException {

    URL website = new URL(url);
    String strBody = "";
    Document doc = Jsoup.connect(url).get();
    Elements bodyTxt = doc.select("body");

    for (Element el : bodyTxt){
    System.out.println("bodyTxt: "+el);
    strBody = strBody + el.toString();
    }

    //escape the string for JSON
    strBody = StringEscapeUtils.escapeJson(strBody);
    return strBody;
    }

    public static void main( String[] args ) throws IOException{

    String[] thisIsAStringArray = {
    "http://www.bing.com/search?q=aesthete+or+flaneur&go=Search&qs=ds&form=QBRE" ,
    "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&first=11&FORM=PERE" ,
    "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&first=21&FORM=PERE1" ,
    "http://www.bing.com/search?q=aesthete+or +flaneur&go=Search&qs=ds&first=31&FORM=PERE2" };

    String content = "";

    for( int i = 0; i < thisIsAStringArray.length; i++) {
    content=content + URLRdr.getText(thisIsAStringArray[i]);
    }
    //System.out.println( content );
    //content = URLencoder.encode(content, "UTF-8");

    //create a Gist from output
    try {

    URL Giturl = new URL("https://api.github.com/gists");

    HttpURLConnection conn = (HttpURLConnection) Giturl.openConnection();
    conn.setDoOutput(true);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", "application/json");

    String input = "{ \"description\": \"2016mpt 7-12-16 Output of flaneur search on Bing\", \"public\" : true , \"files\": {\"mike.html\": {\"content\" : \"" + content + "\"}}}";
    // String input = "{ \"description\": \"2016mpt 7-12-16 Output of flaneur search on Bing\", \"public\" : true , \"files\": {\"mike.html\": {\"content\" : \"" + "test" + "\"}}}";

    OutputStream os = conn.getOutputStream();
    os.write((input.toString()).getBytes("UTF-8"));
    os.flush();

    if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
    throw new RuntimeException("Failed : HTTP error code : "
    + conn.getResponseCode());
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(
    (conn.getInputStream())));

    String output;
    System.out.println("Output from Server .... \n");
    while ((output = br.readLine()) != null) {
    System.out.println(output);
    }

    conn.disconnect();

    } catch (MalformedURLException e) {
    e.printStackTrace();

    } catch (IOException e) {
    e.printStackTrace();
    }


    System.out.println("URLRdr done,..");
    }
    }
    Admin mode

    TimeStamp: 20161005 noon

    TimeStamp: 20161026 pm



    Srch Results for sufi
    Selected Srch Txt for sufi

    https://rekhta.org/
    http://www.urdu-shayari.in/
    http://www.storypick.com/mirza-ghalib-shayaris/

    Yahoo multipg srch "sufi rumi bulleh"


    Avoiding .Net regex timeouts w/backtracking & grouping



    Other reading
    HN: the good parts
    Conversations about Software Engineering (some chkd)
    Harvard Biz Rev
    Frontline Shows
    Movie scripts
    TED Talk transcripts

    p.m: lake mule layer blossom pill shoe obvious current toast senior gesture until
    rp: (num) YYOD + ### nr agitProp + (txt) riot-oriented hollins + (FN) iit bobby prem
    ml: (col) flow'd like de river + (txt) 100EDOok + (numTxt) hollins bonMotty
    g: (reg) hollins BangAcn

    Jan:
    rp:"Bananas x 3 (hin, FN)"; "(txt) hollins suscept. to this kalam"; "TIK acr from Prem's place";
    ml:"Band's narrow? Breakout, probly (1st)";"(num) MMDDOdipti"; "mercurialRepo chinese equiv.";
    fin:"(txt) hollins surpei"; "Change b/h pool 2 get (1st)"; "Huge chap w/a secretary fan (nick)"

    May eom:
    rp:"(num) YYOBS + ##SiteOfHammer"; "(col) ashD or orcl";"(1 wd) 1 lvl up frm advSpkrs"
    ml:"(num) YYOD + ### nr agitProp"; "(col) TrikeBkCol"; "(1 wd) ei-di-ding (x2) goldee"
    June:
    "(col) ashD or orcl", "(num) tri cld've been flooded if in nyc", "(F wd) astr Pan had william's candy"
    "(col) RMGSHouse", "(num) ##ReiSol + ###Haussm.", "(1 wd) Paresh: isi qual __ refl"

    Lazy sequences implementation for Java 8 by Tomasz Nurkiewicz (of Functors/Monad fame) -> article link (a lib)
    (also see: https://www.nurkiewicz.com/2013/05/lazy-sequences-in-scala-and-clojure.html)
    Can be used for loading batches (pages) of data from database. Using ResultSet or Iterator is cumbersome but loading whole data set into memory often not feasible. An alternative involves loading first batch of data eagerly and then providing a function to load next batches. Data is loaded only when it's really needed and we don't suffer performance or scalability issues.
     First let's define abstract API for loading batches of data from database:
    public List loadPage(int offset, int max) {
        //load records from offset to offset + max
    }
    
    I abstract from the technology entirely, but you get the point. Imagine that we now define LazySeq that starts from row 0 and loads next pages only when needed:
    
    public static final int PAGE_SIZE = 5;
    
    private LazySeq records(int from) {
        return LazySeq.concat(
            loadPage(from, PAGE_SIZE), 
            () -> records(from + PAGE_SIZE)
        );
    }
    

    Neal Ford's EITHER (as a tree for pattern matching) -> Either trees and pattern matching https://www.ibm.com/developerworks/java/library/j-ft14/index.html ...consider the declaration Either<Empty, Either<Leaf, Node>>, which creates a three-part data structure...

    Neal Ford on Immutability (https://www.ibm.com/developerworks/java/library/j-ft4/index.html)

    example class (no getters/setters/noArg constr; all flds final; class final):

    public final class Address {
        private final List streets;
        public final String city;
        public final String state;
        public final String zip;
     
        public Address(List streets, String city, String state, String zip) {
            this.streets = streets;
            this.city = city;
            this.state = state;
            this.zip = zip;
        }
     
        public final List getStreets() {
            return Collections.unmodifiableList(streets);
        }
    }
    

    Neal Ford's ex using a memoized cache (https://www.ibm.com/developerworks/java/library/j-ft17/index.html)

    "...Here, I create a class-wide cache to hold previously calculated values ....requires a little dubious class design, forcing it to be stateful so that the instance can act as the owner of the cache. This could be improved, but the improvement is trivial in subsequent examples, so I won't bother here...."

    import fj.F;
    import fj.data.List;
    import java.util.HashMap;
    import java.util.Map;
    import static fj.data.List.range;
    import static fj.function.Integers.add;
    import static java.lang.Math.round;
     
    import static java.lang.Math.sqrt;
     
    public class FjPrimeNumber {
        private int candidate;
        private Map cache;
     
        public FjPrimeNumber setCandidate(int value) {
            this.candidate = value;
            return this;
        }
     
        public FjPrimeNumber(int candidate) {
            this.candidate = candidate;
            cache = new HashMap();
        }
     
        public boolean isFactor(int potential) {
            return candidate % potential == 0;
        }
     
        public List getFactors() {
            final List lowerFactors = range(1, (int) round(sqrt(candidate) + 1))
                    .filter(new F() {
                        public Boolean f(final Integer i) {
                            return isFactor(i);
                        }
                    });
            return lowerFactors.append(lowerFactors.map(new F() {
                public Integer f(final Integer i) {
                    return candidate / i;
                }
            }))
            .nub();
        }
     
        public int sumFactors() {
     
            if (cache.containsKey(candidate))
                return cache.get(candidate);
            else {
                int sum = getFactors().foldLeft(add, 0);
                cache.put(candidate, sum);
                return sum;
            }
        }
     
        public boolean isPrime() {
            return candidate == 2 || sumFactors() == candidate + 1;
        }
    }
    

    ibm devWorks: Neal Ford's Fluent interfaces

    Evolutionary architecture and emergent design: Fluent interfaces
    Build internal DSLs to capture idiomatic domain patterns


    Neal Ford
    July 13, 2010
    This installment of Evolutionary architecture and emergent design continues the discussion ofharvesting techniques for idiomatic patterns in emergent design. When you identify a reusablepattern, you should capture it in a way to sets it apart from the rest of your code. Domain-specific languages (DSLs) offer many techniques for concisely capturing data and functionality.This month, Neal Ford shows you three ways to build internal DSLs that capture idiomaticdomain patterns.

    The preceding installment of this series introduced the subject of using domain-specificlanguages (DSLs) to capture domain idiomatic patterns. This installment continues with that topic,demonstrating various DSL construction techniques.
    In his upcoming book Domain Specific Languages, Martin Fowler differentiates between two typesof DSLs (see Related topics). External DSLs build a new language grammar, requiring tools likelexx and yacc or Antlr. An internal DSL builds new languages atop a base language, whose syntaxit borrows and stylizes. The examples in this installment build internal DSLs using Java as the base language, constructing new mini-languages on top of its syntax.

    About this series

    This series aims to provide a fresh perspective on the often-discussed but elusive conceptsof software architecture and design. Through concrete examples, Neal Ford gives you asolid grounding in the agile practices of evolutionary architecture and emergent design. Bydeferring important architectural and design decisions until the last responsible moment, youcan prevent unnecessary complexity from undermining your software projects.
    Underlying all the following techniques for constructing DSLs is the notion of implicit context.DSLs (especially internal ones) try to eliminate noisy syntax by creating contextual wrappersaround related elements. A good example of this concept appears in XML in the form of parentand child elements, which provide a wrapper around related items. You'll notice many of theseDSL techniques achieve that same effect using language syntactic tricks.

    Readability is one of the benefits of using a DSL. If you write code that nondevelopers can read,you shorten the feedback loop between your team and the people who are requesting features.A common DSL pattern identified in Fowler's book is called fluent interface, which he defines asbehavior capable of relaying or maintaining the instruction context for a series of method calls. I'llshow you several types of fluent interfaces, starting with method chaining.

    Method chaining


    Method chaining uses return values from methods to relay instruction context, which in this case isthe object instance making the first method invocation. This sounds much more complex than it is,so I'll show an example to clarify this concept.
    When working with DSLs, it is common to start with your goal syntax and reverse engineerbackwards to figure out how to implement it. Starting at the end makes sense because readabilityis highly valued in DSLs. The example I'll use is a small application that tracks calendar entries.The application illustrates the DSL's syntax, as shown in Listing 1:
    Listing 1. Goal syntax for a calendar DSL
    
    public class CalendarDemoChained { 
    
      public static void main(String[] args) { 
    	new CalendarDemoChained(); 
      } 
    
      public CalendarDemoChained() { 
    	Calendar fourPM = Calendar.getInstance(); 
    	fourPM.set(Calendar.HOUR_OF_DAY, 16); 
    	Calendar fivePM = Calendar.getInstance(); 
    	fivePM.set(Calendar.HOUR_OF_DAY, 17); 
    
    	AppointmentCalendarChained calendar = new AppointmentCalendarChained(); 
    	calendar.add("dentist"). 
    		from(fourPM). 
    		to(fivePM). 
    		at("123 main street"); 
    
    	calendar.add("birthday party").
    		at(fourPM); 
    	displayAppointments(calendar); 
      } 
    
      private void displayAppointments(AppointmentCalendarChained calendar) { 
    	for (Appointment a : calendar.getAppointments()) 
    		System.out.println(a.toString()); 
    	}
      }
    
    


    After the necessary cruft at the top dealing with Java calendars, you can see the method-chainingfluent interface in action as I add values to the two calendar entries. Notice that I'm using whitespace to separate the parts of what is (from a Java syntax standpoint) a single line of code. It iscommon in internal DSLs to stylize the use of the base language to make the DSL more readable.

    The Appointment class containing most of the fluent-interface methods appears in Listing 2:

    Listing 2. Appointment class
    public class Appointment { 
      private String _name; 
      private String _location; 
      private Calendar _startTime; 
      private Calendar _endTime; 
    
      public Appointment(String name) { 
        this._name = name; 
      } 
    
      public Appointment() { } 
    
      public Appointment name(String name) { 
    	_name = name; 
    	return this; 
      } 
    
      public Appointment at(String location) { 
    	_location = location; 
    	return this;
      } 
    
      public Appointment at(Calendar startTime) { 
    	_startTime = startTime; 
    	return this;
      } 
    
      public Appointment from(Calendar startTime) { 
    	_startTime = startTime; 
    	return this;
      } 
    
      public Appointment to(Calendar endTime) { 
       	_endTime = endTime; 
    	return this;
      }
    
      public String toString() { 
    	return "Appointment:"+ _name + 
    	((_location != null && _location.length() > 0) ? ", location:" + 
    	_location : "") + ", Start time:" + _startTime.get(Calendar.HOUR_OF_DAY) + 
    	(_endTime != null? ", End time: " + _endTime.get(Calendar.HOUR_OF_DAY) : "");
      }
    }
    


    As you can see, building fluent interfaces is straightforward. For each of the mutator methods, youdiverge from standard JavaBean syntax by writing your setter methods to return the host object(this) and by replacing the set naming convention with something more readable. The generaldefinition at the start of this section should now be clear. The context being relayed via the methodchaining is this, meaning that you can make a series of method calls concisely.

    In the article "Leveraging reusable code, Part 2," I showed an API definition for a train car, asshown in Listing 3:

    Listing 3. An API for a train car
    	Car2 car = new CarImpl();
    	MarketingDescription desc = new MarketingDescriptionImpl();
    	desc.setType("Box");
    	desc.setSubType("Insulated");
    	desc.setAttribute("length", "50.5");
    	desc.setAttribute("ladder", "yes");
    	desc.setAttribute("lining type", "cork");
    	car.setDescription(desc);
    


    The problem domain for train cars is complex because of regulatory rules about contents andhistory. On the project that yielded this example, we had lots of complicated testing scenarios thatrequired dozens of lines of set calls like the ones in Listing 3. We tried to get our business analyststo verify that we had the right magical combination of attributes, but they pushed back becausethey viewed it as Java code, which they had no interest in reading. The ultimate impact of thisproblem was the requirement that a developer verbally translate the details, which is of courseerror-prone and time-consuming.

    To resolve this problem, we converted our Car class into a fluent interface, so that the code fromListing 3 became the fluent interface shown in Listing 4:

    Listing 4. Fluent interface for train cars
    	Car car = Car.describedAs() 
    		.box() 
    		.length(50.5) 
    		.type(Type.INSULATED) 
    		.includes(Equipment.LADDER) 
    		.lining(Lining.CORK);
    


    This code was declarative enough and removed sufficient noise from the Java API version that ourbusiness analysts were happy to verify it for us.

    Returning to the calendar example, the last bit of the implementation is the AppointmentCalendarclass, which appears in Listing 5:

    Listing 5. AppointmentCalendar
    public class AppointmentCalendarChained { 
    
    	private List appointments; 
    
    	public AppointmentCalendarChained() { 
    		appointments = new ArrayList(); 
    	} 
    
    	public List getAppointments() { 
    		return appointments;
    	} 
    
    	public Appointment add(String name) {
    		Appointment appt = new Appointment(name); 
    		appointments.add(appt); 
    		return appt; 
    	}
    }
    


    The add() method:
    1. Starts the method chain by creating a new Appointment instance
    2. Adds the new instance to the list of appointments
    3. Ultimately returns the new appointment instance, meaning that subsequent method calls areinvoked on the new appointment

    When you run the application, you see the details of your configured appointments, as shown inFigure 1:

    Figure 1. Results of running the calendar application

    Appointment:dentist, location:123 ~~~~, STart time: ~~
    Appointment:birthday party, Start time: 123

    So far, method chaining looks like a simple way to clean up overly verbose syntax, especiallymethod calls that are mostly declarative. This works well for idiomatic patterns in emergent designbecause domain patterns are frequently declarative.

    Note that using method chaining necessitates violating the syntactic rules for JavaBeans, whichinsist that mutator methods must start with set and return void. Building fluent interfaces is anexample of knowing when it makes sense to break some of the rules. The JavaBeans specificationisn't doing you any favors if it forces you to write obfuscated code! But nothing in the creation oruse of fluent interfaces precludes supporting both the fluent interface and a JavaBeans interface.The fluent interface methods can turn around and call the standard set methods, allowing you touse fluent interfaces even when frameworks insist that it interact with your classes as JavaBeans.

    Solving the finishing problem



    One pitfall that's inherent in fluent interfaces under certain circumstances is known as the finishingproblem. I'll illustrate this issue by making a change to the AppointmentCalendar class fromListing 5. Presumably, you'd like to do more than just display the appointments, such as put themin a database or some other persistence mechanism. Where do you add the code to save thecompleted appointment to storage? You can try to do it in AppointmentCalendar's add() methodjust before you return the appointment. Listing 6 shows an attempt to access the appointment herefor something as simple as printing it:

    Listing 6. Adding printing
    	public Appointment add(String name) { 
    		Appointment appt = new Appointment(name); 
    		appointments.add(appt); 
    		System.out.println(appt.toString()); 
    		return appt;
    	}
    


    When you run the code in Listing 6, the unhappy results illustrated in Figure 2 show up:


    Figure 2. Error output after the addition to AppointmentCalendar
    (nullpointerExc)

    The error displayed is a NullPointerException occurring in the toString() method on theAppointment class. Why it complains here, even though the method worked correctly, is theessence of the finishing problem.

    The error occurs because I'm trying to call the toString() method on the appointment instancebefore the rest of the fluent-interface setter methods are called. The code to try printing theappointment appears in the method that creates the appointment instance and starts the chain. Icould create a save() or finished() method that must be called as the last method in the chain,but I'd rather not impose an easy-to-forget rule on my DSL's users. In fact, I'd rather not imposeany order semantics on the methods in my fluent interface.

    The real problem is that I'm being too aggressive with the method-chaining technique. Methodchaining works best for the creation of simple data objects, yet here I'm using it both for the settermethods on Appointment and in AppointmentCalendar to start the method chain.

    I can fix the finishing problem by wrapping the creation of the appointment entirely with theparentheses of the appointment calendar's add() method, as shown Listing 7:

    Listing 7. Wrapping via parameter
    	AppointmentCalendar calendar = new AppointmentCalendar();
    	calendar.add( 
    		new Appointment("Dentist").
    		at(fourPM));
    	calendar.add( 
    		new Appointment("Conference Call").
    		from(fourPM). 
    		to(fivePM). 
    		at("555-123-4321"));
    	calendar.add( 
    		new Appointment("birthday party"). 
    		from(fourPM). 
    		to(fivePM)). 
    	add( new Appointment("Doctor"). 
    		at("123 Main St"));
    	calendar.add( new Appointment("No Fluff, Just Stuff"). 
    		at(fourPM));
    	displayAppointments(calendar);
    


    In Listing 7, the add() method's parentheses encapsulate the entire use of the Appointmentfluent interface, allowing the add() method to handle whatever additional behavior that it wants(printing, persistence, and so on). In fact, I couldn't resist adding a bit of a fluent interface toAppointmentCalendar itself: you can now chain together the add() methods, as shown in Listing 7and implemented in Listing 8:

    Listing 8. The parameter-wrapping AppointmentCalendar
    public class AppointmentCalendar { 
    	private List appointments; 
    
    	public AppointmentCalendar() { 
    		appointments = new ArrayList();
    	} 
    
    	public AppointmentCalendar add(Appointment appt) { 
    		appointments.add(appt); 
    		return this; 
    	} 
    
    	public List getAppointments() { 
    		return appointments; 
    	}
    }
    


    The finishing problem can arise any time you mix fluent-interface classes. It popped up inthis example because I used the appointment calendar to start the method chain, mixingthe construction and wrapping behaviors. By deferring construction and initialization tothe Appointment class, I make it easier to separate additional wrapping behavior (such aspersistence).

    Wrapping via functional sequence



    Thus far, I've shown two of the three context-passing techniques for fluent-interface DSLs. The third functional sequence uses inheritance and anonymous inner classes to create a contextwrapper. The calendar application rewritten using functional sequence appears in Listing 9:
    Listing 9. Wrapping via functional sequence
    	calendar.add(new Appointment() {{ 
    		name("dentist"); 
    		from(fourPM); 
    		to(fivePM); 
    		at("123 main street");
    	}});
    
    	calendar.add(new Appointment() {{ 
    		name("birthday party"); 
    		at(fourPM);
    	}});
    


    Listing 9 shows a pattern that I introduced in "Leveraging reusable code, Part 2" under the guiseof removing structural duplication. The syntax looks odd because of the double {{ braces. The firstset of enclosing braces delineates the construction of an anonymous inner class, and the secondset delineates the instance initializer for the anonymous inner class. (If this sounds a bit confusing,you can refer back to "Leveraging Reusable Code, Part 2" for a lengthy explanation of this Javaidiom.)

    The main advantage of this style of fluent interface lies in its adaptability. The only thing a classneeds to be used this way is a default constructor (which allows you to create an anonymous innerclass instance inheriting from your class). That means that you can easily add fluent-interface methods to existing Java APIs without changing any of the current calling semantics. This allowsyou to "fluentize" existing APIs gradually.

    Conclusion



    DSLs capture idiomatic domain patterns concisely and effectively. Fluent interfaces provide asimple way to change the way you write code so that you can more readily see the idiomaticpatterns you've fought to identify. They also force you to change your perspective on code just abit: it should be not merely functional but readable as well, especially if nondevelopers need toconsume any aspect of it. Fluent interfaces remove unnecessary noise from your syntax, allowingfor more readable code. For declarative structures, you can express ideas more clearly with lesseffort.
    In the next installment, I'll continue discussing DSL techniques as a mechanism for harvestingidiomatic patterns in emergent design.

    Functional patterns for iterating collections in Java
    • Statements and expressions
    • Iterating and sorting with statements
    • Iterating and sorting with a collection pipeline

    Reusable functions help make your code highly concise, but does conciseness ever go too far?
    • Mysterious syntax
    • Higher-order functions
    • Example 1: A function that receives a function
    • Example 2: A Function that returns a function
    • Creating reusable functions
    • Creating and reusing lambda expressions
    • A recipe for conciseness
    • Understanding cascading lambdas

    Lambdas are stateless, but your programs don''t have to be
    • The stateless life
    • Why we need state
    • Lexical scoping
    • Lexical scoping in a lambda expression
    • How closures carry state
    • Closure lunch break
    • Using closures

    Understanding streams and mutables in the functional pipeline
    • Functional pipelines and the Stream API
    • Lazy evaluation
    • Stream processing
    • Parallelization
    • The rules of functional purity
    • Why functional purity matters
    • Avoid shared mutability

    Venkat Subramaniam's FLUENT DSL java8 Functional stuff

    A neat example of Venkat Subramaniam's 'higher-order' or composed fns + DSL + functional style ->
    from Akka Http Quickstart Java

    @Override
      public Receive createReceive(){
        return receiveBuilder()
                .match(UserRegistryMessages.GetUsers.class, getUsers -> getSender().tell(new Users(users),getSelf()))
                .match(UserRegistryMessages.CreateUser.class, createUser -> {
                  users.add(createUser.getUser());
                  getSender().tell(new UserRegistryMessages.ActionPerformed(
                          String.format("User %s created.", createUser.getUser().getName())),getSelf());
                })
                .match(UserRegistryMessages.GetUser.class, getUser -> {
                  getSender().tell(users.stream()
                          .filter(user -> user.getName().equals(getUser.getName()))
                          .findFirst(), getSelf());
                })
                .match(UserRegistryMessages.DeleteUser.class, deleteUser -> {
                  users.removeIf(user -> user.getName().equals(deleteUser.getName()));
                  getSender().tell(new UserRegistryMessages.ActionPerformed(String.format("User %s deleted.", deleteUser.getName())),
                          getSelf());
    
                }).matchAny(o -> log.info("received unknown message"))
                .build();
      }
    }
    


    // Functions

    Function<String, Integer> toInteger = Integer::valueOf;
    Function<String, String> backToString = toInteger.andThen(String::valueOf);

    backToString.apply("123"); // "123"


    // Suppliers

    Supplier<Person> personSupplier = Person::new;
    personSupplier.get(); // new Person


    // Consumers

    Consumer<Person> greeter = (p) -> System.out.println("Hello, " + p.firstName);
    greeter.accept(new Person("Luke", "Skywalker"));




    LocalTime comes with various factory methods to simplify the creation of new instances, including parsing of time strings.

    LocalTime late = LocalTime.of(23, 59, 59);
    System.out.println(late); // 23:59:59

    DateTimeFormatter germanFormatter =
    DateTimeFormatter
    .ofLocalizedTime(FormatStyle.SHORT)
    .withLocale(Locale.GERMAN);

    LocalTime leetTime = LocalTime.parse("13:37", germanFormatter);
    System.out.println(leetTime); // 13:37


    /***
    * Excerpted from "Functional Programming in Java",
    * published by The Pragmatic Bookshelf.
    * Copyrights apply to this code. It may not be used to create training material,
    * courses, books, articles, and the like. Contact us if you are in doubt.
    * We make no guarantees that this code is fit for any purpose.
    * Visit http://www.pragmaticprogrammer.com/titles/vsjava8 for more book information.
    ***/

    package fpij;

    public class DefaultMethods {
    public interface Fly {
    default void takeOff() { System.out.println("Fly::takeOff"); }
    default void land() { System.out.println("Fly::land"); }
    default void turn() { System.out.println("Fly::turn"); }
    default void cruise() { System.out.println("Fly::cruise"); }
    }

    public interface FastFly extends Fly {
    default void takeOff() { System.out.println("FastFly::takeOff"); }
    }

    public interface Sail {
    default void cruise() { System.out.println("Sail::cruise"); }
    default void turn() { System.out.println("Sail::turn"); }
    }

    public class Vehicle {
    public void turn() { System.out.println("Vehicle::turn"); }
    }

    public class SeaPlane extends Vehicle implements FastFly, Sail {
    private int altitude;
    //...
    public void cruise() {
    System.out.print("SeaPlane::cruise currently cruise like: ");
    if(altitude > 0)
    FastFly.super.cruise();
    else
    Sail.super.cruise();
    }
    }

    public void useClasses() {
    SeaPlane seaPlane = new SeaPlane();
    seaPlane.takeOff();
    seaPlane.turn();
    seaPlane.cruise();
    seaPlane.land();
    }

    public static void main(final String[] args) {
    new DefaultMethods().useClasses();
    }
    }
    ----------------OUTPUT-------------------
    FastFly::takeOff
    Vehicle::turn
    SeaPlane::cruise currently cruise like: Sail::cruise
    Fly::land


    import java.util.List;
    import java.util.stream.Stream;
    import java.io.File;
    import java.io.IOException;

    public class HandleException {
    public static void main(String[] args) throws IOException {
    Stream.of("/usr", "/tmp")
    .map(path -> {
    try {
    return new File(path).getCanonicalPath();
    } catch(IOException ex) {
    return ex.getMessage();
    }
    })
    .forEach(System.out::println);
    }
    }
    ----------------OUTPUT-------------------
    /usr
    /private/tmp


    package fpij;

    public class Mailer {
    public void from(final String address) { /*... */ }
    public void to(final String address) { /*... */ }
    public void subject(final String line) { /*... */ }
    public void body(final String message) { /*... */ }
    public void send() { System.out.println("sending..."); }

    //...
    public static void main(final String[] args) {
    Mailer mailer = new Mailer();
    mailer.from("build@agiledeveloper.com");
    mailer.to("venkats@agiledeveloper.com");
    mailer.subject("build notification");
    mailer.body("...your code sucks...");
    mailer.send();
    }
    }
    ----------------OUTPUT-------------------
    sending...


    package fpij;

    public class MailBuilder {
    public MailBuilder from(final String address) { /*... */; return this; }
    public MailBuilder to(final String address) { /*... */; return this; }
    public MailBuilder subject(final String line) { /*... */; return this; }
    public MailBuilder body(final String message) { /*... */; return this; }
    public void send() { System.out.println("sending..."); }

    //...
    public static void main(final String[] args) {
    new MailBuilder()
    .from("build@agiledeveloper.com")
    .to("venkats@agiledeveloper.com")
    .subject("build notification")
    .body("...it sucks less...")
    .send();
    }
    }
    ----------------OUTPUT-------------------
    sending...


    package fpij;

    import java.util.function.Consumer;

    public class FluentMailer {
    private FluentMailer() {}

    public FluentMailer from(final String address) { /*... */; return this; }
    public FluentMailer to(final String address) { /*... */; return this; }
    public FluentMailer subject(final String line) { /*... */; return this; }
    public FluentMailer body(final String message) { /*... */; return this; }

    public static void send(final Consumer<FluentMailer> block) {
    final FluentMailer mailer = new FluentMailer();
    block.accept(mailer);
    System.out.println("sending...");
    }

    //...
    public static void main(final String[] args) {
    FluentMailer.send(mailer ->
    mailer.from("build@agiledeveloper.com")
    .to("venkats@agiledeveloper.com")
    .subject("build notification")
    .body("...much better..."));
    }
    }
    ----------------OUTPUT-------------------
    sending...


    package fpij;

    import java.util.stream.Stream;
    import java.util.function.Function;
    import java.awt.Color;
    import java.util.function.Consumer;

    @SuppressWarnings("unchecked")
    public class Camera {
    private Function<Color, Color> filter;

    public Color capture(final Color inputColor) {
    final Color processedColor = filter.apply(inputColor);
    //... more processing of color...
    return processedColor;
    }

    //... other functions that use the filter ...

    public void setFilters(final Function<Color, Color>... filters) {
    filter =
    Stream.of(filters)
    .reduce((filter, next) -> filter.compose(next))
    .orElse(color -> color)
    ;
    }
    public Camera() { setFilters(); }

    public static void main(final String[] args) {
    final Camera camera = new Camera();
    final Consumer<String> printCaptured = (filterInfo) ->
    System.out.println(String.format("with %s: %s", filterInfo,
    camera.capture(new Color(200, 100, 200))));

    System.out.println("//" + "START:NOFILTER_OUTPUT");
    printCaptured.accept("no filter");
    System.out.println("//" + "END:NOFILTER_OUTPUT");

    System.out.println("//" + "START:BRIGHT_OUTPUT");
    camera.setFilters(Color::brighter);
    printCaptured.accept("brighter filter");
    System.out.println("//" + "END:BRIGHT_OUTPUT");

    System.out.println("//" + "START:DARK_OUTPUT");
    camera.setFilters(Color::darker);
    printCaptured.accept("darker filter");
    System.out.println("//" + "END:DARK_OUTPUT");

    System.out.println("//" + "START:BOTH_OUTPUT");
    camera.setFilters(Color::brighter, Color::darker);
    printCaptured.accept("brighter & darker filter");
    System.out.println("//" + "END:BOTH_OUTPUT");
    }

    }
    ----------------OUTPUT-------------------
    with no filter: java.awt.Color[r=200,g=100,b=200]
    with brighter filter: java.awt.Color[r=255,g=142,b=255]
    with darker filter: java.awt.Color[r=140,g=70,b=140]
    with brighter & darker filter: java.awt.Color[r=200,g=100,b=200]


    package fpij;

    import java.util.stream.Stream;
    import java.util.function.Function;
    import java.awt.Color;
    import java.util.function.Consumer;

    @SuppressWarnings("unchecked")
    public class Camera2 {
    private Function<Color, Color> filter;

    public Color capture(final Color inputColor) {
    final Color processedColor = filter.apply(inputColor);
    //... more processing of color...
    return processedColor;
    }

    //... other functions that use the filter ...

    public void setFilters(final Function<Color, Color>... filters) {
    filter =
    Stream.of(filters)
    .reduce((filter, next) -> filter.compose(next))
    .orElseGet(Function::identity)
    ;
    }

    public Camera2() { setFilters(); }

    public static void main(final String[] args) {
    final Camera2 camera = new Camera2();
    final Consumer<String> printCaptured = (filterInfo) ->
    System.out.println(String.format("with %s: %s", filterInfo,
    camera.capture(new Color(200, 100, 200))));

    System.out.println("//" + "START:NOFILTER_OUTPUT");
    printCaptured.accept("no filter");
    System.out.println("//" + "END:NOFILTER_OUTPUT");

    System.out.println("//" + "START:BRIGHT_OUTPUT");
    camera.setFilters(Color::brighter);
    printCaptured.accept("brighter filter");
    System.out.println("//" + "END:BRIGHT_OUTPUT");

    System.out.println("//" + "START:DARK_OUTPUT");
    camera.setFilters(Color::darker);
    printCaptured.accept("darker filter");
    System.out.println("//" + "END:DARK_OUTPUT");

    System.out.println("//" + "START:BOTH_OUTPUT");
    camera.setFilters(Color::brighter, Color::darker);
    printCaptured.accept("brighter & darker filter");
    System.out.println("//" + "END:BOTH_OUTPUT");
    }

    }
    ----------------OUTPUT-------------------
    with no filter: java.awt.Color[r=200,g=100,b=200]
    with brighter filter: java.awt.Color[r=255,g=142,b=255]
    with darker filter: java.awt.Color[r=140,g=70,b=140]
    with brighter & darker filter: java.awt.Color[r=200,g=100,b=200]


    package fpij;

    import java.io.File;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.io.IOException;

    public class ListSelectFiles {
    public static void main(String[] args) throws IOException {

    {
    final String[] files =
    new File("fpij").list(new java.io.FilenameFilter() {
    public boolean accept(final File dir, final String name) {
    return name.endsWith(".java");
    }
    });
    /*
    System.out.println(files);
    */
    }

    Files.newDirectoryStream(
    Paths.get("fpij"), path -> path.toString().endsWith(".java"))
    .forEach(System.out::println);
    }
    }
    ----------------OUTPUT-------------------


    import java.io.File;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.stream.Stream;
    import java.util.function.Function;
    import static java.util.stream.Collectors.toList;

    public class ListSubDirs {
    public static void listTheHardWay() {
    List<File> files = new ArrayList<>();

    File[] filesInCurrentDir = new File(".").listFiles();
    for(File file : filesInCurrentDir) {
    File[] filesInSubDir = file.listFiles();
    if(filesInSubDir != null) {
    files.addAll(Arrays.asList(filesInSubDir));
    } else {
    files.add(file);
    }
    }

    System.out.println("Count: " + files.size());
    }

    public static void betterWay() {
    List<File> files =
    Stream.of(new File(".").listFiles())
    .flatMap(file -> file.listFiles() == null ?
    Stream.of(file) : Stream.of(file.listFiles()))
    .collect(toList());
    System.out.println("Count: " + files.size());
    }

    public static void main(String[] args) {
    System.out.println("START:HARDWAY_OUTPUT");
    listTheHardWay();
    System.out.println("END:HARDWAY_OUTPUT");
    betterWay();
    }
    }
    ----------------OUTPUT-------------------
    START:HARDWAY_OUTPUT
    Count: 32
    END:HARDWAY_OUTPUT
    Count: 32


    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.stream.Collectors;
    import java.util.Map;
    import java.util.Optional;
    import java.util.function.BinaryOperator;
    import static java.util.stream.Collectors.*;

    public class OlderThan20 {
    public static void main(String[] args) {
    final List<Person> people = Arrays.asList(
    new Person("John", 20),
    new Person("Sara", 21),
    new Person("Jane", 21),
    new Person("Greg", 35));

    {
    System.out.println("//" + "START:MUTABLE_OUTPUT");
    List<Person> olderThan20 = new ArrayList<>();
    people.stream()
    .filter(person -> person.getAge() > 20)
    .forEach(person -> olderThan20.add(person));
    System.out.println("People older than 20: " + olderThan20);
    System.out.println("//" + "END:MUTABLE_OUTPUT");
    }

    {
    System.out.println("//" + "START:COLLECT_OUTPUT");
    List<Person> olderThan20 =
    people.stream()
    .filter(person -> person.getAge() > 20)
    .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    System.out.println("People older than 20: " + olderThan20);
    System.out.println("//" + "END:COLLECT_OUTPUT");
    }

    {
    System.out.println("//" + "START:COLLECT_TO_LIST_OUTPUT");
    List<Person> olderThan20 =
    people.stream()
    .filter(person -> person.getAge() > 20)
    .collect(Collectors.toList());
    System.out.println("People older than 20: " + olderThan20);
    System.out.println("//" + "END:COLLECT_TO_LIST_OUTPUT");
    }

    {
    System.out.println("//" + "START:GROUP_BY_OUTPUT");
    Map<Integer, List<Person>> peopleByAge =
    people.stream()
    .collect(Collectors.groupingBy(Person::getAge));
    System.out.println("Grouped by age: " + peopleByAge);
    System.out.println("//" + "END:GROUP_BY_OUTPUT");
    }

    {
    System.out.println("//" + "START:GROUP_BY_AGE_NAME_OUTPUT");
    Map<Integer, List<String>> nameOfPeopleByAge =
    people.stream()
    .collect(
    groupingBy(Person::getAge, mapping(Person::getName, toList())));
    System.out.println("People grouped by age: " + nameOfPeopleByAge);
    System.out.println("//" + "END:GROUP_BY_AGE_NAME_OUTPUT");
    }

    {
    System.out.println("//" + "START:OLDEST_IN_EACH_LETTER_OUTPUT");
    Comparator<Person> byAge = Comparator.comparing(Person::getAge);
    Map<Character, Optional<Person>> oldestPersonOfEachLetter =
    people.stream()
    .collect(groupingBy(person -> person.getName().charAt(0),
    reducing(BinaryOperator.maxBy(byAge))));
    System.out.println("Oldest person of each letter:");
    System.out.println(oldestPersonOfEachLetter);
    System.out.println("//" + "END:OLDEST_IN_EACH_LETTER_OUTPUT");
    }
    }
    }
    ----------------OUTPUT-------------------
    People older than 20: [Sara - 21, Jane - 21, Greg - 35]
    People older than 20: [Sara - 21, Jane - 21, Greg - 35]
    People older than 20: [Sara - 21, Jane - 21, Greg - 35]
    Grouped by age: {35=[Greg - 35], 20=[John - 20], 21=[Sara - 21, Jane - 21]}
    People grouped by age: {35=[Greg], 20=[John], 21=[Sara, Jane]}
    Oldest person of each letter:
    {S=Optional[Sara - 21], G=Optional[Greg - 35], J=Optional[Jane - 21]}


    import java.io.File;
    import java.util.Arrays;

    public class ListHiddenFiles {
    public static void main(String[] args) {

    final File[] files = new File(".").listFiles(file -> file.isHidden());

    new File(".").listFiles(File::isHidden);

    Arrays.stream(files).forEach(System.out::println);
    }
    }


    import java.util.List;
    import java.util.Arrays;
    import java.util.stream.Stream;

    public class LazyStreams {
    private static int length(final String name) {
    System.out.println("getting length for " + name);
    return name.length();
    }
    private static String toUpper(final String name ) {
    System.out.println("converting to uppercase: " + name);
    return name.toUpperCase();
    }
    //...

    public static void main(final String[] args) {
    List<String> names = Arrays.asList("Brad", "Kate", "Kim", "Jack", "Joe",
    "Mike", "Susan", "George", "Robert", "Julia", "Parker", "Benson");
    System.out.println("//" + "START:CHAIN_OUTPUT");
    {

    final String firstNameWith3Letters =
    names.stream()
    .filter(name -> length(name) == 3)
    .map(name -> toUpper(name))
    .findFirst()
    .get();

    System.out.println(firstNameWith3Letters);
    }
    System.out.println("//" + "END:CHAIN_OUTPUT");

    System.out.println("//" + "START:SPLIT_OUTPUT");
    {
    Stream<String> namesWith3Letters =
    names.stream()
    .filter(name -> length(name) == 3)
    .map(name -> toUpper(name));

    System.out.println("Stream created, filtered, mapped...");
    System.out.println("ready to call findFirst...");

    final String firstNameWith3Letters =
    namesWith3Letters.findFirst()
    .get();

    System.out.println(firstNameWith3Letters);
    }
    System.out.println("//" + "END:SPLIT_OUTPUT");


    }

    }
    ----------------OUTPUT-------------------
    getting length for Brad
    getting length for Kate
    getting length for Kim
    converting to uppercase: Kim
    KIM
    Stream created, filtered, mapped...
    ready to call findFirst...
    getting length for Brad
    getting length for Kate
    getting length for Kim
    converting to uppercase: Kim
    KIM


    package fpij;

    public class Heavy {
    public Heavy() { System.out.println("Heavy created"); }

    public String toString() { return "quite heavy"; }
    }

    public class HolderNaive {
    private Heavy heavy;

    public HolderNaive() {
    System.out.println("Holder created");
    }

    public Heavy getHeavy() {
    if(heavy == null) {
    heavy = new Heavy();
    }

    return heavy;
    }

    //...

    public static void main(final String[] args) {
    final HolderNaive holder = new HolderNaive();
    System.out.println("deferring heavy creation...");
    System.out.println(holder.getHeavy());
    System.out.println(holder.getHeavy());
    }
    }
    ----------------OUTPUT-------------------
    Holder created
    deferring heavy creation...
    Heavy created
    quite heavy
    quite heavy


    package fpij;

    import java.util.function.Supplier;

    public class Holder {
    private Supplier<Heavy> heavy = () -> createAndCacheHeavy();

    public Holder() {
    System.out.println("Holder created");
    }

    public Heavy getHeavy() {
    return heavy.get();
    }
    //...

    private synchronized Heavy createAndCacheHeavy() {
    class HeavyFactory implements Supplier<Heavy> {
    private final Heavy heavyInstance = new Heavy();

    public Heavy get() { return heavyInstance; }
    }

    if(!HeavyFactory.class.isInstance(heavy)) {
    heavy = new HeavyFactory();
    }

    return heavy.get();
    }

    public static void main(final String[] args) {
    final Holder holder = new Holder();
    System.out.println("deferring heavy creation...");
    System.out.println(holder.getHeavy());
    System.out.println(holder.getHeavy());
    }
    }

    ----------------OUTPUT-------------------
    Holder created
    deferring heavy creation...
    Heavy created
    quite heavy
    quite heavy



    package fpij;

    import java.util.function.Supplier;

    public class Evaluation {
    public static boolean evaluate(final int value) {
    System.out.println("evaluating ..." + value);
    simulateTimeConsumingOp(2000);
    return value > 100;
    }
    //...

    public static void simulateTimeConsumingOp(final int millseconds) {
    try {
    Thread.sleep(2000);
    } catch(Exception ex) { throw new RuntimeException(ex); }
    }

    public static void eagerEvaluator(
    final boolean input1, final boolean input2) {
    System.out.println("eagerEvaluator called...");
    System.out.println("accept?: " + (input1 && input2));
    }

    public static void lazyEvaluator(
    final Supplier<Boolean> input1, final Supplier<Boolean> input2) {
    System.out.println("lazyEvaluator called...");
    System.out.println("accept?: " + (input1.get() && input2.get()));
    }

    public static void main(final String[] args) {

    System.out.println("//" + "START:EAGER_OUTPUT");
    eagerEvaluator(evaluate(1), evaluate(2));
    System.out.println("//" + "END:EAGER_OUTPUT");

    System.out.println("//" + "START:LAZY_OUTPUT");
    lazyEvaluator(() -> evaluate(1), () -> evaluate(2));
    System.out.println("//" + "END:LAZY_OUTPUT");
    }
    }
    ----------------OUTPUT-------------------
    evaluating ...1
    evaluating ...2
    eagerEvaluator called...
    accept?: false
    lazyEvaluator called...
    evaluating ...1
    accept?: false


    import java.util.List;
    import java.util.Arrays;
    import java.util.function.Function;
    import static fpij.Memoizer.callMemoized;

    public class RodCutterBasic {
    final List<Integer> prices;
    public RodCutterBasic(final List<Integer> pricesForLength) {
    prices = pricesForLength;
    }

    //...

    public int maxProfit(final int length) {
    int profit = (length <= prices.size()) ? prices.get(length - 1) : 0;
    for(int i = 1; i < length; i++) {
    int priceWhenCut = maxProfit(i) + maxProfit(length - i);
    if(profit < priceWhenCut) profit = priceWhenCut;
    }

    return profit;
    }

    static
    final List<Integer> priceValues =
    Arrays.asList(2, 1, 1, 2, 2, 2, 1, 8, 9, 15);


    public static void run(final RodCutterBasic rodCutter) {

    System.out.println(rodCutter.maxProfit(5));
    System.out.println(rodCutter.maxProfit(22));
    }

    public static void main(final String[] args) {
    final RodCutterBasic rodCutter = new RodCutterBasic(priceValues);
    run(rodCutter);
    }
    }
    ----------------OUTPUT-------------------
    10
    44


    package fpij;

    import java.util.List;
    import java.util.Arrays;
    import java.util.function.BiFunction;
    import java.util.function.Function;
    import static fpij.Memoizer.callMemoized;

    public class RodCutterMemoized extends RodCutterBasic {
    public RodCutterMemoized(final List<Integer> pricesForLength) {
    super(pricesForLength);
    }

    public int maxProfit(final int rodLength) {
    BiFunction<Function<Integer, Integer>, Integer, Integer> compute =
    (func, length) -> {
    int profit = (length <= prices.size()) ? prices.get(length - 1) : 0;
    for(int i = 1; i < length; i++) {
    int priceWhenCut = func.apply(i) + func.apply(length - i);
    if(profit < priceWhenCut) profit = priceWhenCut;
    }
    return profit;
    };
    return callMemoized(compute, rodLength);
    }

    public static void main(final String[] args) {
    final RodCutterMemoized rodCutterMomoized
    = new RodCutterMemoized(RodCutterBasic.priceValues);
    //run(foo);

    System.out.println(rodCutterMomoized.maxProfit(5));
    System.out.println(rodCutterMomoized.maxProfit(22));
    }
    }
    public class Memoizer {
    public static <T, R> R callMemoized(
    final BiFunction<Function>T,R <, T, R< function, final T input) {
    Function<T, R> memoized = new Function<T, R>() {
    private final Map<T, R> store = new HashMap<>();
    public R apply(final T input) {
    return store.computeIfAbsent(input, key -> function.apply(this, key));
    }
    };
    return memoized.apply(input);

    }
    }
    ----------------OUTPUT-------------------
    10
    44



    import java.util.stream.Stream;

    @FunctionalInterface
    public interface TailCall<T> {

    TailCall<T> apply();

    default boolean isComplete() { return false; }
    //...

    default T result() { throw new Error("not implemented"); }

    default T invoke() {
    return Stream.iterate(this, TailCall::apply)
    .filter(TailCall::isComplete)
    .findFirst()
    .get()
    .result();
    }
    }
    public class TailCalls {
    public static <T> TailCall<T> call(final TailCall<T> nextCall) {
    return nextCall;
    }
    public static <T> TailCall<T> done(final T value) {
    return new TailCall<T>() {
    @Override public boolean isComplete() { return true; }
    @Override public T result() { return value; }
    @Override public TailCall<T> apply() {
    throw new Error("not implemented");
    }
    };
    }
    }



    import java.util.function.Function;
    import static fpij.TailCalls.done;
    import static fpij.TailCalls.call
    ;

    public class Factorial {
    public static int factorialRec(final int number) {
    if(number == 1)
    return number;
    else
    return number * factorialRec(number - 1);
    }

    public static TailCall<Integer> factorialTailRec(
    final int factorial, final int number) {
    if (number == 1)
    return done(factorial);
    else
    return call(() -> factorialTailRec(factorial * number, number - 1));
    }

    public static int factorial(final int number) {
    return factorialTailRec(1, number).invoke();
    }

    public static void main(final String[] args) {
    System.out.println("//" + "START:FACTREC_DISPLAY_5_OUTPUT");
    System.out.println(factorialRec(5));
    System.out.println("//" + "END:FACTREC_DISPLAY_5_OUTPUT");

    System.out.println("//" + "START:FACTREC_DISPLAY_LARGE_OUTPUT");
    try {
    System.out.println(factorialRec(20000));
    } catch(StackOverflowError ex) {
    System.out.println(ex);
    }
    System.out.println("//" + "END:FACTREC_DISPLAY_LARGE_OUTPUT");

    System.out.println("//" + "START:FACTTAILREC_DISPLAY_5_OUTPUT");
    System.out.println(factorialTailRec(1, 5).invoke());
    System.out.println("//" + "END:FACTTAILREC_DISPLAY_5_OUTPUT");

    System.out.println("//" + "START:FACTTAILREC_DISPLAY_LARGE_OUTPUT");
    System.out.println(factorialTailRec(1, 20000).invoke());
    System.out.println("//" + "END:FACTTAILREC_DISPLAY_LARGE_OUTPUT");


    System.out.println("//" + "START:FACTORIAL_DISPLAY_OUTPUT");
    System.out.println(factorial(5));
    System.out.println(factorial(20000));
    System.out.println("//" + "END:FACTORIAL_DISPLAY_OUTPUT");

    }
    }
    ----------------OUTPUT-------------------
    120
    java.lang.StackOverflowError
    120
    0
    120
    0



    import java.math.BigInteger;
    import java.util.function.Function;
    import static fpij.TailCalls.call;
    import static fpij.TailCalls.done;

    public class BigFactorial {
    public static BigInteger decrement(final BigInteger number) {
    return number.subtract(BigInteger.ONE);
    }

    public static BigInteger multiply(
    final BigInteger first, final BigInteger second) {
    return first.multiply(second);
    }

    final static BigInteger ONE = BigInteger.ONE;
    final static BigInteger FIVE = new BigInteger("5");
    final static BigInteger TWENTYK = new BigInteger("20000");

    //...

    private static TailCall<BigInteger> factorialTailRec(
    final BigInteger factorial, final BigInteger number) {
    if(number.equals(BigInteger.ONE))
    return done(factorial);
    else
    return call(() ->
    factorialTailRec(multiply(factorial, number), decrement(number)));
    }

    public static BigInteger factorial(final BigInteger number) {
    return factorialTailRec(BigInteger.ONE, number).invoke();
    }

    public static void main(final String[] args) {
    System.out.println(factorial(FIVE));
    System.out.println(String.format("%.10s...", factorial(TWENTYK)));
    }
    }
    ----------------OUTPUT-------------------
    120
    1819206320...


    import java.util.concurrent.locks.Lock;

    public class Locker {
    public static void runLocked(Lock lock, Runnable block) {
    lock.lock();

    try {
    block.run();
    } finally {
    lock.unlock();
    }
    }
    }
    ------------
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    import static fpij.Locker.runLocked;

    public class Locking {
    Lock lock = new ReentrantLock(); //or mock

    protected void setLock(final Lock mock) {
    lock = mock;
    }

    public void doOp1() {
    lock.lock();
    try {
    //...critical code...
    } finally {
    lock.unlock();
    }
    }
    //...

    public void doOp2() {
    runLocked(lock, () -> {/*...critical code ... */});
    }


    public void doOp3() {
    runLocked(lock, () -> {/*...critical code ... */});
    }

    public void doOp4() {
    runLocked(lock, () -> {/*...critical code ... */});
    }

    }




    Feb 21 reading on Arrows

    haskell - What is indexed monad? - Stack Overflow
    language agnostic - Monads vs. Arrows - Stack Overflow
    haskell - What are arrows, and how can I use them? - Stack Overflow
    Understanding Arrows in Haskell - Stack Overflow
    Haskell: Am I misunderstanding how Arrows may be used? - Stack Overflow
    Hope you know Python
    tru = lambda x,y: x
    fls = lambda x,y: y
    test = lambda l,m,n: l(m,n)
    Usage:
    >>> test(tru,"goto loop","break")
    'goto loop'
    >>> test(fls,"goto loop","break")
    'break'
    test evaluates to the second argument if the first argument is true, otherwise the third.
    >>> x = tru
    >>> test(x,"goto loop","break")
    'goto loop'
    Entire systems can be built up from a few basic combinators.
    (This example is more or less copied out of Types and Programming Languages by Benjamin C. Pierce)

    mloskot>>Shortly, Y combinator is a higher order function that is used to implement recursion on lambda expressions (anonymous functions). Check the
    article How to Succeed at Recursion Without Really Recursing by Mike Vanier - it's one of best practical explanation of this matter I've seen.
    Also, scan the SO archives:
    What is a y-combinator?
    Y-Combinator Practical Example

    Reginald Braithwaite (aka Raganwald) has been writing a great series on combinators in Ruby over at his new blog, homoiconic.
    While he doesn't (to my knowledge) look at the Y-combinator itself, he does look at other combinators, for instance:
    the Kestrel
    the Thrush
    the Cardinal
    the Obdurate Kestrel
    other Quirky Birds
    and a few posts on how you can use them.

    rosetta: The Y combinator is itself a stateless function that, when applied to another stateless function, returns a recursive version of the function. The Y combinator is the simplest of the class of such functions, called fixed-point combinators.

    Norman Ramsey> The fixed-point (Y) combinator does have practical applications, but it takes a very imaginative mind to find them. Like Bruce McAdam. Here's the abstract from his paper That About Wraps it Up.

    BenMorel>You could check out this nifty post on implementing the Y Combinator in C#: Recursive Lambda Expressions, it might help you understand the idea better. As Nathan says, many functional techniques are related to the Y combinator and are useful, so keep at it!

    >>starblue answered May 15 '09 at 17:14
    Sometimes it would be nice to have this combinator under program control, to do similar things as aspect oriented programming (memoizing, tracing, ...), but no programming language I know of allows it. Probably it would be too cumbersome most of the time and/or too hard to learn.

    Nathan Shively-Sanders>> Understanding the Y combinator will help you understand continuations, lazy evaluation, etc.

    Michael Myers>>For the full explanation of how Y does the magic, checked out the linked article



    Working Y-Comb adapted from Rosetta Code

    import java.util.*;
    import java.util.function.*;


    public class Main{

     public static void main(String... arguments) {

     Supplier compl = (() -> {
     System.out.println("in Supplier complete...");
     return Optional.of(3);
     });
     
     Function inProcess = ( num -> {
     System.out.println("...processing # " + ((int)num.get()));
     return Optional.of(((int)num.get()) + 1);
     });

     Function threeTries = YCombinator.Y(f -> n ->
     ( ((int) n.get()) == 3 )
     ? compl.get()
      : f.apply( inProcess.apply(n) )
     );
     
     System.out.println("running threeTries...");
     threeTries.apply(Optional.of(0));
     System.out.println("...done...");
     }
    public interface YCombinator {
     interface RecursiveFunction extends Function, F> { }
     public static  Function Y(Function, Function> f) {
     RecursiveFunction> r = w -> f.apply(x -> w.apply(w).apply(x));
     return r.apply(r);
     }
    }

    }

    Kliesli arrows
    Working with Arrows in Scala (Also has 2 prior links to Kleisli arrs; VERY CLEAR)
    Paper: Generalising Monads to Arrows (John Hughes)
    Bottom line; can use plain Monads instd.; esp.ly for our particular needs;
    arrows only save a few lines here and there.

    Thoughts on Kleisli Arrows in Java (WIP)
    John McClean: A functional approach to dependency injection in Java
    Palatable lambda: Functional patterns for Javasee also: https://github.com/palatable Kliesli compositon: https://www.slideshare.net/pjschwarz/kleisli-composition ***Implementing catamorphisms in Java
    http://www.functionaljava.org/javadoc/3.2/fj/control/parallel/Callables.html Callable>> arrow(). Provides a transformation from a function to a Callable-valued function that is equivalent to it. The first-class Kleisli arrow for Callables. frege: https://github.com/Frege/frege/blob/master/README.md "Winner of the JavaOne Emerging Languages Bowl 2015, 2016, 2017" frege kiesli arrs: http://www.frege-lang.org/doc/frege/control/arrow/Kleisli.html Different ways to understand a monad - kubuszok.com
    A Basis For Sequential Execution: Monads, Arrows, and More
    Why Do Monads Matter? (cat theory & ref to Kl arr @ bott)
    Programming in the Point-Free Style (Cat theory)
    (Haskell)2016 : Monads and Effects Posted by Bartosz Milewski under Category Theory, Haskell, Monads

    Fn.al Data Validation
    def validateName(str: String): Validated[Name] =
        cond(str.length <= 3, Name(str), List("your name is too lo.."))
    
    def validateAge(i: Int): Validated[Age] =
        cond(i >= 18, Age(i), List("bring your parents!"))
    
    def validateTlf(str: String): Validated[Telephone] =
        cond(str.length == 8, Telephone(str), List("No answer!"))
    

    Because Either is a Monad in Scala we can implement our validation function using the map and flatMap properties provided by the Monad type class:
      def validateUser(name: String, age: Int, tel: String): Validated[User] =
        validateName(name).flatMap(
          n =>
            validateAge(age).flatMap(
              a =>
                validateTlf(tel)
                  .map(t => User(n, a, t))
            )
        )
    

    Using for-comprehensions, which are just syntax sugar for flatMap and map we get very nice syntax for defining a sequence of monadic operations:
    def validateUser(name: String, age: Int, tel: String): Validated[User] =
        for {
          n <- validateName(name)
          a <- validateAge(age)
          t <- validateTlf(tel)
        } yield User(n, a, t)
    
    Using the for-comp.'s in Java? SO consensus is 'use flatMap/map; this is just syntactical sugar'

    new Functional stuff ->
    Dec02 '20 addenda

    https://hackernoon.com/superkleisliisfantasticframeworksareatrocious-a-functional-approach-to-dependency-injection-in-e7bc8c4993fa

    https://medium.com/beingprofessional/think-functional-rethinking-criteria-pattern-with-lambdas-2bac1d77fe7d
    ...
    we have written two separate predicates for two different values of gender. What if the set of possible values of a variable is higher ? We dont want to write a separate predicate for each and every value. This can be fixed by writing a function which takes a value and returns a predicate which compares the value with the actual value of the field. This is known as currying.

    
    Function> genderFilter = 
    gender -> person -> person.getGender().equals(gender);
    
    Then we can generate required predicate for a specific value (gender) according to our need.
    
    persons
            .stream()
            .filter(genderFilter.apply("Male"))
            .collect(Collectors.toList());
    
    also:
    
    Function> chkBegLtr(){
    	return ltr -> ( name -> name.startswith(ltr))
    }
    ... names.stream().filter(chkBegLtr().apply("B")).forEa...
    

    https://medium.com/@johnmcclean/lambdas-are-not-functional-programming-63533ce2eb74
    A Java long read : Is functional programming worth it?
    https://medium.com/@johnmcclean/a-java-long-read-is-functional-programming-worth-it-ca53bfcd0c6a

    Sandi Metz: What Does OO Afford?

    Mark Seemann's ploeh blog (lots of useful stuff)...

    okmij.org

    Tomas Petricek's functional blogs (mostly F#, agents, some theory...


    reddit: Is a purely functional algorithm necessarily less asymptotically efficient than a destructive one?


    Fnl langs better?

    "Better" is obviously subjective but Evan Farrer did his master's thesis on rewriting python programs into Haskell (a purely functional language) and seeing how many bugs it caught. You can read his paper, but the Haskell compiler caught many non-trivial bugs...

    Note comment: ...He found Haskell caught bugs because it had 'powerful' type checking, not because it was a functional language. This answer is misleading.



    Functional References - optics
    Debasish Ghosh, in in the book Functional And Reactive Domain Modeling, defined a compose function that allows us to put together Lenses and reuse code:

    def compose[Outer, Inner, Value](
        outer: Lens[Outer, Inner],
        inner: Lens[Inner, Value]
    ) = Lens[Outer, Value](
      get = outer.get andThen inner.get,
      set = (obj, value) => outer.set(obj, inner.set(outer.get(obj), value))
    )
    

    Java DataTable
    Java DataTable is a lightweight, in-memory table structure written in Java. The implementation is entirely immutable. Modifying any part of the table, adding or removing columns, rows, or individual field values will create and return a new structure, leaving the old one completely untouched. This is quite efficient due to structural sharing.
    Refactoring Java code to FP, a case study
    Why java.util.Optional is broken
    Blending FP with OOP.
    Converting OO to FP? (link to domain-driven-design in F#)
    Practical rules for controlling program effects in an imperative / OOP environment.
    reddir r/functionalprog & java (only checked topmost stuff so far)
    DevWorks functional (Lots)**
    Using Either & foldEither, 2 egsUsing EITHER in Java
    Composite(); forBoth() in Java

    ConversionResult c = new ConversionResult<>(new Composite(), warning1);
    ConversionResult p = new ConversionResult<>(new Piece(), warning2);

    c.forBoth(p, (_c, _p) -> _c.piece = _p);
    //the value contained in c has been composed with the value contained in p
    //c now contai

    ConversionResult c = new ConversionResult<>(new Composite(), warning1);
    //Note that c.generatePiece return an object of type ConversionResult.
    We will assume it returns with warning2.
    ConversionResult a = new ConversionResult<>(new Param(), warning3);

    We did, however, create a convenience function which we call mapBoth,
    which simplifies a common but complex pattern:

    ConversionResult p1 = c.flatMap( _c -> a.map( _a -> _c.generatePiece(_a) ) );

    //p1 contains the result of the generatePiece function call,
    and also contains all three warnings

    ConversionResult p2 = c.mapBoth(a, (_c, _a) -> _c.generatePiece(_a) ) ;

    //p2 is identical to p1, but doesn't need nested function calls

    FOLD


    Of interest to us is the API of Either.fold which I will illustrate
    with a simple example. fold takes two parameters, a leftMapper
    function to transform the left value, if the value is a left type,
    and a rightMapper function to transform the right value, should it
    be a right type. In the example below, we transform an
    Either type to another Either
    by using the fold method and lambda functions as parameters.

    Either doSomething() {
    // dummy method stub
    }

    Either foldResult = doSomething().fold((someString) -> {
    // what to return when the result of doSomething() is a string (on the left)
    return Either.left(someString.length());
    }, (someInteger) -> {
    // what to return when the result of doSomething() is a integer (on the right)
    return Either.right(Integer.toString(someInteger));
    });

    from vavr API


    io.vavr.control
    Interface Either

    superInterfaces -> Iterable, Serializable, Value


    Either represents a value of two possible types. An Either is either a Either.Left or a Either.Right.
    If the given Either is a Right and projected to a Left, the Left operations have no effect on the Right value.
    If the given Either is a Left and projected to a Right, the Right operations have no effect on the Left value.
    If a Left is projected to a Left or a Right is projected to a Right, the operations have an effect.

    Example: A compute() function, which results either in an Integer value
    (in the case of success) or in an error message of type String (in the case of failure).
    By convention the success case is Right and the failure is Left.

    Either value = compute().right().map(i -> i * 2).toEither();


    default R getOrElseGet(Function other)
    Gets the Right value or an alternate value, if the projected Either is a Left.



    default Either bimap(Function leftMapper,
    Function rightMapper)
    Maps either the left or the right side of this disjunction.


    default R getOrElseGet(Function other)
    Gets the Right value or an alternate value, if the projected Either is a Left.

    default U fold(Function leftMapper,
    Function rightMapper)

    Folds either the left or the right side of this disjunction.

    Type Parameters:
    U - type of the folded value

    Parameters:
    leftMapper - maps the left value if this is a Left
    rightMapper - maps the right value if this is a Right

    Returns:
    A value of type U





    Talk 'Future of DSL', creating dsl compiler **
    Talk 'Garden of forking paths'

    Functional Programming in JavaScript, Part 3: Introduction to Functors and Monads

    Using map & flatMap

    Unfolding multiple Optional variables in Java 8
    I have the following problem. Let's say you have 2 Optional variables
    Optional c1 = ...
    Optional c2 = ...
    and a method which needs 2 variables of type Contact
    void match(Contact c1, Contact c2) {...}
    and you need to unwrap both c1 and c2 Optional vars and pass them into the match() method. 
    
    "Is this the most elegant way to do that in Java 8?"
    if (c1.isPresent() && c2.isPresent()) {
        match(c1.get(), c2.get());
    }
    
    A:  Solution you provided in scala is just syntax sugar for using flatMaps internally. You can use flatmaps in Java 8 too (but there are no syntax sugar for it). 
    c1.flatMap(contact1 -> c2.flatMap(contact2 -> match(c1,c2)))
    
    A: It has to be ifPresent since match has return type void, and if match will return f.e. boolean it could be Optional result = c1.flatMap(contact1 -> c2.map(contact2 -> match(contact1 ,contact2)))  klappvisor Apr 6 '16 at 11:35 
    A:  Actually, a better way to do it in scala (and without syntax sugar) is something like c1.zip(c2).map { case (a,b) => match(a,b) }. Does java have zip?  Dima Apr 6 '16 at 13:56 
    
    A:  If you consider the arguments not having values as an exception then you could handle them like:
    try {
        match(c1.orElseThrow(NoVal::new), c2.orElseThrow(NoVal::new));
    } catch (NoVal ex) {
        ...
    }
    If they aren't an exceptional case then I would go with your first option as being more explicit about your intent. In my view it's pretty clear and readable, and easy to change to use orElse if you wish to switch to using defaults if the optionals are empty.
    answered Apr 6 '16 at 11:53 
    sprinter 
    	

    What's the difference between map and flatMap methods in Java 8?
    A: The type signature kinda tells the whole story. 
    map :: Stream T -> (T -> R) -> Stream R, 
    flatMap :: Stream T -> (T -> Stream R) -> Stream R.  Chris Martin Oct 31 '14 at 22:56 
    
    A: @michael That type signature looks like Haskell, not Java. But it's not clear whether the actual Java signature is any more readable: 
     Stream flatMap(Function> mapper).  Stuart Marks Jul 20 '17 at 1:34 
    
    A:  Both map and flatMap can be applied to a Stream and they both return a Stream. The difference is that the map operation produces one output value for each input value, whereas the flatMap operation produces an arbitrary number (zero or more) values for each input value.
    This is reflected in the arguments to each operation.
    The map operation takes a Function, which is called for each value in the input stream and produces one result value, which is sent to the output stream.
    The flatMap operation takes a function that conceptually wants to consume one value and produce an arbitrary number of values. However, in Java, it's cumbersome for a method to return an arbitrary number of values, since methods can return only zero or one value. One could imagine an API where the mapper function for flatMap takes a value and returns an array or a List of values, which are then sent to the output. Given that this is the streams library, a particularly apt way to represent an arbitrary number of return values is for the mapper function itself to return a stream! The values from the stream returned by the mapper are drained from the stream and are passed to the output stream. The "clumps" of values returned by each call to the mapper function are not distinguished at all in the output stream, thus the output is said to have been "flattened."
    Typical use is for the mapper function of flatMap to return Stream.empty() if it wants to send zero values, or something like Stream.of(a, b, c) if it wants to return several values. But of course any stream can be returned.
    
    A:  Try viewing it from a different perspective: it's not a transparent case where you can see the inner workings through, but the whole function itself is transparent, i.e. invisible, to you - while still doing their work and letting you see what you're working with. In this case, "flat" refers to the opposite of "nested", flatmap removes one nesting level by flattening.  Zefiro
    
    A: Flattening comes from turning 2-level structure into single level structure, see Dici's answer for an example stackoverflow.com/a/26684582/6012102  andrzej.szmukala Jan 16 at 11:42 
    
    A: 	Stream.flatMap, as it can be guessed by its name, is the combination of a map and a flat operation. That means that you first apply a function to your elements, and then flatten it. Stream.map only applies a function to the stream without flattening the stream.
    To understand what flattening a stream consists in, consider a structure like [ [1,2,3],[4,5,6],[7,8,9] ] which has "two levels". Flattening this means transforming it in a "one level" structure : [ 1,2,3,4,5,6,7,8,9 ].
    edited May 17 '16 at 21:43  asgs 
    
    A:  I would like to give 2 examples to get a more practical point of view: 
    1st example making usage of map:
    @Test
    public void convertStringToUpperCaseStreams() {
        List collected = Stream.of("a", "b", "hello") // Stream of String 
                .map(String::toUpperCase) // Returns a stream consisting of the results of applying the given function to the elements of this stream.
                .collect(Collectors.toList());
        assertEquals(asList("A", "B", "HELLO"), collected);
    }   
    Nothing special in the first example, a Function is applied to return the String in uppercase.
    Second example making usage of flatMap:
    @Test
    public void testflatMap() throws Exception {
        List together = Stream.of(asList(1, 2), asList(3, 4)) // Stream of List
                .flatMap(List::stream)
                .map(integer -> integer + 1)
                .collect(Collectors.toList());
        assertEquals(asList(2, 3, 4, 5), together);
    }
    In the second example, a Stream of List is passed. It is NOT a Stream of Integer! 
    If a transformation Function has to be used (through map), then first the Stream has to be flattened to something else (a Stream of Integer). 
    If flatMap is removed then the following error is returned: The operator + is undefined for the argument type(s) List, int. 
    It is NOT possible to apply + 1 on a List of Integers!
    edited Jan 12 at 22:42   Jan Nielsen 
    
    A:  The function you pass to stream.map has to return one object. That means each object in the input stream results in exactly one object in the output stream.
    The function you pass to stream.flatMap returns a stream for each object. That means the function can return any number of objects for each input object (including none). The resulting streams are then concatenated to one output stream.
    answered Oct 31 '14 at 22:58 Philipp 
    
    A:  for a Map we have a list of elements and a (function,action) f so :
    [a,b,c] f(x) => [f(a),f(b),f(c)]
    and for the flat map we have a list of elements list and we have a (function,action) f and we want the result to be flattened :
    [[a,b],[c,d,e]] f(x) =>[f(a),f(b),f(c),f(d),f(e)]
    answered Oct 8 '17 at 3:19 Bachiri Taoufiq Abderrahman 
    
    A:  One line answer: flatMap helps to flatten a Collection> into a Collection. In the same way, it will also flatten an Optional> into Optional.  
    
    A:  I have a feeling that most answers here overcomplicate the simple problem. If you already understand how the map works that should be fairly easy to grasp.
    There are cases where we can end up with unwanted nested structures when using map(), the flatMap() method is designed to overcome this by avoiding wrapping.
    
    Examples:
    1
    List> result = Stream.of(Arrays.asList(1), Arrays.asList(2, 3))
      .collect(Collectors.toList());
    We can avoid having nested lists by using flatMap:
    List result = Stream.of(Arrays.asList(1), Arrays.asList(2, 3))
      .flatMap(i -> i.stream())
      .collect(Collectors.toList());
    2
    Optional> result = Optional.of(42)
          .map(id -> findById(id));
    
    Optional result = Optional.of(42)
          .flatMap(id -> findById(id));
    where:
    private Optional findById(Integer id)
    edited Apr 15 at 20:08 
    answered Jul 25 '17 at 17:41 Grzegorz Piwowarek 
    
    A:  Oracle's article on Optional highlights this difference between map and flatmap: 
    String version = computer.map(Computer::getSoundcard)
                      .map(Soundcard::getUSB)
                      .map(USB::getVersion)
                      .orElse("UNKNOWN");
    Unfortunately, this code doesn't compile. Why? The variable computer is of type Optional, so it is perfectly correct to call the map method. However, getSoundcard() returns an object of type Optional. This means the result of the map operation is an object of type Optional>. As a result, the call to getUSB() is invalid because the outermost Optional contains as its value another Optional, which of course doesn't support the getUSB() method.
    With streams, the flatMap method takes a function as an argument, which returns another stream. This function is applied to each element of a stream, which would result in a stream of streams. However, flatMap has the effect of replacing each generated stream by the contents of that stream. In other words, all the separate streams that are generated by the function get amalgamated or "flattened" into one single stream. What we want here is something similar, but we want to "flatten" a two-level Optional into one.
    Optional also supports a flatMap method. Its purpose is to apply the transformation function on the value of an Optional (just like the map operation does) and then flatten the resulting two-level Optional into a single one.
    So, to make our code correct, we need to rewrite it as follows using flatMap:
    String version = computer.flatMap(Computer::getSoundcard)
                       .flatMap(Soundcard::getUSB)
                       .map(USB::getVersion)
                       .orElse("UNKNOWN");
    The first flatMap ensures that an Optional is returned instead of an Optional>, and the second flatMap achieves the same purpose to return an Optional. Note that the third call just needs to be a map() because getVersion() returns a String rather than an Optional object.
    http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
    answered Feb 24 '17 at 19:54 
    Rusty Core 
    
    	

    Using Flatmap/Filter
    Q: I have a Stream of Integer and I would like to find the two numbers whose sum is equals to another number. So I came up with the following solution:
    BiPredicate p = (price1, price2) -> price1.intValue() + price2.intValue() == moneyQty;
    flavoursPrices.filter(p);
    But the filter method does not receive a BiPredicate. Why not? What is an alternative for that?
    
    A: You can still work with Bipredicate. The argument that the filter-method needs is a Predicate, so here is an example of how to use this BiPredicate:
     BiPredicate p = (price1, price2) -> price1.intValue() + price2.intValue() == moneyQty;
    
    flavoursPrices.stream().filter(el->p.test(el.price1,el.price2));
    In this example flavoursPrices must be a List. 
    The lambda that we are using:
    el->p.test(el.price1,el.price2)
    Is replacing the anonymous inner class declaration for creating a new Predicate out of the BiPredicate:
     Predicate arg =new Predicate() {
            @Override
            public boolean test(Element el) {
                return p.test(el.price1,el.price2);
            }
        };
    So to filter the stream, we are creating a new Predicate for every element coming from the stream and than we use this Predicate as argument to use it's test-method. The big advantage of this is, that we don't have to create enormous amounts of Predicates in advance, but we can pass every element in the lambda function and get it's attributes.
    answered Dec 24 '16 at 9:46  Matt 
    
    *********** A:  Because filter does not work that way, it only filters one collection at a time. For your task, you need something like Python's itertools.product; this can be implemented using flatMap. In Scala, this looks as short as:
    prices.flatMap(p1 => 
      prices.flatMap(p2 => 
        if (p1 + p2 == 5) List((p1, p2)) else List()))
    If you want to do it in (native) Java, something like this comes out:
    import java.util.*;
    import java.util.stream.*;
    
    public class Main {
    
        public static void main(String[] args) {
    
            List prices =  Arrays.asList(1,2,3,4,5,6,7,8,9);
    
            List> result = prices.stream().flatMap(p1 ->
                prices.stream().flatMap(p2 ->
                    p1 + p2 == 5 ? Stream.of(Arrays.asList(p1, p2)) : Stream.empty()
                )
            ).collect(Collectors.toList());
    
            System.out.println(result);
    
        }
    }
    ... which prints [[1, 4], [2, 3], [3, 2], [4, 1]]. But I wouldn't use that in reality ;) At least, a tuple class would be nice to have.
    It is worth noting that flatMap one of the most powerful functions there is; almost all stream transformations (filter, map, cartesian product, flatten) can be implemented using it. And rest (like zip) is almost always a fold/reduce (or, rarely, an unfold).
    answered Mar 15 '16 at 21:16  phg 
    
    	

    Using Reduce Q: Given a value foo and a Stream of Consumer void functions, what's the most concise way to apply each function to the value?
    Right now I have
    consumers.forEach(c -> c.accept(foo));
    	
    which isn't terrible, but I suspect there might be some way to turn this inside out and do it with just method references (no explicit lambda). Possibly something with a singleton list and zip()? A: You could reduce your consumers by means of the Consumer.andThen method and then apply the resulting consumer to the foo argument:
    consumers.reduce(Consumer::andThen).ifPresent(c -> c.accept(foo));
    	
    But there's no difference between this approach and yours, and yours' is shorter. answered Nov 28 '17 at 22:07 Federico Peralta Schaffner

    https://stackoverflow.com/questions/tagged/java+currying

    Stuff added Oct 13 -> [[Note: much of Mar12 unread]]
    site:medium.com "functional programming state" -react Object-Oriented Programming The Trillion Dollar Disaster Ilya Suzdalnitski
    clojure: Map, Filter & Reduce
    Kris Jenkins
    https://cstheory.stackexchange.com/questions/4007/how-do-i-choose-a-functional-dictionary-data-structure/4028?r=SearchResults&s=22|9.3553#4028 https://cstheory.stackexchange.com/questions/4126/how-are-imperative-languages-more-different-from-each-other-than-functional-lang/4128?r=SearchResults&s=35|7.6795#4128
    Observable pattern applied in massive record update suggests adding addBulk()/delBulk() to proc multiple recs & trigger only 1 notification.
    Pierre-Yves Saumont's Functional-programming-in-java
    src code-> https://www.manning.com/downloads/1124
    (Ch4: Recursion, corecursion & memoization; 4.1.3: using tail call elimination...)

    Stuff added Mar 12 ->


    THIS ARTICLE BASICALLY ALLOWS LIST RECURSION W/O TailCalls USING FOLD (to calc min/average values in a list) John McClean impl.s Circular programming, a Haskell technique in Java "...Java doesnt support Tail Recursion but, as iteration and recursion are functionally equivalent we will attempt to implement circular programming techniques in Java iteratively."
    Using Fold to eval part lazily & in one pass instd of running algo twice
    We can reference the minimum value lazily, as the first element in the data Tuple as follows (using v1 to access the first element of the Tuple2)
    Eval minimum = Eval.later(()->data.v1); (ie, 1st of Tuple var passed in)
    
    System.out.println(minumum(ListX.of(1,2,3,4,5,6,7).shuffle()));
    //[1,1,1,1,1,1,1]       
    
    public ListX minumum(ListX ints){
         Tuple2>> data[] = new Tuple2[1];
    
         Eval minimum = Eval.later(()->data[0].v1);
    
         data[0] = ints.map(i -> tuple(i, minimum))
                       .foldLeft(tuple(Integer.MAX_VALUE, empty()), 
                                 (a, b) -> a.v1 < b.v1 ? tuple(a.v1, a.v2.plus(minimum)) : tuple(b.v1,  a.v2.plus(minimum))
            );
         return data[0].v2.map(Eval::get);
    }
    
    The above defines a List that lazily refers to the result of an operation on that List.
    The last step is to return the List of mimimums, to do this we can lazily map data, extracting the minimum result from the lazy Eval.
    
    System.out.println(minumum(ListX.of(1,2,3,4,5,6,7).shuffle()));
    //[1,1,1,1,1,1,1]       
    
    public ListX minumum(ListX ints){
         Tuple2>> data[] = new Tuple2[1];
    
         Eval minimum = Eval.later(()->data[0].v1);
    
         data[0] = ints.map(i -> tuple(i, minimum))
                       .foldLeft(tuple(Integer.MAX_VALUE, empty()), 
                                 (a, b) -> a.v1 < b.v1 ? tuple(a.v1, a.v2.plus(minimum)) : tuple(b.v1,  a.v2.plus(minimum))
            );
         return data[0].v2.map(Eval::get);
    }
    

    Standardized Ladder of Functional Programming: Heavily Haskell-biased but many pointers to concepts
    Oleg Kiselyov (Fn.al bigwig) on Zippers

    hackerNews java+functional (2018>)
    Go presents itself as a high-performance language with simple concurency (or Java without the JVM) ...I don't need to know by how much Go lowers development costs because it makes no claims that it does, so I simply assume that it doesn't. That it is faster than Python, easy to learn in a day or two, and that it compiles down to a native executable -- are all trivial to verify. If you want, all of its claims are supported by plentiful data.
    Generic Algoriths, or reducing any problem to a tree/graph algo

    Functional reading from medium->

    https://medium.com/@knoldus/functional-java-how-to-do-pattern-matching-in-java-ca3ca0dfb5fc

    https://medium.com/@pra4mesh/callback-function-in-java-20fa48b27797

    https://medium.com/@naveenkumarmuguda/applicative-functors-for-the-java-programmer-7297b527ee90


    https://medium.com/javarevisited/typeclasses-in-java-5ac37ad2483f
    Type Classes in Java - Why functional programming is still hard in Java

    https://medium.com/@johnmcclean/lambdas-are-not-functional-programming-63533ce2eb74
    https://medium.com/@johnmcclean/a-java-long-read-is-functional-programming-worth-it-ca53bfcd0c6a
    https://medium.com/@johnmcclean/4-flavours-of-java-8-functions-6cafbcf5bb4f
    https://medium.com/@johnmcclean/the-rise-and-rise-of-java-functional-data-structures-63782436f93b
    https://medium.com/@johnmcclean/dysfunctional-programming-in-java-i-laziness-cc9c6981de39
    https://medium.com/@johnmcclean/the-java-functional-and-reactive-weekly-26th-oct-2018-8704c025315b
    https://medium.com/@johnmcclean/dependency-injection-using-the-reader-monad-in-java8-9056d9501c75



    https://medium.com/@rmanavalan/5-ways-to-implement-closures-in-java-8-590790659ac5


    https://medium.com/@alonso.delarte/i-would-reword-it-to-no-one-is-doing-functional-programming-in-java-because-there-are-probably-a-e03188320131
    (also gd other articles, incl: Understanding the generated hash code override in Java, line by line)

    https://medium.com/@taluyev/understanding-the-monad-in-java-ce6975706039

    https://medium.com/@horatiujeflea/functional-java-d5275641fe3d
    https://medium.com/@knoldus/functional-java-lets-understand-the-higher-order-function-1a4d4e4f02af


    Functional Programming With Java: Immutability
    Better data structures with immutable state
    https://medium.com/better-programming/functional-programming-with-java-immutability-8dc748e85f9e

    Think Functional: Rethinking criteria pattern with lambdas
    https://medium.com/@sujitkamthe/think-functional-rethinking-criteria-pattern-with-lambdas-2bac1d77fe7d


    https://medium.com/zappos-engineering/java-8-%CE%BBe-vs-scala-part-i-9dd48a119de2

    https://medium.com/swlh/how-to-solve-hackerrank-challenges-in-functional-paradigm-using-java-8-d7b5a5f78f63

    Stuff added Feb 20 ->
    Trees & tree-traversal
    http://rosettacode.org/wiki/Tree_traversal#Java (Level.Order)

    Processing rose-tree data structures


    https://medium.com/@jxxcarlson/on-outlines-rose-trees-and-zippers-1decab0b139a
    **** (elm)
    ...a zipper is a structure endowed with a set of functions for building a tree,
    navigating it, and transforming it...

    **** in the section 'TableOfContents' article mentions expanding/collapsing outline levels!!!
    ..."a rose tree with a subree that is in focus."
    ... uses elm's diff-merge strategy to handle updates


    https://en.wikipedia.org/wiki/Rose_tree

    http://erichgess.github.io/blog/2015/11/01/zippers-2-building-a-rose-tree-zipper/
    http://erichgess.github.io/blog/2015/08/17/f-number-zippers/ (treeZipper @ bottom of pg)

    https://blog.ploeh.dk/2019/08/05/rose-tree-catamorphism/
    https://cs.stackexchange.com/questions/56081/what-are-the-applications-of-rose-trees

    (javaScr) https://github.com/brucou/functional-rose-tree
    (contains links to libs for manipulating tree structures)
    Uses lens for tree transversal etc.
    pruneWhen...

    https://doisinkidney.com/posts/2018-03-17-rose-trees-breadth-first.html

    Cascading lambdas:

    Function<Integer, Predicate<Integer> > isGreaterThan = (pivot) > {
      Predicate<Integer> isGreaterThanPivot = (candidate) > {
        return candidate > pivot;
      };
      
      return isGreaterThanPivot;
    };
    Becomes->
    Function<Integer, Predicate<Integer> > isGreaterThan = pivot > {
      return candidate > {
        return candidate > pivot;
      };
    };
    Becomes->
    Function<Integer, Predicate<Integer> > isGreaterThan = 
      pivot > candidate > candidate > pivot;
    
    The body of the inner lambda uses both the parameter it receives (candidate) and the parameter from the outer scope. That is, the body of the inner lambda relies on both its parameter and its lexical scope or defining scope.

    treat everything to the right of the first arrow as a black box: a lambda expression returned by the outer lambda expression.


    Type inference VERY IMP FOR "fluent" mapping (@bastaInterference)

    (NOTE THIS IS A CAUSE OF VERY FREQUENT @FakeMonkeyBastaCompiler errs) since the appMaker/codeStealer bastas can't use jdk8 they WANT explicit type declaration. The next time they throw fakeA$$ errs, we can help em behave
    List(less-thanString> result =
      cars.stream()
        .map((Car c) > c.getRegistration())
        .map((String s) > DMVRecords.getOwner(s))
        .map((Person o) > o.getName())
        .map((String s) > s.toUpperCase())
        .collect(toList());(newline)
    
    List( result =
      cars.stream()
        .map(car > car.getRegistration())
        .map(registration > DMVRecords.getOwner(registration))
        .map(owner > owner.getName())
        .map(name > name.toUpperCase())
        .collect(toList());(newline)
    
    the explicit type, now redundant, has quietly disappeared.

    curry using cascadingLambdas

    
    	Function> add = x -> y -> x + y;
    	Function add5 = add.apply(5);
    	System.out.println(add5.apply(2));	//prints 7 and 
    

    compose(f, g) (x) = f(g(x))

        public static  Function compose(Function f, Function g) {
            return x -> f.apply(g.apply(x));
        }
     
        public static void main(String[] args) {
            Function sin_asin = compose(Math::sin, Math::asin);
     
            System.out.println(sin_asin.apply(0.5)); // prints "0.5"
        } 
    

    fold https://en.wikipedia.org/wiki/Fold_(higher-order_function)

            System.out.println(Stream.of(1, 2, 3, 4, 5).reduce(1, (a, b) -> a * b));
    
    (the 1st param to reduce is the identity value ie val for which b returns itself)

    parametric polymorphism: a way to define types or functions that are generic over other types.

    http://rosettacode.org/wiki/Parametric_polymorphism
    public class Tree{
    	private T value;
    	private Tree left;
    	private Tree right;
     
    	public void replaceAll(T value){
    		this.value = value;
    		if (left != null)
    			left.replaceAll(value);
    		if (right != null)
    			right.replaceAll(value);
    	}
    }
    


    Folds in javaScript; theory (incl folding for composition); list-of-lists to struct map & fold in java: https://dzone.com/articles/thinking-functional
    An anamorphism is a function that generates a sequence by repeated application of the function to its previous result.
    These objects are used in functional programming as unfolds.
    Motherload of links (to JAVA RosettaCode pgs) http://rosettacode.org/wiki/Y_combinator
    http://rosettacode.org/wiki/Anonymous_recursion#Java
    http://rosettacode.org/wiki/Ackermann_function#Java

    Scala lnks ->

    Alvin Alexander (cookbook author)
    old 'Tour of Scala' @ scala-lang
    Scala tutorials (offers online book)
    Some articles (well written)
    Medium article (links to others)
    Building a REST service with scala
    Creating a DSL w/ Antler & Scala

    Discussion / notes / options

    Q. Is there a Java development workflow - either using IDE, command line build tool or anything of sorts - that allows for hot code redeploying multiple pieces of code without paying the heavy price of bundling?

    (ans 1: jRebel; commercial http://zeroturnaround.com/jrebel/faq/)

    A. There is a tool called DCEVM (which I've never used) that acts as a patch for the JVM to allow repeated class reloading DURING RUNTIME. (used by https://github.com/HotswapProjects/HotswapAgent)

    A. DCEVM supports enhanced class redefinitions and is available for current JDK7 and JDK8.

    https://github.com/dcevm/dcevm/releases

    http://ssw.jku.at/dcevm/

    HotswapAgent is an free JRebel alternative and supports DCEVM in various Frameworks. http://hotswapagent.org/

    A. I believe your options are to patch the JVM with DCEVM or similar (if similar exists), use the jdb (or an abstraction of it such as what IDEs do) to reload classes from the command line debugger tool, or write up a secondary class loader with a hook that you as the developer/user can access during execution to let it know when to dump it's definitions and grab new ones. The last option giving you the most flexibility, but is not an lighthearted engineering task to do well.

    A. Spring Loaded is a JVM AGENT for reloading class file changes whilst a JVM IS RUNNING. It transforms classes at loadtime to make them amenable to later reloading. Unlike 'hot code replace' which only allows simple changes once a JVM is running (e.g. changes to method bodies), Spring Loaded allows you to add/modify/delete methods/fields/constructors. The annotations on types/methods/fields/constructors can also be modified and it is possible to add/remove/change values in enum types.

    Spring Loaded is usable on any bytecode that may run on a JVM, and is actually the reloading system used in Grails 2.

    Once up and running what effectively happens is that any classes loaded from jar files (dependencies) are not treated as reloadable, whilst anything loaded from .class files on disk is made reloadable. Once loaded the .class file will be watched (once a second) and should a new version appear SpringLoaded will pick it up. Any live instances of that class will immediately see the new form of the object, the instances do not need to be discarded and recreated.

    (mpt: nothing to do with "spring mvc")

    https://github.com/spring-projects/spring-loaded

    A. jdk11 possibly has this covered under JVMTI (a Hotspot update)

    see: http://hg.openjdk.java.net/jdk/jdk11/file/f6c70dedae1a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass028.java

    http://ssw.jku.at/dcevm/

    many openJDK tests are @

    http://hg.openjdk.java.net/jdk/jdk11/file/6d6611346837/test/hotspot/jtreg/serviceability/jvmti/

    There's a new kid on the block, RelProxy (https://github.com/jmarranz/relproxy/), it is open source, is not so advanced like JRebel but it can be used to freely change a subset of your code in runtime and reload it with almost no performance penalty and no need of context reloading (no session lost) in development and production if you want.answered Jan 30 '15

    Post from last yr by someone from jRebel also mentions -- Fakereplace is also an instrumenting agent, like JRebel but it has a lot less support for Java code changes (I assume) and the number of supported frameworks isn't as impressive.

    Feenix can do as much as the Java Instrumentation API allows it to do. Which basically means it doesn't really add value on top of standard HotSwap of the JVM. Same for AgentSmith

    JavaWorld article "Add dynamic Java code to your application

    "Write code that can respond to changes at runtime"

    [[Basically monitors a dir; compiles; uses a Proxy for loading the classLoader & switching to the new classLoader with the newly compiled/updated class. Transparent to the user, no reboot. Only issue: STATE]]

    https://www.javaworld.com/article/2071777/design-patterns/add-dynamic-java-code-to-your-application.html

    Add dynamic Java code to your application

    Write code that can respond to changes at runtime

    By Li Yang

    JavaWorld |

    Jun 12, 2006 1:00 AM PT

    JavaServer Pages (JSP) is a more flexible technology than servlets because it can respond to dynamic changes at runtime. Can you imagine a common Java class that has this dynamic capability too? It would be interesting if you could modify the implementation of a service without redeploying it and update your application on the fly.

    The article explains how to write dynamic Java code. It discusses runtime source code compilation, class reloading, and the use of the Proxy design pattern to make modifications to a dynamic class transparent to its caller.

    An example of dynamic Java code

    Let's start with an example of dynamic Java code that illustrates what true dynamic code means and also provides some context for further discussions. Please find this example's complete source code in Resources.

    The example is a simple Java application that depends on a service called Postman. The Postman service is described as a Java interface and contains only one method, deliverMessage():

    public interface Postman {

    void deliverMessage(String msg);

    }

    A simple implementation of this service prints messages to the console. The implementation class is the dynamic code. This class, PostmanImpl, is just a normal Java class, except it deploys with its source code instead of its compiled binary code:

    public class PostmanImpl implements Postman {

    private PrintStream output;

    public PostmanImpl() {

    output = System.out;

    }

    public void deliverMessage(String msg) {

    output.println("[Postman] " + msg);

    output.flush();

    }

    }

    The application that uses the Postman service appears below. In the main() method, an infinite loop reads string messages from the command line and delivers them through the Postman service:

    public class PostmanApp {

    public static void main(String[] args) throws Exception {

    BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));

    // Obtain a Postman instance

    Postman postman = getPostman();

    while (true) {

    System.out.print("Enter a message: ");

    String msg = sysin.readLine();

    postman.deliverMessage(msg);

    }

    }

    private static Postman getPostman() {

    // Omit for now, will come back later

    }

    }

    Execute the application, enter some messages, and you will see outputs in the console such as the following (you can download the example and run it yourself):

    [DynaCode] Init class sample.PostmanImpl

    Enter a message: hello world

    [Postman] hello world

    Enter a message: what a nice day!

    [Postman] what a nice day!

    Enter a message:

    Everything is straightforward except for the first line, which indicates that the class PostmanImpl is compiled and loaded.

    Now we are ready to see something dynamic. Without stopping the application, let's modify PostmanImpl's source code. The new implementation delivers all the messages to a text file, instead of the console:

    // MODIFIED VERSION

    public class PostmanImpl implements Postman {

    private PrintStream output;

    // Start of modification

    public PostmanImpl() throws IOException {

    output = new PrintStream(new FileOutputStream("msg.txt"));

    }

    // End of modification

    public void deliverMessage(String msg) {

    output.println("[Postman] " + msg);

    output.flush();

    }

    }

    Shift back to the application and enter more messages. What will happen? Yes, the messages go to the text file now. Look at the console:

    [DynaCode] Init class sample.PostmanImpl

    Enter a message: hello world

    [Postman] hello world

    Enter a message: what a nice day!

    [Postman] what a nice day!

    Enter a message: I wanna go to the text file.

    [DynaCode] Init class sample.PostmanImpl

    Enter a message: me too!

    Enter a message:

    Notice [DynaCode] Init class sample.PostmanImpl appears again, indicating that the class PostmanImpl is recompiled and reloaded. If you check the text file msg.txt (under the working directory), you will see the following:

    [Postman] I wanna go to the text file.

    [Postman] me too!

    Amazing, right? We are able to update the Postman service at runtime, and the change is completely transparent to the application. (Notice the application is using the same Postman instance to access both versions of the implementations.)

    Four steps towards dynamic code

    Let me reveal what's going on behind the scenes. Basically, there are four steps to make Java code dynamic:

    • Deploy selected source code and monitor file changes

    • Compile Java code at runtime

    • Load/reload Java class at runtime

    • Link the up-to-date class to its caller

    Deploy selected source code and monitor file changes

    To start writing some dynamic code, the first question we have to answer is, "Which part of the code should be dynamicthe whole application or just some of the classes?" Technically, there are few restrictions. You can load/reload any Java class at runtime. But in most cases, only part of the code needs this level of flexibility.

    The Postman example demonstrates a typical pattern on selecting dynamic classes. No matter how a system is composed, in the end, there will be building blocks such as services, subsystems, and components. These building blocks are relatively independent, and they expose functionalities to each other via predefined interfaces. Behind an interface, it is the implementation that is free to change as long as it conforms to the contract defined by the interface. This is exactly the quality we need for dynamic classes. So simply put: Choose the implementation class to be the dynamic class.

    For the rest of the article, we'll make the following assumptions about the chosen dynamic classes:

    • The chosen dynamic class implements some Java interface to expose functionality

    • The chosen dynamic class's implementation does not hold any stateful information about its client (similar to the stateless session bean), so the instances of the dynamic class can replace each other

    Please note that these assumptions are not prerequisites. They exist just to make the realization of dynamic code a bit easier so we can focus more on the ideas and mechanisms.

    With the selected dynamic classes in mind, deploying the source code is an easy task. Figure 1 shows the file structure of the Postman example.

    PostmanExample

       bin

       dynacode

          sample

             PostmanImpl.java

       src

    We know "src" is source and "bin" is binary. One thing worth noting is the dynacode directory, which holds the source files of dynamic classes. Here in the example, there's only one filePostmanImpl.java. The bin and dynacode directories are required to run the application, while src is not necessary for deployment.

    Detecting file changes can be achieved by comparing modification timestamps and file sizes. For our example, a check to PostmanImpl.java is performed every time a method is invoked on the Postman interface. Alternatively, you may spawn a daemon thread in the background to regularly check the file changes. That may result in better performance for large-scale applications.

    Compile Java code at runtime

    After a source code change is detected, we come to the compilation issue. By delegating the real job to an existing Java compiler, runtime compilation can be a piece of cake. Many Java compilers are available for use, but in this article, we use the Javac compiler included in Sun's Java Platform, Standard Edition (Java SE is Sun's new name for J2SE).

    At the minimum, you can compile a Java file with just one statement, providing that the tools.jar, which contains the Javac compiler, is on the classpath (you can find the tools.jar under /lib/):

    int errorCode = com.sun.tools.javac.Main.compile(new String[] {

    "-classpath", "bin",

    "-d", "/temp/dynacode_classes",

    "dynacode/sample/PostmanImpl.java" });

    The class com.sun.tools.javac.Main is the programming interface of the Javac compiler. It provides static methods to compile Java source files. Executing the above statement has the same effect as running javac from the command line with the same arguments. It compiles the source file dynacode/sample/PostmanImpl.java using the specified classpath bin and outputs its class file to the destination directory /temp/dynacode_classes. An integer returns as the error code. Zero means success; any other number indicates something has gone wrong.

    The com.sun.tools.javac.Main class also provides another compile() method that accepts an additional PrintWriter parameter, as shown in the code below. Detailed error messages will be written to the PrintWriter if compilation fails.

    // Defined in com.sun.tools.javac.Main

    public static int compile(String[] args);

    public static int compile(String[] args, PrintWriter out);

    I assume most developers are familiar with the Javac compiler, so I'll stop here. For more information about how to use the compiler, please refer to Resources.

    Load/reload Java class at runtime

    The compiled class must be loaded before it takes effect. Java is flexible about class loading. It defines a comprehensive class-loading mechanism and provides several implementations of classloaders. (For more information on class loading, see Resources.)

    The sample code below shows how to load and reload a class. The basic idea is to load the dynamic class using our own URLClassLoader. Whenever the source file is changed and recompiled, we discard the old class (for garbage collection later) and create a new URLClassLoader to load the class again.

    // The dir contains the compiled classes.

    File classesDir = new File("/temp/dynacode_classes/");

    // The parent classloader

    ClassLoader parentLoader = Postman.class.getClassLoader();

    // Load class "sample.PostmanImpl" with our own classloader.

    URLClassLoader loader1 = new URLClassLoader(

    new URL[] { classesDir.toURL() }, parentLoader);

    Class cls1 = loader1.loadClass("sample.PostmanImpl");

    Postman postman1 = (Postman) cls1.newInstance();

    /*

    * Invoke on postman1 ...

    * Then PostmanImpl.java is modified and recompiled.

    */

    // Reload class "sample.PostmanImpl" with a new classloader.

    URLClassLoader loader2 = new URLClassLoader(

    new URL[] { classesDir.toURL() }, parentLoader);

    Class cls2 = loader2.loadClass("sample.PostmanImpl");

    Postman postman2 = (Postman) cls2.newInstance();

    /*

    * Work with postman2 from now on ...

    * Don't worry about loader1, cls1, and postman1

    * they will be garbage collected automatically.

    */

    Pay attention to the parentLoader when creating your own classloader. Basically, the rule is that the parent classloader must provide all the dependencies the child classloader requires. So in the sample code, the dynamic class PostmanImpl depends on the interface Postman; that's why we use Postman's classloader as the parent classloader.

    We are still one step away to completing the dynamic code. Recall the example introduced earlier. There, dynamic class reload is transparent to its caller. But in the above sample code, we still have to change the service instance from postman1 to postman2 when the code changes. The fourth and final step will remove the need for this manual change.

    Link the up-to-date class to its caller

    How do you access the up-to-date dynamic class with a static reference? Apparently, a direct (normal) reference to a dynamic class's object will not do the trick. We need something between the client and the dynamic classa proxy. (See the famous book Design Patterns for more on the Proxy pattern.)

    Here, a proxy is a class functioning as a dynamic class's access interface. A client does not invoke the dynamic class directly; the proxy does instead. The proxy then forwards the invocations to the backend dynamic class. Figure 2 shows the collaboration.

    When the dynamic class reloads, we just need to update the link between the proxy and the dynamic class, and the client continues to use the same proxy instance to access the reloaded class. Figure 3 shows the collaboration.

    In this way, changes to the dynamic class become transparent to its caller.

    The Java reflection API includes a handy utility for creating proxies. The class java.lang.reflect.Proxy provides static methods that let you create proxy instances for any Java interface.

    The sample code below creates a proxy for the interface Postman. (If you aren't familiar with java.lang.reflect.Proxy, please take a look at the Javadoc before continuing.)

    InvocationHandler handler = new DynaCodeInvocationHandler(...);

    Postman proxy = (Postman) Proxy.newProxyInstance(

    Postman.class.getClassLoader(),

    new Class[] { Postman.class },

    handler);

    The returned proxy is an object of an anonymous class that shares the same classloader with the Postman interface (the newProxyInstance() method's first parameter) and implements the Postman interface (the second parameter). A method invocation on the proxy instance is dispatched to the handler's invoke() method (the third parameter). And handler's implementation may look like the following:

    public class DynaCodeInvocationHandler implements InvocationHandler {

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    // Get an instance of the up-to-date dynamic class

    Object dynacode = getUpToDateInstance();

    // Forward the invocation

    return method.invoke(dynacode, args);

    }

    }

    The invoke() method obtains an instance of the up-to-date dynamic class and forwards the invocation to it. This may involve source code compilation and class reloading if the dynamic class's source file has been modified.

    Now we have completed the Postman service's dynamic code. A client creates a proxy of the service and calls the method deliverMessage() through the proxy. Each invocation on the proxy is dispatched to the DynaCodeInvocationHandler class's invoke() method. In that method, the latest service implementation is first obtained, which may involve necessary source compilation and class reloading. Then, the invocation forwards to the implementation for real processing.

    Put it all together

    We have gone through all the tricks required for the dynamic Java code. It's time to put them together to build something reusable.

    We can build a utility to ease the adoption of dynamic code by encapsulating the four steps mentioned above. The Postman example relies on such a utility called DynaCode. Remember the PostmanApp application and its omitted getPostman() method? It's time to show it:

    public class PostmanApp {

    public static void main(String[] args) throws Exception {

    // ......

    }

    private static Postman getPostman() {

    DynaCode dynacode = new DynaCode();

    dynacode.addSourceDir(new File("dynacode"));

    return (Postman) dynacode.newProxyInstance(Postman.class,

    "sample.PostmanImpl");

    }

    }

    See how the getPostman() method creates a dynamic Postman service, creates an instance of DynaCode, specifies a source directory, and returns a proxy of some dynamic implementation. To use your own dynamic Java code, you simply need to write three lines of code. Everything else is taken care of inside DynaCode. Try it yourself (the DynaCode's source code is included in the example).

    I won't go into further details of DynaCode, but as a review of the technologies we've talked about, take a look at the sequence diagram in Figure 4 to see how DynaCode works at a high level.

    Conclusion

    In this article, I introduced the idea of dynamic Java code and the steps required to realize it. I covered topics such as runtime source compilation, class reloading, and the Proxy design pattern. Though none of these topics are new, by putting them together, we create an interesting dynamic feature for common Java classes so they can be modified and refreshed at runtime just like JSP pages.

    An example is provided for demonstration purposes in Resources. It includes a reusable utility called DynaCode that makes writing your own dynamic code much easier.

    I'd like to conclude by discussing the values and applications of dynamic code: Dynamic code can respond quickly to on-demand change requests. It can be used to implement truly dynamic services and business rules that change from time to time, and to replace embedded scripts used by task nodes of workflows. Dynamic code also eases application maintenance and greatly reduces outages caused by application redeployments.

    Li Yang joined IBM in April 2004 and is a Certified IBM Rational Consultant on Rational Unified Process, requirements management, and object-oriented analysis and design. He has experience with Java server-side technologies, Web architectures, Java EE projects, and Java SE system library development.

    Resources

    • Download the Postman example (tested with Sun J2SE 1.4.2)

    • http://images.techhive.com/downloads/idge/imported/article/jvw/2006/06/jw-0612-dynamic.zip

      "The Basics of Java Classloaders," Chuck McManis (JavaWorld, October 1996)

      http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html

    An in-memory compiler from openJdk

    /*
     * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     *
     * This code is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License version 2 only, as
     * published by the Free Software Foundation.
     *
     * This code is distributed in the hope that it will be useful, but WITHOUT
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     * version 2 for more details (a copy is included in the LICENSE file that
     * accompanied this code).
     *
     * You should have received a copy of the GNU General Public License version
     * 2 along with this work; if not, write to the Free Software Foundation,
     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     *
     * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     * or visit www.oracle.com if you need additional information or have any
     * questions.
     */
    
    package jdk.test.lib.compiler;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    import java.net.URI;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.tools.ForwardingJavaFileManager;
    import javax.tools.FileObject;
    import javax.tools.JavaCompiler;
    import javax.tools.JavaCompiler.CompilationTask;
    import javax.tools.JavaFileObject;
    import javax.tools.JavaFileObject.Kind;
    import javax.tools.SimpleJavaFileObject;
    import javax.tools.StandardLocation;
    import javax.tools.ToolProvider;
    
    /**
     * {@code InMemoryJavaCompiler} can be used for compiling a {@link
     * CharSequence} to a {@code byte[]}.
     *
     * The compiler will not use the file system at all, instead using a {@link
     * ByteArrayOutputStream} for storing the byte code. For the source code, any
     * kind of {@link CharSequence} can be used, e.g. {@link String}, {@link
     * StringBuffer} or {@link StringBuilder}.
     *
     * The {@code InMemoryCompiler} can easily be used together with a {@code
     * ByteClassLoader} to easily compile and load source code in a {@link String}:
     *
     * 
     * {@code
     * import jdk.test.lib.compiler.InMemoryJavaCompiler;
     * import jdk.test.lib.ByteClassLoader;
     *
     * class Example {
     *     public static void main(String[] args) {
     *         String className = "Foo";
     *         String sourceCode = "public class " + className + " {" +
     *                             "    public void bar() {" +
     *                             "        System.out.println("Hello from bar!");" +
     *                             "    }" +
     *                             "}";
     *         byte[] byteCode = InMemoryJavaCompiler.compile(className, sourceCode);
     *         Class fooClass = ByteClassLoader.load(className, byteCode);
     *     }
     * }
     * }
     * 
     */
    public class InMemoryJavaCompiler {
        private static class MemoryJavaFileObject extends SimpleJavaFileObject {
            private final String className;
            private final CharSequence sourceCode;
            private final ByteArrayOutputStream byteCode;
    
            public MemoryJavaFileObject(String className, CharSequence sourceCode) {
                super(URI.create("string:///" + className.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
                this.className = className;
                this.sourceCode = sourceCode;
                this.byteCode = new ByteArrayOutputStream();
            }
    
            @Override
            public CharSequence getCharContent(boolean ignoreEncodingErrors) {
                return sourceCode;
            }
    
            @Override
            public OutputStream openOutputStream() throws IOException {
                return byteCode;
            }
    
            public byte[] getByteCode() {
                return byteCode.toByteArray();
            }
    
            public String getClassName() {
                return className;
            }
        }
    
        private static class FileManagerWrapper extends ForwardingJavaFileManager {
            private static final Location PATCH_LOCATION = new Location() {
                @Override
                public String getName() {
                    return "patch module location";
                }
    
                @Override
                public boolean isOutputLocation() {
                    return false;
                }
            };
            private final MemoryJavaFileObject file;
            private final String moduleOverride;
    
            public FileManagerWrapper(MemoryJavaFileObject file, String moduleOverride) {
                super(getCompiler().getStandardFileManager(null, null, null));
                this.file = file;
                this.moduleOverride = moduleOverride;
            }
    
            @Override
            public JavaFileObject getJavaFileForOutput(Location location, String className,
                                                       Kind kind, FileObject sibling)
                throws IOException {
                if (!file.getClassName().equals(className)) {
                    throw new IOException("Expected class with name " + file.getClassName() +
                                          ", but got " + className);
                }
                return file;
            }
    
            @Override
            public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
                if (fo == file && moduleOverride != null) {
                    return PATCH_LOCATION;
                }
                return super.getLocationForModule(location, fo);
            }
    
            @Override
            public String inferModuleName(Location location) throws IOException {
                if (location == PATCH_LOCATION) {
                    return moduleOverride;
                }
                return super.inferModuleName(location);
            }
    
            @Override
            public boolean hasLocation(Location location) {
                return super.hasLocation(location) || location == StandardLocation.PATCH_MODULE_PATH;
            }
    
        }
    
        /**
         * Compiles the class with the given name and source code.
         *
         * @param className The name of the class
         * @param sourceCode The source code for the class with name {@code className}
         * @param options additional command line options
         * @throws RuntimeException if the compilation did not succeed
         * @return The resulting byte code from the compilation
         */
        public static byte[] compile(String className, CharSequence sourceCode, String... options) {
            MemoryJavaFileObject file = new MemoryJavaFileObject(className, sourceCode);
            CompilationTask task = getCompilationTask(file, options);
    
            if(!task.call()) {
                throw new RuntimeException("Could not compile " + className + " with source code " + sourceCode);
            }
    
            return file.getByteCode();
        }
    
        private static JavaCompiler getCompiler() {
            return ToolProvider.getSystemJavaCompiler();
        }
    
        private static CompilationTask getCompilationTask(MemoryJavaFileObject file, String... options) {
            List opts = new ArrayList<>();
            String moduleOverride = null;
            for (String opt : options) {
                if (opt.startsWith("--patch-module=")) {
                    moduleOverride = opt.substring("--patch-module=".length());
                } else {
                    opts.add(opt);
                }
            }
            return getCompiler().getTask(null, new FileManagerWrapper(file, moduleOverride), null, opts, null, Arrays.asList(file));
        }
    }
    

    Feb12 2021: CLI-only Document level aspect hooks

    Create queryCreate; postCreate
    Open queryOpen; postOpen
    Edit queryModeChng/postModeChng
    Save querySave; postSave
    Refresh?
    Delete queryDelete; postDelete

    DEV aspect hooks for designEls:
    WITHIN docAspect; dispatch on (desEl.docType) {
    //trigger approp. behavior }

    Db level (?? poss not necc)
    Fetch? Update? or copy all docLvl aspects? + qryConnect/etc.?

    custom Fields

    Basic Field Data-Types

    Text < 250 char
    Text /unlimited

    Boolean
    Date
    TimeStamp

    BinaryData (incl opt for user to attach any file)

    Number Int
    Number Long
    Number - Currency

    Calculated (supply Formulas for user to use)
    (Formula based on existing lookupFld value)

    Lookup (supplied list of vals) -> user can choose UI widgets (chckbox/radio/etc)
    Lookup (Tbl Column vals - restricted - only admin users can edit list)
    (Tbl Column vals - unrestricted - user can add to vals)

    Field required?
    lookup value reqd?

    Formatted text/number (user supplied fmt, eg emailAdd, Postal Add, zipcode, stateLookup)

    pwd (hashed/encrypted vals)

    counter (auto-increment, read-only)


    MongoDB's BSON type


    BSON is a binary serialization format used to store documents and make remote procedure calls in MongoDB.
    The BSON specification is located at bsonspec.org.

    Each BSON type has both integer and string identifiers as listed in the following table:

    Type Number Alias Notes
    Double 1 double
    String 2 string
    Object 3 object
    Array 4 array
    Binary data 5 binData
    Undefined 6 undefined Deprecated.
    ObjectId 7 objectId
    Boolean 8 bool
    Date 9 date
    Null 10 null
    Regular Expression 11 regex
    DBPointer 12 dbPointer Deprecated.
    JavaScript 13 javascript
    Symbol 14 symbol Deprecated.
    JavaScript (with scope) 15 javascriptWithScope
    32-bit integer 16 int
    Timestamp 17 timestamp
    64-bit integer 18 long
    Decimal128 19 decimal New in version 3.4.
    Min key -1 minKey
    Max key 127 maxKey
    You can use these values with the $type operator to query documents by their BSON type.
    The $type aggregation operator returns the type of an operator expression using one of
    the listed BSON type strings.


    StackOverflow Q : Custom Fields for a Form representing an object

    A: I want to answer your question in two parts:
    1) Implementing custom fields in a database server
    2) Restricting custom fields to an enumeration of values

    Although common solutions to 1) are discussed in the question referenced by @Simon, maybe you are looking for a bit of discussion on what the problem is and why it hasn't been solved for us already.

    databases are great for structured, typed data
    custom fields are inherently less structured
    therefore, custom fields are more difficult to work with in a database
    some or many of the advantages of using a database are lost
    some queries may be more difficult or impossible
    type safety may be lost (in the database)
    data integrity may no longer be enforced (by the database)
    it's a lot more work for the implementers and maintainers
    As discussed in the other question, there's no perfect solution.
    But these benefits/features still need to be implemented somewhere, and so often the application becomes responsible for data integrity and type safety.
    For situations like these, people have created Object-Relation Mapping tools, although, as Jeff Atwood says, even using an ORM could create more problems than it solved. However, you mentioned that it 'should be generic and be able to deal with all sorts of problems in the future' -- this makes me think an ORM might be your best bet.

    So, to sum up my answer, this is a known problem with known solutions, none of which are completely satisfactory (because it's so hard). Pick your poison.

    To answer the second part of (what I think is) your question:
    As mentioned in the linked question, you could implement Entity-Attribute-Value in your database for custom fields, and then add an extra table to hold the legal values for each entity. Then, the attribute/value of the EAV table is a foreign key into the attribute-value table.

    For example,

    CREATE TABLE `attribute_value` ( -- enumerations go in this table
    `attribute` varchar(30),
    `value` varchar(30),
    PRIMARY KEY (`attribute`, `value`)
    );

    CREATE TABLE `eav` ( -- now the values of attributes are restricted
    `entityid` int,
    `attribute` varchar(30),
    `value` varchar(30),
    PRIMARY KEY (`entityid`, `attribute`),
    FOREIGN KEY (`attribute`, `value`) REFERENCES `attribute_value`(`attribute`, `value`)
    );
    Of course, this solution isn't perfect or complete -- it's only supposed to illustrate the idea. For instance, it uses varchars, and lacks a type column. Also, who gets to decide what the possible values for each attribute are? Can these be changed at any time by the user?

    shareimprove this answer
    edited May 23 '17 at 9:59

    Community
    11
    answered Sep 23 '11 at 16:40

    Matt Fenwick
    29.9k12101165
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    When you let the users create the data models, I would recommend looking at an document database or 'NoSQL' since you want exactly that, to store schemaless data structures.

    Also, sharePoint stores metadata the way you mentioned (10 columns for text, 5 for dates etc)

    That said, in my current project (locked in SharePoint, so Framework 3.5 + SQL Server and all the constraints that follow) we use a somewhat similar structure as below:

    Form
    Id

    Attribute (or Field)
    Name
    Type (enum) Text, List, Dates, Formulas etc
    Hidden (bool)
    Mandatory
    DefaultValue
    Options (for lists)
    Readonly
    Mask (for SSN etc)
    Length (for text fields)
    Order

    Metadata
    FormId
    AttributeId
    Text (the value for everything but dates)
    Date (the value for dates)
    Our formulas employ functions such as Increment: INC([attribute1][attribute2], 6) and this would produce something like 000999 for the 999th instance of the combined values for attribute 1 and attribute 2 for a form, this is stored as:

    AttributeIncrementFormula
    AtributeId
    Counter
    Token
    Other 'formulas' (aka anything non-trivial) such as barcodes are stored as single metadata values. In the actual implementation, we would have something like this:

    var form = formRepository.GetById(1);
    form.Metadata["firstname"].Value
    Value above is a readonly property that decides whether we should get the value from Text or Date and if some additional transform is required. Note that the database here is merely a storage, we hold all the domain complexity in the application.

    We also let our customer decide which attribute is the form title for example, so if firstname is the form title, they'll set an in-memory param that spans the entire application to be something like Params.InMemory.TitleAttributeId = .

    I hope this gives you some insight on a production impl of a similar scenario.

    shareimprove this answer
    answered Sep 23 '11 at 17:16

    Francisco Aquino
    8,0712036
    add a comment
    up vote
    2
    down vote



    This is really more of a comment than an answer, but I need more space than SO will allow for comments, so here 'tis:

    I think your UserConfiguration table approach is good, and would suggest only abstracting the "type" and "value" pieces of your design a bit more:

    Since your application will need to validate user input, each notion of "type" will have an associated piece of evaluation logic. Obviously the more of this you can abstract into data the easier it will be to keep your code small. Enumerated lists are a good start, but if your "validator" logic can be extended to handle pattern matching for text strings and Boolean logical expressions (e.g. to describe/enforce constraints on input values), then you can express pretty much any "type" of input that your application may need to handle in terms of (relatively) simple "atoms" that you can map naturally to DB tables.
    When storing a user-specified value, you can either store the "raw" data (e.g. in JSON) and a foreign key to the associated "type", or you can add an lookup/cache system that assigns an integer to each new value that is encountered by the system ("novelty" can be checked by checking a hash of the "raw" data, for example). The latter approach obviously scales better if you're expecting lots of data duplication (which of course you would in the case of a multiple-choice menu).
    shareimprove this answer
    answered Sep 26 '11 at 18:11

    Peter
    2,0891827


    Q: What are design patterns to support custom fields in an application?

    We develop a commercial application. Our customers are asking for custom fields support. For instance, they want to add a field to the Customer form.

    What are the known design patterns to store the field values and the meta-data about the fields?

    I see these options for now:

    Option 1: Add Field1, Field2, Field3, Field4 columns of type varchar to my Customer table.

    Option 2: Add a single column of type XML in the customer table and store the custom fields' values in xml.

    Option 3: Add a CustomerCustomFieldValue table with a column of type varchar and store values in that column. That table would also have a CustomerID, a CustomFieldID.

    CustomerID, CustomFieldID, Value
    10001, 1001, '02/12/2009 8:00 AM'
    10001, 1002, '18.26'
    10002, 1001, '01/12/2009 8:00 AM'
    10002, 1002, '50.26'
    CustomFieldID would be an ID from another table called CustomField with these columns: CustomFieldID, FieldName, FieldValueTypeID.

    Option 4: Add a CustomerCustomFieldValue table with a column of each possible value type and store values in the right column. Similar to #3 but field values are stored using a strongly-type column.

    CustomerID, CustomFieldID, DateValue, StringValue, NumericValue
    10001, 1001, 02/12/2009 8:00 AM, null, null
    10001, 1002, null, null, 18.26
    10002, 1001, 01/12/2009 8:00 AM, null, null
    10002, 1002, null, null, 50.26
    Option 5: Options 3 and 4 use a table specific to a single concept (Customer). Our clients are asking for custom field in other forms as well. Should we instead have a system-wide custom field storage system? So instead of having multiple tables such as CustomerCustomFieldValue, EmployeeCustomFieldValue, InvoiceCustomFieldValue, we would have a single table named CustomFieldValue? Although it seems more elegant to me, wouldn't that cause a performance bottleneck?

    Have you used any of those approaches? Were you successful? What approach would you select? Do you know any other approach that I should consider?

    Also, my clients want the custom field to be able to refer to data in other tables. For instance a client might want to add a "Favorite Payment Method" field to the Customer. Payment methods are defined elsewhere in the system. That brings the subject of "foreign keys" in the picture. Should I try to create constraints to ensure that values stored in the custom field tables are valid values?

    Thanks




    EDIT 07-27-2009:

    Thank you for your answers. It seems like the list of approaches is now quite comprehensive. I have
    selected the option 2 (a single XML column). It was the easiest to implement for now. I will probably
    have to refractor to a more strongly-defined approach as my requirements will get more complex and as
    the number of custom fields to support will get larger.

    database-design data-modeling
    shareimprove this question
    edited Jul 27 '09 at 21:41
    asked Jul 14 '09 at 17:18

    Sylvain
    10.4k2282123



    The simplest option (an XML column in each table) turned out good. 7 years later we are about
    to change the design. We are going with run time schema modification. When a client adds a
    field, we create a new column in the database on-the-fly, with the right data type and the
    proper foreign keys to other tables. The main reasons for this change: types (data integrity),
    foreign keys (data integrity), performance (indexes), clarity (querying and migration scripts
    are easier to write). XML was easy to implement and served us well; it is a viable option.

    - Sylvain Mar 14 '16 at 19:13




    I do agree with posters below that Options 3, 4, or 5 are most likely to be appropriate. However, each of your suggested implementations has its benefits and costs. I'd suggest choosing one by matching it to your specific requirements. For example:

    Option 1 pros: Fast to implement. Allows DB actions on custom fields (searching, sorting.)
    Option 1 cons: Custom fields are generic, so no strongly-typed fields. Database table
    is inefficient, size-wise with many extraneous fields that will never be
    used. Number of custom fields allowed needs to be anticipated.

    Option 2 pros: Fast to implement. Flexible, allowing arbitrary number and type of
    custom fields.
    Option 2 cons: No DB actions possible on custom fields. This is best if all you
    need to do is display the custom fields, later, or do minor manipulations
    of the data only on a per-Customer basis.

    Option 3 pros: Both flexible and efficient. DB actions can be performed, but the data
    is normalized somewhat to reduce wasted space. I agree with unknown
    (google)'s suggestion that you add an additional column that can be used
    to specify type or source information. Option 3 cons: Slight increase
    in development time and complexity of your queries, but there really
    aren't too many cons, here.

    Option 4 is the same as Option 3, except that your typed data can be operated on at
    the DB level. The addition of type information to the link table in
    Option 3 allows you to do more operations at our application level, but
    the DB won't be able to do comparisons or sort, for example. The choice
    between 3 and 4 depends on this requirement.

    Option 5 is the same as 3 or 4, but with even more flexibility to apply the solution
    to many different tables. The cost in this case will be that the size
    of this table will grow much larger. If you are doing many expensive
    join operations to get to your custom fields, this solution may not
    scale well.

    P.S. As noted below, the term "design pattern" usually refers to object-oriented
    programming. You're looking for a solution to a database design
    problem, which means that most advice regarding design patterns
    won't be applicable.

    shareimprove this answer
    edited Jun 6 '12 at 16:11

    Diederik
    2,27823044
    answered Jul 14 '09 at 18:18

    Eric Nguyen
    33k32030




    I accept this answer because I think it helps choosing a solution.Sylvain Aug 13 '09 at 18:20




    Regarding Option 3, "(...) but there really aren't too many cons, here." Not trying to
    remove any credibility from your answer but #3/4/5 are pretty much the Entity-Value-Attribute
    pattern, considered by some as an anti-pattern and there are plenty of "horror stories"
    about its performance around the Web. On the other hand, many say it's possible to
    search/sort/filter (@ server side) using XML/BLOB, but I have never seen it done...
    I'm scratching my head about which approach (EAV or XML) works best, especially when
    using an ORM.user1987392 Jul 4 '15 at 23:30

    ======================
    http://en.wikipedia.org/wiki/Entity-attribute-value_model

    As far as the application code is concerned I'm unsure. I do know that custom fields
    benefit greatly from a EAV model in the database.

    Per the comments below, the most significant mistake you can make with this model
    is putting foreign keys into it. Never ever put something like FriendID or TypeID
    into this model. Use this model in conjunction with the typical relational model
    and keep foreign key fields in table columns as they should.

    A second significant mistake is placing data in this model that needs to be
    reported with every element. For example putting something like Username in
    this model would mean that anytime you want to access a user and need to know
    their username you've committed yourself to a join at best or 2n queries where
    n is the number of users you're looking at. When you consider that you are
    usually going to need the Username property for every User element it becomes
    obvious this too should remain in the table columns.

    However, if you're just using this model with custom user fields you'll be fine.
    I can't imagine many situations where a user would be entering in relational
    data and the EAV model is not too significantly detrimental to searches.

    Lastly, don't try to join data from this and get a nice pretty recordset.
    Grab the original record and then grab the set of records for the entity. If
    you find yourself tempted to join the tables you've probably made the second
    mistake as mentioned above.

    shareimprove this answer
    edited Jul 14 '09 at 20:12
    answered Jul 14 '09 at 17:23

    Spencer Ruport
    30.5k973124




    I'm using this model in a current project of mine and it has been really
    beneficial. You also generate de-normalized views of the data when
    necessary for simple querying/data binding.
    - Dillie-O Jul 14 '09 at 17:26

    Yup, when carefully applied these are pretty powerful.
    - Spencer Ruport Jul 14 '09 at 17:31

    Pay close attention to the warnings in the Wikipedia article. Done poorly,
    entiry/value pairs can murder a system, as is attested by many disaster
    stories scattered about the web. If user-defined data has to relate to more
    items than just the "direct parent", you are probably much better off adding
    that data to the model as new rows or tables. My main piece of advice would
    be to try very hard not to overused such a system.
    - Philip Kelley Jul 14 '09 at 18:00

    Interesting read on Wikipedia. EAV model is certainly a double edged sword.
    My +1 is putting a name to this approach and the fact that the wikipedia article
    is quite good. Personally I can see lots of pitfuls with following this approach,
    but can see where it would be useful. I think having an XML column is a serious
    alternative though, despite what the wikipedia article states.
    - RichardOD Jul 14 '09 at 19:53

    I think everyone has made good points around this topic. For me: XML is just
    another representation of rows in a database. So adding an XML column is like
    having a tiny database inside a row. :(Diederik Jun 6 '12 at 13:30

    An Adaptive Object Model


    If you're developing with an object oriented language, we're talking about
    adaptive object models here. There are quite a few articles written about
    how you can implement them in oo-languages, but not so much information
    about how to design the data store side.

    In the company where I work, we have solved the problem by using a relational
    database to store AOM data. We have central entity table for presenting all
    the different "entities" in the domain, like people, network devices,
    companies, etc... We store the actual "form fields" to data tables that
    are typed, so we have one table for strings, one for dates and so on.
    All the data tables have a foreign key pointing to the entity table.
    We also need tables to present the type-side, i.e. what kind of attributes
    (form fields) can certain entity have and this information is used to
    interpret the data in data tables.

    Pros of our solution are that anything can be modeled without code changes,
    including references between entities, multivalues and so on. It's also
    possible to add business rules and validations to fields and they can be
    reused in all form. Cons are that the programming model is not very easy
    to understand and query performance will be worse than with a more
    typical DB design. Some other solution than relational database
    could have been better and easier for AOM.

    Building a good AOM with a working data store for it is a lot of work and
    I wouldn't recommend it if you don't have highly skilled developers. Maybe
    one day there will be an OS solution for these kinds of requirements.

    Custom fields have been discussed before in SO:

    * How would you create and store user-defined custom fields
    in a SQL database?
    (https://stackoverflow.com/questions/961232/how-would-you-create-and-store-user-defined-custom-fields-in-a-sql-database)
    * What architecture can I use to handle a shopping cart where
    each product requries different attributes to be saved?
    (https://stackoverflow.com/questions/287093/what-architecture-can-i-use-to-handle-a-shopping-cart-where-each-product-requries)

    edited May 23 '17 at 12:34
    Community answered Jul 14 '09 at 17:40
    Kaitsu 3,07932235




    Something like Option 3 is the way to go and i have used this method previously.
    Create a single table to define additional properties and their corresponding
    values. This would be a 1-N relationship between your Customer and
    CustomerCustomField table (respectively). Your second question regarding
    defining relationships with custom properties would be something to think
    about. The first thing that comes to mind is adding a DataSource field,
    which would contain the table to which the property value is bound to.
    So essentially your CustomerCustomField would look like:

    CustomerId
    Property
    Value
    ValueDataSource (nullable)
    This should allow you to either bind to a specific data structure or simply
    allow you to specify unbound values. You can further normalize this model,
    but something like this could work and should be easy enough to handle in code.

    shareimprove this answer
    answered Jul 14 '09 at 17:41
    Sergey




    Option 4 or 5 would be my choice. If your data is important, I wouldn't go
    tossing away your type information with Option 3. (You might try to implement
    full type-checking yourself, but it's a pretty big job, and the database
    engine already does it for you.)

    Some thoughts:

    *Make sure your CustomFields has a DataType column.
    - Use a UDF-based check constraint on CustomFieldValues to ensure that
    the column specified by CustomFields.DataType is non-null.
    - You'll also want a standard check constraint to make sure
    you have exactly one non-null value.
    *Regarding foreign keys, I would model these as a separate DataType.
    - Each potential cross-table reference would require its own
    column. This is good, because it maintains referential integrity.
    - You would have to support these relationships in application
    code anyway, so the fact that they are hard-coded in the
    database does not actually limit functionality.
    - This will also jive well with your ORM, if you're using one.
    *For Option 5, use intermediary tables to model the relationships.
    -You would still have a CustomerCustomFieldValue, but instead
    with only CustomerID and CustomFieldValueID columns.
    *Think long and hard about your constraints every step of the way. This
    is tricky stuff, and one misstep can cause utter havok down the line.

    I am using this in an application currently in development. There haven't
    been any problems yet, but EAV designs still scare the daylights out of
    me. Just be careful.

    As an aside, XML may also be a good choice. I don't know as much about it
    from direct experience, but it was one of the options I considered when
    starting the data design, and it looked pretty promising.

    shareimprove this answer
    answered Jul 14 '09 at 18:00

    WCWedin
    1,148821



    if those 'extra' fields are incidental and don't care to do searches on
    them, I usually go for option 2 (but like JSON better than XML). If
    there's going to be searches on custom fields, option 3 isn't hard to
    do, and usually the SQL optimizer can get reasonable performance out
    of it.

    answered Jul 14 '09 at 17:59

    Javier
    49.6k767112



    I am currently working on a project with this same problem, and I
    have chosen to use option 3, but I added a FieldType field and a
    ListSource field in case the FieldType="list". The ListSource
    field could be a query, an sql view, a function name, or something
    that results in a list of options for the list. The biggest
    problem with trying to store fields like this in my situation
    is that this field list can change, and the users are allowed
    to edit the data later. So what to do if the field list has
    changed and they go to edit. My solution to that scenario was
    to allow editing only if the list hasn't changed and to
    display read-only data if it has.

    answered May 26 '17 at 19:48

    jbair
    11


    similar Qn :
    Design Patternfor Custom Flds in Rel dbs



    Avoid stringly-typed data by replacing VALUE with NUMBER_VALUE, DATE_VALUE, STRING_VALUE. Those three types are good enough most of the time. You can add XMLTYPE and other fancy columns later if they're needed. And for Oracle, use VARCHAR2 instead of CHAR to conserve space.

    Always try to store values as the correct type. Native data types are faster, smaller, easier to use, and safer.

    Oracle has a generic data type system (ANYTYPE, ANYDATA, and ANYDATASET), but those types are difficult to use and should be avoided in most cases.

    Architects often think using a single field for all data makes things easier. It makes it easier to generate pretty pictures of the data model but it makes everything else more difficult. Consider these issues:

    You cannot do anything interesting with data without knowing the type. Even to display data it's useful to know the type to justify the text. In 99.9% of all use cases it will be obvious to the user which of the 3 columns is relevant.
    Developing type-safe queries against stringly-typed data is painful. For example, let's say you want to find "Date of Birth" for people born in this millennium:

    select *
    from ReportFieldValue
    join ReportField
    on ReportFieldValue.ReportFieldid = ReportField.id
    where ReportField.name = 'Date of Birth'
    and to_date(value, 'YYYY-MM-DD') > date '2000-01-01'
    Can you spot the bug? The above query is dangerous, even if you stored the date in the correct format, and very few developers know how to properly fix it. Oracle has optimizations that make it difficult to force a specific order of operations. You'll need a query like this to be safe:

    select *
    from
    (
    select ReportFieldValue.*, ReportField.*
    --ROWNUM ensures type safe by preventing view merging and predicate pushing.
    ,rownum
    from ReportFieldValue
    join ReportField
    on ReportFieldValue.ReportFieldid = ReportField.id
    where ReportField.name = 'Date of Birth'
    )
    where to_date(value, 'YYYY-MM-DD') > date '2000-01-01';
    You don't want to have to tell every developer to write their queries that way.
    shareimprove this answer
    answered Aug 2 '15 at 5:56

    Jon Heller
    23k34186


    EAV - Entity-Attribute-Value Implentation


    http://mysql.rjweb.org/doc.php/eav

    Table of Contents

    The Desires
    It goes by various Names
    Bad solution
    The Problems
    A Solution
    But what about the ad hoc queries?
    Why it Works
    Details on the BLOB/JSON
    A quick Example
    Conclusions
    Postlog
    Brought to you by Rick James
    The Desires
    Open-ended set of "attributes" (key=value) for each "entity". That is, the list of attributes is not known at development time, and will grow in the future. (This makes one column per attribute impractical.)
    "ad hoc" queries testing attributes.
    Attribute values come in different types (numbers, strings, dates, etc.)
    Scale to lots of entities, yet perform well.

    It goes by various Names

    EAV -- Entity - Attribute - Value
    key-value
    RDF -- This is a flavor of EAV
    MariaDB has dynamic columns that look something like the solution below. They have the added advantage of being able to index the columns otherwise hidden in the blob. (There are caveats.)
    5.7 Has JSON datatype, plus functions to access parts
    MongoDB, CouchDB -- and others -- Not SQL-based.

    Bad solution
    Table with 3 columns: entity_id, key, value
    The "value" is a string, or maybe multiple columns depending on datatype or other kludges.
    a JOIN b ON a.entity=b.entity AND b.key='x' JOIN c ON ... WHERE a.value=... AND b.value=...

    The Problems
    The SELECTs get messy -- multiple JOINs
    Datatype issues -- It's clumsy to be putting numbers into strings
    Numbers stored in VARCHAR do not compare 'correctly', especially for range tests.
    Bulky.
    Dedupping the Values is clumsy.
    Inefficient implementation of the K-V table. See the following on how to improve WordPress somewhat:
    wp_postmeta

    A Solution
    Decide which columns need to be searched/sorted by SQL queries. No, you don't need all the columns to be searchable or sortable. Certain columns are frequently used for selection; identify these. You probably won't use all of them in all queries, but you will use some of them in every query.

    The solution uses one table for all the EAV stuff. The columns include the searchable fields plus one TEXT/BLOB. Searchable fields are declared appropriately (INT, TIMESTAMP, etc). The BLOB contains JSON-encoding of all the extra fields.

    The table should be ENGINE=InnoDB, hence it should have a PRIMARY KEY. The entitity_id is the 'natural' PK. Add a small number of other indexes (often 'composite') on the searchable fields. PARTITIONing is unlikely to be of any use, unless the Entities should purged after some time. (Example: News Articles)

    But what about the ad hoc queries?
    You have included the most important fields to search on -- date, category, etc. These should filter the data down significantly. When you also need to filter on something more obscure, that will be handled differently. The application code will look at the BLOB for that; more on this later.

    Why it Works
    You are not really going to search on more than a few fields.
    The disk footprint is smaller; Smaller --> More cacheable --> Faster
    It needs no JOINs
    The indexes are useful
    The one table has one row per entity, and can grow as needed. (EAV needs many rows per entity.)
    Performance is as good as the indexes you have on the 'searchable fields'.
    Optionally, you can duplicate the indexed fields in the BLOB.
    Values missing from 'searchable fields' would need to be NULL (or whatever), and the code would need to deal with such.

    Details on the BLOB/JSON
    Build the extra (or all) key-value pairs in a hash (associative array) in your application. Encode it. COMPRESS it. Insert that string into the BLOB.
    JSON is recommended, but not mandatory; it is simpler than XML. Other serializations (eg, YAML) could be used.
    COMPRESS the JSON and put it into a BLOB (or MEDIUMBLOB) instead of a TEXT field. Compression gives about 3x shrinkage.
    When SELECTing, UNCOMPRESS the blob. Decode the string into a hash. You are now ready to interrogate/display any of the extra fields.
    If you choose to use the JSON features of MariaDB or 5.7, you will have to forgo the compression feature described.
    MySQL 5.7.8's JSON native JSON datatype uses a binary format for more efficient access.

    For JSON in PHP, see $str = json_encode($hash); and $hash = json_decode($str, true); Also, compress() and uncompress().

    A quick Example
    For example, in Real Estate, num_bedrooms and price are far more useful to split out than has_fireplace or septic_tank. All buyers filter on the first two: only a few buyers filter on fireplaces or have a phobia about septic_tanks. So, the explicit columns would include num_bedrooms TINYINT UNSIGNED and price INT UNSIGNED; the others would be buried in the JSON.

    Conclusions
    Schema is reasonably compact (compression, real datatypes, less redundancy, etc, than EAV)
    Queries are fast (since you have picked 'good' indexes)
    Expandable (JSON is happy to have new fields)
    Compatible (No 3rd party products, just supported products)
    Range tests work (unlike storing INTs in VARCHARs)
    (Drawback) Cannot use the non-indexed attributes in WHERE or ORDER BY clauses, must deal with that in the app. (5.7 partially alleviates this.)

    Postlog
    Posted Jan, 2014; Refreshed Feb, 2016.

    MariaDB's Dynamic Columns
    MySQL 5.7's JSON

    This looks very promising; I will need to do more research to see how much of this blog is obviated by it: Using MySQL as a Document Store in 5.7
    more DocStore discussion
    EAV Fail

    If you insist on EAV, set optimizer_search_depth=1.


    Reading on Predicates
    Note: Still to research but @ this pt. it appears that directly generating preds via byteCode
    mt not be the right approach; because if something goes wrong (e.g. fld no longer exists)
    it'll fail w/Crash; whereas the cumbersome Factory/Bldr method will fail silently & shd
    be relatively err-free.
    Just use fluent dsl to chain & generate
    https://dbooks.online/books/?q=N0d3TDVKVXBQZlBwWVAvOGdMcnNpK3paZ05LLzdjY0gxOVdPSEVjckNWeE5OYXpKbXJiamhtZ0ZxZnNxY0pYcnBrUHI2TTRTQklQYU5nbU9XdlFmckhZeGtiQ3RnY1JROGpyZTB0ZjNRSFRsZDJvd09xREVMMVlLQzZMYVBET0s=&enc=1&id=293&utm_source=https%3A%2F%2Fwww.google.com%2F&utm_term=N0d3TDVKVXBQZlBwWVAvOGdMcnNpK3paZ05LLzdjY0gxOVdPSEVjckNWeE5OYXpKbXJiamhtZ0ZxZnNxY0pYcnBrUHI2TTRTQklQYU5nbU9XdlFmckhZeGtiQ3RnY1JROGpyZTB0ZjNRSFRsZDJvd09xREVMMVlLQzZMYVBET0s=&utm_referrer=https%3A%2F%2F9.bytus.ru%2F2543.pdf&pk_campaign=https%3A%2F%2Fwww.google.com%2F&pk_kwd=N0d3TDVKVXBQZlBwWVAvOGdMcnNpK3paZ05LLzdjY0gxOVdPSEVjckNWeE5OYXpKbXJiamhtZ0ZxZnNxY0pYcnBrUHI2TTRTQklQYU5nbU9XdlFmckhZeGtiQ3RnY1JROGpyZTB0ZjNRSFRsZDJvd09xREVMMVlLQzZMYVBET0s=&tk=0
    jspy-final.pdf
    JPred: Practical Predicate Dispatch for Java
    Bug ID: JDK-7008866 Missing loop predicate for loop with multiple entries
    ACMB099A-07.tex
    Assignment 0 FAQ -- cs 304 fALL, 2000
    An In-Depth Look at ALIA4J
    AshishArteThesis.pdf
    Translation of Lambda Expressions
    The Dark Side Of Lambda Expressions in Java 8
    java - Creating Predicates on the fly - Stack Overflow
    java - Is there a convenience method to create a Predicate that tests if a field equals a given value? - Stack Overflow
    Java 8 Predicates or how to parameterize a method with a boolean-valued function - My Java AdventuresMy Java Adventures
    Lombok defines a Predicate as a Cls (extending Function1)
    w/an evaluate method; you extend it for use-case scenarios.

    This is probably the way we'll have to go (with DSL)

    lombok code (src:https://github.com/peichhorn/lombok-pg/wiki/@Predicate) ->
    
    import java.util.Arrays;
    import lombok.Predicates.Predicate1;
    
    public class Main {
      public static void main(String[] args) {
        Extensions.filter(Arrays.asList(args), isEmpty());
      }
    
      private static Predicate1 isEmpty() {
        return new Predicate1() {
          public boolean evaluate(String s) {
            return (s == null) || (s.isEmpty());
          }
        };
      }
    }
    

    Predicates.java ->
    
    /**
     * Collection of predicate templates.
     */
    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public final class Predicates {
    
    	/**
    	 * Represents the method that defines a set of criteria and determines whether the specified object meets those
    	 * criteria.
    	 * 
    	 * @param 
    	 *            The type of the object to compare.
    	 */
    	public static abstract class Predicate1 extends Function1 {
    		public final Boolean apply(T1 t1) {
    			return evaluate(t1);
    		}
    
    		public abstract boolean evaluate(T1 t1);
    	}
    }
    


    https://raw.githubusercontent.com/AdoptOpenJDK/openjdk-jdk8u/master/jdk/src/share/classes/java/util/regex/Pattern.java
    regex.Pattern.asPredicate() ->

        /**
         * Creates a predicate which can be used to match a string.
         *
         * @return  The predicate which can be used for matching on a string
         * @since   1.8
         */
        public Predicate asPredicate() {
            return s -> matcher(s).find();
        }
    

    Notes on Machine Learning / AI Options

    Eclipse Deep Learning for Java


    Deeplearning4j is the first commercial-grade, open-source, distributed deep-learning library written for Java and Scala. Integrated with Hadoop and Spark, DL4J is designed to be used in business environments on distributed GPUs and CPUs. Skymind is its commercial support arm.

    Deeplearning4j aims to be cutting-edge plug and play, more convention than configuration, which allows for fast prototyping for non-researchers. DL4J is customizable at scale. Released under the Apache 2.0 license, all derivatives of DL4J belong to their authors. DL4J can import neural net models from most major frameworks via Keras, including TensorFlow, Caffe and Theano, bridging the gap between the Python ecosystem and the JVM with a cross-team toolkit for data scientists, data engineers and DevOps. Keras is employed as Deeplearning4j's Python API. Machine learning models are served in production with Skymind's model server.

    Apache Open NLP vs NLTK

    Qn: We have a spring boot application integrated with Node.js and socket.io chat application , to which we want to integrate Natural language processing. Not getting any direction on which of these two Apache-OpenNlp or NLTK would be a better choice for us as both of the frameworks offer the kind of processing we need. Wrt to the features provided by the frameworks , they both are good. Both have features that we are looking for. More than how to choose between features , what would suit our architecture better is a perspective I would like.. Any suggestions ?

    Ans:
    It is tough to answer a question about which product will meet your needs better without know what your needs are. OpenNLP can perform Tokenization, Sentence Detection, POS tagging, Named entity detection, language detection, Document classification, Chunking, and Sentence Parsing. It also has lower-level access to maximum entropy and Naive-bayes classifiers. I use OpenNLP often. NLTK appears to do the same stuff (I don't really use it, so I can't tell you all its benefits). A small difference is that OpenNLP is java whereas NLTK is python. So your preference can come into play. Another difference is that NLTK has build in methods for downloading corpora. If you were a little more specific about what you wanted, people could give you better advice. answered 2 days ago HowYaDoing

    Ans: I think I have.. I know the features provided for both frameworks.. but which would suit an architecture with the above mentioned technologies is the guidance I would like

    Personally, I really like OpenNLP, and because you just need to add the OpenNLP dependencies to maven + download models. I think it will integrate easily with a spring boot app. -- I do this very thing, and it is easy. I am sure that the NLTK community would argue that even though they are python-based, you can integrate it into a java app. Long story short, I suggest openNLP. But keep in mind, I work with AND ON openNLP, so I have a pro-OpenNLP bias.

    What do you think about using DKPro Core? This framework provide a generic API for many NLP frameworks and comes as Maven dependency. This means you can exchange any of the frameworks. If you also use domain specific NLP models by building your own corpus, you can use this project to determine your best-performing NLP pipeline for your domain. Let me know if you have any questions. @Schrieveslaach I am not familiar with DKPro Core, but it appears that wraps many different NLP projects for UIMA. This is very useful if you are creating a UIMA-based solution. But I am not sure that Sharanya is considering UIMA, which brings it's own issues.

    @HowYaDoing, it is true that UIMA adds another architectural layer but DKPro Core unifies all NLP tools through their wrappers. This means Sharanya can exchange any of these tools. I'm don't know the application domain but if the application domain is different to news papers (NLP models won't work well), the models and tools can easily be exchanged with a better working version. Therefore, Sharanya can use the second project to find the best NLP tools for the application domain.


    Java vs Python for NLP is very much a preference or necessity. Depending on the company/projects you'll need to use one or the other and often there isn't much of a choice unless you're heading a project.

    Other than NLTK (www.nltk.org), there are actually other libraries for text processing in python:

    (for more, see https://pypi.python.org/pypi?%3Aaction=search&term=natural+language+processing&submit=search)

    For Java, there're tonnes of others but here's another list:

    This is a nice comparison for basic string processing, see http://nltk.googlecode.com/svn/trunk/doc/howto/nlp-python.html

    A useful comparison of GATE vs UIMA vs OpenNLP, see https://www.assembla.com/spaces/extraction-of-cost-data/wiki/Gate-vs-UIMA-vs-OpenNLP?version=4

    If you're uncertain, which is the language to go for NLP, personally i say, "any language that will give you the desired analysis/output", see Which language or tools to learn for natural language processing?

    Here's a pretty recent (2017) of NLP tools: https://github.com/alvations/awesome-community-curated-nlp

    An older list of NLP tools (2013): http://web.archive.org/web/20130703190201/http://yauhenklimovich.wordpress.com/2013/05/20/tools-nlp


    Other than language processing tools, you would very much need machine learning tools to incorporate into NLP pipelines.

    There's a whole range in Python and Java, and once again it's up to preference and whether the libraries are user-friendly enough:

    Machine Learning libraries in python:

    (for more, see https://pypi.python.org/pypi?%3Aaction=search&term=machine+learning&submit=search)


    With the recent (2015) deep learning tsunami in NLP, possibly you could consider: https://en.wikipedia.org/wiki/Comparison_of_deep_learning_software

    I'll avoid listing deep learning tools out of non-favoritism / neutrality.


    Other Stackoverflow questions that also asked for NLP/ML tools:

    Java

    The first place to look would be Stanford's Natural Language Processing Group. All of software that is distributed there is written in Java. All recent distributions require Oracle Java 6+ or OpenJDK 7+. Distribution packages include components for command-line invocation, jar files, a Java API, and source code.

    Another great option that you see in a lot of machine learning environments here (general option), is Weka. Weka is a collection of machine learning algorithms for data mining tasks. The algorithms can either be applied directly to a dataset or called from your own Java code. Weka contains tools for data pre-processing, classification, regression, clustering, association rules, and visualization. It is also well-suited for developing new machine learning schemes.


    In terms of Java based libraries and tools, another great one that you might look at is LingPipe. alias-i.com/lingpipe


    Generally you'd do these two tasks in the other order:
    Do part-of-speech tagging
    Run a parser using the POS tags as input
    OpenNLP's documentation isn't that thorough and some of it's gotten hard to find due to the switch to apache. Some (potentially slightly out-of-date) tutorials are available in the old SF wiki.
    You might want to take a look at the Stanford NLP tools, in particular the Stanford POS Tagger and the Stanford Parser. Both have downloads that include pre-trained model files and they also have demo files in the top-level directory that show how to get started with the API and short shell scripts that show how to use the tools from the command-line.
    LingPipe might be another good toolkit to check out. A quick search here will lead you to a number of similar questions with links to other alternatives, too!

    Which one should i use? Stanford CoreNLP or The Stanford Parser or The Stanford POS Tagger
    It depends on what you want/need to do. CoreNLP includes the other two tools plus other annotators, so if you're just experimenting with different kinds of annotation, CoreNLP would be a good place to start. From this question and your related questions, it sounds like you might benefit from reading more about computational linguistics before you get started with your task. I'd suggest Speech and Language Processing by Jurafsky and Martin: cs.colorado.edu/~martin/slp.html


    Stanford-nlp's Bootstrapped Entity Learning:
    https://nlp.stanford.edu/software/patternslearning.html
    Input: seed sets (that is, dictionaries) of entities for some classes and unlabeled text.
    Ouput: More entities belonging to the classes extracted from the text.
    Algorithm: bootstrapped pattern-based learning.



    learning based java (lbjava)
    [[mpt: GOOD FOR LEARNING BUT RESTRICTIVE LICENSE; CAN'T USE]]
    * Developed by: The Cognitive Computations Group University of Illinois at Urbana-Champaign
    * http://cogcomp.cs.illinois.edu/
    * http://cogcomp.org/page/software_view/LBJava
    Learning Based Java is a modeling language for the rapid development of software systems with one or more learned functions, designed for use with the JavaTM programming language. LBJava offers a convenient, declarative syntax for classifier and constraint definition directly in terms of the objects in the programmer's application. With LBJava, the details of feature extraction, learning, model evaluation, and inference are all abstracted away from the programmer, leaving him to reason more directly about his application.
    Allows training; defining custom classifiers.
    Lots of sample java code @ http://cogcomp.org/page/software_view/LBJava

    Takipi: How to Get Started with Java Machine Learning
    By Henn Idan (http://blog.takipi.com/author/henn/) - July 7, 2016
    ? 5 min read
    ? 3 comments (http://blog.takipi.com/how-to-get-started-with-javamachine-learning/#disqus_thread)
    What are the best tools to get started with Java machine learning?
    They've been around for a while, but these days it feels like everyone is talking about artificial intelligence and machine learning. Its no longer a secret reserved to scientists and researchers, with implementations in nearly any new emerging technology.
    TAKIPI BLOG (HTTP://BLOG.TAKIPI.COM/)
    10/26/2017 How to Get Started with Java Machine Learning | Takipi Blog
    http://blog.takipi.com/how-to-get-started-with-java-machine-learning/ 2/7
    In the following post we'll do a quick overview of the main Java machine learning frameworks, and show how easy it is to get started without reinventing the wheel and creating your own algorithms from scratch. New Post: How to Get Started with Java Machine Learning
    https://t.co/ohD3zCCA6j (https://t.co/ohD3zCCA6j)
    pic.twitter.com/MU9kwhIKJM (https://t.co/MU9kwhIKJM) Takipi (@takipid) July 7, 2016
    (https://twitter.com/takipid/status/751082272326086657)

    AI for the people


    AI is a wide and cool ??eld that has been around for a while, but always felt a little bit out of reach and made especially for scientists. If you wanted to create an AI system, you had to implement the core algorithms on your own and train them to identify patterns, understand images and process natural language. The recent buzz and evolvement around this ??eld made it more accessible for non-researchers. Now you have easy access to the relevant algorithms and tools. You do have to know what you're doing, but its a lot easier to enhance your applications with machine learning capabilities.

    Getting the machine going


    To make things simpler, we decided to highlight 3 projects to help get you started:
    1. Deeplearning4J (DL4J) (http://deeplearning4j.org/) Open source, distributed and commercial-grade deep-learning library for JVM
    2. BID Data Project (http://bid2.berkeley.edu/bid-data-project/) A collection of patterns that enable fast, large-scale machine learning and data mining
    3. Neuroph (http://neuroph.sourceforge.net/index.html) Objectoriented neural network
    By the way, we recently published another list of interesting open source GitHub libraries that caught our attention. Check it out
    (http://blog.takipi.com/the-hitchhikers-guide-to-github-13-java-projectsyou-should-try/).

    1. DL4J Deep Learning


    DL4J is a tool made to assist you in the process of con??guring deep neural networks which are made of multiple layers. It brings deep learning to the JVM along with fast prototyping and customization at scale, while focusing on more convention than con??guration.
    This is the tool for those who already have the theory needed to create and use deep neural networks, but dont want to actualize the algorithms themselves. You can use it to solve speci??c problems involving massive amounts of data and customize the neural net properties.
    DL4J is written in Java, which makes it compatible with any JVM language such as Clojure, Scala or Kotlin, and it integrates with Hadoop and Spark. Possible use cases include rating or recommendation systems (CRM, adtech, churn prevention), predictive analytics or even fraud detection. If you're looking for a real-world example, you can check out Rapidminer (https://rapidminer.com/). It's an open-source data platform that uses DL4J to streamline predictive analytics processes for their users.
    Setting up a new neural network is as easy as creating a new object:
    Deeplearning4j.java (https://gist.github.com/HennTakipi/b932b32633d81c967f34d0fd769ef302#file-deeplearning4j-java)
    MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
    .iterations(1)
    .weightInit(WeightInit.XAVIER)
    .activation("relu")
    .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
    .learningRate(0.05)
    // ... other hyperparameters
    .backprop(true)
    .build();
    

    The BID Data Project is made for those of you who deal with a great amount of data, and are performance sensitive. This UC Berkeley project is a collection of hardware, software and design patterns that enable fast and large-scale data mining.
    The ??rst library is BIDMach, that holds the records for many common machine learning problems, on single nodes or clusters. You can use it to manage data sources, optimize and distribute data over CPUs or GPUs. It includes many popular machine learning algorithms, and the team is working on developing distributed Deep Learning networks, graph algorithms and other models.
    The other 2 libraries are BIDMat, a fast matrix algebra library that focuses on data mining and BIDParse, GPU-accelerated natural language parser. Other libraries in this project include visualization tools, along with libraries that will let you run on Spark or even on Android.
    BIDMach benchmarks repeatedly show better results than other solutions, even with a single machine compared to alternatives running on larger clusters. A full list of benchmarks can be found right here (https://github.com/BIDData/BIDMach/wiki/Benchmarks).

    3. Neuroph


    Neuroph is a lightweight Java framework used to develop common neural network architectures. The framework provides a Java library along with a GUI tool (called easyNeurons), and you can use it in order to create and train your very own neural networks in Java programs.
    It contains an open source Java library, with a small number of basic classes which correspond to essential neural network concepts. It's a great stepping stone if you're just getting started with neural networks, or if you want to know how they work.
    You can try out Neuroph online demo (http://neuroph.sourceforge.net/online_demo.html) and see how it actually works. Spoiler alert: the interface looks old and outdated, but you can create nice things with it. Also, it received the Duke's Choice Award for 2013
    (http://neuroph.sourceforge.net/dukes_choice_award_2013.html).
    (http://384uqqh5pka2ma24ild282mv.wpengine.netdna-cdn.com/wpcontent/uploads/2016/07/network.png)
    Network graph view
    What About the Others?
    In case these 3 projects are not your cup of tea and youre looking for something a little different for your project, don't worry. If you search GitHub for Machine learning (https://github.com/search? l=Java&q=machine+learning&type=Repositories&utf8=%E2%9C%93)ll find 1,506 Java repositories that might give you the right tool.
    For example, an interesting project from Airbnb is aerosolve
    (https://github.com/airbnb/aerosolve); A machine learning library designed to be human friendly.
    Getting started with a new technology is always a source for trouble. If you will need some help with your exceptions, be sure to check out the OverOps error analysis tool (https://www.overops.com/).

    Final Thoughts

    Every few years there's a new buzz around AI. This time around, it came with reinforcement in the form of machine learning, data mining, neural networks and so on and we're all for it. The fact that these libraries are open sourced means that information and abilities are up for grabs, and all you have to do is think what can be done with this



    General Classification Qns & Notes

    Qn on Supervised tag suggestion for documents ('multiclass labelling')

    I have thousands of documents with associated tag information. However i also have many documents without tags.
    I want to train a model on the documents WITH tags and then apply the trained classifier to the UNTAGGED documents; the classifier will then suggest the most appropriate tags for each UNTAGGED document.
    I have done quite a lot of research and there doesn't seem to be a SUPERVISED implementation to document tag classification.
    I know NLTK, gensim, word2vec and other libraries will be useful for this problem.
    I will be coding the project in Python.
    Any help would be greatly appreciated.
    python machine-learning nlp text-classification
    shareimprove this question
    asked Jun 26 at 15:55
    pwhc



    Supervised document tagging isn't particularly uncommon, though it's usually called "multiclass labelling".
    For many methods it's the same as single labelling but you pick the N-best results.
    See here for a scikit example on made-up data:
    scikit-learn.org/stable/auto_examples/plot_multilabel.html
    polm23 Jun 27 at 4:07

    Depending on your actual use-case you might opt for more complex method but for minimum working model do:
    1) Prepocessing of documents: tokenize, build vocabulary (NLTK has tools for this)
    2) Do bag-of-words encoding per document
    3) Train a machine learning model with onehot encoding for outputs. Start from sklearn random forest, logistic regression, SVM.
    answered Jun 26 at 17:46
    Joonatan Samuel

    thanks, i have a minimum working model; bow representation of document text with an SVM learning model.
    Any advice on taking it further? more pre-processing (stemming ect...). I was thinking of using WMD to cluster tagged documents, then apply the model to untagged documents that would then find the most similar kind of tag documents, therefore giving you your tag.

    From here it will begin to depend on your actual use case. But basically my answer is in three parts.
    1) preprocessing
    2) encoding
    3) training model.
    Depending on your actual use-case and data the prioritization will differ.
    E.g. if you have 100mln documents but at test time don't need to worry about computation work with neural networks to get model better. If you have little data you might want to look into better preprocessing / encoding much more.


    'm currently working on something similar, besides what @Joonatan Samuel suggested I would encourage you to do careful preprocessing and considerations.
    If you want two or more tags for documents you could train several model : one model per tag.
    You need to consider if there will be enough cases for each model (tag)
    If you have a lot of tags, you could run into a problem with document-tag cases like above.
    Stick to most common tag prediction don't try to predict all tags.
    answered Jun 26 at 18:01
    Diego Agher

    in .NET, I'll usually do what was alluded to by samxli. I load all keywords into a hashtable.
    I've done it with up to 120,000 keywords and it works pretty fast.
    The .NET hashtable object has a contains([key]) method. So for each word in the article I'll just call:
    theHashTable.contains(theWord)
    If it does contain the word, I'll index it. Has worked pretty well for me without having to use other frameworks.
    I don't know how hashtables work in PHP. You'd have to google that. I think their normal arrays work like hashtables?
    The key to using a hashtable is that the keys are indexed for fast searching -- I think they use bTrees, but someone may correct me on that. If you're not familiar with the btree concept, you might want to look that up.

    edited Jun 6 '11 at 14:10
    answered Jun 6 '11 at 12:37
    Trevor

    Given *A FIXED SET OF TAGS* one poss approach seems to be to:
    • expand the tagList into a Map by getting ALL poss associated words (from, for example, the datamuse API)
    • get freq. keywords from target
    • lookup ea keyword; find best 'fit'
    • "MANUALLY TRAIN" the corpus by adding custom tags to the list which will aid disambiguation

      • [[note: this is the type of method used by https://www.uclassify.com/; who then picks the result if match > 90%]]


    Qn: I want a machine to learn to categorize short texts
    
    I have a ton of short stories about 500 words long and I want to categorize them into one of, let's say, 20 categories:
    
    Entertainment
    Food
    Music
    etc
    I can hand-classify a bunch of them, but I want to implement machine learning to guess the categories eventually. What's the best way to approach this? Is there a standard approach to machine learning I should be using? I don't think a decision tree would work well since it's text data...I'm completely new in this field.
    
    Any help would be appreciated, thanks!
    
    Ans:
    
    A naive Bayes will most probably work for you. The method is like this:
    
    Fix a number of categories and get a training data set of (document, category) pairs.
    A data vector of your document will be sth like a bag of words. e.g. Take the 100 most common words except words like 
    "the", "and" and such. Each word gets a fixed component of your data vector (e.g. "food" is position 5). 
    A feature vector is then an array of booleans, each indicating whether that word came up in the corresponding document.
    Training:
    
    For your training set, calculate the probability of every feature and every class: 
    	p(C) = number documents of class C / total number of documents.
    Calculate the probability of a feature in a class: 
    	p(F|C) = number of documents of class with given feature (= word "food" is in the text) / number of documents in given class.
    
    Decision:
    
    Given an unclassified document, the probability of it belonging to class C is proportional to 
    	P(C|F1, ..., F500) = P(C) * P(F1|C) * P(F2|C) * ... * P(F500|C). 
    Pick the C that maximizes this term.
    Since multiplication is numerically difficult, you can use the sum of the logs instead, 
    which is maximized at the same C: 
    	log P(C|F1, ..., F500) = log P(C) + log P(F1|C) + log P(F2|C) + ... + log P(F500|C).
    
    Am I right in that the categories of a training set can not be altered? Probably I am a little bit to lazy to do extended research. No, they can't. But as soon as you do, you can train a new classifier anyway.
    I've classified tens of thousands of short texts. What I did intially was to use a tf-idf vector space model and then did k-means clustering on those vectors. This is a very good initial step of exploratory data analysis to get a nice handle on your dataset. The package I used to cluster was cluto: http://glaros.dtc.umn.edu/gkhome/views/cluto/ To do tf-idf, I just wrote a quick script in perl to tokenize on non-alphanumerics. Then, every document consists of a bag of words. Every document is represented as a vector of the words it contains. The value of each index of the vector is the term frequency (tf) * inverse document frequency (idf). It's just the product of the count of that word/term in the document multiplied by the reciprocal of the fraction of the documents that contain that word. (because a word like "the" is very uninformative.) This method will quickly get you about 80%-90% accuracy. You can then manually label the ones that are right (or more importantly: wrong) and then do supervised learning if you so choose. answered Apr 25 '10 at 19:42 user325523
    I think the paper "Machine learning in automated text categorization" (you can Google and download the PDF file) is worth reading. The paper discussed two crucial part:one for feature selection (translate text to feature space), the other for building a classifier on feature space. there is a lot of feature selection methods, and several classification methods (decision tree, naive Bayes, kNN, SVM, etc). you can try some combination to see if it was working on your data set. I did something similar before, I use Python for text manipulation, feature selection, and feature weighting. and Orange for classifier. Orange and Weka already included naive Bayes, kNN... , but nowadays I might write the classifier with Python script directly, it shouldn't be very hard too. Hope this helps. answered Apr 23 '10 at 7:16 sunqiang
    Most people will say that statistical text analysis (like a naive Bayes approach) is the standard approach: "Foundations of Statistical Natural Language Processing", Manning and Schuetze and "Speech and Language Processing", Jurafsky and Martin are the standard references. Statistical text analysis became the standard approach during the late 90's because they easily outperformed symbolic systems. However some symbolic systems incorporate statistical elements and you can also actually use a connectionist approach (there are a few papers demonstrating this). You can also use cosine similarity (a form of k-Nearest Neighbor) although naive Bayes is usually the top performer. Here's a good overview: http://www.cs.utexas.edu/users/hyukcho/classificationAlgorithm.html I used rainbow mentioned on that page for text classification on a search engine prototype I wrote on a dot com project. answered Jan 15 '11 at 16:14 Kirt Undercoffer
    Unless there is a chance that you want to do another 500 classifications in the future I am not sure I would go for a machine learning approach. Unless the categories are very similar ("food" and "italian food" to take an example) I think a quite naive heuristic could work very well. For each category build a table of common words (for food : "potato", "food", "cook", "tomato", "restaurant",...) and for each text count which category got the most word matches. Instead of building the dictionary by hand you could take a sample (say a 100) of the texts, categorize them by hand and then let an algorithm pick out the words and then make sure to remove words that are common between all sets (since they provide no information). This is, in essence, a very simple "learning" system. If you really want a machine learning system there are a number of methods for classification. The downside is that although most methods are quite simple to implement, the hard part is to chose a good method, the right features, and good parameters. answered Apr 23 '10 at 6:12 Hannes Ovr 11.2k34058 This is a good point. Machine learning might not be the best approach for this. Regexps all the way! ash Apr 23 '10 at 9:37
    Try Weka... it's a free data mining tool that implements a lot of machine learning algorithms. It has a GUI and an API, so you can use it directly to on your data set or you can program against it. If you like the results from the various machine learning algorithms and you're still interested in implementing your own algorithms, then you can implement the one(s) that you like the most. This will also help you remove some of the "will it actually work" feeling that you normally get before you build an ML/AI algorithm. answered Apr 23 '10 at 6:24 Kiril
    We can use NLP here. Following would be the steps as I implemented to classify emails in different categories here: 1. Lemmatization: This would remove unnecessary details and would convert all the words into their basic forms or root forms. Like, it will convert working into work, running into run, horses into horse etc. We can Stanford Lemmatizer for this purpose. http://stanfordnlp.github.io/CoreNLP/ Wordnet filtering: We can use only those words which are present in Wordnet. I used Java Wordnet Interface for this purpose. Just filter out the words that are not found in wordnet and take rest of the words. http://projects.csail.mit.edu/jwi/ Find synonyms and further synonyms: For each of the above 5 or 6 categories mentioned above, form separate sets containing synonyms of synonyms of these categories. For e.g., form a set that would contain synonyms of Entertainment and then further synonyms of the synonyms of entertainment found. We can increase this set using web crawling as well. Feed the data: Take all the words after Lemmatization and Wordnet filtering of a particular story and check how many words matches in each category sets. For e.g., if a story contains 100 words, and it matches with 35 words in entertainment category, 40 words with food, 30 words with travel, then it is highly likely to fall under the category of food and hence it would be a food story. I got good results for my email classification using above approach. answered Nov 30 '16 at 0:44 Ashish Kumar
    Qn: Beginner's resources/introductions to classification? I'd recommend first starting with Support Vector Machines (SVM) for general applied classification tasks. They'll give you state-of-the-art performance, and you don't really need to understand all of the theory behind them to just use the implementation provided by a package like WEKA. If you have a larger data-set, you might want to try using Random Forests. There's also an implementation of this algorithm in WEKA, and they train much faster on large data. While they're less broadly used than SVMs, their accuracy tends to match or nearly match the accuracy you could get from one.
    Q: Difference between classification and clustering in data mining? A: In general, in classification you have a set of predefined classes and want to know which class a new object belongs to. Clustering tries to group a set of objects and find whether there is some relationship between the objects. In the context of machine learning, classification is supervised learning and clustering is unsupervised learning.
    Classification -> Use Case: Classify known sample into known classes\ Algorithms: Decision Trees, Bayesian classifiers Data needs: Labelled samples from a set of classes


    Naive-Bayes Text Classification Theory Explained
    Qn:
    
    I am finding it hard to understand the process of Naive Bayes, and I was wondering if someone could explain it with a simple step by step process in English. I understand it takes comparisons by times occurred as a probability, but I have no idea how the training data is related to the actual dataset.
    
    Please give me an explanation of what role the training set plays. I am giving a very simple example for fruits here, like banana for example
    
    training set---
    round-red
    round-orange
    oblong-yellow
    round-red
    
    dataset----
    round-red
    round-orange
    round-red
    round-orange
    oblong-yellow
    round-red
    round-orange
    oblong-yellow
    oblong-yellow
    round-red
    
    
    Ans: I realize that this is an old question, with an established answer. The reason I'm posting is that is the accepted answer has many elements of k-NN (k-nearest neighbors), a different algorithm. Both k-NN and NaiveBayes are classification algorithms. Conceptually, k-NN uses the idea of "nearness" to classify new entities. In k-NN 'nearness' is modeled with ideas such as Euclidean Distance or Cosine Distance. By contrast, in NaiveBayes, the concept of 'probability' is used to classify new entities. Since the question is about Naive Bayes, here's how I'd describe the ideas and steps to someone. I'll try to do it with as few equations and in plain English as much as possible. First, Conditional Probability & Bayes' Rule Before someone can understand and appreciate the nuances of Naive Bayes', they need to know a couple of related concepts first, namely, the idea of Conditional Probability, and Bayes' Rule. (If you are familiar with these concepts, skip to the section titled Getting to Naive Bayes') Conditional Probability in plain English: What is the probability that something will happen, given that something else has already happened. Let's say that there is some Outcome O. And some Evidence E. From the way these probabilities are defined: The Probability of having both the Outcome O and Evidence E is: (Probability of O occurring) multiplied by the (Prob of E given that O happened) One Example to understand Conditional Probability: Let say we have a collection of US Senators. Senators could be Democrats or Republicans. They are also either male or female. If we select one senator completely randomly, what is the probability that this person is a female Democrat? Conditional Probability can help us answer that. Probability of (Democrat and Female Senator)= Prob(Senator is Democrat) multiplied by Conditional Probability of Being Female given that they are a Democrat. P(Democrat & Female) = P(Democrat) * P(Female | Democrat) We could compute the exact same thing, the reverse way: P(Democrat & Female) = P(Female) * P(Democrat | Female) Understanding Bayes Rule Conceptually, this is a way to go from P(Evidence| Known Outcome) to P(Outcome|Known Evidence). Often, we know how frequently some particular evidence is observed, given a known outcome. We have to use this known fact to compute the reverse, to compute the chance of that outcome happening, given the evidence. P(Outcome given that we know some Evidence) = P(Evidence given that we know the Outcome) times Prob(Outcome), scaled by the P(Evidence) The classic example to understand Bayes' Rule: Probability of Disease D given Test-positive = Prob(Test is positive|Disease) * P(Disease) _______________________________________________________________ (scaled by) Prob(Testing Positive, with or without the disease) Now, all this was just preamble, to get to Naive Bayes. Getting to Naive Bayes' So far, we have talked only about one piece of evidence. In reality, we have to predict an outcome given multiple evidence. In that case, the math gets very complicated. To get around that complication, one approach is to 'uncouple' multiple pieces of evidence, and to treat each of piece of evidence as independent. This approach is why this is called naive Bayes. P(Outcome|Multiple Evidence) = P(Evidence1|Outcome) * P(Evidence2|outcome) * ... * P(EvidenceN|outcome) * P(Outcome) scaled by P(Multiple Evidence) Many people choose to remember this as: P(Likelihood of Evidence) * Prior prob of outcome P(outcome|evidence) = _________________________________________________ P(Evidence) Notice a few things about this equation: If the Prob(evidence|outcome) is 1, then we are just multiplying by 1. If the Prob(some particular evidence|outcome) is 0, then the whole prob. becomes 0. If you see contradicting evidence, we can rule out that outcome. Since we divide everything by P(Evidence), we can even get away without calculating it. The intuition behind multiplying by the prior is so that we give high probability to more common outcomes, and low probabilities to unlikely outcomes. These are also called base rates and they are a way to scale our predicted probabilities. How to Apply NaiveBayes to Predict an Outcome? Just run the formula above for each possible outcome. Since we are trying to classify, each outcome is called a class and it has a class label. Our job is to look at the evidence, to consider how likely it is to be this class or that class, and assign a label to each entity. Again, we take a very simple approach: The class that has the highest probability is declared the "winner" and that class label gets assigned to that combination of evidences. Fruit Example Let's try it out on an example to increase our understanding: The OP asked for a 'fruit' identification example. Let's say that we have data on 1000 pieces of fruit. They happen to be Banana, Orange or some Other Fruit. We know 3 characteristics about each fruit: Whether it is Long Whether it is Sweet and If its color is Yellow. This is our 'training set.' We will use this to predict the type of any new fruit we encounter. Type Long | Not Long || Sweet | Not Sweet || Yellow |Not Yellow|Total ___________________________________________________________________ Banana | 400 | 100 || 350 | 150 || 450 | 50 | 500 Orange | 0 | 300 || 150 | 150 || 300 | 0 | 300 Other Fruit | 100 | 100 || 150 | 50 || 50 | 150 | 200 ____________________________________________________________________ Total | 500 | 500 || 650 | 350 || 800 | 200 | 1000 ___________________________________________________________________ We can pre-compute a lot of things about our fruit collection. The so-called "Prior" probabilities. (If we didn't know any of the fruit attributes, this would be our guess.) These are our base rates. P(Banana) = 0.5 (500/1000) P(Orange) = 0.3 P(Other Fruit) = 0.2 Probability of "Evidence" p(Long) = 0.5 P(Sweet) = 0.65 P(Yellow) = 0.8 Probability of "Likelihood" P(Long|Banana) = 0.8 P(Long|Orange) = 0 [Oranges are never long in all the fruit we have seen.] .... P(Yellow|Other Fruit) = 50/200 = 0.25 P(Not Yellow|Other Fruit) = 0.75 Given a Fruit, how to classify it? Let's say that we are given the properties of an unknown fruit, and asked to classify it. We are told that the fruit is Long, Sweet and Yellow. Is it a Banana? Is it an Orange? Or Is it some Other Fruit? We can simply run the numbers for each of the 3 outcomes, one by one. Then we choose the highest probability and 'classify' our unknown fruit as belonging to the class that had the highest probability based on our prior evidence (our 1000 fruit training set): P(Banana|Long, Sweet and Yellow) P(Long|Banana) * P(Sweet|Banana) * P(Yellow|Banana) * P(banana) = _______________________________________________________________ P(Long) * P(Sweet) * P(Yellow) = 0.8 * 0.7 * 0.9 * 0.5 / P(evidence) = 0.252 / P(evidence) P(Orange|Long, Sweet and Yellow) = 0 P(Other Fruit|Long, Sweet and Yellow) P(Long|Other fruit) * P(Sweet|Other fruit) * P(Yellow|Other fruit) * P(Other Fruit) = ____________________________________________________________________________________ P(evidence) = (100/200 * 150/200 * 50/200 * 200/1000) / P(evidence) = 0.01875 / P(evidence) By an overwhelming margin (0.252 >> 0.01875), we classify this Sweet/Long/Yellow fruit as likely to be a Banana. Why is Bayes Classifier so popular? Look at what it eventually comes down to. Just some counting and multiplication. We can pre-compute all these terms, and so classifying becomes easy, quick and efficient. Let z = 1 / P(evidence). Now we quickly compute the following three quantities. P(Banana|evidence) = z * Prob(Banana) * Prob(Evidence1|Banana) * Prob(Evidence2|Banana) ... P(Orange|Evidence) = z * Prob(Orange) * Prob(Evidence1|Orange) * Prob(Evidence2|Orange) ... P(Other|Evidence) = z * Prob(Other) * Prob(Evidence1|Other) * Prob(Evidence2|Other) ... Assign the class label of whichever is the highest number, and you are done. Despite the name, Naive Bayes turns out to be excellent in certain applications. Text classification is one area where it really shines. Hope that helps in understanding the concepts behind the Naive Bayes algorithm. edited Dec 25 '16 at 10:53 JulienD 3,02921743 answered Dec 12 '13 at 23:54 Ram Narasimhan
    Thanks for the very clear explanation! Easily one of the better ones floating around the web. Question: since each P(outcome/evidence) is multiplied by 1 / z=p(evidence) (which in the fruit case, means each is essentially the probability based solely on previous evidence), would it be correct to say that z doesn't matter at all for Naive Bayes? Which would thus mean that if, say, one ran into a long/sweet/yellow fruit that wasn't a banana, it'd be classified incorrectly. covariance Dec 21 '13 at 2:30
    @E.Chow Yes, you are correct in that computing z doesn't matter for Naive Bayes. (It is a way to scale the probabilities to be between 0 and 1.) Note that z is product of the probabilities of all the evidence at hand. (It is different from the priors which is the base rate of the classes.) You are correct: If you did find a Long/Sweet/Yellow fruit that is not a banana, NB will classify it incorrectly as a banana, based on this training set. The algorithm is a 'best probabilistic guess based on evidence' and so it will mis-classify on occasion. Ram Narasimhan Dec 21 '13 at 6:35
    Ram Narasimhan explained the concept very nicely here below is an alternative explanation through the code example of Naive Bayes in action It uses an example problem from this book on page 351 This is the data set that we will be using In the above dataset if we give the hypothesis = {"Age":'<=30', "Income":"medium", "Student":'yes' , "Creadit_Rating":'fair'} then what is the probability that he will buy or will not buy a computer. The code below exactly answers that question. Just create a file called named new_dataset.csv and paste the following content. Age,Income,Student,Creadit_Rating,Buys_Computer <=30,high,no,fair,no <=30,high,no,excellent,no 31-40,high,no,fair,yes >40,medium,no,fair,yes >40,low,yes,fair,yes >40,low,yes,excellent,no 31-40,low,yes,excellent,yes <=30,medium,no,fair,no <=30,low,yes,fair,yes >40,medium,yes,fair,yes <=30,medium,yes,excellent,yes 31-40,medium,no,excellent,yes 31-40,high,yes,fair,yes >40,medium,no,excellent,no Here is the code the comments explains everything we are doing here! [python] import pandas as pd import pprint class Classifier(): data = None class_attr = None priori = {} cp = {} hypothesis = None def __init__(self,filename=None, class_attr=None ): self.data = pd.read_csv(filename, sep=',', header =(0)) self.class_attr = class_attr ''' probability(class) = How many times it appears in cloumn __________________________________________ count of all class attribute ''' def calculate_priori(self): class_values = list(set(self.data[self.class_attr])) class_data = list(self.data[self.class_attr]) for i in class_values: self.priori[i] = class_data.count(i)/float(len(class_data)) print "Priori Values: ", self.priori ''' Here we calculate the individual probabilites P(outcome|evidence) = P(Likelihood of Evidence) x Prior prob of outcome ___________________________________________ P(Evidence) ''' def get_cp(self, attr, attr_type, class_value): data_attr = list(self.data[attr]) class_data = list(self.data[self.class_attr]) total =1 for i in range(0, len(data_attr)): if class_data[i] == class_value and data_attr[i] == attr_type: total+=1 return total/float(class_data.count(class_value)) ''' Here we calculate Likelihood of Evidence and multiple all individual probabilities with priori (Outcome|Multiple Evidence) = P(Evidence1|Outcome) x P(Evidence2|outcome) x ... x P(EvidenceN|outcome) x P(Outcome) scaled by P(Multiple Evidence) ''' def calculate_conditional_probabilities(self, hypothesis): for i in self.priori: self.cp[i] = {} for j in hypothesis: self.cp[i].update({ hypothesis[j]: self.get_cp(j, hypothesis[j], i)}) print "\nCalculated Conditional Probabilities: \n" pprint.pprint(self.cp) def classify(self): print "Result: " for i in self.cp: print i, " ==> ", reduce(lambda x, y: x*y, self.cp[i].values())*self.priori[i] if __name__ == "__main__": c = Classifier(filename="new_dataset.csv", class_attr="Buys_Computer" ) c.calculate_priori() c.hypothesis = {"Age":'<=30', "Income":"medium", "Student":'yes' , "Creadit_Rating":'fair'} c.calculate_conditional_probabilities(c.hypothesis) c.classify() output: Priori Values: {'yes': 0.6428571428571429, 'no': 0.35714285714285715} Calculated Conditional Probabilities: { 'no': { '<=30': 0.8, 'fair': 0.6, 'medium': 0.6, 'yes': 0.4 }, 'yes': { '<=30': 0.3333333333333333, 'fair': 0.7777777777777778, 'medium': 0.5555555555555556, 'yes': 0.7777777777777778 } } Result: yes ==> 0.0720164609053 no ==> 0.0411428571429 Hope it helps in better understanding the problem peace edited Mar 29 '16 at 12:00 answered Mar 29 '16 at 11:15 Sayed Zainul Abideen 437411 add a comment
    8 down vote I try to explain the Bayes rule with an example. Suppose that you know that 10% of people are smokers. You also know that 90% of smokers are men and 80% of them are above 20 years old. Now you see someone who is a man and 15 years old. You want to know the chance that he be a smoker: X = smoker | he is a man and under 20 As you know 10% of people are smokers your initial guess is 10% (prior probability, without knowing anything about the person) but the other evidences (that he is a man and he is 15) can contribute to this probability. Each evidence may increase or decrease this chance. For example the fact that he is a man may increase the chance that he is a smoker, providing that this percentage (being a man) among non-smokers is lower, for example, 40%. In other words being a man must be a good indicator of being a smoker rather than a non-smoker. We can show this contribution in another way. For each feature, you need to compare the commonness (probability) of that feature (f) independently against its probability under the given condition. (P(f) vs. P(f | x). For example, if we know that the probability of being a man is 90% in a society and 90% of smokers are also men, then knowing that someone is a man doesn't change anything (10% * (90% / 90%) = 10%). But if men contribute to 40% of the society, but 90% of the smokers, then being a man increases the chance of being an smoker (10% * (90% / 40%) = 22.5% ). In the same way, if the probability of being a man was 95% in a population, then regardless of the fact that the percentage of men among smokers is high (90%)!, the evidence of being a man decreases the chance of being an smoker! (10% * (90% / 95%) = 9.5%). So we have: P(X) = P(smoker)* (P(being a man | smoker)/P(being a man))* (P(under 20 | smoker)/ P(under 20)) Notice in this formula we assumed that being a man and being under 20 are independent features so we multiplied them, it means that knowing that someone is under 20 has no effect on guessing that he is man or woman. But it may not be true, for example maybe most adolescence in a society are men... To use this formula in a classifier The classifier is given some features (man and under 20) and it must decide if he is an smoker or not. It uses the above formula to find that. To gain the needed probabilities (90%, 10%, 80%...) it uses training set. for example it counts the people in the training set that are smokers and find they contribute 10% of the sample. Then for smokers checks how many of them are men or women .... how many are above 20 or under 20.... edited Nov 11 '16 at 17:04 answered Mar 12 '16 at 16:13 Ahmad
    Qn: What is naive about Naive Bayes? Ans: There's actually a very good example on Wikipedia: In simple terms, a naive Bayes classifier assumes that the presence (or absence) of a particular feature of a class is unrelated to the presence (or absence) of any other feature, given the class variable. For example, a fruit may be considered to be an apple if it is red, round, and about 4" in diameter. Even if these features depend on each other or upon the existence of the other features, a naive Bayes classifier considers all of these properties to independently contribute to the probability that this fruit is an apple. Basically, it's "naive" because it makes assumptions that may or may not turn out to be correct. answered May 16 '12 at 8:35 this.lau_
    The wikipedia article explains it correctly, but I disagree that "it makes assumptions that may or may not turn out to be correct". With right amount of training data it does a good job of filtering out the irrelevant parameters. The "naive" part is that is does not consider dependence between the parameters.. and hence may have to look at redundant data. Chip May 16 '12 at 8:50
    If your data is composed of a feature vector X = {x1, x2, ... x10} and your class labels Y = {y1, y2, .. y5}. Thus, a Bayes classifier identifies the correct class label as the one that maximizes the following formula : P(y/X) = P(X/y) * P(y) = P(x1,x2, ... x10/ y) * P(y) So for, it is still not Naive. However, it is hard to calculate P(x1,x2, ... x10/ Y), so we assume the features to be independent, this is what we call the Naive assumption, hence, we end up with the following formula instead P(y/X) = P(x1/y) * P(x2/y) * ... P(x10/y) * P(y) answered Aug 28 '13 at 19:44 gr33ndata
    It's called naive because it makes the assumption that all attributes are independent of each other. This assumption is why it's called naive as in lots of real world situations this does not fit. Despite this the classifier works extremely well in lots of real world situations and has comparable performance to neutral networks and SVM's in certain cases (though not all). answered May 22 '14 at 11:09 user3664740

    using Naive Bayes in real life (A seemingly brilliant) Writer mentions using Naive Bayes in real life (football pool)...
    ...The beauty of a Bayesian classifier is that it's simplicity itself to implement. The probabilities run away from you on a computer, because multiplying small probabilities will get you into the IEEE math error zone so quickly your head will spin, and your system gets all weirded out, but instead of multiplying probabilities, just use a little bit of seventh grade math (in my day) and simply sum their logarithms:
         p(x | X) = p(a | x) * p(b | x) * p(c | x) ...
    can be re-represented as:
         log p(x | X) = log p(a | x) + log p(b | x) + log p(c | x) ...
    And this way we (greatly) reduce going off into la-la land for your ALU.

    WEKA Related
    note: these seem to be all outdated; but anyway:
    
    WEKA FAQ: http://weka.wikispaces.com/Frequently+Asked+Questions
    IBM DevWorks Intro (Data mining with WEKA): https://www.ibm.com/developerworks/opensource/library/os-weka1/index.html
    Another Intro to WEKA: http://ortho.clmed.ncku.edu.tw/~emba/2006EMBA_MIS/3_16_2006/WekaIntro.pdf
    
    
    Qn: Learning Weka on the Command Line I am fairly new to Weka and even more new to Weka on the command line. I find documentation is poor and I am struggling to figure out a few things to do. For example, want to take two .arff files, one for training, one for testing and get an output of predictions for the missing labels in the test data. How can I do this? I have this code as a starting block java -classpath weka.jar weka.classifiers.meta.FilteredClassifier -t "training_file_with_missing_values.arff" -T "test_file_with_missing_values.arff" -F weka.filters.unsupervised.attribute.ReplaceMissingValues -- -c last -W weka.classifiers.functions.MultilayerPerceptron -- -L 0.3 -M 0.2 -H a Running that code gives me "Illegal option -c last" and I am not sure why. I am also not going to be using MLP as NN tend to be too slow when I have a few thousand features from the text data. I know how to change it to another classifier though (like NB or libSVM so that is good). But I am not sure how to add multiple filters in one call as I also need to add the StringToWordVector filter (and possibly the Reorder filter to make the class the last, instead of first attribute). And then how do I get it actually output me the prediction labels of each class? And then store so those in an arff with the initial data. machine-learning classification weka asked Mar 15 '13 at 20:21 Reily Bourne
    Weka is not really the shining example of documentation, but you can still find valuable information about it on their sites. You should start with the Primer. I understand that you want to classify text files, so you should also have a look at Text categorization with WEKA. The command line you posted in your question contains an error. I know, you copied it from my answer to another question, but I also just noticed it. You have to omit the -- -c last, because the ReplaceMissingValue filter doesn't like it. In the Primer it says: weka.filters.supervised Classes below weka.filters.supervised in the class hierarchy are for supervised filtering, i.e. taking advantage of the class information. A class must be assigned via -c, for WEKA default behaviour use -c last. but ReplaceMissingValue is an unsupervised filter, as is StringToWordVector. Multiple filters Adding multiple filter is also no problem, that is what the MultiFilter is for. The command line can get a bit messy, though: (I chose RandomForest here, because it is a lot faster than NN). java -classpath weka.jar weka.classifiers.meta.FilteredClassifier \ -t ~/weka-3-7-9/data/ReutersCorn-train.arff \ -T ~/weka-3-7-9/data/ReutersCorn-test.arff \ -F "weka.filters.MultiFilter \ -F weka.filters.unsupervised.attribute.StringToWordVector \ -F weka.filters.unsupervised.attribute.Standardize" \ -W weka.classifiers.trees.RandomForest -- -I 100 \ Making predictions Here is what the Primer says about getting the prediction: However, if more detailed information about the classifier's predictions are necessary, -p # outputs just the predictions for each test instance, along with a range of one-based attribute ids (0 for none). It is a good convention to put those general options like -p 0 directly after the class you're calling, so the command line would be java -classpath weka.jar weka.classifiers.meta.FilteredClassifier \ -t ~/weka-3-7-9/data/ReutersCorn-train.arff \ -T ~/weka-3-7-9/data/ReutersCorn-test.arff \ -p 0 \ -F "weka.filters.MultiFilter \ -F weka.filters.unsupervised.attribute.StringToWordVector \ -F weka.filters.unsupervised.attribute.Standardize" \ -W weka.classifiers.trees.RandomForest -- -I 100 \ Structure of WEKA classifiers/filters But as you can see, WEKA can get very complicated when calling it from the command line. This is due to the tree structure of WEKA classifiers and filters. Though you can run only one classifier/filter per command line, it can be structured as complex as you like. For the above command, the structure looks like this: The FilteredClassifier will initialize a filter on the training data set, filter both training and test data, then train a model on the training data and classify the given test data. FilteredClassifier | + Filter | + Classifier If we want multiple filters, we use the MultiFilter, which is only one filter, but it calls multiple others in the order they were given. FilteredClassifier | + MultiFilter | | | + StringToWordVector | | | + Standardize | + RandomForest The hard part of running something like this from the command line is assigning the desired options to the right classes, because often the option names are the same. For example, the -F option is used for the FilteredClassifier and the MultiFilter as well, so I had to use quotes to make it clear which -F belongs to what filter. In the last line, you see that the option -I 100, which belongs to the RandomForest, can't be appended directly, because then it would be assigned to FilteredClassifier and you will get Illegal options: -I 100. Hence, you have to add -- before it. Adding predictions to the data files Adding the predicted class label is also possible, but even more complicated. AFAIK this can't be done in one step, but you have to train and save a model first, then use this one for predicting and assigning new class labels. Training and saving the model: java -classpath weka.jar weka.classifiers.meta.FilteredClassifier \ -t ~/weka-3-7-9/data/ReutersCorn-train.arff \ -d rf.model \ -F "weka.filters.MultiFilter \ -F weka.filters.unsupervised.attribute.StringToWordVector \ -F weka.filters.unsupervised.attribute.Standardize" \ -W weka.classifiers.trees.RandomForest -- -I 100 \ This will serialize the model of the trained FilteredClassifier to the file rf.model. The important thing here is that the initialized filter will also be serialized, otherwise the test set wouldn't be compatible after filtering. Loading the model, making predictions and saving it: java -classpath weka.jar weka.filters.supervised.attribute.AddClassification \ -serialized rf.model \ -classification \ -remove-old-class \ -i ~/weka-3-7-9/data/ReutersCorn-test.arff \ -o pred.arff \ -c last Note: I want to add that before writing this answer here, I had no knowledge about making predictions from the command line whatsoever. I googled your problems and then came to this answer by trial and error ;) edited Nov 12 '13 at 12:58 answered Mar 16 '13 at 10:43 Sentry 3,30721832 1 This is one of the most helpful 'guides' to get started using WEKA for prediction purposes - Thanks! SPi Nov 11 '13 at 23:37 2 You are an absolute saint. Is there any way to give you more credit than marking up? You deserve 1k points for this. Gthoma2 Apr 26 '14 at 0:58
    A better way to do all that you want to use the GUI Explorer. Here is how to do all that you want: 1) Take two separate files for training and testing. Use 'Open File' under the Preprocess tab to choose your training file. Use 'Supplied Test Set' radio under the Classify tab to choose your test file. 2) Output the predictions for the missing labels. Use 'More Options' and choose 'Output Predictions' under the Classify tab to see predictions. 3) Use more than one filters Use 'Filter' under the Preprocess tab to apply as many filters as you want before classifying. 4) Make class the last attribute This is actually unnecessary. You can choose any attribute to be your class. A class is any attribute that you want the classifier to predict. Use the Nom(Class) dropdown on the Classify tab to choose which attribute is your class. answered Mar 15 '13 at 20:33 srrvnn 373618 The problem with your answer for (1) is that when I do that I get the error that they are not compatible. This is because they have different features and will not allow me to test them. That's why I believe I need to use the command line to get them to have the same features. Reily Bourne Mar 15 '13 at 22:26 @JoshWeissbock That's the problem, they must have the same features. Or you must filter them in a way that they have the same features. Sentry Mar 16 '13 at 0:23

    Qn: Precision/recall for multiclass-multilabel classification I'm wondering how to calculate precision and recall measures for multiclass multilabel classification, i.e. classification where there are more than two labels, and where each instance can have multiple labels? machine-learning classification precision-recall edited Mar 12 '16 at 13:31 user2314737
    Well, false would be if you didn't classified correctly, and true where it was correctly classified. Why do you worry about multiple labels? Thomas Jungblut Jan 25 '12 at 17:10 I found a similar question, this might be a duplicate: stackoverflow.com/questions/3856013/ mehaase May 13 '12 at 23:43 The answer is that you have to compute precision and recall for each class, then average them together. E.g. if you classes A, B, and C, then your precision is: (precision(A) + precision(B) + precision(C)) / 3 Same for recall. I'm no expert, but this is what I have determined based on the following sources: https://list.scms.waikato.ac.nz/pipermail/wekalist/2011-March/051575.html http://stats.stackexchange.com/questions/21551/how-to-compute-precision-recall-for-multiclass-multilabel-classification answered May 13 '12 at 23:46 mehaase 15.3k44257 3 If your data has unbalanced number of labels, this averaging may not reflect the real performance. tashuhka Aug 13 '14 at 14:25
    For multi-label classification you have two ways to go First consider the following. $n$ is the number of examples. $Y_i$ is the ground truth label assignment of the $i^{th}$ example.. $x_i$ is the $i^{th}$ example. $h(x_i)$ is the predicted labels for the $i^{th}$ example. Example based The metrics are computed in a per datapoint manner. For each predicted label its only its score is computed, and then these scores are aggregated over all the datapoints. Precision = $\frac{1}{n}\sum_{i=1}^{n}\frac{|Y_{i}\cap h(x_{i})|}{|h(x_{i})|}$ , The ratio of how much of the predicted is correct. The numerator finds how many labels in the predicted vector has common with the ground truth, and the ratio computes, how many of the predicted true labels are actually in the ground truth. Recall = $\frac{1}{n}\sum_{i=1}^{n}\frac{|Y_{i}\cap h(x_{i})|}{|Y_{i}|}$ , The ratio of how many of the actual labels were predicted. The numerator finds how many labels in the predicted vector has common with the ground truth (as above), then finds the ratio to the number of actual labels, therefore getting what fraction of the actual labels were predicted. There are other metrics as well. Label based Here the things are done labels-wise. For each label the metrics (eg. precision, recall) are computed and then these label-wise metrics are aggregated. Hence, in this case you end up computing the precision/recall for each label over the entire dataset, as you do for a binary classification (as each label has a binary assignment), then aggregate it. The easy way is to present the general form. This is just an extension of the standard multi-class equivalent. Macro averaged $\frac{1}{q}\sum_{j=1}^{q}B(TP_{j},FP_{j},TN_{j},FN_{j})$ Micro averaged $B(\sum_{j=1}^{q}TP_{j},\sum_{j=1}^{q}FP_{j},\sum_{j=1}^{q}TN_{j},\sum_{j=1}^{q}FN_{j})$ Here the $TP_{j},FP_{j},TN_{j},FN_{j}$ are the true positive, false positive, true negative and false negative counts respectively for only the $j^{th}$ label. Here $B$ stands for any of the confusion-matrix based metric. In your case you would plug in the standard precision and recall formulas. For macro average you pass in the per label count and then sum, for micro average you average the counts first, then apply your metric function. You might be interested to have a look into the code for the mult-label metrics here , which a part of the package mldr in R. Also you might be interested to look into the Java multi-label library MULAN. This is a nice paper to get into the different metrics: A Review on Multi-Label Learning Algorithms edited Sep 9 '16 at 21:42 answered Sep 9 '16 at 21:33 phoxis
    Let us assume that we have a 3-class multi classification problem with labels A, B and C. The first thing to do is to generate a confusion matrix. Note that the values in the diagonal are always the true positives (TP). Now, to compute recall for label A you can read off the values from the confusion matrix and compute: = TP_A/(TP_A+FN_A) = TP_A/(Total gold labels for A) Now, let us compute precision for label A, you can read off the values from the confusion matrix and compute: = TP_A/(TP_A+FP_A) = TP_A/(Total predicted as A) You just need to do the same for the remaining labels B and C. This applies to any multi-class classification problem. Here is the full article that talks about how to compute precision and recall for any multi-class classification problem, including examples. edited Oct 23 '14 at 20:55 honk
    Simple averaging will do if the classes are balanced. Otherwise, recall for each real class needs to be weighted by prevalence of the class, and precision for each predicted label needs to be weighted by the bias (probability) for each label. Either way you get Rand Accuracy. A more direct way is to make a normalized contingency table (divide by N so table adds up to 1 for each combination of label and class) and add the diagonal to get Rand Accuracy. But if classes aren't balanced, the bias remains and a chance corrected method such as kappa is more appropriate, or better still ROC analysis or a chance correct measure such as informedness (height above the chance line in ROC). answered Mar 20 '15 at 7:18 David M W Powers

    Qn: How to interpret weka classification? How can we interpret the classification result in weka using naive bayes? How is mean, std deviation, weight sum and precision calculated? How is kappa statistic, mean absolute error, root mean squared error etc calculated? What is the interpretation of the confusion matrix? computer-vision classification weka shareimprove this question edited May 10 '12 at 20:54 Atilla Ozgur Ans: Below is some sample output for a naive Bayes classifier, using 10-fold cross-validation. There's a lot of information there, and what you should focus on depends on your application. I'll explain some of the results below, to get you started. === Stratified cross-validation === === Summary === Correctly Classified Instances 71 71 % Incorrectly Classified Instances 29 29 % Kappa statistic 0.3108 Mean absolute error 0.3333 Root mean squared error 0.4662 Relative absolute error 69.9453 % Root relative squared error 95.5466 % Total Number of Instances 100 === Detailed Accuracy By Class === TP Rate FP Rate Precision Recall F-Measure ROC Area Class 0.967 0.692 0.686 0.967 0.803 0.709 0 0.308 0.033 0.857 0.308 0.453 0.708 1 Weighted Avg. 0.71 0.435 0.753 0.71 0.666 0.709 === Confusion Matrix === a b <-- classified as 59 2 | a = 0 27 12 | b = 1 The correctly and incorrectly classified instances show the percentage of test instances that were correctly and incorrectly classified. The raw numbers are shown in the confusion matrix, with a and b representing the class labels. Here there were 100 instances, so the percentages and raw numbers add up, aa + bb = 59 + 12 = 71, ab + ba = 27 + 2 = 29. The percentage of correctly classified instances is often called accuracy or sample accuracy. It has some disadvantages as a performance estimate (not chance corrected, not sensitive to class distribution), so you'll probably want to look at some of the other numbers. ROC Area, or area under the ROC curve, is my preferred measure. Kappa is a chance-corrected measure of agreement between the classifications and the true classes. It's calculated by taking the agreement expected by chance away from the observed agreement and dividing by the maximum possible agreement. A value greater than 0 means that your classifier is doing better than chance (it really should be!). The error rates are used for numeric prediction rather than classification. In numeric prediction, predictions aren't just right or wrong, the error has a magnitude, and these measures reflect that. Hopefully that will get you started. edited Nov 18 '11 at 12:45 answered Aug 16 '10 at 0:33 michaeltwofish -------------------------------------- To elaborate on michaeltwofish's answer, some notes on the remaining values: TP Rate: rate of true positives (instances correctly classified as a given class) FP Rate: rate of false positives (instances falsely classified as a given class) Precision: proportion of instances that are truly of a class divided by the total instances classified as that class Recall: proportion of instances classified as a given class divided by the actual total in that class (equivalent to TP rate) F-Measure: A combined measure for precision and recall calculated as 2 * Precision * Recall / (Precision + Recall) As for the ROC area measurement, I agree with michaeltwofish that this is one of the most important values output by Weka. An "optimal" classifier will have ROC area values approaching 1, with 0.5 being comparable to "random guessing" (similar to a Kappa statistic of 0). It should be noted that the "balance" of the data set needs to be taken into account when interpreting results. Unbalanced data sets in which a disproportionately large amount of instances belong to a certain class may lead to high accuracy rates even though the classifier may not necessarily be particularly good. Further reading: https://www.cs.auckland.ac.nz/courses/compsci367s1c/tutorials/IntroductionToWeka.pdf http://en.wikipedia.org/wiki/Receiver_operating_characteristic#Basic_concept http://en.wikipedia.org/wiki/Information_retrieval#Performance_and_correctness_measures edited Mar 19 '14 at 16:30 projekt-fisch 6411 answered Feb 4 '14 at 11:31 Hybrid System

    Qn: How to read the classifier confusion matrix in WEKA Sorry, I am new to WEKA and just learning. In my decision tree (J48) classifier output, there is a confusion Matrix: a b <----- classified as 130 8 a = functional 15 150 b = non-functional How do I read this matrix? What's the difference between a & b? Also, can anyone explain to me what domain values are? classification weka decision-tree shareimprove this question edited Dec 12 '13 at 17:01 Sam Rad Ans: Have you read the wikipedia page on confusion matrices? The text around the matrix is arranged slightly differently in their example (row labels on the left instead of on the right), but you read it just the same. The row indicates the true class, the column indicates the classifier output. Each entry, then, gives the number of instances of that were classified as . In your example, 15 Bs were (incorrectly) classified as As, 150 Bs were correctly classified as Bs, etc. As a result, all correct classifications are on the top-left to bottom-right diagonal. Everything off that diagonal is an incorrect classification of some sort. edited Oct 23 '13 at 16:19 answered Mar 5 '13 at 1:28 Junuxx
    I'd put it this way: The confusion matrix is Weka reporting on how good this J48 model is in terms of what it gets right, and what it gets wrong. In your data, the target variable was either "functional" or "non-functional;" the right side of the matrix tells you that column "a" is functional, and "b" is non-functional. The columns tell you how your model classified your samples - it's what the model predicted: The first column contains all the samples which your model thinks are "a" - 145 of them, total The second column contains all the samples which your model thinks are "b" - 158 of them The rows, on the other hand, represent reality: The first row contains all the samples which really are "a" - 138 of them, total The second row contains all the samples which really are "b" - 165 of them Knowing the columns and rows, you can dig into the details: Top left, 130, are things your model thinks are "a" which really are "a" <- these were correct Bottom left, 15, are things your model thinks are "a" but which are really "b" <- one kind of error Top right, 8, are things your model thinks are "b" but which really are "a" <- another kind of error Bottom right, 150 are things your model thinks are "b" which really are "b" So top-left and bottom-right of the matrix are showing things your model gets right. Bottom-left and top-right of the matrix are are showing where your model is confused. answered Oct 28 '14 at 19:14 Mental Nomad

    NLP Links
    https://www.uclassify.com/
    uClassify is a free machine learning web service where you can easily create and use text classifiers.
    We offer generous licenses, you can make 500 free calls per day!
    Join 41022 developers and bring machine learning into your project! We provide simple and powerful JSON and XML APIs that allows you to use, create, train private and public classifiers
    We love machine learning and so does our community who have created 3824 classifiers! Sentiment, Topics, Language detection, IAB, Mood, Gender, Age and Myers Briggs are some of our most popular and many are available in multiple languages!
    
    http://text-processing.com/ Natural Language Processing APIs and Python NLTK Demos: Natural Language Text Processing APIs The Text Processing API supports the following functionality: Stemming & Lemmatization Sentiment Analysis Tagging and Chunk Extraction Phrase Extraction & Named Entity Recognition The APIs are currently open & free, but limited. If you'd like higher limits, then signup for the Mashape Text-Processing API. If you have any questions, please checkout the FAQ or the StreamHacker blog. Python NLTK Demos You can also see demos of all the API functionality: Stemming Demo Sentiment Analysis Demo Tagging and Chunk Extraction Demo Tokenization Demo



    Mallet

    Quick Start				http://mallet.cs.umass.edu/quick-start.php
    Document Classification Quck Start	http://mallet.cs.umass.edu/classification.php
    
    MALLET is a Java toolkit for machine learning applied to natural language. It provides facilities for document classification, information extraction, part-of-speech tagging, noun phrase segmentation, general finite state transducers and classification, and much more---all desgined to be extremely efficient for large data and feature sets. Although quite mature in functionality, documentation is still sparse.
    
    The toolkit is Open Source Software, and is released under the Common Public License.
    
    From the dev guide:
    
    Document Classification Developer's Guide
    
    MALLET provides a simple interface to a large collection of classification algorithms. The examples provided here include some of the common tasks required to add classification techniques to your software.
    
    All classifiers (MaxEnt, NaiveBayes, DecisionTree, etc.) extend the Classifier object. Each type of classifier has its own trainer class, all of which extend the ClassifierTrainer class. In this example, we train a MaxEnt classifier using a list of training instances (for information on creating instance lists, see the data import developer's guide).
    
    Allows saving trained Classifiers; allows using multiple algorythms (Naive B. default, also
    has options incl Max Entropy/C45/DecisionTree/others) see http://mallet.cs.umass.edu/classification.php
    
    In addition, MALLET provides tools for evaluating classifiers.
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    
    Prof. Andrew McCallum
    Computer Science Department
    University of Massachusetts Amherst
    
    (guy behind MALLET)
    
    Bow: A Toolkit for Statistical Language Modeling, Text Retrieval, Classification and Clustering
    
    Bow (or libbow) is a library of C code useful for writing statistical text analysis, language modeling and information retrieval programs. The current distribution includes the library, as well as front-ends for document classification (rainbow), document retrieval (arrow) and document clustering (crossbow).
    
    Bow Library Front-Ends
    
    Provided in the library source distribution, there are currently three executable programs based on the library.
    Rainbow is an executable program that does document classification. While mostly designed for classification by naive Bayes, it also provides TFIDF/Rocchio, Probabilistic Indexing and K-nearest neighbor.
    Arrow is an executable program that does document retrieval. It currently only performs simple TFIDF-based retrieval.
    Crossbow is a an executable program that does document clustering (and also classification).
    
    Src code: http://www.cs.cmu.edu/~mccallum/bow/src
    The code conforms to the GNU coding standards. It is released under the Library GNU Public License (LGPL).
    
    

    Snippets of some Mallet classes to @Override
    As the process moves thro the pipe; the instance data can change type from 1 data type to another.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    /**Alphabet.java
     *  A mapping between integers and objects where the mapping in each
     * direction is efficient.  Integers are assigned consecutively, starting
     * at zero, as objects are added to the Alphabet.  Objects can not be
     * deleted from the Alphabet and thus the integers are never reused.
     * 
     * The most common use of an alphabet is as a dictionary of feature names
     * associated with a {@link cc.mallet.types.FeatureVector} in an
     * {@link cc.mallet.types.Instance}. In a simple doc classification usage,
     * each unique word in a document would be a unique entry in the Alphabet
     * with a unique integer associated with it.   FeatureVectors rely on
     * the integer part of the mapping to efficiently represent the subset of
     * the Alphabet present in the FeatureVector.
     *
     * @see FeatureVector
     * @see Instance
     * @see cc.mallet.pipe.Pipe
     */
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    Text2Classify.java:
    	while (iterator.hasNext()) {
    			Instance instance = iterator.next();
    			
    			Labeling labeling = classifier.classify(instance).getLabeling();
    
    			[StringBuilder] output.append(instance.getName());
    
    			for (int location = 0; location < labeling.numLocations(); location++) {
    				output.append("\t" + labeling.labelAtLocation(location));
    				output.append("\t" + labeling.valueAtLocation(location));
    			}
    			out.println(output);
    
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    Text2Vectors.java:
    /**
     * Convert document files into vectors (a persistent instance list).
    
    		ArrayList pipeList = new ArrayList();
    
    			// Convert the "target" object into a numeric index
    			//  into a LabelAlphabet.
    			pipeList.add(new Target2Label());
    
    			// Set "data" to the file's contents. "data" is now a String.
    			pipeList.add( new Input2CharSequence(encoding.value) );
    
    		// Tokenize the input: first compile the tokenization pattern
    		tokenPattern = Pattern.compile(tokenRegex.value);
    
    			// Add the tokenizer
    			pipeList.add(new CharSequence2TokenSequence(tokenPattern));
    
    
    		// So far we have a sequence of Token objects that contain 
    		//  String values. Look these up in an alphabet and store integer IDs
    		//  ("features") instead of Strings.
    			pipeList.add( new TokenSequence2FeatureSequenceWithBigrams() );
    
    	// write vector file	ObjectOutputStream oos;......
    	oos.writeObject(instances);
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    public class Instance{
    	protected Object data;		// The input data in digested form, e.g. a FeatureVector
    	protected Object target;	// Output data; often a label associated with the instance
    	protected Object name;		// A readable name of the source, e.g. filename
    	protected Object source;	/* The input in a reproducable form, e.g. enabling re-print of
    					 string w/ POS tags, usually without target information,
    					 e.g. human-readable sourceinformation, such as the original text */
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    
    package cc.mallet.util;
    
    import cc.mallet.types.*;
    import java.io.*;
    
    public class InstanceListPrinter {
    
    	public static void main(String[] args) throws Exception {
    		InstanceList instances = InstanceList.load(new File(Paths.get(System.getProperty("user.dir"), "")));
    
    		for (Instance instance: instances) {
    			System.out.println("Name: " + instance.getName());
    			System.out.println("Target: " + instance.getTarget());
    			System.out.println("Data: " + instance.getData());
    		}
    	}
    
    }
    

    Mallet docs

    MALLET Docs


    Note: see "User-provided Labeled Features" in Document Classification with Expectation Constraints

    Quick Start
    Once you have downloaded and installed MALLET, the easiest way to get started is through the mallet script. If you installed MALLET in the directory ~/Applications/mallet, this script will be in ~/Applications/mallet/bin. The following instructions assume that your current working directory is the MALLET directory. To use the script, specify a command and then some number of options, in this pattern:
    bin/mallet [command] --option value --option value ...
    Type bin/mallet to get a list of commands, and use the option --help with any command to get a description of valid options.
    Data Import: To load all documents in specified directories into a MALLET data file, with class labels specified by the directory, use the command
    bin/mallet import-dir --input [dir1] [dir2] [...] --output data.mallet
    For more information, and many more options, see the data import quick start guide.
    Classification: To evaluate MaxEnt and Naïve Bayes classifiers trained on this data using 10-fold cross validation, use the command
    bin/mallet train-classifier --input data.mallet \
      --trainer MaxEnt --trainer NaiveBayes \
      --training-portion 0.9 --num-trials 10
    This command will run 10 trials, in which the input data is randomly split into 90% training instances and 10% testing instances. For each trial, MALLET trains a MaxEnt classifier and a Naïve Bayes classifier on the training instances, then prints accuracy results and a matrix of correct and predicted labels for each classifier. For more information about training and evaluating classifiers, see the classification quick start guide.

    Document Classification
    A classifier is an algorithm that distinguishes between a fixed set of classes, such as "spam" vs. "non-spam", based on labeled training examples. MALLET includes implementations of several classification algorithms, including Naïve Bayes, Maximum Entropy, and Decision Trees. In addition, MALLET provides tools for evaluating classifiers.
    Training Maximum Entropy document classifiers using Generalized Expectation Criteria is described in this separate tutorial.
    To get started with classification, first load your data into MALLET format as described in the importing data section.
    Training a classifier: To train a classifier on a MALLET data file called training.mallet, use the command
    bin/mallet train-classifier --input training.mallet --output-classifier my.classifier
    Run the train-classifier command with the option --help for a full list of options, many of which are described below.
    Choosing an algorithm: The default classification algorithm is Naïve Bayes. To select another algorithm, use the --trainer option:
    bin/mallet train-classifier --input training.mallet --output-classifier my.classifier \
      --trainer MaxEnt
    Currently supported algorithms include MaxEnt, NaiveBayes, C45, DecisionTree and many others. See the JavaDoc API for the cc.mallet.classify package to see the complete current list of Trainer classes.
    Evaluation: No classifier is perfect, so it is important to know whether a classifier is producing good results on data not used in training. To split a single set of labeled instances into training and testing lists, you can use a command like this:
    bin/mallet train-classifier --input labeled.mallet --training-portion 0.9
    This command will random split the data into 90% training instances, which will be used to train the classifier, and 10% testing instances. MALLET will use the classifier to predict the class labels of the testing instances, compare those to the true labels, and report results.
    Reporting options: The default report option is a "confusion matrix" showing, for each true class label (one per row), the number of instances assigned to each predicted class label (in the colums). Off-diagonal elements represent prediction errors. In addition, you can choose to report other statistics such as accuracy and F1 (a balance between precision and recall). To report accuracy for the training data and F1 for the class label "sports" on test data, use the command
    bin/mallet train-classifier --input labeled.mallet --training-portion 0.9 \
      --report train:accuracy test:f1:sports
    Multiple random splits / Cross-validation: Performing multiple test/train splits can provide a better view of the performance of a classifier. To use 10 random 90:10 splits, use the options --training-portion 0.9 --num-trials 10. To use 10-fold cross-validation use --cross-validation 10.
    Comparing multiple algorithms: It is possible to train more than one classifier for each trial, by simply providing more than one --trainer option:
    bin/mallet train-classifier --input labeled.mallet --training-portion 0.9 \
      --trainer MaxEnt --trainer NaiveBayes
    Note that this option cannot take more than one argument, so you must add --trainer [type] for every algorithm.
    Applying a Saved Classifier to New Unlabeled Data: To apply a saved classifier to new unlabeled data, use Csv2Classify (for one-instance-per-line data) or Text2Classify (for one-instance-per-file data).
    bin/mallet classify-file --input data --output - --classifier classifier
    bin/mallet classify-dir --input datadir --output - --classifier classifier
    Using the above commands, classifications are written to standard output. Note that the input for these commands is a raw text file, not an imported Mallet file. This command is designed to be used in "production" mode, where labels are not available.

    Importing data
    MALLET represents data as lists of "instances". All MALLET instances include a data object. An instance can also include a name and (in classification contexts) a label. For example, if the application is guessing the language of web pages, an instance might consist of a vector of word counts (data), the URL of the page (name) and the language of the page (label).
    For information about the MALLET data import API, see the data import developer's guide.
    There are two primary methods for importing data into MALLET format, first when the source data consists of many separate files, and second when the data is contained in a single file, with one instance per line.
    One instance per file: After downloading and building MALLET, change to the MALLET directory. Assume that text-only (.txt) versions of English web pages are in files in a directory called sample-data/web/en and text-only versions of German pages are in sample-data/web/de (download sample data). Now run this command:
    bin/mallet import-dir --input sample-data/web/* --output web.mallet
    MALLET will use the directory names as labels and the filenames as instance names. Note: make sure you are in the mallet directory, not the mallet/bin directory; otherwise you will get a ClassNotFoundException exception.
    One file, one instance per line: Assume the data is in the following format:
    [URL]  [language]  [text of the page...]
    After downloading and building MALLET, change to the MALLET directory and run the following command:
    bin/mallet import-file --input /data/web/data.txt --output web.mallet
    In this case, the first token of each line (whitespace delimited, with optional comma) becomes the instance name, the second token becomes the label, and all additional text on the line is interpreted as a sequence of word tokens. Note that the data in this case will be a vector of feature/value pairs, such that a feature consists of a distinct word type and the value is the number of times that word occurs in the text.
    There are many additional options to the import-dir and import-file commands. Add the --help option to either of these commands to get a full list. Some commonly used options to either command are:
    --keep-sequence. This option preserves the document as a sequence of word features, rather than a vector of word feature counts. Use this option for sequence labeling tasks. The MALLET topic modeling toolkit also requires feature sequences rather than feature vectors.
    --preserve-case. MALLET by default converts all word features to lowercase.
    --remove-stopwords. This option tells MALLET to ignore a standard list of very common English adverbs, conjunctions, pronouns and prepositions. There are several other options related to stopword specification.
    --token-regex. MALLET divides documents into tokens using a regular expression. By default, a token is one or more characters in [A-Za-z]. Better options include:
    • For non-English text, a good choice is --token-regex '[\p{L}\p{M}]+', which means Unicode letters and marks (required for Indic scripts). MALLET currently does not support Chinese or Japanese word segmentation.
    • If you would like to include punctuation inside tokens (for example contractions like "don't" and internet addresses), you might use --token-regex '[\p{L}\p{P}]*\p{L}', which means any sequence of letters or punctuation marks that ends in a letter. Note that this will include quotation marks at the beginning of words.
    SVMLight format: SVMLight-style data in the format
    target feature:value feature:value ...
    
    can be imported with
    bin/mallet import-svmlight --input train test --output train.mallet test.mallet
    
    Note that the input and output arguments can take multiple files that are processed together using the same Pipe. Note that the target and feature fields can be either indices or strings. If they are indices, note that the indices in the Mallet alphabets and indices in the file may be different, though the data is equivalent. Real valued targets are not supported.

    Data Import for Java Developers
    If you require greater flexibility than the command-line data import tools offer or you would like to embed MALLET into a larger application, it is useful to understand the MALLET data import API. This API is based around two types of classes: data, in the form of Instance objects contained in InstanceList objects; and classes that operate on data, iterators and pipes.
    A MALLET Instance consists of four fields, which can be of any Object type.
    • Name: This field should contain a value that identifies this instance, usually a String.
    • Label: The label is primarily used in classification applications. It is usually a value within a finite set of labels, a LabelAlphabet.
    • Data: Generally a FeatureVector (unordered feature-value pairs) or a FeatureSequence (an ordered list of features, for example a sequence of words).
    • Source: A representation of the original state of the instance. Often a File object or a String containing the original, untokenized text. Frequently null.
    Instances are usually stored in InstanceList objects, which inherit from ArrayList. Currently the standard format for storing MALLET data on disk is serialized InstanceLists.
    When importing data, it is common to pass an instance through a series of processing steps. These steps are represented in MALLET using the Pipe interface. There are a large number of Pipes -- see the MALLET javadoc API for details. A typical import pipeline begins with an Iterator, such as a FileIterator for data that is in one file per instance or a CsvIterator for data that is in a single file, which is then passed through a SerialPipes object that wraps a sequence of Pipes.
    The following example code takes the name of a directory as input and recurses through all sub-directories, loading files that end in .txt as instances. Sample data is available for download. Each instance is passed through a series of pipes, defined in the buildPipe() method. The label of each instance is taken from the name of the directory that contains the instance.
    package edu.umass.cs.iesl.mimno;
    
    import java.io.*;
    import java.util.*;
    import java.util.regex.*;
    
    import cc.mallet.pipe.*;
    import cc.mallet.pipe.iterator.*;
    import cc.mallet.types.*;
    
    public class ImportExample {
    
        Pipe pipe;
    
        public ImportExample() {
            pipe = buildPipe();
        }
    
        public Pipe buildPipe() {
            ArrayList pipeList = new ArrayList();
    
            // Read data from File objects
            pipeList.add(new Input2CharSequence("UTF-8"));
    
            // Regular expression for what constitutes a token.
            //  This pattern includes Unicode letters, Unicode numbers, 
            //   and the underscore character. Alternatives:
            //    "\\S+"   (anything not whitespace)
            //    "\\w+"    ( A-Z, a-z, 0-9, _ )
            //    "[\\p{L}\\p{N}_]+|[\\p{P}]+"   (a group of only letters and numbers OR
            //                                    a group of only punctuation marks)
            Pattern tokenPattern =
                Pattern.compile("[\\p{L}\\p{N}_]+");
    
            // Tokenize raw strings
            pipeList.add(new CharSequence2TokenSequence(tokenPattern));
    
            // Normalize all tokens to all lowercase
            pipeList.add(new TokenSequenceLowercase());
    
            // Remove stopwords from a standard English stoplist.
            //  options: [case sensitive] [mark deletions]
            pipeList.add(new TokenSequenceRemoveStopwords(false, false));
    
            // Rather than storing tokens as strings, convert 
            //  them to integers by looking them up in an alphabet.
            pipeList.add(new TokenSequence2FeatureSequence());
    
            // Do the same thing for the "target" field: 
            //  convert a class label string to a Label object,
            //  which has an index in a Label alphabet.
            pipeList.add(new Target2Label());
    
            // Now convert the sequence of features to a sparse vector,
            //  mapping feature IDs to counts.
            pipeList.add(new FeatureSequence2FeatureVector());
    
            // Print out the features and the label
            pipeList.add(new PrintInputAndTarget());
    
            return new SerialPipes(pipeList);
        }
    
        public InstanceList readDirectory(File directory) {
            return readDirectories(new File[] {directory});
        }
    
        public InstanceList readDirectories(File[] directories) {
            
            // Construct a file iterator, starting with the 
            //  specified directories, and recursing through subdirectories.
            // The second argument specifies a FileFilter to use to select
            //  files within a directory.
            // The third argument is a Pattern that is applied to the 
            //   filename to produce a class label. In this case, I've 
            //   asked it to use the last directory name in the path.
            FileIterator iterator =
                new FileIterator(directories,
                                 new TxtFilter(),
                                 FileIterator.LAST_DIRECTORY);
    
            // Construct a new instance list, passing it the pipe
            //  we want to use to process instances.
            InstanceList instances = new InstanceList(pipe);
    
            // Now process each instance provided by the iterator.
            instances.addThruPipe(iterator);
    
            return instances;
        }
    
        public static void main (String[] args) throws IOException {
    
            ImportExample importer = new ImportExample();
            InstanceList instances = importer.readDirectory(new File(args[0]));
            instances.save(new File(args[1]));
    
        }
    
        /** This class illustrates how to build a simple file filter */
        class TxtFilter implements FileFilter {
    
            /** Test whether the string representation of the file 
             *   ends with the correct extension. Note that {@ref FileIterator}
             *   will only call this filter if the file is not a directory,
             *   so we do not need to test that it is a file.
             */
            public boolean accept(File file) {
                return file.toString().endsWith(".txt");
            }
        }
    
    }
    

    Document Classification
    A classifier is an algorithm that distinguishes between a fixed set of classes, such as "spam" vs. "non-spam", based on labeled training examples. MALLET includes implementations of several classification algorithms, including Naïve Bayes, Maximum Entropy, and Decision Trees. In addition, MALLET provides tools for evaluating classifiers.
    Training Maximum Entropy document classifiers using Generalized Expectation Criteria is described in this separate tutorial.
    To get started with classification, first load your data into MALLET format as described in the importing data section.
    Training a classifier: To train a classifier on a MALLET data file called training.mallet, use the command
    bin/mallet train-classifier --input training.mallet --output-classifier my.classifier
    Run the train-classifier command with the option --help for a full list of options, many of which are described below.
    Choosing an algorithm: The default classification algorithm is Naïve Bayes. To select another algorithm, use the --trainer option:
    bin/mallet train-classifier --input training.mallet --output-classifier my.classifier \
      --trainer MaxEnt
    Currently supported algorithms include MaxEnt, NaiveBayes, C45, DecisionTree and many others. See the JavaDoc API for the cc.mallet.classify package to see the complete current list of Trainer classes.
    Evaluation: No classifier is perfect, so it is important to know whether a classifier is producing good results on data not used in training. To split a single set of labeled instances into training and testing lists, you can use a command like this:
    bin/mallet train-classifier --input labeled.mallet --training-portion 0.9
    This command will random split the data into 90% training instances, which will be used to train the classifier, and 10% testing instances. MALLET will use the classifier to predict the class labels of the testing instances, compare those to the true labels, and report results.
    Reporting options: The default report option is a "confusion matrix" showing, for each true class label (one per row), the number of instances assigned to each predicted class label (in the colums). Off-diagonal elements represent prediction errors. In addition, you can choose to report other statistics such as accuracy and F1 (a balance between precision and recall). To report accuracy for the training data and F1 for the class label "sports" on test data, use the command
    bin/mallet train-classifier --input labeled.mallet --training-portion 0.9 \
      --report train:accuracy test:f1:sports
    Multiple random splits / Cross-validation: Performing multiple test/train splits can provide a better view of the performance of a classifier. To use 10 random 90:10 splits, use the options --training-portion 0.9 --num-trials 10. To use 10-fold cross-validation use --cross-validation 10.
    Comparing multiple algorithms: It is possible to train more than one classifier for each trial, by simply providing more than one --trainer option:
    bin/mallet train-classifier --input labeled.mallet --training-portion 0.9 \
      --trainer MaxEnt --trainer NaiveBayes
    Note that this option cannot take more than one argument, so you must add --trainer [type] for every algorithm.
    Applying a Saved Classifier to New Unlabeled Data: To apply a saved classifier to new unlabeled data, use Csv2Classify (for one-instance-per-line data) or Text2Classify (for one-instance-per-file data).
    bin/mallet classify-file --input data --output - --classifier classifier
    bin/mallet classify-dir --input datadir --output - --classifier classifier
    Using the above commands, classifications are written to standard output. Note that the input for these commands is a raw text file, not an imported Mallet file. This command is designed to be used in "production" mode, where labels are not available.

    Tutorial: Training Maximum Entropy document classifiers using Generalized Expectation Criteria

    Use Mallet 2.0.7 or greater for this code. The implementation of GE training of MaxEnt models in pre-2.0.7 versions of Mallet contains a bug that often results in low accuracy when the number of constraints is small. Specifically, the Gaussian prior was not always being included in the objective function value, which caused problems in numerical optimization. (Published experiments, i.e. [Druck, Mann, and McCallum 2008], used a different implementation and are not affected by this bug.)
    To report problems with this code (including obtaining unexpected results), please contact gdruck@cs.umass.edu.

    Document Classification with Expectation Constraints

    In this tutorial we describe training maximum entropy document classifiers with expectation constraints that specify affinities between words and labels. See [Druck, Mann, and McCallum 2008] for more information. We assume that the task is classifying baseball and hockey documents and that we have processed data sets baseball-hockey.train.vectors and baseball-hockey.test.vectors.
    These methods require unlabeled training data. We can hide labels using Vectors2Vectors.
    java cc.mallet.classify.tui.Vectors2Vectors \
    --input baseball-hockey.train.vectors \
    --output baseball-hockey.unlabeled.vectors \
    --hide-targets
    
    If the data is truly unlabeled, then the easiest way to import it is to assign an arbitrary label to each document, ensuring that each label is used at least once.

    Generalized Expectation

    Suppose we know a priori that the words baseball and puck are good indicators of labels baseball and hockey respectively. Specifically, suppose that we estimate that 90% of the documents in which the word puck occurs should be labeled hockey, and similarly for baseball. We may specify these constraints in a file as follows.
    baseball hockey:0.1 baseball:0.9
    puck hockey:0.9 baseball:0.1
    
    The general format for a constraints file is:
    feature_name label_name=probability label_name=probability ...
    
    The number of probabilities must be equal to the number of labels. The feature and label names must match the names in the data and target alphabets exactly.
    The following command trains a MaxEnt classifier with the above constraints (assumed to be in file baseball-hockey.constraints) using Generalized Expectation (GE) (as described in [Druck, Mann, and McCallum 2008]). We specify the constraints file using constraintsFile and specify a regularization penalty with gasussianPriorVariance.
    mallet train-classifier \
    --training-file   baseball-hockey.unlabeled.vectors \
    --testing-file    baseball-hockey.test.vectors \
    --trainer "MaxEntGETrainer,gaussianPriorVariance=0.1,
      constraintsFile=\"baseball-hockey.constraints\"" \
    --report test:accuracy
    

    L2 Penalty

    By default, the difference between the target and model expectations is penalized using KL divergence (as in [Druck, Mann, and McCallum 2008]). Instead, we can impose an L2 penalty using the L2 option.
    mallet train-classifier \
    --training-file   baseball-hockey.unlabeled.vectors \
    --testing-file    baseball-hockey.test.vectors \
    --trainer "MaxEntGETrainer,gaussianPriorVariance=0.1,L2=true,
      constraintsFile=\"baseball-hockey.constraints\"" \
    --report test:accuracy
    

    API

    The underlying trainer is cc.mallet.classify.MaxEntGETrainer. New GE constraints and penalties for training MaxEnt models can be defined by implementing cc.mallet.classify.constraints.ge.MaxEntGEConstraint.

    Generalized Expectation with Target Ranges

    It is also possible to specify L2 constraints that do not impose a penalty if the model expectation is within some target range. For example, we can encourage model expectations to be in the range 90-100%.
    baseball baseball:0.9,1 
    hockey hockey:0.9,1
    
    In general, the format for range constraints is:
    feature_name label_name=lower_probability,upper_probability ...
    
    Support for such constraints is provided by MaxEntGERangeTrainer.
    mallet train-classifier \
    --training-file   baseball-hockey.unlabeled.vectors \
    --testing-file    baseball-hockey.test.vectors \
    --trainer "MaxEntGERangeTrainer,gaussianPriorVariance=0.1,
      constraintsFile=\"baseball-hockey.range_constraints\"" \
    --report test:accuracy
    

    API

    The underlying trainer is cc.mallet.classify.MaxEntGERangeTrainer. New GE constraints and penalties for training MaxEnt models can be defined by implementing cc.mallet.classify.constraints.ge.MaxEntGEConstraint.

    Posterior Regularization

    There is also support for training MaxEnt models with Posterior Regularization (PR) [Ganchev, Graça, Gillenwater, and Taskar 2010]. The following command trains a MaxEnt classifier using the above constraints (assumed to be in file baseball-hockey.constraints) with PR for 100 iterations. We specify the constraints file using constraintsFile and specify a regularization penalty for each step (c.f. [Bellare, Druck, and McCallum 2009]) with pGasussianPriorVariance and qGaussianPriorVariance.
    mallet train-classifier \
    --training-file   baseball-hockey.unlabeled.vectors \
    --testing-file    baseball-hockey.test.vectors \
    --trainer "MaxEntPRTrainer,minIterations=100,maxIterations=100,
      pGaussianPriorVariance=0.1,qGaussianPriorVariance=1000,
      constraintsFile=\"baseball-hockey.constraints\"" \
    --report test:accuracy
    

    API

    The underlying trainer is cc.mallet.classify.MaxEntPRTrainer. New PR constraints and penalties for training MaxEnt models can be defined by implementing cc.mallet.classify.constraints.pr.MaxEntPRConstraint.

    Automated Methods for Obtaining Constraints

    Below, we discuss machine-assisted methods for obtaining constraints. Note that these methods do not yet support target ranges.

    User-provided Labeled Features

    Rather than specifying the target expectations directly, we may instead specify "labels" for features, and have these converted into target expectations. Suppose we know that the word puck is associated with hockey, and the word baseball is associated with the label baseball. We may specify these labeled features in a file (baseball-hockey.labeled_features) as follows.
    baseball baseball
    puck hockey
    
    The general format for a file with labeled features is:
    feature_name label_name label_name ...
    
    Vectors2FeatureConstraints can estimate target expectations from a file with labeled features. A simple heuristic for obtaining expectations from labeled features is to uniformly divide constant probability mass among the labels for a feature. By default, 0.9 probability is allocated to the labels for a feature. This estimation method can be specified using heuristic for the targets command option.
    java cc.mallet.classify.tui.Vectors2FeatureConstraints \
    --input baseball-hockey.train.vectors \
    --output baseball-hockey.constraints \
    --features-file baseball-hockey.labeled_features \
    --targets heuristic 
    
    The option majority-prob can be used to specify a value other than 0.9. We can use the constraints file baseball-hockey.constraints to perform GE training as above.

    Machine-provided Candidate Features

    We may obtain a set of candidate features for which constraints may be expressed using the Latent Dirichlet Allocation (LDA) based method of [Druck, Mann, and McCallum 2008].
    java cc.mallet.classify.tui.Vectors2FeatureConstraints \
    --input baseball-hockey.train.vectors \
    --output baseball-hockey.features \
    --feature-selection lda \
    --lda-file baseball-hockey.train.lda \
    --targets none \
    --num-constraints 10 
    
    The lda-file is a serialized LDA model file. See the topic modeling tutorial for more information. Setting targets to none tells Vectors2FeatureConstraints to output candidate features only. baseball-hockey.features will then contain a list of ten candidate features, one per line.
    The above method is unsupervised (i.e. does not look at the true labels). We can also select candidate features using an "oracle" information gain method (infogain) that looks at the true labels. (Note that when using true labels obtaining constraints, baseball-hockey.train.vectors, rather than baseball-hockey.unlabeled.vectors, must be used.)
    java cc.mallet.classify.tui.Vectors2FeatureConstraints \
    --input baseball-hockey.train.vectors \
    --output baseball-hockey.features \
    --feature-selection infogain \
    --targets none \
    --num-constraints 10
    

    Machine-provided Target Expectations

    Given a set of candidate features, we may estimate constraints using two methods. The first method is to have the machine label the features (by revealing the true labels and using the method of [Druck, Mann, and McCallum 2008]), and convert these labels into expectations using the same heuristic as above.
    java cc.mallet.classify.tui.Vectors2FeatureConstraints \
    --input baseball-hockey.train.vectors \
    --output baseball-hockey.constraints \
    --features-file baseball-hockey.features \
    --targets heuristic
    
    Note that if the candidate features are also machine-provided, we may perform both steps at the same time using, for example, the command:
    java cc.mallet.classify.tui.Vectors2FeatureConstraints \
    --input baseball-hockey.train.vectors \
    --output baseball-hockey.constraints \
    --feature-selection lda \
    --lda-file baseball-hockey.train.lda \
    --num-constraints 10 \
    --targets heuristic
    
    Finally, we may estimate the expectations using the exact target expectations from the labeled data. The targets option to do this is oracle.
    java cc.mallet.classify.tui.Vectors2FeatureConstraints \
    --input baseball-hockey.train.vectors \
    --output baseball-hockey.constraints \
    --features-file baseball-hockey.features \
    --targets oracle
    
    Note that when using heuristic targets, the machine may discard candidate features in the labeling process (c.f. [Druck, Mann, and McCallum 2008]). However, the machine does not discard any candidate features when using --targets oracle .

    Tips

    • For GE training, a gaussianPriorVariance of 1 is a reasonable default choice.
    • For PR training, in our experience large values for qGaussianPriorVariance and small values for pGaussianPriorVariance work best.
    • The command line interfaces only provide basic functionality. In some cases it may be necessary to tweak the optimization code (by for example setting convergence tolerances or step sizes) in order to obtain good results.
    • As a rule of thumb, try to specify a set of constraints that is balanced among labels and covers many documents.


    Date Mod Desc
         
    Column1 Column2 Column3
    30-Dec-19   Updated prnEx to printOut exceptions only once per line #
      Removed extra logMsgs for compiler ("skipping writing class file...") etc.
    28-Dec-19   added ui BufferedImg fns from spx + popupMenu for paginationBar
    @ToDo added defaultColor tint to desktopIcons (@ToBeTested)
      removed the legacy GraphicsUtils stuff
    27-Dec-19   continuing the refactor; esp. data stuff...
    26-Dec-19   removed svr stuff
    23-Dec-19   refactoring ->
      removed actions (moved useful snippets to disable menuItems)
      added prnEx / prnOut
    @ToDo some work on desktopAnim (left off @ ln 1642)
    21-Dec-19   worked on spanTbl (popDat/expandCollapse etc.) in another file (spxServer.spx)
    20-Dec-19   Many updates made on 12.18 lost (monkeys messed w/clipBd & pasted crap)
      another reminder to backup often; the devil does not sleep.
      Re-instated changes from 12.18; incl desktopIco blur
    19-Dec-19   Worked on asyncSockCli/Svr; some progress. Either the code snippet
      contains major errors OR the monkeyBastas up to their usu tricks (display
      doesn't reflect actual code)
    17-Dec-19   Added support for pasting last item from clipBdHistory (via keybd shortcut)
      Added new interfaces userInt, srcRelated & moved fns into them for org
    16-Dec-19   Repl all lstDlg calls w/new buildable calls; removed earlier ver. of class
      Repl outline fn w/version that uses new listDlg
    13-Dec-19   Created new shell for testing interface buildable independently
        Buildable working, stable, ported into system
        First impl used to load embedded srcFiles from jar; working & stable
    12-Dec-19   Created cryptoEd.j w/all the latest updates. Stable
        updated Fatty.jar by importing all regularly used src files; worked on auto-loading
        updates to launcher.j to offer embedded choices. Stable.
        updates to enStrComp.j to suppress/auto-fill class/pkg names; monkeys jam the compiler, shelved for now
        (note that we ported the functionality into the menu (internal) so launcher was backported for above changes)
        spxTbl stable, showing categs. Last work on wonkyTbl (stable) ported into cryptoEd.j
    11-Dec-19   The monkeys are now jamming the nettySvr (only allows 1 connection; using Stable netty-provided example)
        There's a sm chance one import is missing, will investigate.
    10-Dec-19   The monkeys began jamming the server work (as usu) so decided to use Netty (as we did jetty for ht httpSvr)
        (the reasoning: get the handlers etc. working & then repl the server w/a custom impl)
    9-Dec-19   worked on asyncSocketSvr/Cli (contd. from legacy work)
    8-Dec-19   spxTbl stable, spanning, several updates to categRenderer
    7-Dec-19   Created new paginationToolBar; added icons (NOTE: subseq. Monkey removed these; might have to recover)
    6-Dec-19   debugging log (monkeys put in non-ascii chars etc.); these need to be reset
        - fn createAndConfigTab try/catch remmed
        - fn publicKeyCheckCommented whole fn remmed (fakeCompiler fails)
        - meth Boolean save() remmed
        - fn getNewRiddle remmed
        they're still throwing fakeA$$ errMsgs so we'll pause for now
        Testing the new features/additions: (using the wonkyTbl-dec2 ver)
        - winDisp() PASSES - addIconsFromBytes PASSES
        - testIconFromAdmin(no objInpStrm) FAILED with IllegalArgumentException: Illegal base64 character
        (ie, content not base64, ie, binDirect) and now (updated code) PASSES
        Updated fnGetIcon w/changes; as well as the spxTbl
        Henceforth we shall apply changes to this file & test w/wonkyTbl
    5-Dec-19   further work on openEmbedded prior to testing w/builder, incl. builder
    4-Dec-19   Added BiCons prnEx, updated all catch sts.
        lstDlg fontSize superSized
        File|winDispose()
        Added addBookmark(menu) & next/prev func (in keyAdapter) TO BE DEBUGGED; needs icons
        Added 3 new testMenu icon-related items
        Updated some refs to riddle.getRiddle() to rid.getQn() (baseEnc inside cls)
        Added listDlg (impl buildable) TO BE TESTED w/FileLister list (or similar)
        Added File|openEmbedded menuitem to test above list w/blder
    3-Dec-19   ported dslBuilderFactoryImpl.j into this file
        applied SHAChk in loadFn; much debugging (the hashes didn't match)
        but eventually fixed it all.
        Many updates incl. new params to allow createPane to set title/txt of new pane
        plus check hash on Load
        Other updates as a result of sRiddle extending tuple
    2-Dec-19   Ported snippet to load jarFiles (from launcher.j)
        Added menuOptions to load AllTbls internally or via ide
    1-Dec-19   created utilFn to print dat rows (for debugging spxTbl populateDat)
        some further work on outline regexp; working but need to tinker w/
        positions (match.start() vs str.substring)
    30-Nov-19   some further work on outline regexp
        some work (incomplete) on table rowRollover
        completed/tested dslBuilderFactoryImpl.j
    28-Nov-19   lib closed 28,29
    27-Nov-19   changed/ren Consumer fontSetter to superSizer; updated relevant code
    26-Nov-19   Created/tested dslBuilderFactoryImpl.j, to be impl here
    25-Nov-19   Attempted changes to tuple/sRid classes but @monkeyBastaInterf.
        Added datBtn
    24-Nov-19   Added toolbar; moved find panel to toobar
        (earlier there was unnecc. duplication: findPanel in ea tab)
        added openInArchive to menu & removed legacy action
    23-Nov-19   reading func stuff
    22-Nov-19   some work on scanning all classLoaders to find a class etc...
        entire compilation routine moved to anonClass in menu
        added new func taGotoLine vs ~pos after outline changes
    21-Nov-19   some updates to findPane, some other minor updates
        outline fixed & operational
        new fn ui.hex2Rgb
    20-Nov-19   updated enStrComp (launcher); ported methods to fns
    19-Nov-19   added goTo to outliner; rewrote outliner for html output
        added new logger
        outline & jEditorPane working; but unfortunately the HTML uses CSS
        and the monkeyBastards like to mess with that; so they're having the
        time of their lives :-) effing children :-) we'll have to find another way.
    18-Nov-19   fixed compiler diagMsgs, moved to menu (no methInvocations)
        debugged goTo func
    17-Nov-19   debugged spxTbl & related classes
    16-Nov-19   reconciled ALL deltas into this file; remming where necc. to allow compile
        moved ToolsSubMenu one over for usability reasons
    15-Nov-19   cleaned up the outliner; added dsl to lstDlg
        added fn tAGoToPos (remmed, on which the bastards crash the compiler; just like goTo)
        added regexp findFunc (to be tested) (<- uses tuple, need to import fr wherever...)
    14-Nov-19   added txtA.setTabSize(); ported class files & some fns from spxSvr
        fixed outliner to not use HTML; still need to add goTo func.
    12-Nov-19   upd keys
    10-Nov-19   this file contains all changes from yesterday BUT still needs deltas from 11.08
        refactored all refs to textAreas etc. to use the new tabMngr
        npe being thrown on getPane() -- FIXED
        added PlainDocument doc to tabMngr
        added 11.08 deltas ->
        ->added fn ui.getOutlinePane
        ->added fn cypher.SHAChk
        ->added sphinxv1/v2 logic in getKey && SphinxifyFn
    9-Nov-19   added class tabMngr to store refs to tab stuff; allows resetting title
        removed setCurrentTitle
        added a tabMngr class & updated all refs to currentTA & textArea vars
        NOTE that this file @ this point does NOT contain the deltas from yesterday's
        changes made in the PM; will have to incorporate them here
    8-Nov-19   added setCurrentPaneTitle
        ->ported yesterday's findFn fix to this file
        ->note: yesterday's goTo still won't compile;
        the bastas get the compiler to throw wrong errMsgs
    7-Nov-19   npe bug again (set currentTA to newlyAddedTA; autoFocus on newlyAdded
        updated fnGetKey to use swingDlg instd of stdOut
        -> @ this point the monkeyBastas (perhaps because they can't get the pwds)
        make the compiler fail. New additions:
        -> goTo line fn marked w/@monkeyBasta1107
        -> Find func. pos fixed (from 0 to caretPos)
    6-Nov-19   fixed minor bug w/tabbedPane
    1-Nov-19   reset keyBd actions (the clever monkey Bastards moved the cut action to steal code, the effers)
        added new trigger for clipbdDlg
        added tabbedPane; new docPane setup; assoc menuItems/changeListener
    31-Oct-19   compiler.compile was filling strAI w/dubious ecj errDiags;
        reset out from stdOut to baos piped into strAI
        added paste capability to clipBd historyDlg
    30-Oct-19   delta fixes
         
         
    14-Oct-19   jdk13 runImg; initial testing/compiling edited mfs
    12-Oct-19 tbl few tblTest.j updates before the bastards begin effing w/the compiler again, the S.O.B.s
    2-Oct-19 dat imp.j - updated w/latest AllTbls in prep to export to spx
      svr Created spxServer & obfuscated; monkeys messed w/compiler (mTbl class)
    1-Oct-19 tbl Some work on tblTest (spxTbl/tkList, needs to be inc into old treeTbl)
      tbl Added new flds (Imp, Urg) cellRenderer remains
    30-Sep-19 svr AsynchServer / Client
    29-Sep-19   cits
    28-Sep-19   cits
    27-Sep-19 svr researched / tested AsynchSocketServer
    26-Sep-19   mfs5 / tkTree -> updated / poss fixed level Issues by ensuring mods added to Proj; not root
    25-Sep-19   vaca
    8-Sep-19   vaca
    7-Sep-19 dat - created msf5, basically mfs2 (~0806) + mfs4 dat fns
    6-Sep-19 all - added crypto func. to mfs4; reFactored the entire module to
        remove every method (crucial to prevent methodInterceptors)
        Henceforth it will work using higher-order fns.
    5-Sep-19   - Created a new file (imp.j/privRepo) for blding mfs4. Rebuilt
        AllTbls w/all but tkTbl. Imported icons to mAd & mPanes to mATbl
        **NOTE** that current spx file dataClasses produce
        a serializationException; so used a prior version. @ToDo: verify that any/all
        changes made to dataClasses in spx (versioning?) are applied to curr featureSet.
    4-Sep-19   - Added mAd strings for custom mT Priority ttip mappings
        (using adapted Covey System) to 'loadAdList' menuAction
    3-Sep-19 fEnd - Completed work on iconAnimation, created animFactory class w/DSL
    1-Sep-19   closed
    2-Sep-19   closed
    28-Aug-19 fEnd (upto ~ 9th Spt)- worked on Desktop.j (icons, windows, et al.)
         
    27-Aug-19 dat - changed all occurences of LocalDate.MIN to constant LocalDateMin
        (in dataEng, set to 1900.1.1 coz the java MIN causes issues with n
        -@ToDo: any/all data containing this val needs to be updated
        - added new menu item to Load mPanes to mArticles (from imp.java)
    26-Aug-19   - prepWork for recreating mAd tbl; downloaded materialIcons
      pEng - some work on preparing (for test) an async procEng pipeline
    25-Aug-19   - Updated interface iTable; added updated srchFn
      ut - added tuple to utils (?? done earlier??)
    24-Aug-19 tbl - merged regularTbl into this file
        - added treeView DSL to allow regular/spxTbl creation
    23-Aug-19   - merged MFS3 (treeView) into this file
      tbl - worked on indep impl of regularTbl to use for Srch/etc.
    22-Aug-19 all - removed 'that' refs from code; made most classes static
      tbl - removed old treeTbl (w/tree on left & table on rt) & repl
      tbl w/spanTbl impl i.e., tree INSIDE tbl
    21-Aug-19 tbl - continued spanTbl coding, incorp categPaths
    20-Aug-19   - migrated menuOptions for mAd, AllTbls data actions to Menu into this file
      tbl - migrated spanTbl into this file
      tbl - created framework for spanTbl, funct. to launch it using existing setup (created for treeTbl)
      tbl - coded some of the initial func. for spanTbl (generating top level categories)
    14-Aug-19   - renamed all resource imgs in obfJar to confirm to naming conventions
    13-Aug-19 tbl added new Fn tkAddLineItemToTop so that when this list is ported
        to the tkList we can add latest updates to the top.
      tbl updated acl enum to return intVal for getToolBar()
      dat added docVersNum field to mData & edited mTbl.put to do versioning by default.
      all updated getIcon() to use mAd resources
        updated treeTbl.getToolBar() to supply generic tbar
        udpated ACLs to int; impl rudimentary acl logic in getToolbar
        ren taskTree to treeView
    12-Aug-19   Updated mfs2.j (priv Repo) with coupla Admin fns to rebuild
        mAd + serialize AllTbls; incl DeflaterInpStrm.
    11-Aug-19   mostly new Icons etc since the monkey Bastas are messing again with the compiler.
    10-Aug-19   mostly new Icons etc since the monkey Bastas are messing again with the compiler.
    9-Aug-19   dt of stable (min) obf version; has no chkKey; still saves keys & uses old dlgs / perhaps we need to patch THIS ONE
        Some further work on genericizing taskTree
        created obfusc mfs_2; need to update config for:
        Exception in spxTaskListAction -> classNotFoundException: com.trivedi.sphinx$mTbl
    8-Aug-19   Added some new icons, updated tibbie Dlg
        reconciled ALL (prob.ly) edits/updates into sphinx.j
        Found some code impl JSR199 for ecj (incl an impl using ForwardingFileMngr)
        Cld work on that & pipe results into proG
    6-Aug-19   ReWrote taskTree generator to add 2nd level nodes (proj/mod)
        Recompiled stable-ish jar (doesn't incl dlg updates etc.)
        Tried to run proG but the monkeys interfered.
    5-Aug-19  nbsp; Debugged/edited tkEdit form, stable-ish @ end
        Ported most menuItems from Action classes to anon inners.
        Updated code to use Serialized tkData; updated menuItems
    4-Aug-19   worked on tList
    3-Aug-19   worked on tList
    2-Aug-19   Added a tabbedPane & assoc menuItems to ide.
    1-Aug-19   prepared minFeatureset compiler # 2 incl taskList
        the monkey Bastas messed with the VM and interfered with the compile again.
    31-Jul-19   pulled some remaining methods from 2018eoy & refactored them into fns
    30-Jul-19   Reconciled the 3 major deltas:
        - taskTbl; various updates incl Dlgs (presently commented inside)
        - legacy from Hammer
        - legacy from eoy lastYr
        Reduced to minFeatureSet; rest of the classes/mods labelled @mfs
    29-Jul-19   Incorporated taskList class into sphinx.j; removed redundancies
        Then reconciled sphinx.j w/the FULL (non-minFeatureSet) version
        We shd have everything here now; poss some duplication in fns.
    28-Jul-19   look & feel
        -> -> changes below applied to taskList.j; ported to sphinx.j 07.29 <- <-
    27-Jul-19   added dsl to taskForm + modes (create/edit)
        refactored the frm logic; put some methods to new toplevel ui class
        added fn treeNodeCreater to generically generate dv-like trees.
    26-Jul-19   taskEditForm / backend (save etc.) handcoded for now;
        need to genericize later
    25-Jul-19   taskEditForm
    24-Jul-19   more l&f
        taskEditForm
    23-Jul-19   changed some lookAndFeel colors; added ttips
        began work on adding add/edit functionality
        Added toolBar
        reconfigured jtree stuff to display allByPriority for root clicks
    22-Jul-19   built jtree & added tbl stuff
        -> -> changes above applied to taskList.j; ported to sphinx.j 07.29 <- <-
    18-Jul-19   Added dataStatsAction; imported pipeLine; more categJTable work;
        reverted to using static (hey, the jdk uses it so it can't be bad)
    17-Jul-19   Added dataEngine, utils classes; reFactored to cleanup
        Created/added loadTaskListAction to load serialized file to AllTbls
    12-Jul-19   Added adapters
        Removed mUtil class; changed other structure somewhat
        Refactored some actions to fns
    8-Jul-19   Imported legacy classes (mA, mTbl etc.)
        minor edits to compile settings etc.
    5-Jul-19   Major security updt -> removed keySave (prompt instd for all saves).
        fns affected incl Load; Sphinxify; SaveFil -> each of these now loads & nulls a key
    3-Jul-19   Imported new spxDialogs & applied related updates (fifeURL etc).
    29-Jun-19   Applied classNm changes (some issues related to earlier compiled class expecting a diff name)
    28-Jun-19   Added fn to fmt sphinxStrings to mimeLen 76 (one col)
        Name changes -> mUtil.sphinx becomes mUtil.cipherEngine; cryptoEd becomes sphinx
    26-Jun-19   upd JTable to listen to rowClicks
    25-Jun-19   dt of stable compiler version; has to be a more recent one (perhaps gitee) coz this still expects cryptoEd.java
    25-Jun-19   Repl new keyVault riddles via hand-picking; checked both maps for integrity.
    24-Jun-19   monkeys going beserk; reinited the keys to keep them in order (new keyVault reduced Qns unused)
        2nd sess: fixed Action4 console msgs + simplified patternMatcher; fixed compiler modPath.
    22-Jun-19   moved LookAndFeel to main per oracle docs.
    21-Jun-19   The bastards are trying to steal the code again: they replaced the cut/paste classes in the editor.
        Fixed the theme.load but the eclipse scheme looks funny....
    02-Jun-19   Separated the modules fife/sphinx; fixed sphinx to use mod declarations
    19-Jun-19   Imported legacy JAR manip code (2017)
    18-Jun-19   Added AboutAction & nested classes txtDlg, listDlg, abtDlg to ide
    17-Jun-19   fixed compiler path issues for class files; other minor compiler complaints
        imported action4
    15-Jun-19   OpenInArchiveAction (has zip spanning & listDlg code now)
    12-Jun-19   ClipboardKeyAdapter wasn't triggering History updates on copy/cut; added chk that text exists
        Attempt #2 @ classLoad after compile
        Added some new Actions, moved others
    11-Jun-19   compl. work on reverse Sphinxify
        added cut/copy intercepts to feed into History
    01-Jun-19   updated compiler options; began work on reverse Sphinxify
    09-Jun-19   rebuilt 0609 w new keyVault & slight changes; test compilation works
    31-May-19   new func. sphinxifyToClipbd(byte, byte) to add to actions
    29-May-19   applied all the minor fixes/updates from the last few days; we now have the popup not cutting/pasting
        HOWEVER the monkeys have been extra busy so it's likely we'll need to
        do the Action intercept (they're using prefs;datatransf;xml etc. which they've
        inserted very slyly into my runtime)
        Added a check for chkKey == false; triggering a newSession
    24-May-19   stable version, save new Fmt spx; rewrote getKey for optional
    23-May-19   reset riddleMe & map
    22-May-19   EOD STABLE! except failing sphinx chk... (probably corrupt map; chk w/only 1 entry)
        refactored sphinx; added sRiddle class & assoc fns
    21-May-19   PM session delayed (the bastards keep messing with the source files
    21-May-19   launcher ready; last stable ver of cryptoEd is 13th Gameplan:
        - add compile capab & see if there are too many flags#NAME?
        - if not, get it ready. if yes, revert to 13th version & add piecemal
        - FOR NOW, ignore/disable clipboardPopup; use Actions to access the clipboardBuffer; we'll worry about that stuff later.
        re-applied yesterday's changes, added new class sRiddle to sphinx
    19-May-19   Many changes incl renaming sphinx to sphinx + map etc. LOST (monkeys
    18-May-19   overwrote the file. We shall persevere.)
        further work on wall (renamed sphinx) & timer to invoke
    15-May-19   new handlers for openPlainTxt actions, openInArchive etc.;
        moved io/utils/sys to ide local vars etc.
        in-Mem compiler code
    14-May-19   ***************new stable version*********************
    13-May-19   added recent updates for clipBoard intercepts incl printScn
    10-May-19   added code for "LoadWithNewKey"
    09-May-19   applied changes and saved (encr) w/new stable version
    Date Mod Desc
    28-Dec-20 spxClient added helperMethod listOf; some fiddling w/compiler
    debugged/prepped copyFileToJar for autoSpxToJar
    23-Dec-20 spxClient added diff; some more shuffledKeys
    tot keys/riddles in vault=20
    22-Dec-20 GridTester (note: this is not in the file but in a patch; beaucoup @MBI)
    worked a bit on Grid Srch button before realizing that it might be moot (can use filter)
    created/added new dvView '/by TgtVer'
    added versionMap to consts w/alpha/bet in unicode esc
    18-Dec-20 spxClient removed log (to tkDat)
    remmed bookmarksPaintCode for ide
    renamed some classes
    added keys
    16-Dec-20 Grid reconciled updates from last couple of days; updateed dat w/some addendas
    set JTbl horizScrPol
    upd priorityRndrr
    15-Dec-20 General mostly worked w/clj & predicates
    14-Dec-20 Grid Some work on dvSwitcher; comboBox
    13-Dec-20 Grid Added SubMod/TgtVer to Grid, cal, dat
    some other minor grid updates
    An incomplete update to the JButton("Switch View")
    11-Dec-20 Grid updates to mTpl/matcher
    utilDlg uses matcherPreds & dClone bypass for sysUpdates
    other minor updates to refresh tbl etc.
    09-Dec-20 minor updates to importer to fix content fld; add default proj etc.
    new cls utilDlg
    08-Dec-20 minor update to importer to add recs to tkTbl
    01-Dec-20 to 08-Dec-20 Grid postCovid imports into allData
    06Oct to 26Oct-20
    As before (Feb06 on) the monkeyBastas began being absolute pests; could not be productive with their constant deleting local files; replacing clipBd contents w/crap and general nuisance. What normally would've taken two days (updating the tkTable w/the ~200 new tasks) dragged on for weeks until they began preventing saves etc.; so productive work was again impossible and now we've shifted to research & maintenance.
    06-Oct-20
    more minor bugfixes; the unid turned out to be a tblModel issue
    05-Oct-20
    minor bugfixes
    02-Oct-20
    Edited dblFn to accept intSplitOn
    01-Oct-20
    Added Function<List<String>, List<String>> fixDblLines (finds/removes wrapped dblLines)


    needs to be updated for index of dblRec beginning
    30-Sept-20
    Various updates incl new funcs to parseDblRecs
    29-Sept-20
    Reverted to 9.23 version; will have to patch/debug each modification peacemeal.


    The monkeys've modified the updates file; changed nbk#s etc., so we're


    now working w/the old updates; and adding modifs remmed into this file & debugging em 1 at a time.
    28-Sept-20
    Further work on imports; discovered that the monkeys have messed with the data file (updates) and added


    /modified nbk#s (10 didn't exist before; now there are two 10s) Will have to revert to old version & patch.
    25-Sept-20
    Further work on populating/cleaning/formatting dat & docRefs; impl fluentMapping
    24-Sept-20
    Added comparator for TgtVer; completed import work; UNID -> existing empty col; docRefs


    Manually corrected data errs (colShift, typos). Updated input file.
    23-Sept-20
    applied a couple of bugFixes; data much cleaner; shows various docRefs etc.
    22-Sept-20
    Updated docRef regExp to accept >1 space betw ea. + minor fixes elsewhere;


    some new func.s to proc data for tbl
    21-Sept-20
    Some updates to this file for createdDt/docRefs; not compiled/chked
    11-18-Sept-20
    Explored alt ways to avoid monkeyBastaInterference; they seem to be hacking into the JVM


    However, their being monkeys allows us to overcome their feeble efforts...
    10-Sept-20
    Added form (jTxtPane-based)
    09-Sept-20
    Added fnGetShorty (util fn for now to be used in generating tgtVer comparator)


    Began init work on bldUNID & updRefs


    Continued work on SpringForm/SpringUtils in a separate file


    (for debugging, the monkeyBastas are throwing fakeErrs again in this file)
    08-Sept-20
    Incorporated the tbl file (w pred, datClass etc) into this file as an inner class to work w/jre8


    applied tmp workarounds to get tbl to show for now; sort of using Tpl but not really
    04-Sept-20
    Considerable headway; fixed tpl issues w/mapping etc; impl dvDefLift() method in tpl & tested; assignable
    03-Sept-20
    mTpl testing; working as exp so work continues on dvDef etc.
    02-Sept-20
    Minor update to mTpl file (flatMap unwrap, errs w/empty); recompiled lib to common jar
    01-Sept-20
    Minor updates incl fn getRschItms
    31-Aug-20
    Further work on predSupplier in file postCovidTbl
    28-Aug-20
    Some updates + early testing w/mTpl
    27-Aug-20
    Resumed work on mTpl; compiled files using jdk8


    Removed all the jar junk; we have better versions in legacy code.
    26-Aug-20
    Added readJarArch(), readEntry() etc. methods to access prior archives


    -- can't run the former locally; monkeys adding spurious chars in srcFile as before
    25-Aug-20
    Continued working on import Mod


    One occurance of a NumFmtErr fixed in new .64 file


    Many updates to mTpl file; ready to compile whenever
    24-Aug-20
    Decided to use update tks instd of sample data


    Began version on rebuilding mTpl (for rTpl); (incl in this file @ bottom after divider)


    wrote minor fns to read/import updates
    21-Aug-20
    Began work on swing-filterWindow; predBldr
    20-Aug-20
    Tested available security (insufficient; the meher.zip file doesn't contain


    readable files. We have used this file numerous times before; so either:


    - the monkeys are replacing the files on the fly (they've done this before)


    - something in the settings (jdk ver? security?) is insuff (however, errMsg?)
    10-20Aug-20
    Entered taskList (>200 items).
    Mar17-Aug08-20   Post-COVID shutdown, i.e., 03/17 to 08/08 was spent planning/taskList (offline)
    Feb06-Mar17-20   At this point the monkeyBastas began throwing WAY too many fake compiler errors and generally began being real pests; it became impossible to be productive with their antics. Therefore the rest of this period was spent mostly planning/updating the taskList; with occasional updates, mostly to the Grid; until even that was halted when the library closed on Mar17 (COVID)
    6-Feb-20 further refactoring to remove tries & impl mTuple usage
      Removed ALL of 'em (exc some commented stuff)
    next->remove cls tuple (riddle extends)
      refactor cypher (also upgradeVer? poss AFTER?)
    refactor grid
    5-Feb-20   (GridTester.spx) This is the stable gridTester ported to the stable (encapsulated) spxClient
    Note: BOTH the grid & the client've been refactored further; but not stable
      So this is essentially the version frozen into 01.29's client
    w/A few caveats: Alltbls moved into mTbl; renamed treeV to dvT
      spxCli menuBar left _in_situ_ & dataMenu inserted w/updates
    NO other changes; so once (mTuple/map) refactoring is complete;
      we shd be able to merge it into this file w/o many probs.
    (spxCli) Repl mTuple w/tested version containing all missing stuff + lift7
    4-Feb-20   Some tinkering w/functional EitherTree (Either+Tree) but it's practically
    useless (redundant) in the spxTbl context; in fact a little naive like
      the chap who inserted an entire tree in col1 of a table to make a "tree-table".
    heh.Typical freshman; a more exp guy will always snicker @ this
      but it works, "i used an OCR library to create an IDE that reads pictures!!".
    hehe.clever.very clever.
    3-Feb-20   Began refactoring GridTester w/encapsulation refactoring but the
    monkeyBastas began throwing way too many fake CompilerErrs,
      so forced to postone.
    Some further refactoring in this file (untested because they're throwing
      fake errs here too, of course)
    2-Feb-20 (Wkend) reading; mostly functional; some testing
    1-Feb-20   (Wkend) Created a shell for testing/building rowRenderer(s) from supplied preds
    31-Jan-20 some further cleanup; many fakeMonkeyBastaErrMsgs
      (for instance; renamed class UI since it looks for a nonExistent class;
    probably existing on the basta's machine.Now it finds one static method but
      not another.Perhaps the bastas are simply effing lazy and only steal/copy
    SOME of the code at one time.Anyway, effers.)
      Changed meth createDesktopMenu to a fn
    Updated desktopIcn builder to new build
      Removed a few more tries, repl w mTuple/map
    (eventually we want to get to "there IS no try")
    30-Jan-20   ren curr stuff to "old" (oldmTuple, oldbuild, _Build, oldFinisher)
    in order to refactor w/ new classes/methods while testing piecemeal
      REALLY must save more often, the effing monkeys are behaving like their innate selves
    29-Jan-20 created new class Constants; moved static global stuff there.
      further work on incr encapsulation; removing global refs; removing static
    28-Jan-20 NOTE: 3:02pm commit has the latest/stable/tested mTuple w/Generic Types
      backported this file to 01.24 stable; applied appropriate deltas
    The last couple of days were spent updating stuff and mapping over
      optionals; which won't do (no try; we need to map over mTuple)
    so the plan is now to
      - make encapsulation cleaner by just passing the ide ref in constr.s
    - make mTuple generic, test & THEN update the build stmts etc.
    27-Jan-20   Further refactoring; worked on removing fn.getTA (repl w/getTab.tA)
    as a part of incr encapsulation (removing global refs incl ide)
      MonkeyBastards throwing fakeErrs again; additions marked @01.27TBD
    26-Jan-20 Added 2 new interfaces (TriFunction/Quad) + testcode (@eof) for lift3/4
    25-Jan-20   Added 2 util classes tuple2/3 using Optional, so mappable
    remmed (@monkeyBastaFakeCompilerErrs)
      updated ideCons to repaint container on init (@ToBeTested since icons are off)
    Removed global var i (for ide) & changed all refs
      couple of changes remain (outline -remmed), getTA()
    24-Jan-20 backported this file to 01.21 stable; applied all deltas
      @Present this file contains the new build ren to _Build_ in the interface
    & all 1.21 build() calls remmed & inserted _in_situ_
    @ToDo EXCEPT desktopIcon.build() which needs to be ported to _Build()
    @ToDo 1st bld() (File|Open(ui.listDlg)) throwing zipFileSystem err
      & also mapping errs (seems like @monkeyBastaInterference) postponed.
    Fixed outline issues (cls regexp & escHTML)
      Some other minor edits
    23-Jan-20 minor update to lineNumPanel
      Many updates to GridTester (deepClone/saveNewRevision)
    21-Jan-20 Some updates to GridTester (new interface dataProc)
      Some updates to buildable in this file (added finisher to build())
    & updated all the bld stmts w/new fmt; @monkeyBastaInterf fakeErrMsgs
      Some work on fn.cypher.backupToJar
    18-Jan-20 Many updates to tuple/lift/etc., all stable/working as expected
      Copied latest outline regexes; changes not updating
    (ie bastas are showing incorrect version of dlg); postponed
      Did some work on the desktopIcon builder
    it's possible that, like the other stuff; the bastas have tampered with
      this section (desktop says the components are there, but not visible
    Check location etc. from old src).
    17-Jan-20   (spxCli) Applied mTuple changes from GridTester to this file.
    Much new work as well.
    17-Jan-20   (spxCli) Further changes to mTuple (added lift) & buildable.build()
    some updates after using online compilers (local one still throwing
      fake monkeyErrs)
    refactored all refs to strBaseURL to use new Supplier<String> strBaseURL
    @ToDo
    16-Jan-20 (GridTester.spx) Added SubMod fld to tkFrm
      The subMods have disappeared (the monkeyBastas probably~)
    created menuItm to reInsert and the bastas immediately
      began tampering w/the compiler (so postponed).
    Reinserted mTuple type info (from jdk.Optional) which the
      monkeyBastas managed to remove yesterday (via fake compilerMsgs)
    Began work on redoing yesterdays' monkeySpoilt mapping
      (look for UPDATED ON 01.16)
    **Yesterday's fn to remove fakeCompilerErrors rendered defunct
      (now the bastas are showing ONLY fakeErrors, no real ones @ all)
    -> with the result that the monkeys are now on their own
      (no compiler, screw you, learn on your own you hopeless losers)
    Our prev work w/o compiler has been quite solid; we'll just debug l8r.
      NEED TO ENSURE that deltas are properly labelled for isolated testing/debugging
    Updated all current (3) calls to buildable.build() w/new Tuple fmt. & map
    15-Jan-20   (GridTester.spx) Pasted in the latest mTuple from spxCli (mapR returns tuple)
    updated the class (removed R refs; updated flatMap/map)
      Shall be working further on it in this file; ensure it gets copied over
    Separated docRevision logic into new fn (saveNewRevision) to work on later
      REPLACED existing ui.listDlg fns (3) with more concise mTuple versions
    Created a sml util fn using regex to remove fakeCompilerMsgs from output
    14-Jan-20   (GridTester.spx) many updates but all of em probably unnecc; caused by fakeCompilerErrs
    from the monkeyBastards
    13-Jan-20   (GridTester.spx) Further updates to mTbl.put for docVersioning
    12-Jan-20 (GridTester.spx) turned on docVersioning;
      various updates incl mTbl.put & mData incl new flds related
    10-Jan-20 (GridTester.spx) removed old treeTbl
    9-Jan-20   Continued w/reduction: removed dMngr commented methods kept for
    reference (we're almost stable now & it's avail anyway online)
      Removed class AnimFactory (remmed single ref: iconifyFrame/snapShot)
    mTuple: incorporated try within mapR which now returns an mTuple
      Updated fns to read BufferedImg instd of Img
    work interrupted @monkeyBastaInterference
      Tested/compiled Stable ObjEchoClient (requires netty 4.0)
    8-Jan-20 updated Outline func class/int regexp to incl extends/Implements info
      further work on fx
    Added new _Build() to buildable interface; & naturally ->
    @ToDo @monkeyBastaInterference; remmed/postponed (search for "Openv2");
    The monkeys are now effing w/the class regexp Pattern (they're weak at regexp)
    @ToDo this is postponed too; the debug stmts don't print
    @monkeyBastaInterference
      Removed beaucoup unnecc meths from textLN, resulting in
    @ToDo (probably monkeyBastaInduced) reset of tlnPanel width to 1 digit
      updates to desktopIcon.bld (buildable)
    icons not showing (poss @monkeyBastaInt) so added alt way of launching ide
    7-Jan-20   inc spxDlg images from legacy jarFile
    updated Outline labels to all grey (except names)
      some further work on ui.dlgs (interrupted; look for ->
    @ToDo //@monkeyBastaInterference; postponed @0107
    6-Jan-20   @monkeyBastaInterference; lost all deltas; spent the rest of the day reading functional articles
    5-Jan-20 reCommented exit calls for badPaddingEx et.al in cypher
      updated Outline func regexps to highlight ONLY names in color
    @ToDo ported ui classes (spxDlg & related) from spx.j into this file
      Also ported chkAuth which invokes above (for testing)
    <<the animation code was ported from dlgs.j_08.05>>
    @ToDo Also ported jarFileRelated fns for ideAutoSave impl.
    4-Jan-20 backported desktopIcon img changes to stable ver
      (2 deltas; marked @remmed 01.04)
    Built new fatty.jar & recompiled launcher for options;
      resulting in various crashes poss related to @monkeyBastas
    trying to launch their add-ons/agents/etc.(a little slow, them)
    3-Jan-20   Ported mTuple (from spxSvr);
    added interface fx using mTuple
      added cls toaster
    Modified regexp for methods in fnOutline (tested; Stable)
    Date Mod Desc
    03 to 15-Feb-21 general NoSQL rsch/eval
    02-Feb-21 general rsch/eval: mongoDb, GOOG FireStore
    01-Feb-21 general Some tinkering w/SecurityManager (Jar FileSystem throws), snippet saved
    29-Jan-21 general Composing fns/mapping made me think of routing; and tubelight(!): mTpl.pointCut (Stable/works; also incl inlined tpl) pastebin jyubUJ2z
    28-Jan-21 spxClient recovered/resaved spxClient.spx with 2-ply qns (Stable) pastebin g1CPFNXq
    27-Jan-21 general The monkeyBastas won't allow the launcher to work. It's obvious they've replaced the binary (they delete the class file if recompiled) Related note: they keep retrograding little snippets of code here and there: the compile&Load now reverts to NO fileExt; which was fixed ages ago. Spent the day reading/research.
    26-Jan-21 general The monkeyBastas continue to test patience; they jam EVERYthing now Since we changed the pwds, they're probably trying to "force" open coding so they can steal code as usual; anyway it's useless to fools so spent the day creating a dblList (needs to be bldable) for later
    20-Jan-21 spxClient further research on noSQL/dynamoDB/others
    19-Jan-21 spxClient too much @MBI with almost ANY work; so researched noSQL/dynamoDB
    14 to 18-Jan-21 spxClient WF office closed
    13-Jan-21 spxClient completed work on 'patchify'; couldn't test (@MBI) created genVault.spx: Stable; updated to gen auth qns; expects riddle# as arg; displays map.put
    12-Jan-21 spxClient created 'patchify' fn/menuItem to persist 21 udpates only to dat created calGen fn; slmost ready; blds from intStream
    11-Jan-21 spxClient resaved newVer again (w/keys; MBI keep corrupting the save)
    08-Jan-21 general More research on Arrows in General & Kiesli arrows in particular;
    decided we can do without
    08-Jan-21 Grid Fixed various icon issues; incl pagTBar
    (Why no prob earlier? newKeys)
    inlined (and made non-static) mTpl
    updated keys (remmed non-working)
    updated all copyright msgs for '21
    07-Jan-21 general Some research on Arrows in General & Kiesli arrows in particular
    07-Jan-21 Grid Much @MBI w/newClient; applied some further deltas
    06-Jan-21 spxClient Checked/updated/applied new Keys:
    Monkeys rewrote the clipboard content again;
    so the vault now contains some commented non-working keys
    04-Jan-21 Grid added versionMap to consts (remmed)
    updated keys
    added byTgtVer dv stuff in popDat

    module Constants =
    #if Hephaestus
    let delimFil =
    let rawFil =
    let Colors9x9Panel =
    let chkBoxList =
    let a2z =
    let titleTxt:string =
    let mLTxt:string =
    let testList =
    let srchKeywords =
    let windowedList =
    let α =
    let β =
    let ``↠`` =
    let verMap =
    let subScriptNumbers:char list =
    let superScriptNumbers:char list =
    #endif
    module Base =
    let ``⍲`` =
    #if November
    let ``⍭`` f:('a -> 'r) -> 'r =
    #endif
    let (|>|) f x =
    let trueFn =
    let falseFn =
    let (|?) pred x y =
    let inline (?) (obj: 'a) (propName: string) : 'b =
    let inline (?<-) (obj: 'a) (propName: string) (value: 'b) =
    let ઓપ્ત_ઓર (opt:option<_>) def =
    let ઓપ્ત_ટૂ_સ્ટ્રીન્ગ (o:option<'a>):string =
    let isTuple tuple =
    let merge xs ys =
    let tibbie s =
    let curry f a b =
    let uncurry f (a,b) =
    let સ્ટ્રી_લેન (str:string) : int =
    let સ્ટ્રી_કન્ટેનર્સ (str:string) (str2:string) : bool =
    let સ્ટ્રી_ટ્રીમ (str:string) : string =
    let સ્ટ્રી_સપ્લીટ (str:string) (c:string) : string[] =
    let સ્ટ્રી_રિપ્લ (x:string) (y:string) (z:string) =
    let સ્ટ્રી_બાઇટ (s: string) : byte[] =
    let સ્ટ્રી_ફ્રોમ_બાઇટ_અરે (bArr:byte[]):string =
    let સ્ટ્રી_ઇસ_લોઅર (str:string) : bool =
    let સ્ટ્રી_ઇસ_ડિજીટ (pos:int) (str:string) : bool =
    let સ્ટ્રી_ટીલ (str:string) (fstIdx:string) : string =
    let સ્ટ્રી_આફટર (str:string) (fstIdx:string) : string =
    let સ્ટ્રી_ગેટ_પેડેડ (padLen:int) (s:string) =
    let strContains (substr:string) (str:string) =
    let escHTML s =
    let tick =
    let tickSignif =
    #if !Hotel
    let rand =
    let getRnum f s =
    #else
    let rand =
    let getRnum f s =
    let getSeededRnum f s sd =
    #endif
    let ટીન x y z =
    let ટીનtp x y z =
    let કારલોસ =
    let બારી f s t =
    let ભોલે x =
    let કરાફે f =
    let ઍસોપ a b =
    let પ્રાઈજ a b c =
    let ગ્રુનડીગ a b =
    let શૂકામ_શૂકામ x y =
    let rec regReplSingle (srch:string) (r:Regex) (s:string):string =
    let લી_મેપ_ફોલ્ડ_સ f l =
    let લી_મેપ_ફોલ્ડ_લ f l =
    let liBrk2Tpl (s:string) (l:list<string>) =
    let લી_રેગેકસ_રિપ્લેસ (s:string) (srch:list<string>) (r:list<Regex>) =
    let લી_સિવાય_ઈન્ડેક્ષ idx l =
    let લી_શફલ (listIn:list<_>) (listOut:list<_>) (r:option<Random>) =
    let લી_અન_શફલ (listIn:list<_>) (listOut:list<_>) (r:option<Random>) =
    let લી_સિવાય (li:list<_>) (excludeLi:list<_>) =
    let flattenOpts (li:option<'t> list) : list<'t> =
    let લી_સિવાય_ઈનડેકસ_લી idxLi l =
    let throwSpxErr t =
    let errDivZero() =
    let tryParseInt (str:string) =
    let logHR =
    let fCoreVer =
    let stat str x =
    let stati str x =
    let log x =
    let db s =
    let dbx s =
    let stripQuotes (s: string) : string =
    let currentDate =
    let tod =
    let defDt =
    let toOb x =
    let tryOf f x =
    #if Trump
    #endif
    let tryOfL f li =
    let inline getString (sb : System.Text.StringBuilder) =
    let inline appendString (sb : System.Text.StringBuilder) (str : string) =
    let buildString strings =
    let htmlUnesc s:string =
    let b64Enc (str : string) =
    let b64EncB (bArr : byte[]) =
    let b64Dec (str : string) =
    let bytesToZipFileBase (x:byte[]) e z =
    #if Hotel
    let bytesToZipFile (x:byte[]) e z =
    let bytesToZip64 x =
    let testZip() =
    #endif
    let (|Even|Odd|) input =
    let writeC C (s:string) =
    let toOption x =
    let tryWith f x =
    let bi =
    let serBase x =
    let ser x =
    let serToFile x fn =
    let deSerBase (str : string) =
    let deSer (str : string) =
    let deSerToList (fn:string):list<string> =
    let (|ParseRegex|_|) regex str =
    let (|BarDelim|_|) (str: string) =
    let (|TabDelim|_|) (str: string) =
    #if BushSr
    let ThreeKingdoms x y z =
    let Yuan =
    let જિન x y z =
    let NorthernAndSouthernDynasties x y z =
    let સૂઈ x y =
    let હાન x y z =
    let ટેન્ગ x y z =
    let સૂંગ x y z =
    let મિંગ x y z =
    let ક્વિન્ગ x y z =
    let tkEx :seq<int*int> =
    let વરેપ1 x y z =
    let વરેપ2 (x,(a,y)) =
    let વરેપ2a (x,(a,y)) =
    let વચલૂં mid aft x =
    let વરેપ befFn mainFn aftFn x =
    let વરેપ_2 befFn mainFn aftFn x =
    #endif
    module Types =
    let currentDate =
    let getQn r =
    let getK r =
    let newD(id,cr,md,cont) =
    let datToSStr (d:Dat) =
    let newAdDoc(id, cr, tit, tags, cont) =
    let taskToSStr (t:TaskDoc) =
    let newA(id, cr, tit, tags, cont) =
    let adToSStr (a:AdDoc) =
    #if !Papa
    #else
    let newTaskImp(s:string) =
    let newAdImp(s:string) =
    #endif
    let intComparer a b =
    let resultInt =
    let ex =
    let Imp x =
    let Urg x =
    let getQuad (a:int*int) =
    let QuadComparer a b =
    #if Victor
    #endif
    let getGenericTypArg (x:obj) =
    let tkTblDef():TblDefDoc<TaskDoc> =
    let DesDocInf() =
    let tkPred =
    module Session =
    let initSession (userNm:option<string>) =
    let cliHandlr (req:string) (g:DataGridView) =
    module Mtpl =
    let setInitialEnv (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s> =
    let tmpEnv =
    let empty =
    let MtplOf x y z =
    let ``☞`` =
    let addErr errStr m =
    let inline (>!>) (f:Mtpl<'m,'t,'p> -> Mtpl<'r,'e,'t>) m =
    let inline (>!!>) mapList mapper m =
    let hasFst m =
    let setFst x m =
    let getFst m =
    let hasSnd m =
    let setSnd x m =
    let getSnd m =
    let hasThd m =
    let setThd x m =
    let getThd m =
    let setErr x m =
    let setEnv x m =
    module State =
    let inject m s =
    let get =
    let gets f s =
    let put s =
    let eval m s =
    let run m s =
    let modify f s =
    let bind f m =
    let ``⍒`` =
    let લાય =
    let લે =
    let ભગાય =
    #if Bacchus
    let =
    #endif
    let પહેલું_લે x =
    let બીજું_લે x =
    let ત્રીજું_લે x =
    let પહેલું_લાય =
    let બીજું_લાય =
    let ત્રીજું_લાય =
    let ઘૂમાય_તેર =
    let ઘૂમાય_બત્રિસ =
    let setM x =
    let setE x =
    let getUNID (cls:string) =
    module Control =
    let કબૂતર =
    let પોપટ =
    let ચકલી =
    let કાબર =
    let બુલબુલ =
    let કાગડો =
    let ઢેલ =
    let નિ_કેશ =
    let નિ_બસ =
    let સસલૂ =
    let ખિસખોલી =
    #if !Otho
    let modNm2Idx nm =
    let getK k CombPath mod =
    #endif
    module Meta =
    #if Sierra
    let getFldInfo(): (Type*string*bool*string) list =
    let initSetFldTest:TaskDoc =
    let setFld (o:obj) (fldNm:string) (newVal:obj) =
    let runTest() =
    let dTest =
    let t =
    let getObVals o =
    let getEmbObVal o i =
    let rec recGetFlds o (subT:string option) =
    let getFlds o =
    let code1 =
    let code2 =
    let synthAssembly =
    let synthMethod =
    #endif


    CoreExt

    as of May 24th: CoreExt Map
        let statTpl msg (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s> =
        let ચકલી_લે x = fun s ->
        let પોપટ_લે x = fun s ->
        let કબૂતર_લે x = fun s ->
        let ચકલી_લાય = fun s ->
        let ચકલી_લાય1of2 = fun s ->
        let ચકલી_લાય2of2 = fun s ->
        let ચકલી_લાય1of3 = fun s ->
        let ચકલી_લાય2of3 = fun s ->
        let ચકલી_લાય3of3 = fun s ->
        let ચકલી_જોડ x = fun s ->
        let પોપટ_લાય = fun s ->
        let પોપટ_લાય1of2 = fun s ->
        let પોપટ_લાય2of2 = fun s ->
        let પોપટ_લાય1of3 = fun s ->
        let પોપટ_લાય2of3 = fun s ->
        let પોપટ_લાય3of3 = fun s ->
        let પોપટ_જોડ x = fun s ->
        let કબૂતર_લાય = fun s ->
        let કબૂતર_લાય1of2 = fun s ->
        let કબૂતર_લાય2of2 = fun s ->
        let કબૂતર_લાય1of3 = fun s ->
        let કબૂતર_લાય2of3 = fun s ->
        let કબૂતર_લાય3of3 = fun s ->
        let કબૂતર_જોડ x = fun s ->
        let વધારે_પડતો_ચૂનો chk msg s =


    module WWW =
    #if Sisyphus
    let listItr str l =
    let getNthLitm (lrefs:list<int>) (lget:list<string>) =
    let getURL1 url =
    let fetchUrl callback url =
    let myCallback (reader:IO.StreamReader) url =
    let getURL (u:string):string =
    let noose() =
    #if mjDeck2
    let getHeaders =
    #endif
    let uri =
    let client =
    let content =
    let AsyncFormPoster() =
    #endif //Sisyphus



    module Base =
    let getHash (b:byte[]) =
    let bytJuggler (li:byte[] list) : byte[] list =
    let isTwoBase =
    let isThrBase =
    let getSeed1Of3 =
    let oneOfTwo dt x y =
    let getSeed1Of2 =
    let getPtr() : IntPtr =
    let iterationCount =
    let getHdr r sl iv dat =
    let getVTpl r sl iv dat =
    let બનારસી_એંક_Base (r:string option) (dat:string) =
    let બનારસી_એંક_નવું (r:string option) (dat:string) =
    let બનારસી_એંક_જહૂનૂ (r:string option) (dat:string) =
    let બનારસી_ડિક (b:string) (p:IntPtr option) =
    let genVlt() =
    let genVlt2 (r:string) =
    let testHeaderDecr() =
    let commonChk (ans:string) (qL: list<string*string*string*string>) =
    let removeDupe (li:list<string>) =
    let testVaultBuilder (i:int) =
    let asTpl() =
    #if Obama
    let testFetch (rtb:RichTextBox) (frm:Form) =
    #endif
    #if Oscar
    let testVlt() =
    #endif
    let કલકતી_એંક (inDat:byte[]) (rsaKey:RSAParameters) (oaepPad:bool) =
    let કલકતી_ડિક (inDat:byte[]) (rsaKey:RSAParameters) (oaepPad:bool) =
    #if Taft
    let cspp =
    let EncrFolder =
    let DecrFolder =
    let SrcFolder =
    let PubKeyFile =
    let keyName =
    let CreateAsmKeys =
    let કલકતી_એંક_ફાઈલ (rsaP:RSAParameters) (inFile:string) =
    let કલકતી_ડિક_ફાઈલ (rsaP:RSAParameters) (inFile:string) =
    let ExportPublicKey =
    let ImportPublicKey =
    let GetPrivateKey_Click(object sender, EventArgs e) =
    let (|Banarasi|_|) (પાન: string) =
    let (|Calcutti|_|) (પાન: string) =
    let પાન (સુપારી: string) (લવલી:string option) (ક્વિમામ:IntPtr option) (ચબાવો:int option) (પીચાક: bool) =
    #if Three
    module ECDH =
    let bobReceive (encryptedMessage:byte[]) (iv:byte[]) =
    let alice (bobPubKey: byte[]) =
    let aliceSend (key:byte[]) (secretMessage:string) =
    let getBobKey =
    module testECDH =
    let CreateKeyPair() =
    let CreateSharedSecret (privateKey:byte[]) (publicKey:byte[]): byte[] =
    let aliceKeyPair =
    let bobKeyPair =
    let bobSharedSecret:byte[] =
    let aliceSharedSecret:byte[] =
    #endif //mjDeck2
    #endif //Taft
    module PathBuilder =
    #if !Grant
    let keyGen inL =
    let postProc aStr =
    let Rnum() =
    let getShuffled3 =
    let extendd li =
    let extended =
    let getExtOutcome (mPath2:list<_>) =
    let scrambled5 (li:string list array) =
    let scrambled3 (li:string list array) =
    let scrambled (li:string list array) =
    let genP inL =
    let buildPath path sz =
    let test1() =
    let bldMask (p1:list<_>) (p2:list<_>) (p3:list<_>) =
    #endif
    #if !Coolidge
    module Cards =
    let cardSuit =
    let cardRank =
    let bldHand (numCrds:int) =
    #endif
    module GenTags =
    let strIn =
    let initFn (x:int) =
    let prnL x =
    let li1 =
    let genTagsForEa (x:char[]) (y:int) (z:int) : list<string> =
    let genRandoms() =
    let testGenTags() =
    module internal PgnProc =
    let stripComments (gm:string):string =
    let getGames (nm: string) (s:string) =
    let getGroupCounts l =
    let getLastMove (s:string) =
    let spawnShellProcess fn gm mv =
    let getOutp fn gm mv =
    let runAs l =
    let procGames l =
    let runInitialProc (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s> =
    let load() =
    let initPgn =
    let runStatePGN() =
    module CodeServices =
    let getHeader =
    #if Victor
    let loadBldInstr doc =
    let genPortable doc =
    let loadDocLet =
    let saveDocLet doc =
    #endif
    #if Augustus
    let uri =
    let flattenOpts (li:option<'t> list) : list<'t> =
    let proc (str:string) =
    let AsyncMain() =
    #endif
    let getAdList (key:string):obj =
    let genDirs =



    module Base =
    let getUNID_Depr (cls:string) : DocUNID =
    module CitCollector =
    #if Alfa
    #if Venom
    #else
    #endif
    #endif
    module internal DatCreater =
    module dataReporter =
    let hdr =
    let UNIDsList =
    let TitlesList =
    let DomsList =
    let DomsList2 (l:string list) =
    let AbstractsList =
    let allTags =
    let allTags2 l1 l2 l3 =
    let genContent l1 l2 l3 =
    let getRpt() =
    module internal DatImporter =
    let deSerToList (fn:string):list<string> =
    let સ્ટ્રી_સપ્લીટ (str:string) (c:string) : string[] =
    let strUnquote (str:string) =
    let tkUpdates =
    let inp =
    let newTkImp (li:string[]) =
    let newTkImp2 (s: string) =
    let pcTaskImporter (l:list<string>) =
    let adToSStr (a:AdDoc) =
    let newAdImp (li:string list) =
    let newAdImp2 (s: string) =
    let importTasksFromStringDelimFile() =
    #if Trump
    #endif
    #if !Trump
    let importPCTasks (inp:string) =
    #else
    let importPCTasks (inp:string) =
    #endif
    let importAdFromStringDelimFile (inp:string) =
    let getDeSerializedDatFile fn =
    let runSer inF outF =
    #if Venom
    let runSerS() =
    #endif
    let listContentGrps datFl =
    #if Ares
    let reconcileAdDocs() =
    #endif
    #if Alfa
    let tpl2Type (typ:string) (datFl:string list list) =
    #endif
    let listContents fn typ =
    #if Trump
    let compareEntries (t1: TaskDoc) (t2: TaskDoc) =
    let sorted() (tkRes:TaskDoc list) =
    #endif
    #if Venom
    let load (f:string) =
    let listContains (li1:list<_>) (li2:list<_>) =
    let genStubs (i:int) =
    let run =
    let strUnquote (str:string) =
    let procLine (str:string) (i:int) =
    let init() =
    #endif
    let importLegacyTasks inp =
    let imptkUpdItms inp =
    let (|ParseRegex|_|) r str =
    let importSnippets inp =
    let fl() =
    let loadLegacyTasks() =
    let loadTkUpdates() =
    #if Ares
    let tkLoader =
    #endif
    let getZippedTkList outL =
    let ``લી_સિવાય_ઈનડેકસ_લી`` idxLi l =
    let applyUpd_1 x =
    let applyUpd_2 x =
    let applyUpd_3 x =
    let applyUpd_4 x =
    #if Papa
    let genRpt x =
    #endif
    let statGrp hdr li =
    let listGrps x =
    let applyTkFilter (x:list<_>) =
    #if mjDeck3
    let tkLoadWithPatches() =
    #endif
    #if Sung
    #endif
    #if Tang
    #endif
    #if Han
    #endif
    #if Shan
    #endif
    #if Venom
    let setInitialEnv (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s> =
    let mainCE() =
    #endif
    let datInit() =
    let getUnidS (cls:string) =
    let main =
    #if mjDeck2
    module standAloneDatLoader =
    let prn s =
    let strUnquote (str:string) =
    let prnAdList (ob:list<AdDoc>) =
    let getDeSerializedDatFile fn =
    let procLine (str:string) (i:int) =
    let init() =
    let legImgs() =
    let defFont:Font =
    let rtb =
    let mainFrm() =
    let runner() =
    let prn2 s =
    let prnAdList2 (ob:list<TaskDoc>) =
    #if mjDeck2
    let byProj (outL:list<TaskDoc>) =
    #endif
    #endif
    module DesignDocs =
    let colDispIdx:option<list<int>> =
    let colFillWeight: option<list<float32>> =
    let colNames =
    let rowData: list<array<obj>> =
    let getUNID (cls:string) : DocUNID =
    let toDojoTableRow tk =
    let tkTblDef():TblDefDoc<TaskDoc> =
    let DesDocInf() =
    let tkPred =
    let tkDefGrpBy =
    let tkDefSortBy =
    let musicDat: list<array<obj>> =
    let DV1() =
    let getDeSerTFile fn =
    let loadAndRun() =
    let grpBy (projections:list<'T -> 'Key>) (tgtLi:list<'T>) : ('Key * 'T list) list =
    let inputs =
    let proj1 =
    let proj2 =
    let proj3 =
    let addTTip (g: DataGridView) (colNum:int) (str:string) : DataGridView =
    let newD(id,cr,md,cont) =
    let strBytes (s: string) : byte[] =
    let dTest =
    let t =
    let (TaskDoc(d, pNm, modu, subM, obj, imp, urg, par, comp, dtComp, tgt, docL)) =
    let (Dat(u, crDt, modDt, tit, cont, tags, flag)) =
    let (duCaseinfo, duValueArray) =
    let attribs =
    let tkFldsLi =
    let genFldDocs() =
    #if Diana
    let isDesTyp (o:obj) =
    #else
    let isDesTyp (o:obj) =
    #endif
    let desDVSortOrder =
    let li =
    let ord =
    #if Vespasian
    let SortWithCustomComparer listIn custmOrder =
    #endif
    let genDox() =



    module Rook =
    module Trivia =
    let GetGrkNm (grkNm , romNm , desc , sym) =
    let GetRomNm (grkNm , romNm , desc , sym) =
    let GetDesc (grkNm , romNm , desc , sym) =
    let GetSym (grkNm , romNm , desc , sym) =
    let GetGndr (grkNm , romNm , desc , sym) =
    let GetAns g =
    let ListExcept (li:list<_>) (excludeLi:list<_>) =
    let getUniqueItems (numNdd:int) (li:list<_>):list<_> =
    let Rom2Grk =
    let Grk2Rom =
    let DescQn =
    let SymQn =
    let BeheadedQn =
    let PrincipateQn =
    let philoQn =
    let GenAllOlympianQns =
    let GenBeheadedQns =
    let GenPrincipateQns =
    let pickOneOf4 =
    let runTrivia (typ:string) =
    let res(q:string, opts:list<string>, ans:string, inf:string ) =
    module Setup =
    let prefixes =
    let colLi =
    let numLi =
    let txt1Li =
    let txt2Li =
    let setInitialEnv (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s> =
    let runInitSetup () =
    #if Zeus
    let applyShuffled3 li =
    let pickR() =
    let pickR3 =
    let rndChk() =
    #endif
    #endif //!Minerva
    #if ump
    module StateWin =
    let btnHandler =
    let initForm =
    let finalSt =
    let mainSt =
    let inp : Mtpl<string,'a list,'b [],'c,'d> =
    let statState =
    let inp : Mtpl<Cit list,obj,obj,obj,obj> =
    #endif
    module Runner =
    #if ump
    let mainCE() =
    let main argv =
    #endif
    let initF () =
    let defFrm :Form =
    let main argv =

    #nowarn "20" "58" "66" "67" "64" "760" "1182" "1558"
    module internal Helpers =
    let defFont:Font =
    let defPadding =
    let toP (o:obj):Panel =
    let toTblP (o:obj):TableLayoutPanel =
    let toFlowP (o:obj):FlowLayoutPanel =
    let toBtn (o:obj):Button =
    let toTxtBox (o:obj):TextBox =
    let toLbl (o:obj):Label =
    let titleTxt:string =
    let titleTxt2:string =
    let titleTxt3:string =
    let titleTxt4:string =
    let mLTxt:string =
    let testList =
    let choiceL =
    let comboChoiceL =
    let imgLi =
    let icn =
    let getAdIcon (tag:string) =
    let dCobaltBlue:Color =
    let AirForcefBlue:Color =
    let LimeBlue:Color =
    let PlatinumBlue:Color =
    let MediumDark:Color =
    let Dark:Color =
    let Light:Color =
    let Lighter:Color =
    let Darkest:Color =
    let Linen:Color =
    let SlateGray:Color =
    let Lightest:Color =
    let lightColors =
    let darkColors =
    let allColors:list<_> =
    let getRandomColor:Color =
    let getRandomLightColor:Color =
    let getRandomDarkColor:Color =
    let anc =
    let doc =
    let ancA =
    let ancN =
    let ancTL =
    let ancLR =
    let ancTB =
    let ancTR =
    let ancBL =
    let ancBR =
    let docT =
    let docB =
    let docR =
    let docL =
    let docN =
    let docF =
    let ctrlSnapShot (c: Control) (fn:string) =
    let getPlatform =
    let panelAddRange (rng) (p:Panel) : Panel =
    let ctrlAddRange (rng:Control[]) (c:Control) =
    let ctrlAddHandler (hdlr:option<EventArgs -> unit>) (c:Control) : Control =
    let ctrlAddTags (li:list<string*obj>) (c:Control) =
    let ctrlGetTag (itm:string) (c:Control) =
    let ctrlGetTagFromTop (tag:string) (o:obj) =
    let getCurrentRTB (f:Form) =
    let getAdDoc key =
    let getImg nm =
    let txtBtn nm =
    let getTxtButton nm optF =
    let getImgButton nm optF =
    let getChkBoxBtn:CheckBox =
    let getButton txt imgNm optF :Button =
    let getLRFlowPanel() =
    let getTDFlowPanel() =
    let getTitlePanel =
    let getTSTxtBox nm :ToolStripItem =
    let getTSButton txt imgNm optF :ToolStripItem =
    let getTBItemByNm (strNm:string) (ideTS:ToolStrip):ToolStripItem option =
    let addDropDn (m:ToolStripMenuItem) (l:list<ToolStripMenuItem>) =
    let getTxtLbl txt =
    let getPwdBox =
    let getMenuItm nm (f:EventArgs -> unit) :ToolStripMenuItem =
    let dissItm (inO:option<ToolStripMenuItem>) =
    let dissLi (inO: option<list<ToolStripMenuItem>>) =
    let addCopyPasteDisableHandlers (c: Control) =
    let centerOnScreen (d:Form) =
    let getPnlWith (cList:list<Control>) =
    let getTblPnlWith (cols:int) (rows:int) (cList:list<Control>) =
    let getTSImgBtn t i =
    let gridTSAddRange (li:ToolStripItem list) (ts:ToolStrip) =
    let StrStatTpnl (tagLi:string list) (d:Form) =
    let statTpnl (tagLi:string list) (d:Form) =
    let કબૂતર x =
    let પોપટ =
    let ચકલી =
    let કાબર =
    let બુલબુલ =
    let કાગડો =
    let ઢેલ =
    let નિ_કેશ =
    let નિ_બસ =
    let સસલૂ =
    let ખિસખોલી =
    let calcDropDnSize (c:ComboBox) =
    module DV =
    let cliHandlr (req:string) (g:DataGridView) =
    let colDispIdx:option<list<int>> =
    let colFillWeight: option<list<float32>> =
    let colNames =
    let musicDat: list<array<obj>> =
    let iDat: list<array<obj>> =
    let getTS (g:DataGridView) =
    let getToolStrip (g:DataGridView) =
    let addDragDrop (g:DataGridView) =
    #if Ares
    let getToolStripDVList state =
    let getToolStrip state =
    let addGridToolBar (f: Form) (g:DataGridView) state =
    #endif
    let getCol (g:DataGridView) (n:int):DataGridViewColumn =
    let addRows (g:DataGridView) (rows:DataGridViewRow[]) =
    let AddRows (g:DataGridView) (rows:DataGridViewRow[]) =
    let setColHdrStyle (g: DataGridView) =
    #if Ares
    let PopulateDV_v2 (g: DataGridView) (bindingLi:List<Dat>) =
    let freezeBand (g: DataGridView) (num:int) rowOrcol =
    #endif
    let addttip (g: DataGridView) (colNum:int) (str:string) =
    let addTTip (g: DataGridView) (colNum:int) (str:string) =
    let populateDV (colDispIdx:option<list<int>>) (colFillWeight:option<list<float32>>) (rowData:list<array<obj>>) (g: DataGridView) =
    let PopulateDV (dsp:option<list<int>>) (fw:option<list<float32>>) (rowData:list<array<obj>>) (g: DataGridView) =
    let setupDV (colNames:list<string>) (g:DataGridView) =
    let SetupDV (colNames:list<string>) (g: DataGridView) =
    let addChkBoxColAt (i:int) (g:DataGridView) =
    let addImgColAt (i:int) (g:DataGridView) =
    let paintCustomImgCell (g:DataGridView) =
    let getDef (dat:list<array<obj>>) =
    let setColHdrs (g:DataGridView) =
    let getPgBar (g:DataGridView) =
    let getPaginationBar (g:DataGridView) =
    let categPaintH (g:DataGridView) =
    let mergeCategRows (g:DataGridView) =
    #if tbdb
    #endif
    #if Ares
    let loadDef (dat:obj) (g:DataGridView) =
    let loadDat (dat:obj) (g:DataGridView) =
    let saveDat (dat:obj) (g:DataGridView) =
    let dvOpenChk (strDvName:string) (strTblName:string):option DataGridView =
    let bld (owner:Form) =
    #endif
    #if StableVerApr8
    let કલકતી_120_પાન (dsp:option<list<int>>) (fw:option<list<float32>>) (colNames:list<string>) (dat:list<array<obj>>) (owner:Form) =
    let કલકતી_120_પાન (dsp:option<list<int>>) (fw:option<list<float32>>) (colNames:list<string>) (dat:list<array<obj>>) (owner:Form) =
    #else
    #endif
    module Dlg =
    #if Fillmore
    let getCInputDlg inpTxt (i:Form) =
    #endif
    let getDlgBase (i:Form) (sz: int) =
    let getDlgBase_v2 (i:Form) (sz: int) =
    let addTitlePanel (t:string) (dlg:Form) =
    let addTitlePanel_v2 (t:string) (dlg:Form) =
    let sizeButtonWids (lb:list<Button>) =
    let addBtnPanel (n:int) (dlg:Form) =
    let addBtnPanel_v2 (n:int) (dlg:Form) =
    let getDlgMini (i:Form) (t:string option) =
    let getDlg (i:Form) (t:string option) =
    let getDlg75 (i:Form) (t:string option) =
    let getDlg100 (i:Form) (t:string option) =
    let get3BtnDlgMini (i:Form) (t:string option) =
    let get3BtnDlg (i:Form) (t:string option) =
    let get3BtnDlg75 (i:Form) (t:string option) =
    let get3BtnDlg100 (i:Form) (t:string option) =
    let dlgLayoutHdlr =
    let dlgLayoutHdlr_v0 =
    let addPanelAndCustomize (dlg:Form) (midP:Panel) =
    let addPanelAndCustomize_v2 (dlg:Form) (midP:Panel) =
    let getDlgMidPanel_v0 (c:Control option) (d:Form) =
    let getDlgMidPanel (singleCtrl:Control option) (d:Form) =
    let getTextDlgPanel (strIn:option<string>) (d:Form) =
    let textConsumeFn (txtIn:string option) (dlg:Form) =
    let inpConsumeFn (txtIn:string option) (dlg:Form) =
    #if Hestia
    let getComboChoiceDlg (befLi:list<string>) (aftLi:list<string>) (d:Form) =
    let comboChoiceConsumeFn (l:Option<list<string>*list<string>>) (d:Form) =
    #endif
    let getListDlgPanel (l:option<list<_>>) (d:Form) =
    let listConsumeFn (optP:option<_>) (dlg:Form) =
    let combDlgUpdate (iNm:string) (idxOf:int) (idx:int option) =
    let getCombDlgPanel (l:option<list<_*string>>) (d:Form) =
    let CombConsumeFn (optP:option<_>) (dlg:Form) =
    let getTextDlgPanel_v2 (strIn:option<string>) =
    let getTextDlgPanel_v3 (strIn:option<string>) =
    let textConsumeFn_v2 (dlg:Form) =
    let textConsumeFn_v3 (dlg:Form) =
    let getSecDlgPanel =
    let secDlgConsumeFn (dlg:Form) =
    #if !Foxtrot
    let getPathDlgPanel (inL:list<string>) =
    let pathConsumeFn (dlg:Form) =
    #endif
    #if Mars
    let listOrderingConsumeFn (dlg:Form) =
    let monoTesterForListBox =
    #endif
    #if Diana
    let getTagCloudPanel (tl:list<(string * int)>) =
    let tagDlgConsumeFn (dlg:Form) =
    #endif
    #if !Pierce
    #else
    let getAllCardsDlgPanel =
    #endif
    #if VanBuren
    let addCombos (inL:list<string*string*string>) (f: Form) (p:TableLayoutPanel) : TableLayoutPanel =
    let getArrowBtnPanel (cB:ComboBox) (lB:ListBox) : FlowLayoutPanel =
    let getPathComboBoxes (inL:list<list<string>>):Panel =
    let getPathPanel (lB:ComboBox) (brackts:list<string>) =
    let getPathListDlgBtnPanel =
    let getPathListDlg (i: Form) (li:list<list<string>>) (brackts:list<string>) =
    let getPathParams =
    let bldPath (f:Form) =
    let bldPathS =
    let getCloudDlg (dlg: Form) (l:option<list<string*int>>) (t:string) (dlgTyp:int) =
    let createAndShowMDIFrm =
    #if Three
    #endif
    #endif //Bacchus
    let toggleViz (d:Form) =
    let કબૂતર2 =
    let પલંગ_તોડ_પાન (સુપારી:int) (લવલી:string option) (ક્વિમામ:option<_>) પીચાક (બનાવો:Form) =
    module Desktop =
    let getDesktopHandler hdlrNm state =
    let getStatusBar state =
    let addDesktopIcons pnl state =
    let dskPopupEventHandler =
    let dskLayoutHdlr =
    let getDesktopForm (li:(Bitmap*string*string*string) list) :Form =
    let getDskFrm() =
    let bld() =
    module Ide =
    let diffOb =
    #if !Clinton
    let getDiffsLineMode (bef:string) (aft:string) =
    #endif
    let getDiffs (bef:string) (aft:string) =
    let getDiffsHtml (bef:string) (aft:string) (frm:Form) =
    let getPatch (bef:string) (aft:string) (benc:bool) (frm:Form) =
    let applyPatch patch (bef:string) =
    let setupMainFrm (frm:Form) =
    let main argv =
    #if Minerva
    #endif
    let addUIMenu (frm:Form) =
    #if !Clinton
    #endif
    #if !Hestia
    #endif
    #if !Hestia
    #endif
    let frm =
    let runner() =
    module Crypto =
    #if tbdb
    let getKeyPadDlgFrm:Form =
    let keyPadBtnPanel =
    let keyPadTblPanel =
    let keyPadDlg() =
    let get9x9Panel (i:Control) =
    let getTblDlg (i: Form) (li:list<Riddle>) (o:option<EventArgs -> unit>) =
    #endif
    module Form =
    #if Alcibiades
    let colorPicker =
    let fontPicker =
    let getCommDlgPnl (lblTxt:string) (dlg:Form) (h:EventHandler) : Panel =
    let bldCfgForm (owner:Form) =
    let fldList =
    let getDefaultLbl (t:string):Label =
    let getDefaultTextBox:TextBox =
    let getTaskRangeWidget =
    let getLrgTxtBox =
    let getDatePicker =
    let getDefaultFldPanel =
    let getFldPanel (rng:Control[]) =
    let getLFldPanel (rng:Control[]) =
    let getPanels acc x =
    let build (li:list<string*FldTypes>) =
    #endif
    let btnCl (x:int) =
    let txtVal (x:int) =
    #if Taft
    let validatingForm:Form =
    let errorProviderForm:Form =
    #endif
    module Chess =
    let getGlyph (pc:string): string =
    let glyphToChar (pc:string): string =
    let getBdPos (toPl:string) (col:int) (row:int) =
    let getBdHdrs (toPl:string) =
    let transformFen (thisRow:string) =
    let toBoard (li:string list list) =
    let strIsDigit (str:string) : bool =
    let getToPlay (fen:string) =
    let genDat (fen:string) =
    let addDragDrop (g:DataGridView) =
    let g() =
    let assignHdrFmt (g: DataGridView) =
    let chessDlgGrid() =
    let assignDat (rowData:string list list) (g: DataGridView) =
    let assignHdrs toPlay (g: DataGridView) =
    let chessConsumeFn =
    let getChessDlg (fenStr:string) (d:Form) =
    #if Pythogoras
    module Main =
    let addUIMenu (frm:Form) =
    #if Neptune
    #endif
    #if Neptune
    #endif
    let appContext =
    let uiTester:Form =
    let main argv =
    #endif //Pythagoras


    module Core
    let delimFil
    let rawFil
    let Colors9x9Panel
    let chkBoxList
    let a2z
    let srchKeywords
    let windowedList
    let T
    let CJ
    let ``α``
    let ``β``
    let ``↠``
    let verMap
    let (|>|) f x
    let trueFn
    let falseFn
    let (|?) pred x y
    let optOr (opt:option<'a>) def
    let isTuple tuple
    let merge xs ys
    let tibbie s
    let curry f a b
    let uncurry f (a,b)
    let strLen (str:string) : int
    let strContains (str:string) (str2:string) : bool
    let strTrim (str:string) : string
    let strSplit (str:string) (c:string) : string[]
    let strRepl (x:string) (y:string) (z:string)
    let strBytes (s: string) : byte[]
    let strFromBarr (bArr:byte[]):string
    let throwSpxErr t
    let errDivZero()
    let rand
    let swap (a: _[]) x y
    let shuffle a
    let tryParseInt (str:string)
    let getRnum f s
    let logHR
    let stat str x
    let stati str x
    let log x
    let stripQuotes (s: string) : string
    let currentDate
    let defDt
    let toObj x
    let oToStr (o:option<'t>)
    let tryOf f x
    let flattenOpts (li:option<'t> list) : list<'t>
    let tryOfL f li
    let inline getString (sb : System.Text.StringBuilder)
    let inline appendString (sb : System.Text.StringBuilder) (str : string)
    let buildString strings
    let htmlUnesc s:string
    let b64Enc (str : string)
    let b64EncB (bArr : byte[])
    let b64Dec (str : string)
    #
    let bytesToZipFile (x:byte[]) e z
    let bytesToZip64 x
    let testZip()
    #
    let (|Even|Odd|) input
    let logMsg msg
    let logMsgN msg
    let toOption x
    let tryWith f x
    let bi
    let ser x
    let deSer (str : string)
    let deSerToList (fn:string):list
    let (|ParseRegex|_|) regex str
    let (|BarDelim|_|) (str: string)
    let (|TabDelim|_|) (str: string)
    let M
    let L
    let O
    let T
    let W
    let W1
    let B
    let H
    let C
    let R2
    let R
    let F
    let V
    let combine
    let Q1
    let Q
    let Q2
    let Q3
    let Q4
    #
    let L
    let B()
    let W
    let C()
    let G()
    let HoT()
    let ML x y
    #
    let ThreeKingdoms x y z
    let Yuan
    let Jin x y z
    let NorthernAndSouthernDynasties x y z
    let Sui x y
    let addStr (x:string)
    let addStr' (x:string)
    let addStr2 (x:string) (y:string)
    let Han
    let Tang x y z
    let Song
    let Ming x y z
    let Qing x y z
    let tkEx :seq
    let currentDate
    type SessionId
    type DocUNID
    let getUNID (cls:string) : DocUNID
    type OptModID
    type DocVersionModule
    type DocEditHistoryModule
    type DocAttachmntModule
    type DocImgModule
    type DocRelationModule
    type Riddle
    let getQn r
    let getK r
    type Mpath
    type TriviaRiddleQn
    type Dat
    let newD(id,cr,md,cont)
    let datToSStr (d:Dat)
    type Cit
    type SpxLog
    type Snippet
    type AdDoc
    let newAdDoc(id, cr, tit, tags, cont)
    type ArticleDoc
    type TgtVer
    type TaskDoc
    let taskToSStr (t:TaskDoc)
    let newA(id, cr, tit, tags, cont)
    let adToSStr (a:AdDoc)
    let newTaskImp(s:string)
    let newAdImp(s:string)
    type Quad
    let intComparer a b
    let resultInt
    let ex
    let Imp x
    let Urg x
    let getQuad (a:int*int)
    let QuadComparer a b
    type IdeW
    type DskW
    type GridW
    type activeWin
    type Env
    type Env
    let initSession (userNm:option)
    let cliHandlr (req:string) (g:DataGridView)
    type Mtpl<'m,'t,'p>
    let tmpEnv
    let empty
    let MtplOf x y z
    let addErr errStr m
    let inline (>!>) (f:Mtpl<'m,'t,'p> -> Mtpl<'r,'e,'t>) m
    let inline (>!!>) mapList mapper m
    let hasFst m
    let setFst x m
    let getFst m
    let hasSnd m
    let setSnd x m
    let getSnd m
    let hasThd m
    let setThd x m
    let getThd m
    let setErr x m
    let setEnv x m
    type State<'St, 'm>
    let inject m s
    let get
    let gets f s
    let put s
    let eval m s
    let run m s
    let modify f s
    let bind f m
    type StateBuilder()
    let ``⍒``
    let setF x
    let setM x
    let setE x
    #
    type CombPath
    let modNm2Idx nm
    let getK k CombPath mod
    #
    module Comm
    #
    let listItr str l
    let getNthLitm (lrefs:list) (lget:list)
    let getURL1 url
    let fetchUrl callback url
    let myCallback (reader:IO.StreamReader) url
    let getURL (u:string):string
    let google()
    let getHeaders
    let uri
    let client
    let content
    let AsyncFormPoster()
    #
    module Crypto
    let getPtr() : IntPtr
    let iterationCount
    let getHdr r sl iv dat
    let AESEnc (r:string option) (dat:string) : string
    let AESDec (b:string) (p:IntPtr option)
    let genVlt()
    #
    let testFetch (rtb:RichTextBox) (frm:Form)
    #
    let testVlt()
    let RSAEncr (inDat:byte[]) (rsaKey:RSAParameters) (oaepPad:bool)
    let RSADecr (inDat:byte[]) (rsaKey:RSAParameters) (oaepPad:bool)
    #
    let cspp
    let EncrFolder
    let DecrFolder
    let SrcFolder
    let PubKeyFile
    let keyName
    let CreateAsmKeys
    let EncryptFile rsa inFile
    let DecryptFile rsa inFile
    let ExportPublicKey
    let ImportPublicKey
    let GetPrivateKey_Click(object sender, EventArgs e)
    #
    #
    let keyGen inL
    let postProc aStr
    let Rnum()
    let getShuffled3
    let extendd li
    let extended
    let getExtOutcome (mPath2:list<_>)
    let scrambled5 (li:string list array)
    let scrambled3 (li:string list array)
    let scrambled (li:string list array)
    let genP inL
    let buildPath path sz
    let test1()
    let bldMask (p1:list<_>) (p2:list<_>) (p3:list<_>)
    #
    #
    type Rank
    type Suit
    type Card
    let desc (c:Card)
    let getRnum f s
    let bldHand
    let tryParse (str:string)
    let testL
    let resL
    let runCards()
    #
    let strIn
    let initFn (x:int)
    let prnL x
    let li1
    let genTagsForEa (x:char[]) (y:int) (z:int) : list
    let genRandoms()
    let testGenTags()
    let rec stripComments (gm:string) (i:option):string
    let getGames (nm: string) (s:string)
    let getGroupCounts l
    let getLastMove (s:string)
    let spawnShellProcess fn gm mv
    let getOutp fn gm mv
    let runAs l
    let procGames l
    let runInitialProc (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s>
    let load()
    let initPgn
    let runStatePGN()
    module Data
    #
    let (|StrOut|_|) (str: string)
    let (|LrbCit|_|) (str: string)
    let (|ALDailyCit|_|) (str: string)
    let (|ParseRegex|_|) regex str
    let parseValWithActivePattern str
    let parseVal (str:string)
    let lrbUrlBase
    let lrbUrlNums
    let lrbExpanded
    let aldUrlBase
    let aldUrlNums
    let aldExpanded
    let runAlDgetter()
    let uri
    let autoParse2 tpl
    let autoParse1 (s:string)
    let breakTo5 (s:string)
    let run()
    #
    let listRaw()
    let procDat (dat:string list) (u:string)
    let tL
    let toOpt
    let funcMapFld acc (x:Cit option)
    let procRes
    let flattened
    let res, acc
    let collapsedRes
    let procCits()
    #
    let tkUpdates
    let inp
    let newTaskImp(s:string)
    let adToSStr (a:AdDoc)
    let newAdImp(s:string)
    let importTasksFromStringDelimFile()
    let importAdFromStringDelimFile(inp:string)
    let ser x
    let getDeSerializedDatFile()
    let runSer()
    let runSerS()
    let listContents()
    let reconcileAdDocs()
    let init()
    let testStateVersion()
    #
    module UI
    let defFont:Font
    let ctrlAddRange (rng:Control[]) (c:Control) : Control
    let ctrlAddHandler (hdlr:option unit>) (c:Control) : Control
    let getAdDoc key
    let getImg nm
    let txtBtn nm
    let getTxtButton nm optF
    let getImgButton nm optF
    let getChkBoxBtn:CheckBox
    let getButton txt imgNm optF :Button
    let getTSTxtBox nm :ToolStripItem
    let getTSButton txt imgNm optF :ToolStripItem
    let getTxtLbl txt
    let getPwdBox
    let getMenuItm nm (f:EventArgs -> unit) :ToolStripMenuItem
    let addCopyPasteDisableHandlers (c: Control)
    let centerFrm (f:Form)
    let getDefaultDlgFrm (i:Form)
    let getInpDlg msg (i:Form)
    let getChoiceDlg msg (i:Form) (l1:list) (l2:list)
    let getCInputDlg inpTxt (i:Form)
    let getTitlePanel str
    let getLRFlowPanel
    let getTDFlowPanel
    let getDefaultDlgBtnPanel (o:option unit>)
    #
    let getBtnPanel
    let addMenu (frm:Form)
    #
    let getTxtDlg (i: Form) (strIn:option) (o:option unit>)
    let get9x9Panel (i:Control)
    let getTblDlg (i: Form) (li:list) (o:option unit>)
    #
    let getDlgFrm:Form
    let btnPanel
    let titlePanel s
    let btnCl (x:int)
    let txtVal (x:int)
    let tblPanel
    let dlg1()
    let validateFrm (sender:obj) (evtArgs:EventArgs)
    let validatingForm()
    let errorProviderForm:Form
    #
    let getHeader
    #
    let loadBldInstr doc
    let genPortable doc
    let loadDocLet
    let saveDocLet doc
    #
    #
    let uri
    let flattenOpts (li:option<'t> list) : list<'t>
    let proc (str:string)
    let AsyncMain()
    #
    #
    type sDlg
    let addCombos (inL:list) (f: Form) (p:TableLayoutPanel) : TableLayoutPanel
    let getArrowBtnPanel (cB:ComboBox) (lB:ListBox) : FlowLayoutPanel
    let getPathComboBoxes (inL:list>):Panel
    let getPathPanel (lB:ComboBox) (brackts:list)
    let getPathListDlgBtnPanel
    let getPathListDlg (i: Form) (li:list>) (brackts:list)
    let getPathParams
    let bldPath (f:Form)
    let bldPathS
    type PathDlg
    let getListDlg (i: Form) (l:option list) (o:option unit>)) (t:int)
    let cliHandlr (req:string) (g:DataGridView)
    let createAndShowMDIFrm
    let getDesktopForm
    let getDskLayoutPanel
    let dskIconBox icnNm
    let bldIcnPanel icnNm tx hdlr
    let getDesktopHandler hdlrNm state
    let getStatusBar state
    let addDesktopIcons pnl state
    let bld()
    type FldTypes
    let fldList
    let getDefaultLbl (t:string):Label
    let getDefaultTextBox:TextBox
    let getTaskRangeWidget
    let getLrgTxtBox
    let getDatePicker
    let getDefaultFldPanel
    let getFldPanel (rng:Control[])
    let getPanels acc x
    let build (li:list)
    #
    let getPaginationBar (g:DataGridView)
    let getToolStripDVList state
    let getToolStrip state
    let addGridToolBar (f: Form) (g:DataGridView) state
    #
    let getCol (g:DataGridView) (n:int):DataGridViewColumn
    let AddRows (g:DataGridView) (rows:DataGridViewRow[])
    let setColHdrStyle (g: DataGridView)
    #
    let PopulateDV_v2 (g: DataGridView) (bindingLi:List)
    #
    let freezeBand (g: DataGridView) (num:int) rowOrcol
    let addTTip (g: DataGridView) (colNum:int) (str:string) : DataGridView
    #
    #
    let PopulateDV (g: DataGridView)
    let SetupDV (f:Form) (g:DataGridView)
    let addChkBoxColAt (i:int)
    let addImgColAt (i:int)
    let paintCustomImgCell g
    let getDefDV1
    let setColHdrs (g:DataGridView)
    let getDefDV
    let bld (owner:Form)
    let bldGrid (owner:Form)
    let diffOb
    #
    let getDiffsLineMode (bef:string) (aft:string)
    #
    let getDiffs (bef:string) (aft:string)
    let getDiffsHtml (bef:string) (aft:string)
    let getPatch (bef:string) (aft:string) (benc:bool)
    let applyPatch patch (bef:string)
    let testDiff (bef:string option) (aft:string option)
    let setupMainFrm (frm:Form)
    #
    #
    let main argv
    #
    #
    #
    #
    #
    module Init
    let prefixes
    let colLi
    let numLi
    let txt1Li
    let txt2Li
    let setInitialEnv (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s>
    let runInitSetup ()
    #
    let applyShuffled3 li
    let pickR()
    let pickR3
    let rndChk()
    #
    #
    let btnHandler
    let initForm
    let finalSt
    let mainSt
    let inp : Mtpl
    let statState
    let inp : Mtpl
    #
    #
    let initF ()
    let defFrm :Form
    let main argv
    #
    let mainCE()
    let main argv
    #



    #
    module Base
    let Cmp()
    module Comm.WWW
    #
    let listItr str l
    let getNthLitm (lrefs:list) (lget:list)
    let getURL1 url
    let fetchUrl callback url
    let myCallback (reader:IO.StreamReader) url
    let getURL (u:string):string
    let google()
    let getHeaders
    let uri
    let client
    let content
    let AsyncFormPoster()
    #
    module Crypto.Base
    let getPtr() : IntPtr
    let iterationCount
    let getHdr r sl iv dat
    let AESEnc (r:string option) (dat:string) : string
    let AESDec (b:string) (p:IntPtr option)
    let genVlt()
    #
    let testFetch (rtb:RichTextBox) (frm:Form)
    #
    let testVlt()
    let RSAEncr (inDat:byte[]) (rsaKey:RSAParameters) (oaepPad:bool)
    let RSADecr (inDat:byte[]) (rsaKey:RSAParameters) (oaepPad:bool)
    #
    let cspp
    let EncrFolder
    let DecrFolder
    let SrcFolder
    let PubKeyFile
    let keyName
    let CreateAsmKeys
    let EncryptFile rsa inFile
    let DecryptFile rsa inFile
    let ExportPublicKey
    let ImportPublicKey
    let GetPrivateKey_Click(object sender, EventArgs e)
    #
    module PathBuilder
    let hr()
    let a2z
    let z2a
    let liprAll
    let lipr
    let rndUns
    let lilen (l:list<_>)
    let lifo
    let liExc
    let liGetRnd
    #
    let getBrack
    #
    #
    let keyGen inL
    let postProc aStr
    let Rnum()
    let getShuffled3
    let extendd li
    let extended
    let getExtOutcome (mPath2:list<_>)
    let scrambled5 (li:string list array)
    let scrambled3 (li:string list array)
    let scrambled (li:string list array)
    let genP inL
    let buildPath path sz
    let test1()
    let bldMask (p1:list<_>) (p2:list<_>) (p3:list<_>)
    #
    #
    module Crypto.Cards
    type Rank
    type Suit
    type Card
    let desc (c:Card)
    let getRnum f s
    let bldHand
    let tryParse (str:string)
    let testL
    let resL
    let runCards()
    #
    module Crypto.GenTags
    let strIn
    let initFn (x:int)
    let prnL x
    let li1
    let genTagsForEa (x:char[]) (y:int) (z:int) : list
    let genRandoms()
    let testGenTags()
    module PgnProc
    module
    let hr()
    let lifo
    let lim
    let liprAll
    let lipr
    #
    let strContains
    let tryParse (str:string)
    let getMatchesForGrpNums
    let getMatchesForGrpNms
    let rec replSingle
    let reg
    #
    #
    #
    let rec stripComments (gm:string) :string
    #
    let getGames
    #
    #
    let getEaPos
    #
    #
    #
    let getBdHdrs
    let getGlyph
    let સપ્લીટ
    let inp
    let allRows
    let toL
    let ઇસ_ડિજીટ
    let rowStrToBd
    let fen2Rows
    #
    let getGroupCounts l
    let getLastMove (s:string)
    let spawnShellProcess fn gm mv
    #
    let getOutp fn gm mv
    let runAs l
    let procGames l
    let runInitialProc (m:Mtpl<'m,'t,'p>) : Mtpl<'r,'e,'s>
    let load()
    let initPgn
    let runStatePGN()
    #
    let someGames
    let getMvTrips
    let liToStr
    let res
    let resA, resB
    let toPl
    let mvs:list<_>
    let mvsMid
    let lasStr mvsL
    let toTrips
    let fenInps
    #
    let fenInps
    #
    #
    module TriviaTrebek
    let strR
    let somQns
    let someQns
    let r
    let rFull
    let l()
    let categsL
    let resL
    module TriviaLaureates
    type Laureates
    let tryParseInt
    let txt
    let લેન
    let સપ્લીટ
    let rows
    let len
    let trimUnq
    let noHdr
    let toTy
    let main argv



    module CitCollector
    ; #
    ; let (|StrOut|_|) (str: string)
    ; let (|LrbCit|_|) (str: string)
    ; let (|ALDailyCit|_|) (str: string)
    ; let (|ParseRegex|_|) regex str
    ; let parseValWithActivePattern str
    ; let parseVal (str:string)
    ; let lrbUrlBase
    ; let lrbUrlNums
    ; let lrbExpanded
    ; let aldUrlBase
    ; let aldUrlNums
    ; let aldExpanded
    ; let runAlDgetter()
    ; let uri
    ; let autoParse2 tpl
    ; let autoParse1 (s:string)
    ; let breakTo5 (s:string)
    ; let run()
    ; #
    ; module internal DatCreater
    ; let listRaw()
    ; let procDat (dat:string list) (u:string)
    ; let tL
    ; let toOpt
    ; let funcMapFld acc (x:Cit option)
    ; let procRes
    ; let flattened
    ; let res, acc
    ; let collapsedRes
    ; let procCits()
    ; #
    ; module DatImporter
    ; let tkUpdates
    ; let inp
    ; let newTaskImp(s:string)
    ; let adToSStr (a:AdDoc)
    ; let newAdImp(s:string)
    ; let importTasksFromStringDelimFile()
    ; let importAdFromStringDelimFile(inp:string)
    ; let ser x
    ; let getDeSerializedDatFile()
    ; let runSer()
    ; let runSerS()
    ; let listContents()
    ; let reconcileAdDocs()
    ; let init()
    ; let testStateVersion()
    ; #



    type SessionId
    type Env
    type Mtpl
    type DocUNID
    type OptModID
    type TgtVer
    type DocFld
    type Dat
    #
    #
    type Ad
    type Task
    #
    type Article
    type Cit
    type Quad
    type Doc<'d>
    type Cfg<'c>
    type TblDef<'d>
    #
    module Core
    let lim
    let limi
    let limf
    let limfs
    let limfl
    let liRemAt
    let liUpdAt
    let liprAll
    let lipr
    let lilen (l:list<_>)
    let lifo
    let liExc
    let reg
    let rec replSingle
    #
    #
    let ListUpdateAt
    let ListRemoveAt
    #
    let Optઓર
    let Strબાઇટ
    #
    let (|>|) f x
    let defEnc:Encoding
    let currentDate
    let defDt
    let now()
    let currTicks
    let Htrue
    let Hfalse
    let toOb
    let oToStr (o:option<'t>)
    let (|?) pred x y
    let optOr (opt:option<'a>) def
    let isTuple tuple
    let merge xs ys
    let tibbie s
    let curry f a b
    let uncurry f (a,b)
    let tryOf f x
    let tryOfL f li
    let tryWith f x
    let bi
    let ser x
    let deSer (str : string)
    let deSerToList (fn:string):list
    let (|ParseRegex|_|) regex str
    let (|BarDelim|_|) (str: string)
    let (|TabDelim|_|) (str: string)
    let fCoreVer
    let platform
    let T
    let CJ
    let ``α``
    let ``β``
    let ``↠``
    let verMap
    let flattenOb
    let flat
    let defFont
    let bur
    let tyOf
    let isTy
    let hasInt
    let isEnum
    let pr
    let hr()
    let tibbie
    let defPadding
    let anc
    let doc
    let b64EncB
    let b64EncB_SingleLine
    let b64Enc
    let b64Enc_SingleLine
    let b64Dec
    let bytes2Str
    let getRnum f s
    let rndUns
    let initSession (userNm:option)
    let tryParseInt (str:string)
    let tmpEnv
    let mLTxt
    let topFrmMenuItm
    let ctrlGetTag
    let rec ctrlAddTags
    let get1
    type State
    let getS
    let putS s
    let eval m s
    let exec m s
    let empty
    let modif f s
    let bind k m
    type StateBuilder()
    let ``⍒``
    type ContinuationBuilder()
    let ``⍲``
    let ``⍭`` f:('a -> 'r) -> 'r
    #
    #
    let M
    let L
    let O
    let T
    let W
    let W1
    let B
    let H
    let C
    let R2
    let R
    let F
    let V
    let combine
    let Q1
    let Q
    let Q2
    let Q3
    let Q4
    #
    let L
    let B()
    let W
    let C()
    let G()
    let HoT()
    let ML x y
    let ટીન x y z
    let ટીનtp x y z
    let કારલોસ
    let બારી f s t
    let ભોલે
    let કરાફે f
    let ઍસોપ a b
    let પ્રાઈજ a b c
    let ગ્રુનડીગ a b
    #
    let ThreeKingdoms
    let Yuan
    let જિન
    let NorthernAndSouthernDynasties x y z
    let સૂઈ
    let addStr
    let addStr'
    let addStr2
    let હાન
    let ટેન્ગ
    let સૂંગ
    let મિંગ
    let ક્વિન્ગ
    let વરેપ1 x y z
    let વરેપ2 (x,(a,y))
    let વરેપ2a (x,(a,y))
    let વચલૂં mid aft x
    let વરેપ befFn mainFn aftFn x
    let વરેપ_2 befFn mainFn aftFn x
    let tkEx :seq
    module CodeServices
    let getHeader
    #
    let loadBldInstr doc
    let genPortable doc
    let loadDocLet
    let saveDocLet doc
    #
    #
    let uri
    let proc (str:string)
    let AsyncMain()
    #
    module Control
    let Counties
    let tmpPick
    let aFl
    #
    #
    #
    #
    #
    #
    #
    #
    #
    #
    let origHdr
    let getHdr
    let bldHdr
    let rec pick30
    let flipCase
    let alignWithPrior
    let aProcChk
    let allMatches
    let hasBang
    let Proc



    module internal Helpers
    let imgLi
    let dCobaltBlue
    let AirForcefBlue
    let LimeBlue
    let PlatinumBlue
    let MediumDark
    let Dark
    let Light
    let Lighter
    let Darkest
    let Linen
    let SlateGray
    let Lightest
    let lightColors
    let darkColors
    let allColors
    let getRandomColor
    let getRandomLightColor
    let getRandomDarkColor
    let defPadding:Padding
    let defFont:Font
    let ctrlAddRange (rng:Control[]) (c:Control) : Control
    let ctrlAddHandler (hdlr:option unit>) (c:Control) : Control
    let getTopForm
    let stati s o
    let anc
    let doc
    let tibbie s
    let tryParseInt
    type Glyphs
    let CreateGlyphIcon
    let વિજય_ની_જમીન
    let લી_વિજય_ની_જમીન
    let mLTxt
    let read s
    let write x s
    let run x s
    let eval x s
    let modify f
    let topFrmMenuItm
    let addDropDn
    let disItm
    let disLi
    let centerOnScreen
    let ctrlGetTag
    let rec ctrlAddTags
    let getAdDoc key
    let getImg nm
    let txtBtn nm
    let getTxtButton nm optF
    let getImgButton nm optF
    let getChkBoxBtn:CheckBox
    let getButton txt imgNm optF :Button
    let getTSTxtBox nm :ToolStripItem
    let getTSButton txt imgNm optF :ToolStripItem
    let getTxtLbl txt
    let getPwdBox
    let getMenuItm nm (f:EventArgs -> unit) :ToolStripMenuItem
    let addCopyPasteDisableHandlers (c: Control)
    let centerFrm (f:Form)
    let getDefaultDlgFrm (i:Form)
    let getTitlePanel str
    let getLRFlowPanel
    let getTDFlowPanel
    let getDefaultDlgBtnPanel (o:option unit>)
    #
    let getBtnPanel
    let addMenu (frm:Form)
    #
    #
    let getDlgFrm:Form
    let btnPanel
    let titlePanel s
    let btnCl (x:int)
    let txtVal (x:int)
    let tblPanel
    let dlg1()
    let validateFrm (sender:obj) (evtArgs:EventArgs)
    let validatingForm()
    let errorProviderForm:Form
    #
    #
    module Dlg
    let getHalfScreenSz
    let setupDlg
    type dlg private (own:Form) as this
    let z
    let defPadding
    let getPlatform
    let sizeButtonWids
    let getDlgBase
    let addTitlePanel
    let addBtnPanel
    let પલંગ_તોડ_પાન
    let getDlgBase (i:Form) (sz: int)
    let addTitlePanel (t:string) (dlg:Form)
    let sizeButtonWids (lb:list
    [let flattenOb
    ; let flat
    ; let (|>|) f x
    ; let defEnc:Encoding
    ; let currentDate
    ; let defDt
    ; let now()
    ; let toOb
    ; let removeAt idx li
    ; fsharpc --nologo --out:main.exe main.fs mono main.exeres: [let flattenOb
    ; let flat
    ; let (|>|) f x
    ; let defEnc:Encoding
    ; let currentDate
    ; let defDt
    ; let now()
    ; let toOb
    ; let removeAt idx li
    ; let updateAt idx newVal li
    ; let currTicks
    ; let tk
    ; let ઓર
    ; let બાઇટ
    ; type DocUNID
    ; type OptModID
    ; type TgtVer
    ; type DocFld
    ; type Dat
    ; #
    ; #
    ; type Ad
    ; type Task
    ; type Cit
    ; type Cfg
    ; type TblDef
    ; type Doc
    ; let tbl
    ; let cfg1
    ; let cfg2
    ; let a1
    ; let a2
    ; let c1
    ; let l:Doc list
    ; let l2
    ]


    let hr()
    let toOb
    let flattenOb
    let flatten
    let tickSignif()
    let ListUpdateAt idx newVal li
    let ListRemoveAt idx li
    type Mtpl
    let ob1
    let ob2
    let ob3
    let ob4
    let ob6
    let r
    let s
    let getRes
    type State<'Mtpl, 'T>
    let getS
    let putS s
    let eval m s
    let exec m s
    let empty
    let modif f s
    let bind k m
    type StateBuilder()
    let ``⍒``
    let tplRun
    type ContinuationBuilder()
    let ``⍲``
    let ``⍭`` f:('a -> 'r) -> 'r
    let SumList l
    let FFst ss
    let TThd ss
    let rec SSum ss
    let Remmer()
    let Disp()
    let SumListSt