health

Prescription drug alternatives

Share

Micro Services

A contrarian’s (with vested interests) view

Trulia switches to “Islands”

Why Doctors hate their computers Feature creep; the “Tar Pit”

Proprietary IT give big companies their edge.

Microservices as innovation enablers best practices == common practices

Split the monolith

Now, don’t get me wrong. It was architected in multiple tiers, and those tiers had many components in them. But they’re all very tightly coupled together, where they behaved like one big monolith. Now, a lot of startups, and even projects inside of big companies, start out this way. They take a monolith-first approach, because it’s very quick, to get moving quickly. But over time, as that project matures, as you add more developers on it, as it grows and the code base gets larger and the architecture gets more complex, that monolith is going to add overhead into your process, and that software development lifecycle is going to begin to slow down.

Rob Brigham, Amazon AWS senior manager for product management

Share

GsDevKit

After reading an article evangelizing smalltalk, learning that it is a pure OO language, and works on top of GemStone, I decided to give it a try. I follow the GemTalk Systems installation instructions which are essentially:

1
2
3
4
5
6
7

git clone https://github.com/GsDevKit/GsDevKit_home.git
cd GsDevKit_home
. bin/defHOME_PATH.env # define GS_HOME env var and put $GS_HOME into PATH
installServerClient
createStone devKit_33 3.3.0
createClient tode1

I am running on Debian 9.3 which is not supported so a few hacks were required.

modify .bashrc

.bashrc
1
2
3
4
5

.....
export GS_HOME=~/GsDevKit_home
export PATH="/home/mbc/bin:$GS_HOME/bin:$PATH"
.....

Change OS recognition. Note - this may invalidate all warranties!
One of the scripts called is ~/GsDevKit_home/bin/utils/installOsPrereqs

Look for the method installPrereqsForDebian() and change testing | 8.3 to 9.3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
installPrereqsForDebian(){
case "$osVersion" in
testing | 9.3)
sudo dpkg --add-architecture i386
installUbuntuPackages
sudo apt-get -y install fonts-dejavu # ensure that DejaVu Sans Mono font present (default font for tODE)
sudo ln -f -s /usr/lib/i386-lin-gnu/libstdc++.so.6 /usr/lib/i386-linux-gnu/libstdc++.so
;;
*) usage; exit_1_banner "unrecognized Debian version $os";;
esac
}



To get started with tODE:

1
2
3
startStone -b devkit_33
startClent tode1

‘stones’ command in the terminal will show running stones
‘testLogin’ in tODE will confirm connection

Share

Walls Work

Good fences make good neighbors

EU pays for Turkey’s wall with Syria

Walls work

Walls can be 100% effective

Using an estimate of $6 billion for a border wall with Mexico we could have built 25 walls with the $150 billion obama gave to Iran.

The US gives $45 billion per year in aid to African countries - 7 more walls.

We need to stop debating the cost or effectiveness of walls. They are effective and affordable. What needs to be debated is whether the US has the resolve to protect its borders.

Share

JavaHelp for Clojure

To get everything working in clojure a few modifications need to be performed. First in project.clj you must add javahelp as a dependency, and indicate the resource path where you will store the helpset. By default leinengen will create a MyProject/resources directory and I placed my helpset in a subdirectory there:

project.clj
1
2
3
4
5
6

:dependencies [[org.clojure/clojure "1.8.0"]
[javax.help/javahelp "2.0.05"]]

:resource-paths ["resources"]

In core I only show some of the required namespace additions and the menu entries.

core.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

(:require [clojure.java.io :as io] )
(:import [java.net.URL])


