Tuesday, September 23, 2014

Be encouraged; everyone starts somewhere

It's easy to become discouraged when you compare the work of successful companies to your own initial attempts.  But remember that the successful companies didn't start as successful.  Here's a sample of how some company websites have changed over time.  Take courage from their early... attempts.

All of these images come from the Internet Archive.

DigitalOcean (from 2001)

This is the oldest site that I looked at, and it shows.  Here's what the site looked like in 2001:

And here is today:

And here's all the ones in between:


Duolingo (from 2010)

 Duolingo's site has become the least friendly to being recorded by the Internet Archive.  Here's the first site featuring the owl mascot (does he have a name?) from 2010:


Here's today (but all stretchy):

Everything in between:

 GitHub (from 2008)

The early GitHub landing page featured beautiful briefcases.  Mmm... wonderful briefcases of 2008.


Watch it change over time.

 Heroku (from 2007)

Heroku has gone from light to dark to light, always maintaining the purple.  (It started out bluer).  Here's their earliest home page from 2007:


And here's the evolution:


Stripe (from 2011)

Stripe is kind of the discouraging exception to this group (at least as far as website design is concerned).  They started out with this beautiful site in 2011:



And didn't fundamentally change it until late 2013:

The latest version isn't too different:




So, keep trying.  Don't worry too much about being perfect now.  Any other great "ugly ducklings" you know of?

Tuesday, August 19, 2014

Dear Weather.com

I like how weather.com organizes their site.  Here's what a typical view looks like.  Hi, Flo.


And here I've outlined the distinct regions of the page:


I need, somehow, to train my muscle memory to type something other than "weather" when I want to see the weather.  Something like "wunder."

Sunday, July 27, 2014

Who is this?

One problem I have when looking at my family tree is that I get lost.  I end up looking at the details of a person and forget how I'm related to them.  I think there's probably a way to make visualizing and exploring family trees clear, orientable and memorable, but we're not there yet (or at least I'm not satisfied yet).

Maybe one way to fix the "how am I related to this person, again?" problem is with a graph that's really easy to display succinctly.  Here are some ideas:


All of the above drawings represent my dad's mom's dad's dad's mom.  The first three are nice because they vary in two dimensions (and seem easy to grasp at a glance).  The last two are nice because they have a uniform height.

1. Without color, the gender of the person on the left is ambiguous (unless you know it's you).
2. Could you extend this to show cousin/sibling relationships?  Maybe something like:
A: My mom's mom's sister's child.
B: My dad's brother's son (here the lines on the left without dots indicate gender)
C: My mom's mom's sibling (gender is ambiguous unless a dot-less left line was included on the leaf dots).

After drawing the MMFMMF one from above, I thought, "How about a series of interlocking Ms and Ws?"
Voila! :)

What do you think?

Wednesday, May 14, 2014

Do UTA a favor


I think I've figured out why no one takes the bus in Utah County.  Let me explain:

I love riding the bus.  It's slower, kind of inconvenient and kind of expensive (since I already have a car).

But taking a bus gives me a little thrill -- I get more exercise (3.4 miles walking to/from work) and time to think.  And I feel like I'm doing my civic duty and saving the environment.  When I dump my quarters into the slot, I feel like I'm doing my community and UTA a favor and that my fare is a generous offering to a good cause.  It feels good.

And that is exactly why no one rides the bus.  The situation is backward.

Certainly there is a list of specific problems, but

No one will ride the bus until they feel like the bus is doing them a favor (not the other way around).
That is the principle that should guide decisions at UTA: instead of making us feel like we're doing you a favor, do us a favor and make riding the bus way better than using our cars.

Monday, February 24, 2014

Gaming Family History

I had an idea last night.

Pop Quiz

In your scriptures, where on the page is John 3:16?

Right page, first column, near the top.  I know right where it is.  If you read the Bible, you likely do too (though it might be in a different spot in your scriptures).

