Sandbox

This is where I do experimental testing/list useful little scripts, so don't expect anything to work perfectly :)

Facebook Messenger Analysis

Analyzes Facebook Messenger conversations from a data archive, creating visualizations and compiling various statistics. Todo: generate word cloud

TMSCA Number Sense Problem Generators

A collection of scripts to generate TMSCA Number Sense style practice problems. Can later be extended into creating a full-fledged test generator...

Skyward Grade Verification

Checks user's Skyward account (contains student grades) against given requirements and writes results to encrypted log file.

Significant Figure Calculator

Currently checks number of significant figures. In the future: perform calculations with significant figure rules - need to probably write a custom Shunting-yard algorithm to make it work correctly.

  1. Any number that isn't a zero is always a sig fig.
  2. Zeroes that are between two non-zeroes are always sig figs.
  3. Zeroes that don't have any non-zeroes before them are not sig figs (this includes leading zeroes).
  4. Zeroes that come at the end of a number are sig figs only if the number contains a decimal point.
console.assert(sigFigs('-0') === 1, '-0' + ' fails with ' + sigFigs('-0'));
console.assert(sigFigs('0.0') === 1, '0.0' + ' fails with ' + sigFigs('0.0'));
console.assert(sigFigs('-0.00') === 2, '-0.00' + ' fails with ' + sigFigs('-0.00'));
console.assert(sigFigs('0e5') === 1, '0e5' + ' fails with ' + sigFigs('0e5'));
console.assert(sigFigs('-0.0e5') === 1, '-0.0e5' + ' fails with ' + sigFigs('-0.0e5'));
console.assert(sigFigs('-0.0e-5') === 1, '-0.0e-5' + ' fails with ' + sigFigs('-0.0e-5'));
console.assert(sigFigs('1000') === 1, '-1000' + ' fails with ' + sigFigs('1000'));
console.assert(sigFigs('-1000.') === 4, '1000.' + ' fails with ' + sigFigs('-1000.'));
console.assert(sigFigs('.1000') === 4, '-.1000' + ' fails with ' + sigFigs('.1000'));
console.assert(sigFigs('-0.1000') === 4, '.1000' + ' fails with ' + sigFigs('-0.1000'));
console.assert(sigFigs('1010') === 3, '-1010' + ' fails with ' + sigFigs('1010'));
console.assert(sigFigs('-1e3') === 1, '-1e3' + ' fails with ' + sigFigs('-1e3'));
console.assert(sigFigs('1.00e3') === 3, '1.00e3' + ' fails with ' + sigFigs('1.00e3'));
console.assert(sigFigs('-1200.0034') === 8, '-1200.0034' + ' fails with ' + sigFigs('-1200.0034'));
console.assert(sigFigs('1200.0034e8') === 8, '1200.0034e8' + ' fails with ' + sigFigs('1200.0034e8'));
console.assert(sigFigs('1200.0034e-8') === 8, '1200.0034e-8' + ' fails with ' + sigFigs('1200.0034e-8'));
console.assert(sigFigs('-1234') === 4, '-1234' + ' fails with ' + sigFigs('-1234'));
console.assert(sigFigs('1234.1234') === 8, '1234.1234' + ' fails with ' + sigFigs('1234.1234'));
console.assert(sigFigs('-00001000') === 1, '-00001000' + ' fails with ' + sigFigs('-00001000'));
console.assert(sigFigs('00001000.0000') === 8, '00001000.0000' + ' fails with ' + sigFigs('00001000.0000'));
console.assert(sigFigs('-00001000.00001') === 9, '-00001000.00001' + ' fails with ' + sigFigs('-00001000.00001'));
console.assert(sigFigs('-0.1234') === 4, '.1234' + ' fails with ' + sigFigs('.1234'));
console.assert(sigFigs('-.12340000') === 8, '-.12340000' + ' fails with ' + sigFigs('.12340000'));
console.assert(sigFigs('-.00001234') === 4, '-.00001234' + ' fails with ' + sigFigs('-.00001234'));
console.assert(sigFigs('-123400001234') === 12, '123400001234' + ' fails with ' + sigFigs('123400001234'));
console.assert(sigFigs('-12340001234.1234') === 15, '-12340001234.1234' + ' fails with ' + sigFigs('-12340001234.1234'));

console.assert(parseFloat(multiply('20', '1234')) === 20000 && sigFigs(multiply('20', '1234')) === 1, '20 * 1234' + ' fails with ' + multiply('20', '1234'));
/* Copyright (C) 2013 Sushain Cherivirala
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see [http://www.gnu.org/licenses/].
 */

function sigFigs(x) {
	var sf;
	x = x.toString(); //force x to be a String
	x = x.replace(/^[\-\+]+/, '') //remove + or - sign

	if(isNaN(x)) {
		alert('Invalid input: ' + x);
		throw new Error('Invalid input');
	}
	else if(parseFloat(x) === 0) { //handle corner case of 0
		if(x.search(/^0+(e[0-9]+)?$/) === 0) //if no more precise than 0
			sf = 1;
		else {
			x = x.replace(/^0+/, '') //remove all leading zeroes
			x = x.replace(/\./, '').replace(/e[\-\+]*[0-9]+/, ''); //remove decimal point and exponential notation
			sf = x.length;
		}
	}
	else {
		x = x.replace(/^0+/, '') //remove all leading zeroes

		var sf = 0;
		var ePoint = x.toLowerCase().indexOf('e'); //find exponential form marker
		if(ePoint !== -1) {
			x = x.replace(/\./, '').replace(/e[\-\+]*[0-9]+/, ''); //remove decimal point and exponential notation
			sf = x.length;
		}
		else
		{
			var iPart, fPart; //extract integral part and mantissa
			var dPoint = x.indexOf('.');
			if(dPoint !== -1) {
				if(dPoint === (x.length - 1)) { //handle decimal point at end of number
					sf = dPoint;
				}
				if(dPoint === 0) { //handle decimal point at start of number
					x = x.replace(/\./, '').replace(/^0+/, ''); //remove decimal point and all leading zeroes
					sf = x.length;
				}
				else { //handle decimal point in middle of number
					sf = x.length - 1;
				}
			}
			else {
				x = x.replace(/0*$/, ''); //remove trailing zeroes
				sf = x.length;
			}
		}
	}
	return sf;
}

function multiply(x, y) {
	var xNum = parseFloat(x), yNum = parseFloat(y);
	return (xNum * yNum).toPrecision(Math.min(sigFigs(x), sigFigs(y)));
}

function divide(x, y) {
	var xNum = parseFloat(x), yNum = parseFloat(y);
	return (xNum / yNum).toPrecision(Math.min(sigFigs(x), sigFigs(y)));
}

File to BMP

Add a BMP file signatures to any file, creating a valid bitmap image and preserving original file contents. A visual representation of your files that is the file itself.

Google Contact Sync

Use OAuth2 as an authentication protocol for syncing Google Contacts between emails.

Virtual Bookshelf Builder

Integrate with Goodreads a service that allows the generation of HTML5 bookshelves using a drag-and-drop interface.