Skip to content

Instantly share code, notes, and snippets.

@pianosnake
pianosnake / spark-core-listener.html
Last active August 29, 2015 14:06
Setup Server Sent Events (SSE) from Spark Core. Connect potentiometer to A0 and average out the readings for sse-potentiometer.ino. Connect switch to D2 for sse-switch.ino. Clients are notified when values change.
<html>
<head>
<style>
body{
font-family: sans-serif;
}
#spark{
font-size: 90px;
font-weight: bold;
@pianosnake
pianosnake / hasOwnProperties.js
Created June 24, 2016 15:37
Recursive implementation of JavaScript hasOwnProperty().
//example:
//var nestedObj = {planet: {earth: {'@continent': 'africa'}}};
//hasOwnProperties(nestedObj, 'planet.earth.@continent') //returns true
//hasOwnProperties(nestedObj, 'planet.earth.@continent', 'africa') //returns true
//hasOwnProperties(nestedObj, 'planet.earth.unicorns') //returns false
hasOwnProperties: function(target, path, value){
if (typeof target !== 'object' || target === null) { return false; }
var parts = path.split('.');
@pianosnake
pianosnake / arduino-hammond-pedals.ino
Last active July 23, 2016 16:39
This enables polyphonic MIDI output from a Hammond M-3 12 pedal console through an Arduino Nano. The original wiring has all the switches connected in series. Keep the black wire coming to each key, but cut the exposed wires connecting the keys to each other. Lastly connect the ground from each key together to the main ground.
#include <MIDI.h>
const byte tones = 12;
const byte midiStart = 36;
const byte onDebounce = 10;
const byte offDebounce = 60;
const byte pedalPins[] = {2, 3, 4, 5, 6, 7, 8, A0, A1, 11, 12, A2};
byte note;
byte playing[tones];
@pianosnake
pianosnake / remove-query-param.js
Created July 22, 2016 21:15
Remove a query param from URL
function removeQueryParam(url, param){
var paramInMiddle = new RegExp('&' + param + '=\\w*'); // &param=blah
var paramInFront = new RegExp('\\?' + param + '=\\w*&'); // ?param=blah&
var paramSolo = new RegExp('\\?' + param + '=\\w*'); // ?param=blah
return url
.replace(paramInMiddle, '')
.replace(paramInFront, '?')
.replace(paramSolo, '');
}
@pianosnake
pianosnake / jasmine-time-reporter.js
Last active May 31, 2017 21:35
Custom reporter for Jasmine to display the slowest tests in a Node project
'use strict';
//This reporter shows the slowest specs at the end of a test run
const chalk = require('chalk');
const specs = {};
function sortedSpecs(){
return Object.keys(specs)
.map(key => specs[key]) //convert object to array
@pianosnake
pianosnake / gist:af8b04f9db7987f55832ca2394b74ae0
Created June 2, 2017 22:54
Find out who wrote the bad JavaScript!! Use `git blame` on each line output by ESLINT
eslint "**/**.js" -f unix | perl -n -l -e '/(.*\.js):(\d*):/ && print "$1 $2"' | xargs -n 2 sh -c 'git blame $0 -L$1,$1'
@pianosnake
pianosnake / throttle-promises.js
Created August 22, 2017 21:13
Promise throttling using a generator
function throttlePromises(elements, asyncForEach, groupSize){
return new Promise(function(resolve, reject){
//create a generator object that 'yields' for every group
const genObj = function* gen(){
while(elements.length > 0){
yield Promise.all(elements.splice(0, groupSize).map(asyncForEach))
.then(() => genObj.next());
}
return resolve(true);
}();
@pianosnake
pianosnake / insistent request using generators.js
Last active September 21, 2017 19:47
retry a Request repeatedly until it succeeds or the try limit is reached
function insistentRequest(request, tryLimit){
if(!tryLimit) return Promise.reject('tryLimit must be above 0');
let tries = 0;
return new Promise(function(resolve, reject){
//create a generator object that repeatedly 'yields' the same promise until it succeeds or the try limit is reached
const genObj = function* gen(){
while(1){
yield request()
.then(resolve)
@pianosnake
pianosnake / cardinalDirection.js
Last active April 18, 2018 16:00
Convert bearing (0-360 degrees) to cardinal direction (N, NW, etc...)
//divide 360 into 16 equal slices
const degrees = (new Array(16)).fill(null).map((x, i) => 360/16 * i + 11.25);
const directions = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'];
function cardinalDirection(bearing) {
for (let i = 0, l = degrees.length; i < l; i++) {
if (bearing < degrees[i]) return directions[i];
if (i == l - 1) return directions[0];
}
}
@pianosnake
pianosnake / bounding-box-area.js
Last active July 16, 2018 22:38
Computes the area of a geographic bounding box assuming spherical Earth
// adapted from http://mathforum.org/library/drmath/view/63767.html
const r = 6371.0072; //earth radius in KM
function toRadians(degrees) {
return degrees * Math.PI / 180;
};
function computeArea(bbox){
const [minLng, minLat, maxLng, maxLat] = bbox;