The tangible page provides a frame of reference that jives well with my memory.  The same is not true of digital scriptures in their current state.

Driving v. Riding

The act of driving a car to a destination solidifies how to get there much more than simply riding in the car.  I'm not sure of all the reasons for this, but something about the tangible interaction makes it more memorable.

Alive Family

Before I met my (now) wife's family, I had a hard time remembering who was who when my wife would talk about them.  I couldn't remember who was married to who, what their kids were named or where they were from.  It was a big muddled puddle in my head.

But after I met them in person I didn't have trouble anymore.  (You'll be proud to know that I still know all the names of my in laws and their spouses and children).

After I'd met them, I had a reference.

Dead Family

I have a similar problem with the people in my own family that I've never met -- my ancestors who have long since passed.  But unlike my wife's family, I can't meet them in person.  I have no way to create a reference for remembering details about their lives.  To help provide some kind of reference people have made visualizations:

Pedigree chart
Fan chart
These charts make it easy to see the names and some vital data about a person's direct ancestors.  The first chart has details on 4 generations, while the second has basic information about 8 generations.  Both are excellent at emphasizing incomplete information: blanks are easy to see.  Both also have some deficiencies:
  1. Adding more generations requires exponential space.
  2. Limited space prevents showing siblings and descendants for each person.
  3. There are no photos or stories -- there's no life -- for these once-living, real people.
  4. The charts misrepresent time.  Not all my 4th great grandparents lived at the same time (but the chart leads me to think they did).  These people have an interesting solution for this.

2D v. 3D

Since a big limitation (and benefit) of paper is its 2D nature, I've tried to imagine how 3 dimensions might help.  3D printers are becoming more common.  Maybe you could print a family tree with detachable branches?  (Someone please do this!)

