Monday, October 23, 2017

sublime - autosave when you change apps

The new hotness standard brought by IntelliJ seems to be autosave, cmd-s is old and busted.  For a while I thought this was black magic but I think sometimes it's as simple as a "save when you lose focus".

I still use sublime for other work, and among some other tips this page tells me I can just add
"save_on_focus_lost": true
to my preferences>settings (currently set to
{
"auto_match_enabled": false,
"color_scheme": "Packages/Color Scheme - Default/Solarized (Light).tmTheme",
"font_size": 15,
"auto_close_tags": false,
"save_on_focus_lost": true
}
for what it's worth.

From a UX standpoint, autosave is kind of an paradigm shift, but in an age of really good cmd-z undo, it's not as problematic as my old self would have thought.

Friday, October 20, 2017

a little light reading

Articles on stuff my company is looking into...


Oh and https://www.fullstackreact.com/30-days-of-react/ and https://learnredux.com/ oh and then https://cssgrid.io/

local music fingerprinting in 1/2 a GB?

Huh - Google's Pixel 2 does Shazam/Soundhound style audio fingerprinting locally? And that db for that is only half a GB? I never would have suspected the numbers were like that (even knowing factoids how like a simple formula "does the subsequent note in series go up or down, note by note makes a unique key for melodies in a surprisingly small number of notes")

Thursday, October 19, 2017

more quick and dirty php: finding matching tags

Just here for my future reference - did another "PHP as command line scripting tool to recursively go over directories", this one to get a rough idea of, in our Freemarket Template codebase, how many
<#macro fooBar blah blah>
macro definitions were orphans, and never called with a
<@foobar blah blah >
tag. (Freemarker is hella flexible in terms of how you build a macro name to call, though, so this is far from bullet proof...)

<?
$directory = "/Users/kisrael/cargurus/cg-main/cargurus-site-static/templates/";

$macroDefLocations = array();
$macroCallLocations = array();

#checkfile("inventorylisting/ocrFilterMacros.ftl");

$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
while($it->valid()) {
    $pathname = $it->getSubPathName();
    if (endsWith($pathname, ".ftl")) {
    checkfile($pathname);
    }
    $it->next();
}

function checkfile($pathname){
global $macroDefLocations, $macroCallLocations;
    lookForMatches($pathname,$macroDefLocations,"/\<\#macro.*?\>/s","/\<\#macro\s(\w*)\W/s");
    lookForMatches($pathname,$macroCallLocations,"/\<\@.*?\>/s","/\<\@(\w*)\W/s");
}

foreach($macroDefLocations as $definedMacro => $usages){
if(! array_key_exists($definedMacro, $macroCallLocations)){
$file = array_keys($macroDefLocations[$definedMacro])[0];
print "[".$definedMacro."]\t".$file."\n";
$orphanedMacrosInFile[$file]++;
$orphan++;
} else {
$calledMacrosInFile[$file]++;
$wellcalled++;
}
}
#print "$orphan orphans $wellcalled called\n";
#print "CALLED:\n";
#print_r($calledMacrosInFile);
#print "ORPHANED:\n";
#print_r($orphanedMacrosInFile);

foreach($orphanedMacrosInFile as $file => $countOrphans){
$countCalled = 0;
if(array_key_exists($file, $calledMacrosInFile)){
$countCalled = $calledMacrosInFile[$file];


$percentOrphans[$file] = (100.0 * ($countOrphans) / ($countCalled +$countOrphans ));
$orphanDesc[$file] = "$countOrphans orphans / ".($countCalled +$countOrphans)." defs";

}
arsort($percentOrphans);

$keys = array_keys($percentOrphans);


foreach($keys as $file){
print round($percentOrphans[$file],3)."\t".$orphanDesc[$file]."\t".$file."\n";;
}


function lookForMatches($pathname,&$results,$regexFind,$regexExtract){
global $directory;
$content = file_get_contents($directory.$pathname);
preg_match_all($regexFind,$content,$matches);
foreach ($matches[0] as $key => $tag){
preg_match($regexExtract,$tag,$finds);
$macro = $finds[1];
#print "vvv\n$tag\n^^^\n";
if (! array_key_exists($macro,$results)){
$results[$macro] = array();

if (! array_key_exists($pathname,$results[$macro])){
$results[$macro][$pathname] = 0;
}
$results[$macro][$pathname]++;
}
}

function endsWith($haystack, $needle) {
    return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false);
}
?>

Tuesday, October 10, 2017

The one true Javascript exception handler:
try {
  something
} catch(e) {
  window.location.href = "http://stackoverflow.com/search?q=[js] +" e.message;
}
(via)

Monday, October 2, 2017

what perl taught me (in the early-mid-90s)

Perl was the first language I learned after the "C" that was taught in my Intro to Computer Science class (so probably my fourth language overall, after BASIC and Logo growing up.)

Compared to C of that era, it was like manna from heaven. Here's what it gave me that C lacked:

  • Maps, or as Perl called them, Associative Arrays. Key/Value pairs are such an ENORMOUSLY powerful concept, and this was my first exposure to them.
  • Regular Expressions - being able to match strings is also very powerful and fundamental
  • Strings as first class entities - compared to C saying "you can make a string as an array of strings ending with a \0 character", this was great. In this way too, C was oddly inferior to the BASICs I grew up with.
  • Duck-Typing. I'm not as sold on the importance of duck-typing as I used to be, but I liked it. I especially like Perl's habit of quiet context-based assumptions... assuming false-y or null things are zero if you're trying to do math, compared to Javascripts tendency to panic with "NaN" is more robust and less error-prone than some purists probably realize.
  • Not having to micromanage memory. Man, was C annoying in this regard; having to carefully de-allocate every hunk of memory explicitly was a real pain. (In retrospect, Perl may have gotten away with this more because of its "script" feeling... in general things that do some work than quit can be more forgiving than long-running processes...
Such a breath of fresh air... and then when I learned I could rent cheap webspace that would let me run Perl and that CGI mapped fairly wonderfully to that Key/Value concept... the sky was the limit. I could do nearly anything the web could do.

I was shocked a decade later when a coworker pointed out that most of that stuff I loved about Perl was actually from its history as a glue language, wrapping C(!)-based Unix system calls.  That stunned me... I knew the wonky syntax came from Perl's history as a bit of a mongrel, but compared to other stuff (especially early PHP) it always felt very professional, you hardly ever saw the skeleton, and there wasn't much in it that was obviously for the convenience of the language implementer rather than the programmer. And all these new tricks felt like the very opposite of C...

These days, my Perl is decidedly rusty. PHP eventually matured and having all the stuff for webtasks baked into the language rather than the ugliness of CPAN module compiling was great. Also I'm worried I should have been learning Python, rather than blowing it off because the given task was easier in more familiar Perl. And I never did get my head wrapped around Perl's flavor of Object Oriented thinking. Still, I'll always be grateful to it for opening my eyes to new ways of thinking about programming, which is what the worthy languages and frameworks do.

2026 UPDATE:
I was thinking about this further. I realize 3 of the 5 things I learned from Perl, was actually a return to what I had in 8-bit BASIC. (Everything but the regex and the maps).

And there's a sixth point of Perl-from-C that BASIC also shared (along with, say, Lisp) - the power of quick code-run loops without a compile step. Slow 8-bit computers were made slower by BASIC's interpretation, but it was probably worth it. And that background of mine led me to a very iterative style of coding, kinda like the opposite of Waterfall. I code step by step, I have high confidence each bit works.



quick jquery check for repeated / duplicate ids in DOM

Coworker suggested this console-code proof that ids were being duplicated:
  $('[id]').each(function(){
var ids = $('[id="'+this.id+'"]');
if(ids.length>1 && ids[0]==this)
console.warn('Multiple IDs #'+this.id);
});

If I was less lazy I'd cook up the non-jQuery version.