Monday, November 21, 2016

De-Annoying Amazon Smile with a UserScript

There are things on many web sites that are annoying, but if I just have to use them once in a while, I shrug and keep going.  However, when there is something annoying on a web site like Amazon.com, that I have to put up with all the time, I sometimes hit my frustration limit and try to fix it.  A while back, I got tired of the search category on Amazon.com switching to the category of the currently viewed product.  That's pretty much NEVER what I want.  More recently, I had my fill of the Amazon Smile popup just below the search box grabbing the focus to tell me what I already know... I'm supporting a charity with BLA BLA BLA.... shut up already.

The easiest way to de-annoy a web site, if you know a little html and Javascript is to install a user-script browser plugin (like GreaseMonkey, TamperMonkey, or Scriptish), and add a user-script that will fix the web site's issues after it loads.  That's how I managed to fix Amazon.com (and smile.amazon.com).

It was easy to fix the first issue by just setting the selection on the search category drop-down box back to index zero ("All") every time any amazon.com page loads.  In the user-script, that just looks like this:

document.getElementById("searchDropdownBox").selectedIndex=0;

The second issue was a little trickier, but still not too tough.   The issue may be unique to me and my habits, but I have to believe there are others who are aggravated by this usability failure.  If you click in the search box, and then get the mouse cursor out of the way by moving it down a bit, you end up triggering a hover-pop-up for your Amazon Smile charity.  That would be fine, except it takes focus away from the search text box and forces you to move the mouse cursor somewhere else, letting the pop-up go away, before you can type anything.  There were a few things I would have bought at Amazon.com but that stupid pop-up just ticked me off and I decided they could do without my business those times.