(from http://www.3ders.org/)
But a tangible 3D object will still become exponentially unwieldy at some point.

Interaction

Another limitation (and benefit) of paper is that it is not interactive.  I can't "click" a link on a piece of paper to get more information.  The lack of interactivity is partially what enables the remembering-scripture-location trick, but the Internet and its hyperlinks have shown how valuable interaction can be.  Also, it's the very interaction while driving that makes a trip more memorable.

I think interaction will need to be part of a good solution.  All this leads me to:

Video Games

Before you balk, consider that people have done real things with video games, such as protein folding research.

Also consider all the ten-year-olds (and 30-year-olds) in your neighborhood who play Minecraft.


Have you watched them play?  (have you played yourself?)  If you haven't, go find someone who plays and watch them for a few minutes.  One thing you'll notice is that they know their way around the virtual world.  They know right where the secret door to their mansion is and where their sheep farm is.  They know this because of landmarks that provide reference and because of the memory of creating many of the world's interesting features.

My own personal village?

What if your family history was represented as village of houses in Minecraft?  There could be a cemetery with gravestones on the edge of town near the lake (complete with birth and death records).  You could visit your grandparents house over the hill to the east.  Inside you find pictures of them on their walls and books full of their stories.

Oh, you discovered the name of your 5th great uncle?  Build him a house by the quarry.

What about Earth?

There's a small problem with this Minecraft model.  If I (Matt) build the village, I will know where everything is, but no one else would know why I decided that Great Aunt Heloise's house should be on an island in the middle of a lava pit.  I could unintentionally (or intentionally) lose valuable information.

Incidentally, this problem is prevalent with people's personal piles of family research, organized (or not) according to their system and out of reach to everyone else.

So what if, instead of a fictitious virtual world, we used a fact-based virtual world: Earth?  An earth inhabited only with my ancestors and their descendants?

From Google Earth
There could be a gravestones on the earth in the spot where a person died, a house where they lived, a crib where they were born, etc...  In each home, there could be a list of children born to a couple; you select a person and the HUD will tune the compass to point toward significant places in a person's life.

And instead of clicking links to go from place to place, you walk or swim across the earth.  It wouldn't be practical to walk at the speed of a human, but you might lose the benefit of the memorable journey if you flew like bird.  Maybe you could grow to giant size, climb over mountains and jump over oceans?  Like an MMO, people could "play" at the same time and talk and collaborate.

There are lingering questions (e.g. what if we don't know where a person was born?) but it's a start.  And such a visualization of family history data wouldn't solve every problem, but it would certainly make it easier for me to remember.



Anyway, tell me what you think of the idea.

Monday, December 16, 2013

YNO-phasic Sleep

Recently, we've seen an increased interest in polyphasic sleep. Proponents claim to be able to extract extra hours out of the day, as well as other benefits. However, not as much interest has been paid to a more ancient and natural sleep pattern: Young Needy Offspring (YNO) phasic sleep.

Tools


Intelclinic)
Unlike polyphasic sleep, which may require additional equipment to be effective, YNO-phasic sleep simply requires one or more offspring. Typically more, younger offspring produce more dramatic results.

24-hour cycle

The charts below show sample 24-hour cycles for monophasic, polyphasic and YNO-phasic sleep:

Monophasic1
8 hours of sleep followed by 16 hours of wakefulness
Polyphasic (Biphasic TED)
4 hours of sleep, 2 hours of wakefulness, 4 hours of sleep, 14 hours of wakefulness
YNO-phasic
~3 hours of sleep followed by random intervals of wakefulness and sleep-like wakefulness. At 6:15am, the offspring will awake for the day, fully rested and ready to play.

Sleep transitions

Monophasic

A preferred sleep cycle involves gentle transitions from sleep to wakefulness. The following chart shows a desirable monophasic sleep cycle.

Note the gentle transitions from wakefulness down to sleeping and back up to wakefulness.

YNO-phasic

YNO-phasic sleep cycles are characterized by abrupt changes from sleeping to wakefulness. The return transition from wakefulness to sleeping does not happen again until the next evening.

Abrupt changes to wakefulness are typically caused by offspring producing highly audible noises, foul odors and surprisingly strong slaps to the face 2. Not infrequently, changes to wakefulness also happen due to the discomfort caused by a spouse's hands lightly strangling the sleeper while moaning, "I can't take it anymore!" through clenched teeth.

Direct benefits

Critics of YNO-phasic sleep3 claim that such sleep has no benefits, but it is obvious from research that this is unfounded. YNO-phasic sleep provides several benefits:

  • Longer days

    As shown above, a person following YNO-phasic sleep will have more wakeful hours during the day, sometimes eliminating sleep altogether for several days (especially when the initial transition is made from monophasic to YNO-phasic sleep). The implications for productivity are obvious.

  • Reading time

    Many people wish they had more time to read. YNO-phasic sleep offers ample opportunity for reading. Just last night, at 3am, I was able to spend 30 minutes repeatedly reading Goodnight Moon. The kittens end up on the chair, and the mouse ends up looking out the window.

  • Improved Resistance

    Those following YNO-phasic sleep build up resistence to some forms of torture, and may earn credits toward bypassing portions of Navy SEAL training or Army Ranger Training.

Indirect benefits

In addition to direct benefits of YNO-phasic sleep, people report many indirect benefits, such as:

  • Increased chance of progeny

    It has been proven that those who have offspring have a greater chance of having descendents than those who don't.

  • Laughter

    The first time the offspring emits laughter4 is very nice. Subsequent times are also nice.

  • Amazement

    After some time of enduring following YNO-phasic sleep, adherents frequently report astonishment and surprise at what their offspring can do (e.g. walking, talking, teasing, telling jokes, performing, etc...)

Notes

This article has been peer reviewed (I had a peer review it).

1 Studies have shown that adherents to YNO-phasic sleep who are shown monophasic sleep diagrams exhibit increased levels of sarcasm and violence.

2 Because of the abrupt and frequent nature of changes to wakefulness, adherents to YNO-phasic sleep have been known to vocalize the name during the night as "Why?! Nooooo!"

3 Interestingly, the most ardent critics of YNO-phasic sleep are often the strictest adherents. The reason for this overlap has yet to be researched.

4 also, giggles, belly laughs, smiles, funny faces.

Monday, October 7, 2013

Tell, don't Ask.

tl;dr

If you rely on asking, you're asking for trouble. Instead:

  1. Tell functions what to do, don't make them ask.
  2. Tell processes what to do, don't make them ask.
  3. Keep all your environment variable queries in one place, apart from the rest of the code.

You probably think this is obvious, but it isn't

The principle of asking versus telling has many faces in programming. Some of the faces are obvious—others are more subtle. This articles moves from the more obvious to the more subtle.

So if you find yourself saying, "Well, duh!" Keep reading.

Telling v. Asking

This Python code illustrates telling:

# teller.py
import sqlite3

def connectToDatabase(filename):
return sqlite3.connect(filename)

The connectToDatabase function accepts an argument for the database connection details. Other code that calls connectionToDatabase tells the function what it wants to do.

This Python code illustrates asking:

# asker.py
import sqlite3

DATABASE_FILENAME='/tmp/database.sqlite'

def connectToDatabase():
return sqlite3.connect(DATABASE_FILENAME)

The connectToDatabase function in the above snippet is not told database connection details. Instead, the function asks for the connection details—in this case, it asks from the global scope (which is a bad place to be in).

Telling > Asking

Telling, as described above, is better than Asking for the following reasons:

  1. The code is more flexible for reuse.

    I can more easily connect to different databases using the teller.py.

  2. The code is easier to test.

    Because teller.py is more flexible for reuse, I can use the code in tests very easily.

  3. It's easier to know how to use the code and harder to use incorrectly.

    It's obvious in teller.py that I must provide a filename to connect to (because of the argument spec of the function). I can't accidentally connect to /tmp/database.sqlite.

    To use asker.py I must know that the function looks at DATABASE_FILENAME either from reading the source code or the docstring of the function (which is absent in this case). This would be much more difficult to do if connectToDatabase called other functions in other files which accessed a global variable.

Abusing Environment Variables

In asker.py the function asks for information from the global scope. The global scope is just one place to get information from. The environment is another. Take a look at this:

# asker-env.py
import sqlite3
import os

def connectToDatabase():
return sqlite3.connect(os.environ['DATABASE_FILENAME'])

Instead of asking for the database filename from the global scope, asker-env.py asks the environment of the process for the database filename. This is more reusable that asker.py but is still not as good as teller.py because:

  • it still suffers from problem #3: that you must rely on the docstring or reading the source code to understand how to use it, and
  • you can only have one connection per process.

A better approach would be to tell the process which database filename to use as in this example:

# teller-cli.py
import sqlite3
import argparse

def connectToDatabase(filename):
return sqlite3.connect(filename)

if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('filename', help="Filename of the SQLite database")
args = parser.parse_args()
connectToDatabase(args.filename)

teller-cli.py is better than asker-env.py because you can ask it (using teller-cli.py --help) what you need to tell it instead of having to read docstrings or source code. Having a --help option which fully describes configuration options and is enforced when running the process is similar to teller.py having an argument spec that is enforced by Python.

But I thought environment variables were good...

(this is a picture of an environment -- much better than the one on your computer)

If you subscribe to The Twelve-Factor App's ideas, you will store all your configuration in environment variables. Or if you use Travis-CI or Heroku you will also have used environment variables to great effect. Environment variables seem like a great way to do configuration.

Environment variables are cross-language and easy to change. They have huge benefits. Environment variables are a great way to do configuration! It would be nice to leverage the great qualities of environment variables along with the great qualities of code that is told.

You can!

Convert Asking to Telling

To write Telling code that also uses environment variables, restrict the environment variable querying to a single, documented place. Consider this:

# env-runner.py
import argparse
import os

# Define ALL the environment variables this process might use.
env_vars = [
('DATABASE_FILENAME', 'Filename of the SQLite database.'),
]

# Read the environment. This function must only be called from within this
# module if you want to prevent writing asking code.
def getArgs(environ, config):
ret = {}
for (env_name, description) in config:
try:
ret[env_name] = environ[env_name]
except KeyError:
print 'Missing env var: %s %s' % (env_name, description)
raise
return ret


def main():
from teller import connectToDatabase
args = getArgs(os.environ, env_vars)
db = connectToDatabase(args['DATABASE_FILENAME'])
# ...

The above snippet has all the benefits of telling code and the flexibility of asking code:

  1. The code is flexible for reuse.
  2. The code is easy to test.
  3. It's easy to know how to use this code and hard to use incorrectly.

Real-world examples

As proof that the concept of Telling instead of Asking is not obvious, here are some real-world examples (both good and bad):

Klein's improvement on Flask

Flask, a micro web framework for Python, loves the global scope. This is the Hello, World! from the front page:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World!"

if __name__ == "__main__":
app.run()

And this is the recommended way for accessing a database:

from flask import g

app = Flask(__name__)

@app.before_request
def before_request():
g.db = connect_db()

@app.route("/")
def hello():
db = g.db
# ...

You use a package-global named g, which is "magical" and comes with appropriate warnings:

We store our current database connection on the special g object that Flask provides for us. This object stores information for one request only and is available from within each function. Never store such things on other objects because this would not work with threaded environments. That special g object does some magic behind the scenes to ensure it does the right thing. http://flask.pocoo.org/docs/tutorial/dbcon/

Consider the improvement offered by Klein, a similar micro web framework. With Klein you can easily make apps with Non-global state:

from klein import Klein

class MyApp(object):

app = Klein()

def __init__(self, db_connection):
self.db_connection = db_connection

@app.route('/')
def hello(self, request):
db = self.db_connection
# ...

There is no magical, global g here. You can instantiate MyApp with a database connection, or even have three different instances of MyApp with three different database connections all running in the same app.

Klein lets you tell instead of ask.

Ansible

Ansible is a (really good) configuration management tool. It's mostly straightforward, but it's easy to use it in an asking way—which becomes unmaintainable.

For instance, if in one of our tasks we want to download a resource from http://dev.example.com if we're in the development environment or from https://production.example.com if we're in the production environment, Ansible easily lets us do this:

# main.yml
- name: Get the files
command: wget {{ source_server }}/thefile.tgz /tmp/thefile.tgz
creates=/tmp/thefile.tgz

The command asks for source_server. This task likely lives in a role's task file, which could be in roles/mymachine/tasks/main.yml, deep within the directory structure of my configuration. The problem is that I have no way of knowing (short of manually parsing the task file) when writing my inventory file or anything else that uses/includes main.yml, that source_server is a needed variable.

Ansible lets you ask yourself into an unmaintainable hole. To be more maintainable, Ansible should provide a mechanism for specifying the parameters needed by tasks. Perhaps something like:

# main-with-vars.yml
- variables:
- name: source_server
description: URL of the server to download source files from. For
example: http://foo.com
default: http://example.com

- name: Get the files
command: wget {{ source_server }}/thefile.tgz /tmp/thefile.tgz
creates=/tmp/thefile.tgz

Such a file would allow you to produce a list of all the configurable variables for a role/task and then be able to tell instead of ask.

AngularJS

AngularJS does a lot to help you avoid asking through dependency injection.

Twisted's Reactor

Twisted is currently working toward making the reactor not global in an effort to make testing easier and perhaps allow for new features.

Conclusion

In conclusion, read the tl;dr at the top :) Also, do you have some example of telling v. asking? Or counter-arguments? Post a comment.