Skip to content

Instantly share code, notes, and snippets.

View kragen's full-sized avatar

Kragen Javier Sitaker kragen

View GitHub Profile
@kragen
kragen / README.md
Last active December 31, 2015 18:39 — forked from mbostock/.block

This page demonstrates a simple approximate algorithm for finding the closest point on any given SVG path element.

A coarse linear scan of the path provides an initial guess. Then, a binary search improves the guess to the desired level of precision (here, about 1px). To account for kinks in the path that can cause the binary scan to get stuck in a local minimum, the coarseness of the initial scan is dependent on the number of path segments. I doubt this algorithm is provably correct, but it seems to produce fairly good results even for the kinky path shown above. This technique is based on Mike Kamermans’ excellent Primer on Bézier Curves.

Knowing the closest path to a given point is useful for multi-line charts in the same way the Voronoi tessellation is useful for scatterplots: it makes it easier to select or highlight elements using the mouse. Instead of requiring the user to hover over a line

;; This pretty much works. A couple of remaining quibbles:
;;
;; - it’s possible for the region to not include a single Python
;; expression, in which case the code transformation will be
;; invalid.
;; - it should error out if called interactively when
;; transient-mark-mode is active and the mark is inactive, but it
;; doesn’t, because I don't know how to do that.
;; - it would be nice to highlight the other occurrences of the
;; expression, if any, and provide a key (maybe the same key?) to
<!-- --> <script>
// Euler problem 1, in APL semantics implemented in JS
// Count zero to n, not including n.
function iota(n) {
var rv = [];
for (var ii = 0; ii < n; ii++) rv.push(ii);
return aplify(rv);
}

Bathroom deodorants

The standard approach to bathroom deodorization — covering up the smell with a stronger smell — is a dead end. It will never work well, and it's noxious.

As a simple alternative, you could replace all the air in the bathroom with new air upon completion. The old air could be filtered to remove odors and other impurities. Clean-room-style airflow systems will run into certain difficulties with the toilet bowl, but a simple directed fan should solve the problem.

The average volume of air needed in an office environment might be 40 uses over an 8-hour day, but it's desirable that the air replacement be complete within a few seconds of the use of the bathroom. A minimal bathroom might be 1.5m x 3m x 2m, or 9 m^3, roughly 9kg of air, and three air changes might be needed to purify it entirely. That's 27 * 40 / 8 = 5 * 27 = 135 m^3 per hour of average filtration, or 38 liters per second, which I think will require a filter of a few square meters — perhaps comparable to the size of

<?php
function basic_bs_register_settings() {
register_setting('basic_bs_settings_group', 'basic_bs_settings');
}
add_action('admin_init', 'basic_bs_register_settings');
$basic_bs_options = get_option('basic_bs_settings');
function business_tools_admin_menu() {

Here's an excerpt from xev output from me typing "¤xo", which is to say, Compose x o x o. What you can see from this:

  1. The keystrokes eaten by the Compose key still appear as KeyPress and KeyRelease events. They just have XFilterEvent=True on the KeyPress events. The other keystrokes (and the KeyRelease events) have XFilterEvent=False.
  2. The ¤ character is injected as a fake KeyPress, with keycode 0 and a keysym corresponding to the actual Unicode code point. I tried ☺ later; the corresponding keysym is keysym 0x100263a, U263A.
  3. I believe that all of this compose-key hackery is being done by Xlib, not by the X server, because you have to start a new X client in order to get it to notice changes to .XCompose.
PropertyNotify event, serial 30, synthetic NO, window 0x6800001,
    atom 0x19d (_NET_WM_ICON_GEOMETRY), time 1774437600, state PropertyNewValue
@kragen
kragen / lunchvoting.coffee
Created August 22, 2012 20:43
A CoffeeScript and corrected version of https://gist.github.com/3428922.
# CoffeeScript version of voting code from
# <http://www.cap-lore.com/CapTheory/Language/lambdaSecurity.html>:
mocntr = ->
x = 0
voterMaker: ->
yet = true
-> if yet
yet = false
++x
// Original code in Scheme, from
// <http://www.cap-lore.com/CapTheory/Language/lambdaSecurity.html>:
//
// (define (mocntr) (let ((x 0)) (cons (lambda () (let ((yet #t))
// (lambda () (if yet (begin (set! yet #f) (set! x (+ 1 x)) x)))))
// (lambda () x))))
// (define restaurants (list "Mandarin" "Casa Lupe" "Coffee Shop"))
// (define (noontime) (let ((bb
// (map (lambda(r) (cons r (mocntr))) restaurants)))
// (for-each (lambda (e) ((cdr e) (cons "Lunchtime!" (map
# Simplified CoffeeScript version of voting code from
# <http://www.cap-lore.com/CapTheory/Language/lambdaSecurity.html>:
# simplified from <https://gist.github.com/3429195>.
counter = ->
x = 0
voterMaker: ->
yet = true
-> if yet
yet = false
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""A DSL for making paths of interesting shapes.
Nick Johnson and Kragen Javier Sitaker
<https://gist.github.com/2555227>
"""
import math