So, to fix the moronic hover-pop-up, I found the page elements that trigger the pop-up, and switched their display style to hidden (which means the hover isn't triggered when the mouse cursor is over them).  The following code goes in a user-script:

    document.getElementById("nav-pldn-msg-wrapper").style.visibility = "hidden";
    document.getElementById("nav-supra").style.visibility = "hidden";
    document.getElementById("nav-pldn-org-name").style.visibility = "hidden";
    document.getElementById("pldn-supporting-arrow").style.visibility = "hidden";
    document.getElementById("pldn-supporting-arrow").style.display = "none";


This is just an example of how to de-annoy a web site you might use frequently enough to spend a little time suppressing those annoying "features."  User-scripts are good for all kinds of things like this.  Leave a comment if this was helpful or if you've figured out how to de-annoy a frustrating web site you use.

The whole user script is shown below:

// ==UserScript==
// @id           FixAmazonAnnoyances
// @name         FixAmazonAnnoyances
// @namespace    http://deannoy.amazon.com/fixamazonannoyances
// @version      1.0
// @description  Fix some of Amazon's annoying page automation
// @author       Whirly
// @include      https://*.amazon.com/*
// @run-at       document-end
// ==/UserScript==
(function() {
    'use strict';
    // Pop the search back to "all" automatically to prevent the next search
    // from being constrained to the department of whatever item might be displayed.
    document.getElementById("searchDropdownBox").selectedIndex=0;
   
    // hide the amazon smile hover-popup stuff that takes the focus away from
    // the search box if the mouse is moved a bit after clicking in the search box
    document.getElementById("nav-pldn-msg-wrapper").style.visibility = "hidden";
    document.getElementById("nav-supra").style.visibility = "hidden";
    document.getElementById("nav-pldn-org-name").style.visibility = "hidden";
    document.getElementById("pldn-supporting-arrow").style.visibility = "hidden";
    document.getElementById("pldn-supporting-arrow").style.display = "none";
})();




Saturday, October 22, 2016

Fright Props Park Motor Mod

Fright Props Motor

There's a company called FrightProps that sells a really awesome geared electric motor for a reasonable price.  They primarily sell them for the purpose of haunted-house prop animation, like spinning the head of a robot-zombie or vampire around while its devil-red eyes flash and shrieking noises emanate from a little speaker it its left arm... but I digress.

Re-purposed

I had a slightly different purpose in mind for which these motors are also well suited.  I'm putting them in Jigging machines for ice fishing.

PicoVolt

I'll have another blog post with WAY more details on that.  Anyway, FrightProps also sells a nifty little controller box (called a PicoVolt) that works very well for running the motor through a short sequence of recorded motions (e.g. forward a bit, backwards a bit, around and around for a little while), but the motions are not very precise and getting the recording done is not unlike putting a greeting on voicemail... "Hi, you've reached..." !@#$%.  "Hello, I can't take you call..." grrrr... no.  "Hi, Leave me a message and I'll try to..." (sheesh, my voice sounds so goofy)... whatever... "Leave a message.  BEEP".  Back to the re-purposing, the PicoVolt has its place, but it isn't perfect for what I'm doing.

Park Switch

Inside the gear box of the motor is a "park switch."  The motor resembles a windshield wiper motor and I suspect the "park switch" is the same kind of feature that allows wiper blades on some cars to find the spot where they're tucked out of the way, and stop there.

Proprietary Pairing

In order for the FrightProps park motor to work with their PicoVolt controller the way they've designed it, the motor comes with the red wire (one of the motor coil voltage wires) also connected to the "park switch".  When the motor is in the "park" position or as it is passing through that position, since there is voltage applied to the motor coil, that voltage also flows to the "yellow" (common) wire of the park switch.  It will be positive or negative, depending upon which direction the motor is turning.  That appears to be part of how the PicoVolt senses that the motor has reached the "park" position.  In fact they may have designed it so that the motor has to be running forward (red-wire-positive) for the park function to work at all.

Arduino Uses 5V TTL Logic Voltage

My slightly different purpose for the FrightProps motor also has a slightly different requirement for the park-position switch.  I'm operating the motor using an Arduino micro-controller and a "high-amp/high-voltage motor shield" so I can precisely program (using Arduino/c++ code) the sequence of motions.  I want to be able to sense when the motor is in its "park" position, but I didn't want to try figuring out whether the motor was currently running forward or reverse, and I didn't want to add extra electronics components (resistors, zener diodes, capacitors, etc) to convert and isolate the motor voltage (sometimes as much as 13V) to a clean "logic level" +5V signal.

Motor Mod Time

The simple solution was to modify the FrightProps motor a little from the way it is wired when they ship it.  By disconnecting the red wire from the "park switch" and adding a separate wire (with white insulation in my case), I could keep the entire park switch circuit separate from the motor voltage and wire it directly to Arduino input pins.  The diagram here shows approximately how the switch works and includes notes about where I made the changes.


Also, here are a few photos showing the modifications on the actual motor.

Remove the shrink wrap where the red wire is soldered to the park position switch.
Heat the solder and disconnect the red wire from the park switch, leaving it connected only to the motor coil.
Solder a new wire to the park switch and cover both the bare spot in the red wire, and the solder joint on the new wire, with shrink wrap.

Monday, September 19, 2016

PVC Console for Hobie PA-17T

The Hobie PA-17T has a huge head start for rigging with the "h-rails" down both sides, floor hatches, vantage seats, mesh rubber side pockets, and rod holder holes on either end.  For the first few trips, I thought that would about cover it, but I put a cooler in the middle and got really annoyed having to remove and replace bungee cords dozens of times a day so it wouldn't slide around and get in the way.  As with most kayaks I've ever had, the easiest and least expensive remedy for shortcomings in the stock rigging always seems to lead back to PVC pipes and elbows.  The Hobie PA-17T's lack of a good place to put a cooler was no exception.  So, in case someone else is looking for inspiration, here's what I did...

The rail around the cooler and the posts that go into the scupper holes are made from 3/4" PVC.


The rod holders on either side are made with 1-1/4" PVC crosses, pipe and caps.  The bungee cords are retained by threading them across a short cross-cut piece of 1-1/4" PVC.


The 3/4" PVC is adapted to the 1-1/4" cross with a step-down bushing.


The 3/4" pipes extend a few inches into the scupper holes which combines with a bungee on either side to keep the whole thing very secure.

Parts List

  • (4) 1.25" PVC Cross
  • (2) 0.75" PVC Cross
  • (4) 1.25" PVC External Cap
  • (4) 0.75" PVC 90deg Elbow
  • (4) 1.25" to 0.75" Bushing
  • (1) 0.75" 10' Sched 40 PVC Pipe
  • (1) 1.25" 10' Sched 40 PVC Pipe
  • (1 Small Can) General Purpose PVC Cement 

SketchUp PVC Drawings






Tuesday, March 8, 2016

Premature Optimization

Context

This topic has bugged me for most of my career in software development.  In nearly every project I've been involved with, there's always someone on the team who wants to solve all the anticipated performance "problems" well before any such problem has been encountered.  The trip off into the weeds of analysis-paralysis usually starts with some wild, worst-case-scenario supposition that often derives from a fundamental misunderstanding of real-world system demands (actual load) or a fundamentally flawed mental calculation regarding real-world resource capacity (e.g. processing or network speed).

Manifesto

Bottom line: DON'T PREMATURELY OPTIMIZE!!!

In nearly every circumstance I can remember, it would have been WAY easier to just write the single-threaded, memory-hogging, un-cached, poorly organized, klunker of a piece of software, and THEN profile it to see where it really suffered in a real-world load scenario.  Attempting to anticipate which optimizable areas will present the real problems is a sure-fire way to waste 80% of the available development time figuring out how to solve 20% of the contribution to poor performance.  That old 80/20 rule can be turned in your favor so easily by waiting until you're 80% done with the functional bits and then spend 20% as much effort fixing the things that contribute 80% of the "slow."

Demonstration

If you didn't get the point by now, I'd be wasting my time to try to convince you.  Just try suppressing your urge to make that next program/module you write run in 0.1ms until you have enough information to understand that the rest of the system won't notice any difference until your stuff takes more than 15 seconds to complete.

AWS Lambda Java Deployment Maven Build

Summary


This post describes a "recipe" for building a deployment package for an Amazon AWS Lambda function authored in Java.  The current AWS Lambda documentation (links below in the "references" section) suggest using the "shade" plugin with Maven, which produces an "uber-jar", or using Gradle to produce a zip file containing classes and a "lib" subdirectory with dependency jars.  Neither of those approaches is ideal.  "Uber-jars" cause problems with any code that uses reflection, and using Gradle seems to assume you've completely set Maven aside as a build tool.  This "recipe" assumes you want to use Maven, but you'd still like the zip-containing-jars style deployment package instead of an "uber-jar."

Use Maven's Assembly Plugin


This should be at least a good 90%+ head start on configuring Maven to produce an AWS Lambda deployment package with the dependency libraries still in their original jars and your AWS Lambda function code included in package-directory / class-file format.

Create Assmembly Descriptor

Within the Maven project directory structure, create a file named:

        src/assembly/lambda_deployment_package_assembly.xml

...containing the following content...

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>lambda_deployment_package_assembly</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/classes</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>**/*.class</include>
            </includes>
        </fileSet>
        <fileSet>
            <outputDirectory>extras</outputDirectory>
            <includes>
                <include>readme.md</include>
            </includes>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>lib</outputDirectory>
            <useProjectArtifact>false</useProjectArtifact>
        </dependencySet>
    </dependencySets>
</assembly>

Add Plugin Configuration to pom.xml

Note: If this is a multi-module project, with each module producing its own AWS Lambda function deployment package (.zip), then this goes in the sub-module's pom.xml, not the parent.  If you have a lot of AWS Lambda function sub-modules, it might be worth trying to use pluginManagement in the parent pom, but that's outside the scope of this post.

pom.xml (excerpt)

<project>
    <dependencies>
    ...
    </dependencies>
    ...
    <plugins>
        <plugin>
            <!--  Note: Normally, this plugin would be run using
            "mvn compile assembly:single" but the execution
            clause below binds it to the normal 'package' lifecycle phase
            -->
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptors>
                    <descriptor>src/assembly/lambda_deployment_package_assembly.xml</descriptor>
                </descriptors>
            </configuration>
            <executions>
                <execution>
                    <id>lambda_deployment_package_execution</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    ...
</project>

References


  • http://docs.aws.amazon.com/lambda/latest/dg/create-deployment-pkg-zip-java.html
  • http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html

Wednesday, February 10, 2016

MicroServices are not MuServices

Someone where I work recently decided to edit a script that had variables named microservice_this or microservice_that to uservice_this and uservice_that.

What is a uservice?  alcohol? cigarettes? weed?

I’m curious why he decided to change the variables in the script and make them inconsistent with pretty much ALL other references to microservices in pretty much EVERY other document or code (at least around here).

I’m not a fan of using the science/electronics abbreviation of "micro" applied to the semantics of the "microservice" software architecture strategy.  IMO, it just makes things more confusing.  Also, it isn’t actually an English alphabet “u” that is used to represent "micro" in those other disciplines, it’s a greek lower case Mu – “μ”.  I’d be really surprised if that special character didn’t render the script un-runnable, so, after this guy made his changes, the script is either wrong, or broken.

One of the reasons it bothers me is that there is a distinction between the prefix micro, which has come to have a legitimate alternative meaning of “very small”, and the more technical meaning of the prefix which means millionth.  "Microservices" really aren’t services that are one millionth the size of bigger services.  They’re just smaller, so the secondary meaning of the prefix “micro" makes some sense, but the singular meaning of Mu (μ) DOES NOT!!!

I guess it will all be moot soon when things like AWS Lambda take over the world and we all switch to nano-services. Will some people insist on calling them nservices???


Just for grins, compare these results:

And then, search this page for “uservice”.


Ok… rant over.  Decided to vent here instead of picking a fight with the genius who decided to change the script variable names.

Also, BTW, this isn't an invitation to argue with me.  This is just my opinion on the matter.  I don't really care whether you agree, and I won't publish any boneheaded, "you're wrong because" comments.

One of my new favorite jokes...

Job Interview
Interviewer: What would you say is your biggest weakness?
Job Applicant: Honesty.
Interviewer: I don't think honesty is really a weakness.
Job Applicant: I don't care what the f*&^ you think!

Sunday, January 10, 2016

Making a Small Lure Cover Using a Toothbrush Cover

Not sure why I didn't think of this sooner but it's a fairly simple task to modify one of those cheap toothbrush covers that snaps over just the head of a toothbrush, and turn it into a handy lure cover.  This will be mostly pictures since most people reading already got the concept.  The only modification that seems to be necessary is to glue a little piece of foam into the toothbrush cover to close up the toothbrush-handle-sized" hole to keep the cover from easily falling off the rod tip / lure. 

Total cost to make two of these is about $1.

Materials:
  • Toothbrush Cover
  • 3/16" Craft Foam Sheet

Tools:
  • Scissors
  • Hot Glue Gun

1) Get the toothbrush covers at Wal-Mart, Dollar Tree, or where-ever such things are sold.

2) Heat up a dual-temp glue gun to the "low" heat setting so you don't melt the foam or plastic.


3) For each toothbrush cover, cut a piece of craft foam to a size that will cover the toothbrush handle opening when attached to the inside of the toothbrush cover lid.


4) Hot glue the foam piece into the lid.


5) Insert both the small lure and the rod tip into the modified toothbrush cover.