Calculating gear sizes
The math is lightweight and the features just rich enough to make it an interesting problem for client side development - both in terms of features and usability. Sheldon has done us a great service by providing a nicely documented thought process and nomenclature not to mention the math for calculating gear sizes. Feature wise we often see:
- gear size tables in inches or meters
- ratios in one form or another
- distance travelled
- speed at x crank revolutions for a given gear size
and so on.
Version 1: MVP via HTML Template and CoffeeScript
UI-Features / Requirements
- Provide UI that enables side by side comparison of two chainring and cassette alternatives - to compare apples to apples use a standard gear ratio..
- Provide gear ratio in the traditional club rider vernacular, Gear Inches, see quote below.
- Provide summary information about the inputs that made the gear size in inches - mouse hover tips
- Render gear-size from these inputs
- Chainring teeth
- Sprocket teeth
- Bare rim diameter
- Tyre size
Gear Inches specification by Sheldon:
[Gear inches is] the diameter of the drive wheel, times the size of the front sprocket divided by the size of the rear sprocket
- Provide an alternative comparison via other algorithms e.g.
- Gear size in meters
- Gear ratio that derives from crank length - as Sheldon suggested
- Speed at 100 revs for a given gear
- Provide means to render entire gear table as opposed to chainring-cassette comparison mode
- Usability: rendering on every drop down change sucks
- Improve hover styling
- Computation code and rendering code separated
- Gear-size computation authored in my gear-size-calculator Node module.
- Computation code and unit-tests in CoffeeScript
- Rendering code not implemented via TDD
- Rendering and Computation code not versioned so could cause cache version issues as the scripts are not time-stamped e.g. forcing updates to end-user
- Computation code has a promiscuous API overly exposing private API members to enable unit-testing those private methods.
Instead of this:
it should just expose one method to the web app:
This could be resolved by using the sandbox feature of nodeunit for testing the private api parts.
- No front-end timings for comparison and evaluating regression
- Node Computation module not published
- Node Computation module does not validate inputs to the public Api
- Math extensions wrapped into the Node module
This is where it gets hacky…did I say it’s a WiP aka MVP?
- Manual intervention required to deploy computation script
- Rendering library is untested
- Rending library is not easy to import to another project, versioned & etc
- Rendering library code suffers from repetition and general lack of readability
- Default values for render template are hard wired instead of from configuration
- Use Browserify to web-enable the node module(s) used
- Provide Gulp automation for the build process
- Make the render script a second private node module to enable:
- default configuration for range values for the end user to pick from
- make it easier to deploy into different targets
- testability of render via node dom
- better eventing using Node’s Event Emitter
What I learned
How to wire in a client side application to a Jekyll site:
- Using _includes as a component wrapper.
- Using Jekyll front matter and Liquid templates to load page specific assets
- Using array comprehensions in CoffeeScript
- Using node-unit
Version 1 demo
|Rim Diameter||Tyre Size|