;; this is the Help item on my menubar
(menu :text "Help"
:halign :right
:items [(action :handler (fn [e]
(let [helpURL (io/resource "helpset/pmhelp.hs")
hs (new javax.help.HelpSet nil helpURL)
hb (. hs createHelpBroker)
dummy (. hb setCurrentID "assaytype")
dummy2 (. hb setDisplayed true)]))
:name "Help"
:key "menu H"
:tip "Launch help app.")

I have 2 dummy variables in there so I can use the let expression, but I could rearrange using doto:

core.clj
1
2
3
4
5
6
7
8
9

(menu :text "Help"
:halign :right
:items [(action :handler (fn [e]
(doto (.createHelpBroker (new javax.help.HelpSet nil (io/resource "helpset/pmhelp.hs") ))
(.setCurrentID "assaytype")(.setDisplayed true)))
:name "Help"
:key "menu H"
:tip "Launch help app.")

I prefer the let method. Though it has those messy dummy variables, I can more clearly decipher what is going on.
Code available on github

Share

A JavaHelp Class

With my helpset prepared as described in the last post I am ready to launch the javahelp viewer.

Given the opacity of the api pdf files, I decided that I needed to first implement a Java class that would open a help dialog. Once I have defined the required methods, it will be easier to recode in Clojure. It has been >10 years since I last thought about Java code so getting back in the swing (hah!) won’t be easy. When I last worked with the language generics and enums were yet to be defined.

I call my class OpenHelpDialog and don’t bother putting it in a package.

OpenHelpDialog.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

import javax.help.*;
import java.net.URL;

public class OpenHelpDialog {

public static HelpSet hs;
public static HelpBroker hb;
public static String helpHS;
public static URL hsURL;

public OpenHelpDialog(){
helpHS = "../pmhelpset/pmhelp.hs";

ClassLoader cl = OpenHelpDialog.class.getClassLoader();

try {
hsURL = HelpSet.findHelpSet(cl, helpHS);
hs = new HelpSet(null, hsURL);
} catch (Exception ee) {
// Say what the exception really is
System.out.println( "HelpSet " + ee.getMessage());
System.out.println("HelpSet "+ helpHS +" not found");
}
hb = hs.createHelpBroker();
hb.setCurrentID("assaytype");
hb.setDisplayed(true);
}

public static void main(String [ ] args){
new OpenHelpDialog();
}
}

I navigate to its directory which is “/home/mbc/plate-manager/jws/pm/pmhelpclasses” and:

compile.sh
1
2
3

javac -cp /home/mbc/plate-manager/jws/pm/pm/helpclasses:/home/mbc/plate-manager/jws/pm/pmhelpset:/home/mbc/plate-manager/jws/pm/resources/javahelp-2.0.05.jar OpenHelpDialog.java

Note that I include the helpset directory in the classpath, as well as the helpclasses. Then run:

run.sh
1
2
java -cp /home/mbc/plate-manager/jws/pm/pmhelpclasses:/home/mbc/plate-manager/jws/pm/pmhelpset:/home/mbc/jh2.0/javahelp/lib/jhall.jar OpenHelpDialog

Looks good. By default a MainWindow is displayed.

From the api pdf it looks like the main function of the HelpBroker is to enable objects (menu items, buttons, etc.) with the ability to launch the help viewer when a HelpActionListener is activated. Looking through the methods on HelpBroker I see hb.setDisplayed(true), which allows me to launch the viewer directly. A prior version of OpenHelpDialog had a button that was activated with the HelpBroker.enableHelpOnButton() method. If I were writing in Java, that may be the preferred method, but I was uncertain how to utilize the HelpBroker that way in Clojure, given that I have another layer of abstraction between clojure and java - the seesaw gui classes.

Share

jhelpdev

Preparing the Helpset

A helpset is a set of html and xml files that work together to provide a help system. Getting the layout correct is tedious but jhelpdev automates a lot of the process. The best place to start is generate a project so that you can see what the html template looks like, and start populating the system with explanatory html help files.

I want to get the help system up and running early in the development process because I find the help files are a good place to take notes and narrate to myself the processes that my application should be handling. Once I have a skeleton helpset, it is easy to add information as the coding project progresses. At any point I can delete the xml files (not the htmls!!) and regenerate the helpsystem with jhelpdev.

To get jhelpdev running, navigate to its directory and:

jelpdev.sh
1
java -cp ./jhelpdev.jar:./jars/jhall.jar:./jars/xmlenc.jar -jar ./jhelpdev.jar

Here is what the interface looks like when a few html files have been added to the helpset directory:

Map.jhm provides a mapping between target and html file.
HelpTOC.xml proves text for TOC and mapping to target (a name).

Note the disclaimer in the jhelpdev help:

“You acknowledge that this software is not designed, licensed or
intended for use in the design, construction, operation or
maintenance of any nuclear facility.”

Code with caution.

Once your helpset is in shape you can use hsviewer.jar to view in the standard javahelp MainWindow. This is a good test to make sure all is working.

Share

Help for Clojure

Introduction

I would like to author a help file for my Plate Manager clojure application. I queried the Clojure google group but did not get any response as to which options might be viable. About 15 years ago I used JavaHelp for a java application I wrote. Given that clojure runs on top of java, I considered JavaHelp as an option.

The most recent update to javahelp, v2.0.05, appears to be from 2010. That could be a cause for concern or evidence of a mature full featured API. I remember the old Windows 3.1 .hlp files were very efficient with useful features like hyperlinks, full text search, context sensitive help, etc. Even Windows though has now migrated to an html based help format with the .chm files.

JavaHelp help content files are written in html. There are additional XML files that organize headings, table of content, search, context sensitive help, etc. Here is a view of the MainWindow interface. It also has a popup window without multiple frames and buttons, as well as tooltip help.

After a bit of hacking, I conclude that JavaHelp will work and is best implemented in three steps, for which I will generate three posts:

  • Generate html help files using jhelpdev
  • Use java to test and learn which javahelp methods are needed
  • Translate to clojure

It does not seem like Oracle is forthcoming with information on javahelp. I had to poke around and ultimately downloaded api files from other sites. I have collected them on my git site for you to retrieve.

Share

Own vs. Share

Today is the 3 year anniversary of the purchase of our 2013 Ford Explorer XLT. Purchased at two years old, 30,000 miles for $28,050, it originally sold for $38,000. The original owner suffered about $5000/year depreciation. Currently with 47,000 miles it is valued at $16,380 by KBB, bringing my depreciation costs to about $4000/year over 3 years.

In addition to depreciation I have spent $1080 on repairs and service which included replacing brakes and rotors and an expensive (500+) routine service (Service level C?). Works out to a yearly average of about $350. Total expenses:

Item $/year
Depreciation 4000
registration 30
inspection 35
insurance 1180
repairs and routine service 350
Total 5600

By far the biggest expense is depreciation. What if you own a higher quality vehicle? We also have a 2005 Lexus LS430, possibly the most reliable car on the road. Original purchase price ~$66,000, now worth ~$12,000 (49,000 miles) for an average depreciation cost of ~$4100 over 13 years. Not any better. And the Lexus is expensive to insure and repair,

How does this compare to car sharing?

I looked up the cost of a family friendly SUV on Turo. Ford Explorers were in the mix and the typical cost was $80-100 per day. Let’s say $100 per day, that would allow 56 one day rentals before breaking even with owning. Sounds compelling given that we only use the Ford for long distance travel when vacationing. Convenience is the other consideration. Sharing/renting is a hassle, having to pick up and return the vehicle, deal with paperwork etc. It is a great convenience to just walk out the door and have a vehicle at your disposal. But clearly that convenience comes at a price. There are inconveniences to owning too - repairs, service, inspection, cleaning etc. Maybe it’s a wash.

Another option is to own and share to reduce cost.

Share