jake bowkett

Sable

Map of Australia showing endangered species.

Sable is a sup­ply chain sus­tain­abil­i­ty ap­pli­ca­tion de­vel­oped by Jake and his team at the CSIRO. It al­lows busi­ness­es to add sup­ply chain and op­er­a­tional data which is then used to analyse en­vi­ron­men­tal im­pacts and op­por­tu­ni­ties.

Two nodes representing supply chain stages being connected.

Im­port­ing is pos­si­ble for large quan­ti­ties of data but edit­ing and com­pre­hen­sion of input / re­sults still re­quires an ef­fi­cient and com­pelling vi­su­al in­ter­face. Jake was re­spon­si­ble for pro­gram­ming tools that al­lowed for di­rect­ly draw­ing to and in­ter­act­ing with maps.

Map of a business' operation with a polygon being drawn on it.

You can see some of the fea­tures Jake im­ple­ment­ed on pages 3, 7, and 16 of the Sable fea­ture brochure with ad­di­tion­al con­text. Tech­nolo­gies used in­clude React, Type­Script, Go, Web­pack, and Post­greSQL.


StoryDevs

Demonstration of story devs' user interface.

Story­Devs is a web­site for de­vel­op­ers of story-fo­cused video games. Jake pro­grammed the front and back end of the site, along with the de­sign and cre­ation of all graph­ics, logo, UI, and user ex­pe­ri­ence con­sid­er­a­tions.

The ma­jor­i­ty of the site is cus­tom made: from its con­tent man­age­ment sys­tem to au­then­ti­ca­tion. The back­end tech­nolo­gies are Go, Post­greSQL, TOML, and some small bash scripts, all run­ning on Ubun­tu.

Sto­ry­De­vs' fron­tend is vanil­la HTML, CSS, and Java­Script. The biggest achieve­ment here is the WYSI­WYG ed­i­tor writ­ten from scratch in Java­Script. It is tai­lored to both desk­top and mo­bile.


Access Terminal Mu

Science fiction themed user interface.

Ac­cess Ter­mi­nal Mu is a fun desk­top-only ex­er­cise that al­lowed Jake to demon­strate his Re­ac­t.js and Type­Script abil­i­ties. It takes the form of a short epis­to­lary fic­tion with a novel UI.

Full repos­i­to­ry avail­able here.


JPEG/PNG Privacy Tool

Often times im­ages are saved with meta­da­ta such as the name of the per­son who took a photo, co­or­di­nates of the photo, etc. Jake re­alised that users up­load­ing im­ages to Story­Devs may in­ad­ver­tent­ly re­veal more than they in­tend­ed if they weren't aware of this some­times au­to­mat­ic process.

// Get a file handle. Anything
// that implements the Read and
// Seek methods will work.
f, err := os.Open("image.jpg")
if err != nil {
    log.Fatal(err)
}

// Create the map that will hold
// the replacement metadata and
// populate it with known tags.
m := make(jpegutil.Meta)
m[jpegutil.MetaArtist] = "Jake Bowkett"

// Supply ReplaceMeta with the
// file and metadata map.
r, err := jpegutil.ReplaceMeta(f, nil)
if err != nil {
    log.Fatal(err)
}

The jpegutil and pngutil pack­ages he au­thored pro­vide a sim­ple func­tion for re­mov­ing or re­plac­ing meta­da­ta. This re­quired de­tailed knowl­edge of both file for­mats as well as low-level con­cepts such as byte order.

The tools are writ­ten such that they do not copy the im­ages and waste mem­o­ry un­nec­es­sar­i­ly. In­stead, a meta struc­ture is cre­at­ed that marks the in­dices where meta­da­ta that is to be re­moved or spliced in re­sides. When it comes time to write the file these por­tions are sim­ply skipped over or added in as need­ed.


Auto Hyphenation Tool

Web browser support for nicely formatted text is quite poor. Justified text, like columns in a magazine or the pages of a novel isn't seen often online. More likely is a right margin thats jagged and uneven like a worn saw blade.Web brows­er sup­port for nice­ly for­mat­ted text is quite poor. Jus­ti­fied text, like columns in a mag­a­zine or the pages of a novel isn't seen often on­line. More like­ly is a right mar­gin thats jagged and un­even like a worn saw blade.

When it does appear one quickly understands its rarity: words are stretched far too much apart on one line only to be squished the next. Jake's reason for creating this tool is to rectify the main cause of that ugliness: the inabilty of browsers to partition words to allow for a more even distribution of 'word chunks' per line.When it does ap­pear one quick­ly un­der­stands its rar­i­ty: words are stretched far too much apart on one line only to be squished the next. Jake's rea­son for cre­at­ing this tool is to rec­ti­fy the main cause of that ug­li­ness: the in­abilty of browsers to par­ti­tion words to allow for a more even dis­tri­b­u­tion of 'word chunks' per line.

Browsers will allow words to be broken if a shy hyphen (an invisible character that tells the browser "it's okay to have a line break here") is placed within them. However with any significant body of text this is impractical to do by hand.Browsers will allow words to be bro­ken if a shy hy­phen (an in­vis­i­ble char­ac­ter that tells the brows­er "it's okay to have a line break here") is placed with­in them. How­ev­er with any sig­nif­i­cant body of text this is im­prac­ti­cal to do by hand.

This package can be fed text offline which is useful for content you know won't change regularly. It's not perfect and would need to be accompanied by more complex algorithms to get a book-like layout. Nonetheless it's a significant improvement — try toggling the hyphenation off and on with the button at the start of this section.This pack­age can be fed text of­fline which is use­ful for con­tent you know won't change reg­u­lar­ly. It's not per­fect and would need to be ac­com­pa­nied by more com­plex al­go­rithms to get a book-like lay­out. Nonethe­less it's a sig­nif­i­cant im­prove­ment — try tog­gling the hy­phen­ation off and on with the but­ton at the start of this sec­tion.

StoryDevs, Mu, and this site use the hyphenation tool.Story­Devs, Mu, and this site use the hy­phen­ation tool.


Auto Retry Tool

Since the Story­Devs data­base pol­i­cy is very strict about data con­sis­ten­cy it's pos­si­ble for op­er­a­tions to fail if they at­tempt to act con­cur­rent­ly on the same data. Jake de­vel­oped the retry pack­age to ad­dress the need to retry op­er­a­tions later if they fail under cer­tain con­di­tions (such as a busy data­base).

There were a few sub­tleties in­volved in cre­at­ing this tool. The first being the need to "back off" ex­po­nen­tial­ly — retry­ing a given op­er­a­tion after a pro­gres­sive­ly longer and longer pe­ri­od if it con­tin­ued to fail. Chances are if an op­er­a­tion has failed three times in the past 30ms it will fail again if the pro­gram blind­ly tries it again after an­oth­er 10ms. There­fore the gap must grow with each at­tempt to give time for some­thing to change that will allow tue op­er­a­tion.

The next con­cern is adding in jit­ter — a lit­tle bit of ran­dom­ness to the wait time be­tween at­tempts. If there were 10,000 re­quests being made to the data­base, each it's own op­er­a­tion and each try­ing to act on the same data, 1 would suc­ceed and 9,999 would fail. Then they'd all wait for the exact same in­ter­val and try again, mu­tu­al­ly block­ing each other. By ran­domis­ing the wait times a lit­tle many of the op­er­a­tions will slip in­be­tween each other like play­ing cards being shuf­fled.