Professional Documents
Culture Documents
Hacker Monthly is published by Netizens Media and not affiliated with Y Combinator in any way.
2
Contents
FEATURES
12 ($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)
[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
By Adam Cecchetti
STARTUP
16 The Designer Who Learned Django and Launched Her First Web App in 6 Weeks
By Tracy Osborn
20 What I Wish Someone Had Told Me About Startups 4 Years Ago
By Amir Khella
SPECIAL
DESIGN
PROGRAMMING
For links to the posts on Hacker News, visit hackermonthly.com/issue-11. All articles and comments are reprinted with permission of their original author.
3
FEATURES
By Tom Preston-Werner
G it is asimple,
but extremely
powerful
system. Most
people try to teach Git by demon-
strating a few dozen commands and
then yelling “tadaaaaa.” I believe this
magical incantations. Doing anything
out of the ordinary will be terrifying.
Until you understand the concepts
upon which Git is built, you’ll feel
like a stranger in a foreign land.
The following parable will take
you on a journey through the
prepare yourself t harness the full
power of Git. The concepts them-
selves are quite simple, but allow for
an amazing wealth of functionality
to spring into existence. Read this
parable all the way through, and
you should have very little trouble
method is flawed. Such a treatment creation of a Git-like system from mastering the various Git commands
may leave you with the ability to the ground up. Understanding the and wielding the awesome power
use Git to perform simple tasks, but concepts presented here will be the that Git makes available to you.
the Git commands will still feel like most valuable thing you can do to
4 FEATURES
The Parable ideal solution to your version control Branches
Imagine that you have a computer dilemma. Snapshots, like save points After a bit of time on the project,
that has nothing on it but a text in a video game, are really what you a candidate for release begins to
editor and a few file system com- care about when you need to interact emerge. Late nights at the keyboard
mands. Now imagine that you have with a VCS. What if you could take finally yield snapshot-99, the nascent
decided to write a large software snapshots of your codebase at any form of what will become Release
program on this system. Because time and resurrect that code on Version 1.0. It comes to pass that
you’re a responsible software devel- demand? Alfred reads the dawning this snapshot is packaged and
oper, you decide that you need to realization spreading across your face distributed to the eagerly awaiting
invent some sort of method for keep- and knows you’re about to leave him masses. Stoked by excellent response
ing track of versions of your software without another word to go back and to your software, you push forward,
so that you can retrieve code that implement whatever genius idea he determined to make the next version
you previously changed or deleted. just caused you to have. You do not an even bigger success.
What follows is a story about how disappoint him. Your VCS has so far been a
you might design one such version You start your project in a direc- faithful companion. Old versions of
control system (VCS) and the rea- tory named working. As you code, your code are there when you need
soning behind those design choices. you try to write one feature at a them and can be accessed with ease.
time. When you complete a self- But not long after the release, bug
Snapshots contained portion of a feature, you reports start to come in. Nobody’s
Alfred is a friend of yours that works make sure that all your files are saved perfect, you reassure yourself, and
down at the mall as a photographer and then make a copy of the entire snapshot-99 is readily retrievable,
in one of those “Special Moments” working directory, giving it the name glad to be brought back to life for
photo boutiques. All day long he snapshot-0. After you perform this the purposes of applying bug fixes.
takes photos of little kids posing copy operation, you make sure to Since the release, you’ve cre-
awkwardly in front of jungle or never again change the code files in ated 10 new snapshots. This new
ocean backdrops. During one of the new directory. After the next work must not be included in the
your frequent lunches at the pretzel chunk of work, you perform another 1.0.1 bug fix version you now need
stand, Alfred tells you a story about copy, only this time the new direc- to create. To solve this, you copy
a woman named Hazel who brings tory gets the name snapshot-1, and snapshot-99 to working so that
her daughter in for a portrait every so on. your working directory is at exactly
year on the same day. “She brings the To make it easy to remember what the point where Version 1.0 was
photos from all the past years with changes you made in each snapshot, released. A few swift lines of code
her,” Alfred tells you. “She likes to you add a special file, named and the bug is fixed in the working
remember what her daughter was message, to each snapshot directory directory.
like at each different stage, as if the that contains a summary of the work It is here that a problem becomes
snapshots really let her move back that you did and the date of comple- apparent. The VCS deals very well
and forth in time to those saved tion. By printing the contents of each with linear development, but for the
memories.” message, it becomes easy to find a first time ever, you need to create
Like some sort of formulaic plot specific change that you made in the a new snapshot that is not a direct
device, Alfred’s innocent statement past, in case you need to resurrect descendent of the preceding snap-
acts as a catalyst for you to see the some old code. shot. If you create a snapshot-110
5
(remember that you created 10 a single upstream pointer will enable of data. Additionally, it still wouldn’t
snapshots since the release), then you to easily and accurately trace the help you efficiently locate the latest
you’ll be interrupting the linear flow history of any given snapshot all the snapshot on a branch.
and will have no way of determining way back to the root. The least amount of information
the ancestry of any given snapshot. necessary to identify a branch is the
Clearly, you need something more
Branch Names location of the latest snapshot on that
Your code history is now a tree.
powerful than a linear system. branch. If you need to know the list of
Instead of having a single latest
Studies show that even short snapshots that are part of the branch
snapshot, you have two: one for each
exposures to nature can help you can easily trace the parentage.
branch. With a linear system, your
recharge the mind’s creative poten- Storing the branch names is trivial.
sequential numbering system let you
tial. You’ve been sitting behind In a file named branches, stored
easily identify the latest snapshot.
the artificially polarized light of outside of any specific snapshot, you
Now, that ability is lost.
your monitor for days on end. A simply list the name/snapshot pairs
Creating new development
walk through the woods in the that represent the tips of branches. To
branches has become so simple that
brisk autumn air will do you some switch to a named branch, you need
you’ll want to take advantage of it all
good,and, with any luck, will help only look up the snapshot for the
the time. You’ll be creating branches
you arrive at an ideal solution to corresponding name from this file.
for fixes to old releases, for experi-
your problem. Because you’re only storing the
ments that may not pan out; indeed
The great oaks that line the trail latest snapshot on each branch,
it becomes possible to create a new
have always appealed to you. They creating a new snapshot now con-
branch for every feature you begin!
seem to stand stark and proud tains an additional step. If the new
But like everything good in life,
against the perfectly blue sky. Half snapshot is being created as part of
there is a price to be paid. Each time
the ruddy leaves have departed from a branch, the branches file must be
you create a new snapshot, you must
their branches, leaving an intricate updated so that the name of the
remember that the new snapshot
pattern of branches in their wake. branch becomes associated with the
becomes the latest on its branch.
Fixating on one of the thousands of new snapshot. A small price to pay
Without this information, switching
branch tips you idly try to follow for the benefit.
to a new branch would become a
it back to the solitary trunk. This
organically produced structure
laborious process indeed. Tags
Every time you create a new After using branches for a while
allows for such great complexity,
branch you probably give it a name in you notice that they can serve two
but the rules for finding your way
your head. “This will be the Version purposes. First, they can act as mov-
back to the trunk are so simple, and
1.0 Maintenance Branch,” you might able pointers to snapshots so that
perfect for keeping track of multiple
say. Perhaps you refer to the former you can keep track of the branch
lines of development! It turns out
linear branch as the master branch. tips. Second, they can be pointed at a
that what they say about nature and
Think about this a little further, single snapshot and never move.
creativity are true.
though. From the perspective of a The first case allows you to keep
By looking at your code history as
tree, what does it mean to name a track of ongoing development, things
a tree, solving the problem of ances-
branch? Naming every snapshot that like “Release Maintenance.” The
try becomes trivial. All you need to
appears in the history of a branch second case is useful for labeling
do is include the name of the parent
would do the trick, but requires the points of interest, like “Version 1.0”
snapshot in the message file you
storage of a potentially large amount and “Version 1.0.1.”
write for each snapshot. Adding just
6 FEATURES
“Auniquely
snapshot is identified by a SHA1 that
identifies it (and its parent).”
Mixing both of these uses into a her for a week. In the meantime distinct directories named 8ba3441b-
single file feels messy. Both types are you both code up a storm. When 6b89cad23387ee875f2ae55069291f4b
pointers to snapshots, but one moves she finally gets back, you discover a and db9ecb5b5a6294a8733503ab-
and one doesn’t. For the sake of clar- critical flaw in your VCS. Because 57577db96ff2249e.
ity and elegance, you decide to create you’ve both been using the same With the updated naming scheme,
another file called tags to contain numbering system, you each have it becomes trivial for you to fetch all
pointers of the second type. directories named snapshot-114, the new snapshots from Zoe’s com-
Keeping these two inherently dif- snapshot-115, and so on, but with puter and place them next to your
ferent pointers in separate files will different contents! existing snapshots. Because every
help you from accidentally treating a To make matters worse, you snapshot specifies its parent, and
branch as a tag or vice versa. don’t even know who authored the identical messages (and therefore
changes in those new snapshots. identical snapshots) have identical
Distributed Together, you devise a plan for names no matter where they are cre-
Working on your own gets pretty dealing with these problems. First, ated, the history of the codebase can
lonely. Wouldn’t it be nice if you snapshot messages will henceforth still be drawn as a tree. Only now,
could invite a friend to work on your contain author name and email. the tree is comprised of snapshots
project with you? Well, you’re in Second, snapshots will no longer be authored by both Zoe and you.
luck. Your friend Zoe has a computer named with simple numbers. Instead, This point is important enough
setup just like yours and wants you’ll use the contents of the mes- to warrant repeating. A snapshot is
to help with the project. Because sage file to produce a hash. This hash identified by a SHA1 that uniquely
you’ve created such a great version will be guaranteed to be unique to identifies it (and its parent). These
control system, you tell her all about the snapshot since no two messages snapshots can be created and moved
it and send her a copy of all your will ever have the same date, mes- around between computers without
snapshots, branches, and tags so she sage, parent, and author. To make losing their identity or where they
can enjoy the same benefits of the sure everything goes smoothly, you belong in the history tree of a project.
code history. both agree to use the SHA1 hash What’s more, snapshots can be shared
It’s great to have Zoe on the team
algorithm that takes the contents of or kept private as you see fit. If you
but she has a habit of taking long a file and produces a 40-character have some experimental snapshots
trips to far away places without hexadecimal string. You both update that you want to keep to yourself,
internet access. As soon as she has your histories with the new tech- you can do so quite easily. Just don’t
the source code, she catches a flight nique, and instead of clashing snap- make them available to Zoe!
to Patagonia and you don’t hear from shot-114 directories, you now have
7
Offline Once you complete the merge, file. To accomplish this revision of
Zoe’s travel habits cause her to spend Zoe fetches all the snapshots that history you copy drunk to working
countless hours on airplanes and you have that she does not, which and delete the file that is new in the
boats. Most of the places she visits include your development on the series. Now working represents the
have no readily available internet math branch and your merge snap- correct modifications to the existing
access. At the end of the day, she shot. Once she does this, both of function. You create a new snapshot
spends more time offline than online. your histories match exactly! from working and write the message
It’s no surprise, then, that Zoe to be appropriate to the changes. For
raves about your VCS. All of the Rewriting History the parent you specify the SHA1 of
Like many software developers you
day to day operations that she needs the drunk^^^ snapshot, essentially
have a compulsion to keep your code
to do can be done locally. The only creating a new branch off of the
clean and very well organized. This
time she needs a network connec- same snapshot as last night. Now
carries over into a desire to keep
tion is when she’s ready to share her you can copy drunk to working and
your code history well groomed. Last
snapshots with you. roll a snapshot with the new file
night you came home after having
addition. As the parent you specify
Merges a few too many pints of Guinness
that snapshot you created just before
Before Zoe left on her trip, you at the local brewpub and started
this one.
had asked her to start working off coding, producing a handful of
As the last step, you change the
of the branch named math and to snapshots along the way. This morn-
branch name drunk to point to the
implement a function that gener- ing, a review of the code you wrote
last snapshot you just made.
ated prime numbers. Meanwhile, last night makes you cringe a little
The history of the drunk branch
you were also developing off of the bit. The code is good overall, but you
now represents a nicer version of
math branch, only you were writing a made a lot of mistakes early on that
what you did last night. The other
function to generate magic numbers. you corrected in later snapshots.
snapshots that you’ve replaced are
Now that Zoe has returned, you are Let’s say the branch on which
no longer needed so you can delete
faced with the task of merging these you did your drunken development
them or just leave them around
two separate branches of develop- is called drunk and you made three
for posterity. No branch names are
ment into a single snapshot. Since snapshots after you got home from currently pointing at them so it will
you both worked on separate tasks, the bar. If the name drunk points at be hard to find them later on, but if
the merge is simple. While construct- the latest snapshot on that branch, you don’t delete them, they’ll stick
ing the snapshot message for the then you can use a useful notation to around.
merge, you realize that this snapshot refer to the parent of that snapshot.
is special. Instead of just a single The notation drunk^ means the Staging Area
parent, this merge snapshot has two parent of the snapshot pointed to As much as you try to keep your
parents! The first parent is your latest by the branch name drunk. Similarly new modifications related to a
on the math branch and the second drunk^^ means the grandparent of single feature or logical chunk, you
parent is Zoe’s latest on her math the drunk snapshot. So the three sometimes get sidetracked and start
branch. The merge snapshot doesn’t snapshots in chronological order are hacking on something totally unre-
contain any changes beyond those drunk^^, drunk^, and drunk. lated. Only half-way into this do you
necessary to merge the two disparate You’d really like those three lousy realize that your working directory
parents into a single codebase. snapshots to be two clean snap- now contains what should really be
shots. One that changes an existing separated as two discrete snapshots.
function, and one that adds a new
8 FEATURES
To help you with this annoying Diffs Eliminating Duplication
situation, the concept of a staging With a working directory, a staging After a few more trips to Namibia,
directory is useful. This area acts area, and loads of snapshots lying Istanbul, and Galapagos, Zoe starts
as an intermediate step between around, it starts to get confusing as to complain that her hard drive is
your working directory and a final to what the specific code changes filling up with hundreds of nearly
snapshot. Each time you finish a are between these directories. A identical copies of the software. You
snapshot, you also copy that to a snapshot message only gives you too have been feeling like all the file
staging directory. Now, every time a summary of what changed, not duplication is wasteful. After a bit of
you finish an edit to a new file, create exactly what lines were changed thinking, you come up with some-
a new file, or remove a file, you can between two files. thing very clever.
decide whether that change should Using a “diffing” algorithm, you You remember that the SHA1
be part of your next snapshot. If it can implement a small program that hash produces a short string that is
belongs, you mimic the change inside shows you the differences in two unique for a given file’s contents.
staging. If it doesn’t, you can leave it codebases. As you develop and copy Starting with the very first snapshot
in working and make it part of a later things from your working directory in the project history, you start a
snapshot. From now on, snapshots to the staging area, you’ll want to conversion process. First, you create
are created directly from the staging easily see what is different between a directory named objects outside of
directory. the two, so that you can determine the code history. Next, you find the
This separation of coding and what else needs to be staged. It’s most deeply nested directory in the
preparing the stage makes it easy to also important to see how the snapshot. Additionally, you open up
specify what is and is not included staging area is different from the last a temporary file for writing. For each
in the next snapshot. You no longer snapshot, since these changes are file in this directory you perform
have to worry too much about what will become part of the next three steps.
making an accidental, unrelated snapshot you produce. 1. Calculate the SHA1 of the contents.
change in your working directory. There are many other diffs you
2. Add an entry into the temp file that
You have to be a bit careful, might want to see. The differences
contains the word “blob” (binary
though. Consider a file named between a specific snapshot and
large object), the SHA1 from the
README. You make an edit to this file its parent would show you the
first step, and the filename.
and then mimic that in staging. You “changeset” that was introduced
go on about your business, editing by that snapshot. The diff between 3. Copy the file to the objects direc-
other files. After a bit, you make two branches would be helpful tory and rename it to the SHA1
another change to README. Now you for making sure your development from step 1. Once finished with
have made two changes to that file, doesn’t wander too far away from all the files, find the SHA1 of the
but only one is in the staging area! the mainline. temp file contents and use that to
Were you to create a snapshot now, name the temp file, also placing it
your second change would be absent. in the objects directory.
The lesson is this: every new edit
If at any time the objects direc-
must be added to the staging area if
tory already contains a file with a
it is to be part of the next snapshot. given name, then you have already
stored that file’s contents and there is
no need to do so again.
9
Now, move up one directory and message file and extracting each tree The True Git
start over. Only this time, when you and blob into their corresponding The VCS you have constructed is
get to the entry for the directory that directory and file. now a reasonable facsimile of Git.
you just processed, enter the word For a single snapshot, this The main difference is that Git gives
“tree,” the SHA1 of the temp file transformation process doesn’t you very nice command line tools to
from last time, and the directory’s get you much. You’ve basically handle such things as creating new
name into the new temp file. In this just converted one file system into snapshots and switching to old ones
fashion you can build up a tree of another and created a lot of work (Git uses the term “commit” instead
directory object files that contain the in the process. The real benefits of of “snapshot”), tracing history, keep-
SHA1s and names of the files and this system arise from reuse of trees ing branch tips up-to-date, fetching
directory objects that they contain. and blobs across snapshots. Imagine changes from other people, merging
Once this has been accomplished two sequential snapshots in which and diffing branches, and hundreds
for every directory and file in the only a single file in the root direc- of other common (and not-so-
snapshot, you have a single root tory has changed. If the snapshots common) tasks.
directory object file and its cor- both contain 10 directories and 100 As you continue to learn Git,
responding SHA1. Since nothing files, the transformation process will keep this parable in mind. Git is
contains the root directory, you must create 10 trees and 100 blobs from really very simple underneath, and
record the root tree’s SHA1 some- the first snapshot, but only one new it is this simplicity that makes it so
where. An ideal place to store it is in blob and one new tree from the flexible and powerful. One last thing
the snapshot message file. This way, second snapshot! before you run off to learn all the
the uniqueness of the SHA1 of the By converting every snapshot Git commands: remember that it is
message also depends on the entire directory in the old system to object almost impossible to lose work that
contents of the snapshot, and you files in the new system, you can has been committed. Even when
can guarantee with absolute certainty drastically reduce the number of files you delete a branch, all that’s really
that two identical snapshot message that are stored on disk. Now, instead happened is that the pointer to that
SHA1s contain the same files! of storing perhaps 50 identical copies commit has been removed. All of
It’s also convenient to create an of a rarely changed file, you only the snapshots are still in the objects
object from the snapshot message in need to keep one. directory, you just need to dig up the
the same way that you do for blobs commit SHA. In these cases, look up
and trees. Since you’re maintaining
Compressing Blobs git reflog. It contains a history of
Eliminating blob and tree duplication
a list of branch and tag names that what each branch pointed to, and in
significantly reduces the total storage
point to message SHA1s, you don’t times of crisis, it will save the day. n
size of your project history, but that’s
have to worry about losing track of
not the only thing you can do to save
which snapshots are important to you. Tom Preston-Werner lives in San Francisco
space. Source code is just text. Text and is a cofounder of GitHub and the inven-
With all of this information stored
can be very efficiently compressed tor of Gravatars. He loves giving talks about
in the objects directory, you can
using something like the LZW or entrepreneurship, writing Ruby and Erlang,
safely delete the snapshot directory
DEFLATE compression algorithms. and mountain biking through the Bay Area’s
that you used as the source of this
operation. If you want to reconsti- If you compress every blob before ancient redwood forests.
computing its SHA1 and saving it to
tute the snapshot at a later date it’s Reprinted with permission of the original author.
disk, you can reduce the total storage
simply a matter of following the First appeared in hn.my/gitparable.
size of the project history by another
SHA1 of the root tree stored in the
very admirable quantity.
10 FEATURES
By Adam Cecchetti
12 FEATURES
C are to guess
it does?
what language that is and what
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
The browser executes Window.Array["sort"]() which
returns a reference to Window. And this reference is used
to call,
Window["alert"](1)
($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__
Which executes as,
[_+~$]+$_[_]+$$](document.cookie)
Window.alert(1)
That’s right. This is a JavaScript alert(), and if it lands
Let’s start to tear this apart bit by bit and see how we get
anywhere in an executable section of JavaScript/DOM it
["sort"] and ["alert"] out of the jumble above:
pops up the browser cookie.
If you want to test this out make a sample HTML file __ = "false" via [(__ = !$ + $ )]
and put the first line inside a <script> tag, open it in your __ = [(!Array + Array.ToString())]
browser, and it will pop up a “1”. __ = false + Array.ToString()
This JavaScript itself is not a new form of Cross Site __ = "false"
Scripting attack but an interesting form of obfuscation. _ = -~-~-~$
It also should be the final comment when someone says The ~ operator in JavaScript means -(N+1), so operating
they are protecting against Cross Site Scripting attacks by '-~' = '+1'. So, '-~-~-~$' = '3'.
filtering bad characters or using simple regular expressions And, '_' = '3', and thus '_/_' = '3/3' = '1'.
to filter “script” or “document.cookie”.
(__ = !$ + $ )[ _ = -~-~-~$]
I started to reverse this JavaScript because it fascinated
("false")[_]
me and I wanted to know how it worked.
("false")[3]
Firstly, I realized there are really two different lines here.
"false"[3] = "s"
First,
13
+[] calls Array.prototype.toString() for its primitive I’d like to give credit where credit is due in a few places.
value and then converts the empty string to a 0. I didn’t write or find this JavaScript. I saw it in a slide deck
from BlackHat DC 2011. This line caught my eye in the
"true"[0] = "t"
middle of the presentation. I learned a lot of strange things
$_ = "true" about JavaScript looking at these two lines, and some folks
$$ = "rt" were nice enough to point out a few errors in assumptions
I had made. n
($$ = ( $_ = !'' + $)[_/_] + $_[+$] ))
$_[_/_] + $_[+$]
"true"[_/_]
"true"
Commentary
$_[0] = "t"
By Jonathan rockway (jrockway)
$$ = "rt"
Thus, the first line becomes sort(): (On the purpose of the script...)
14 FEATURES
#badass
16 STARTUP
“Nothing kills a new idea better
than taking too much time on it.”
@kennethlove, who I’d IM at all finished, all I had to do was “skin” site was live, so I created three fake
points in the night for help with it before getting it live with the profiles and emailed 10+ designers
specific bugs. I also used @kenneth- assumption that I would be iterating with screenshots of the homepage
love’s screencast blog tutorial on the design after it launches. Also, and future profile pages, explaining
[hn.my/djangostart], since I could if I needed to abandon the project that I was building it for fun and it
relate it directly to my project. Pro- due to some insurmountable code would be free to list them. It’s a win-
files on WeddingInviteLove are like problem, the time wasted wouldn’t win scenario for the designers and
blog posts on a blog; I just changed include the time spent on design. myself, but emailing out of the blue
some names around. All code was can look shady. One designer replied
written by me while I took advantage
Launch as fast as possible that my email looked like spam, but
Nothing kills a new idea better than
of the numerous Django applica- the professional design in the screen-
taking too much time on it. There are
tions, such as django-registration. shot I linked convinced her to sign up
thousands of things more that I could anyways. My design meant the differ-
Build the web app first, then have done to improve WeddingInvi- ence between someone ignoring my
design it teLove before I launched it, but get- email versus taking it more seriously.
It was tempting to build the entire ting it out and generating feedback Once the website received its first
interface first, but I deliberately was much, much more important. 3 profiles, I got it live (onDotcloud),
ignored the design until I had I don’t mean you should launch an but continued to email designers
things 90% working. This got me incomplete project, but pare down directly, now pointing to the live
to constantly work on the code your features to the very minimum site. Overall, I emailed 67 designers
before working on the “fun stuff.” and get it live as fast as possible. directly (see screenshot), with an
Plus, it encouraged me to launch One problem I faced was convinc- approximate 50% response rate and
quickly since as soon as the code was ing designers to sign up before the slightly less sign-up rate.
17
“Ifdon’t
you’re learning a new language,
do tutorials verbatim.”
18 STARTUP
What I Wish Someone
Had Told Me About
Startups 4 Years Ago
By Amir Khella
T he year is 2007,
and I had just left
Microsoft to dive
into the startup
world. Like many first-time entrepre-
neurs, I was very excited about the
adventure. And like many first-time
great conversation topics during
the events, the meetups, and the
conferences.
I even joined a startup incubator!
It wasn’t until I decided to launch
my own startup that I realized
that nothing I’ve read, watched, or
when I made peace with the fact
that I’d just wasted a good deal of
time learning things I didn’t really
need, believing there was a magic
word someone would utter that
would launch me into action. Every
event, every conference, and every
entrepreneurs, I didn’t know where attended really prepared me for it. blog post was just another excuse
to start. And I mean it. Absolutely nothing. to postpone action one more day. I
So I attended events, meetups, I had forgotten most of what I’ve made peace with it and moved on
conferences, and mingled with the learned, and what I remembered with a beginner’s mindset, believing
local startup community in Seattle. didn’t apply much to my situation. that I will figure out what I need
When time came to move to the I’ve been snacking on other people’s along the way.
Bay Area, I found even more events, experiences and successes, and like And that made all the difference.
more meetups, and more confer- good junk food, it made me feel There is a part in each one of us
ences. The startup ecosystem was so bloated and satisfied. that wants to create, deliver, and
busy and alive, and I found a wealth Sorry to be a party pooper, but launch into an entrepreneurial adven-
of knowledge and experience being that’s reality. ture with all the uncertainty and
shared, which I consumed eagerly. In the beginning, I tried apply- risk that it brings. But there is also
There were also blogs, videos, ing the things I’ve learned to my the other part, the one that wants to
interviews, and books that I situation. That didn’t work. The feel certain and confident that we’re
ingested with passion. They made magic moment really happened making the right decision, and we’re
20 STARTUP
“The only thing that counted was to
actually sit down and do the work.”
not going to fail and hurt ourselves But unless you’re already working • I stopped going to startup events
along the way. And that’s where most on something that provides the for a couple of months, and started
of the friction comes from. framework for your learning and catching up with friends over
But these blogs, these events, and networking, you’d be wasting some coffee or drinks instead. I still go
these interviews didn’t really remove valuable time. to one or two events each month,
that friction. For a while, it just gave Here are some action steps that but I do it for fun. I no longer
me some comfort knowing there helped me overcome the “startup confuse going to entrepreneurship
were enough people doing the same friction syndrome”: events with being an entrepreneur.
things. Going into entrepreneurship • I stopped reading startup news and • I taught myself through small
was outside of my comfort zone, and blogs for a few weeks, and I real- projects. I broke down ideas into
I’d just I moved from one comfort ized I didn’t miss anything related small manageable chunks, and gave
zone into another. And you know to my products. It didn’t matter myself deadlines to finish each of
what? I was in good company! who got funded, who got acquired, them. Projects and experiments
One day I had my reality check or why Internet Explorer was are amazing teaching devices,
and saw that I was busy doing losing market share against Google because you learn as needed, and
many things, except working on my Chrome. The only “who”s I care you learn first-hand. Keynotopia
product. A couple of months later, I about are the customers, and the has helped tremendously in
can say with full confidence: the only only “what”s I focus on are their getting ideas out of my head and
thing that counted was to actually sit needs and desires, and how to best into a format that I can quickly
down and do the work. deliver value to them. see, interact with, and show to
Don’t get me wrong. I think some potential customers — that’s why
blogs and conferences are valuable. I created it in the first place!
21
“Don’t be an entrepreneur by association.
Be an entrepreneur by action and results.”
• In each step, I came up with a list take action: I was Milton from • I faced reality: nothing was going
of questions that would help me Office Space, tucked in the corner to happen until I went out of my
move to the next step. Whether it cubicle of Innotech, staring at my comfort zone and did it. Many
was getting more traffic, improv- red stapler, and waiting for my wait, but a few act.
ing the product, or increasing next paycheck. That was the magic I want to leave you with a quote
revenue without increasing traffic, kick-in-the-butt I was looking for. that changed my life: “successful
I came up with the best questions • I first got things done, then I got people aren’t necessarily smarter or
I could, then I did research, asked them done right. I learned (the luckier than others. They just try so
people, and I put the answers into hard way) that momentum mat- many things and fail until something
action immediately. Every piece tered most. If I can’t take action works out.”
of information not acted on takes right away on my idea, chances Don’t be an entrepreneur by
too much space in my biological are I never will. Whenever I get an association. Be an entrepreneur by
memory stick. idea nowadays, I do something to action and results. n
• This is my favorite: I created more pin it to my reality, and to make it
fear of not starting than the fear of tangible. I do it in a quick and ugly Amir is an entrepreneur, hacker, designer,
starting. I realized that every day I way, then figure out how to do it and artist. He enjoys simplifying complex
waited a customer was not getting better, and learn only what I need problems and launching small profitable
my solution, and a competitor for that. products. His latest venture, Keynotopia.com,
was getting closer to that solution was launched in 3 hours, with a $47.50
budget, and had its first paying customer
before I did. I even imagined my
within 10 minutes of launch.
worst nightmare if I’d failed to
Reprinted with permission of the original author.
First appeared in hn.my/action.
Commentary
By ed weissman (edw519)
22 STARTUP
SPECIAL
common wisdom
learn-
ing a new language,
24 SPECIAL
form for men and women. The best You can extend these “cheap 'n Do a little of this each day, and
way to make it part of you is just to easy” drilling techniques to harder without even realizing it, you will
drill it in some funny way like this, stuff like conditional forms, future, be able to generate phrases without
until it is as natural as saying “hello!” colors, numbers, and whatever, just effort, whether speaking or writing.
You can also use old business cards by sheer persistence and a constant, Read a little daily, and the future
(or here in Spain, train tickets, which playful spirit. Throw a few dice and with your language could not be
are credit card sized) to practice say the number they spell. Count any brighter. n
verb conjugation. Write in the blank your pocket money in Irish. Plan
side of one the conjugation of “to your weekend in Icelandic. Be cre- Ruben Berenguel is a mathematician fin-
be” (in Icelandic, að vera, in Irish bí) ative! If what you really want is to be ishing his PhD about invariant manifolds
and put it in your pocket. Whenever able to communicate, being playful is in infinite dimensional dynamical systems.
you have a few spare seconds, like a must. This is especially important if A lifelong language geek, he is currently
waiting in queue to pay at the store you’re trying to pass an exam! trying to learn Irish and Icelandic, and set-
ting sights on Norwegian and Swedish. He
or waiting for the streetlight to turn Keep in mind that perfect practice
blogs in mostlymaths.net and tweets as
green (as a pedestrian), take a look at makes perfect. You should try to
@berenguel.
it and repeat them to yourself. You pronounce words correctly and (if
will be amazed how easily this hard- necessary) have a clear idea of how Reprinted with permission of the original author.
wires constructs into your brain. they are written. And mixing differ- First appeared in hn.my/flip.
ent kind of drills will also help: keep
a stack of verbs by your door and
pick one different each morning!
Commentary
By Hamlet D’Arcy (hamletdrc2)
I moved to a German-speaking
country about a year ago. I’m not
brilliant at languages, but I’ve made
2. Read trashy literature — People, In
Touch, Celebrity Rags — these are
all written so 10-year-olds can read
box now and it is really awful and
frustrating. Not recommended at
all. Not one bit.
great progress, and most people it. Newspapers use bigger words 5. German Tuesday - Deutsche
are surprised to find out how little and don’t have pictures. Reading Dienstag - Every Tuesday was
German I spoke a year ago. Here are about celebrities is a hassle, but it German Tuesday. Anyone caught
some of my tips: helps and it’s an appropriate level. speaking English to me had to
1. Use Mnemosyne every day. It is 3. Got kids? Turn the Wii and pay a Franc into a Jar. If I spoke
computerized flash cards based on Cartoons to the foreign language. English then I paid. This makes my
the SuperMemo algorithm. Do not This makes your play time also a German a fun game in the office.
skip days. At around 2,000 words learning process. Plus we had Bier Freitag at the end
memorized (9 months) the “switch of the week. I stole this idea from
4. Do not turn your computer to a
flipped”. At 2,000 words you can an outsourcing company I worked
foreign language. This will cripple
have conversations with about with where Tues and Thur were
your productivity. I am forced to
anyone. Business is still hard, but English-only days.
work in German on a Windows
small talk is easy.
25
DESIGN
26 DESIGN
Three Boxes
This is probably the simplest layout on the list. In fact, Simple, effective, and attractive. You can probably pull
you’ll be tempted to think that it’s far too simple to ever off a full, live web page with this layout in under an hour!
fit your own needs. If this is the case, you’ll be surprised if
you really put some thought into how versatile the arrange-
ment really is.
The three-box layout features one main graphic area
followed by two smaller boxes underneath. Each of these
can be filled with a graphic, a block of text, or a mixture of
both. The main box in this layout is often a jQuery slider,
capable of showcasing as much content as you want!
The silhouetted shapes along the top are areas that can
be used for logos, company names, navigation, search bars
and any other informational and functional content typically
on a website.
3D Screenshots
As developers continue to create an endless collection of
web apps, the 3D screenshots layout seen below, or some
variant of it, is becoming more and more popular. The basic
idea is to top your page with a headline and then toss in
some stylized previews of your application. These often
come with reflections, heavy shadows, big background
graphics, or even complex adornments such as vines crawling
all over the screenshots, but the core idea is always really
simple.
27
Pixelworkshop uses this technique, not as a stock theme, As with the three boxes example, there’s one primary
but to actually showcase stock themes! Here the 3D screen- graphic heading up the page. This is followed by a simple
shots swap out in a slideshow and come up in a number of twist on the idea of a uniform grid of thumbnails. The
different arrangements. Stop by and take a look to see all space would allow for a span of four squares horizontally,
the various ways the designer presents the images. but instead we’ve combined the first two areas so that the
left half of the page differs from the right.
As we mentioned with the first layout, the blocks don’t
have to be images. For example, you can imagine this as
blocks of text on the left flanking square images on the right.
In the gorgeous example below, this layout is used for a
children’s clothing website. Notice that near the bottom
of the alignment, they’ve switched things up even further
so that the left side features an almost oddly-sized image
followed by a paragraph, neither of which perfectly line up
with the content on the right side.
Advanced Grid Again, once you’ve got your basic layout in mind, you
Many of the layouts that you’ll see in this article adhere to can make subtle changes like this while maintaining the
a pretty strict grid alignment. However, for the most part, integrity of the underlying structure. Another interesting
they don’t simply suggest a page full of uniform thumbnails. trick they used was to split up the main graphic into two
For instance, the layout below mixes up the size of the areas. It’s actually all one JPG, but it has been divided into
images to avoid redundancy. two images to show off even more content.
28 DESIGN
Featured Graphic Five Boxes
Sometimes you don’t have enough content for a page full of The five-box layout is simply an evolution of the three-box
images. So what do you do if you want to showcase one icon, layout. All of the same logic applies, it’s just been modified
photo, or perhaps even a symbol such as an ampersand? The to hold even more content. It could easily be four boxes as
layout below is a super easy solution that is quite popular well, it just depends on what you want to showcase. It also
and reads very well due to the lack of distractions. makes it look like you put a little more effort into the design!
Obviously, as you add to the layout, the secondary items
become smaller and smaller so for most uses, five boxes is
probably going to approach the limit.
29
As with the previous example, the two sites below actu-
ally look very different, even from a layout standpoint.
However, if you look again you’ll notice that they both
use a left-side vertical sidebar and the four-box layout. The
second example has simply moved the smaller boxes to the
top of the page! Yet another interesting idea that you should
keep in mind when creating a site based on these examples.
Fixed Sidebar
Thus far all the sites that we’ve seen have had a top-side
horizontal navigation. The other popular option is of course
a vertical navigation, which lends itself to creating a strong
vertical column on the left side of the page. Often this is
a fixed element that stays where it is while the rest of the
page scrolls. The reason for this is so the navigation can stay
easily accessible from any point in the site.
The rest of the content can borrow from one of the
other layouts on this list. Notice that I’ve again modified
the three-box layout, this time in a four-box arrangement.
Once you’re done reading this article, look at all the layouts
again and think about how you can mix and match the ideas
to create new layouts.
30 DESIGN
Headline & Gallery Featured Photo
Everyone loves a good gallery page. From a layout per- The layout below is extremely common, especially among
spective, what could be simpler? All you need is a solid, the photography community. The basic idea here is to have
uniform grid of images and some room for a headline with a large image displaying either your design or photogra-
an optional sub-head. The key here is to make your headline phy (anything really), accompanied by a left-side vertical
big and bold. Feel free to use this as a point of creativity navigation.
and include a script or some crazy typeface.
31
Power Grid
The power grid is the most complex layout in this article, However, it all fits tightly inside the grid that the designer
but it is one of the most effective layouts I’ve seen for pages has established. This layout is easily extendable so that no
that need to contain all kinds of various related content. matter how much you throw at it, the overall appearance
From images and music players to text and videos, you can should remain fairly logical and uncluttered as long as you
cram just about anything into this layout and it stays strong. format and arrange your content properly.
32 DESIGN
Full Screen Photo Conclusion
The final layout on the list is another that is ideally suited There were a few key points made above that I want to
for photographers, but will work on any site with a big, reiterate in closing. First, even though page layout definitely
attractive background graphic to display and a limited isn’t necessarily a “one size fits all” practice, there is a science
amount of content. to it that can be quickly and easily applied in an incredibly
vast number of circumstances.
Next, the layout ideas presented above need not result
in cookie cutter websites that all look the same, but instead
merely provide you with a basic canvas on which to build
a notably unique, finished design.
Finally, the key to successfully implementing these ideas
is to remember that they’re not set in stone. Each should be
changed to fit your specific project and can even be mixed
and matched to create new ideas! n
33
PROGRAMMING
Using Git to
Manage a Web Site
By Abhijit Menon-Sen
34 PROGRAMMING
Back on the workstation, we define a name for the remote [remote "web"]
mirror, and then mirror to it, creating a new master branch url = ssh://server.example.org/home/ams/website.git
there. url = ssh://other.example.org/home/foo/website.git
$ git remote add web ssh://server.example.org/home/ There are also other hooks. See githooks(5) [hn.my/
ams/website.git githooks] for details. For example, you could use pre-receive
$ git push web +master:refs/heads/master to accept or deny a push based on the results of an HTML
validator. Or you could do more work in the post-receive
On the server, /var/www/www.example.org should now
hook (such as send email to co-maintainers; see contrib/
contain a copy of your files, independent of any .git
hooks/post-receive-email).
metadata.
I wrote this after reading Daniel Miessler’s piece, “Using
The Update Process Git to Maintain Your Website [hn.my/gitmaintain].” His
Nothing could be simpler. In the local repository, just run: setup is straightforward: push to a bare repository on the
server and pull the changes into a second clone that is used
$ git push web
as the DocumentRoot. My implementation has the same
This will transfer any new commits to the remote reposi- effect, but there are fewer moving parts, and .git is far
tory, where the post-receive hook will immediately update from the DocumentRoot. n
the DocumentRoot for you.
(This is more convenient than defining your workstation Abhijit Menon-Sen is a freelance Unix programmer in New Delhi,
as a remote on the server, and running git pull by hand India. He switched from Perforce to Git some years ago, and enjoys
or from a cron job, and it doesn’t require your workstation helping people to understand Git better.
to be accessible by ssh.)
Reprinted with permission of the original author. First appeared in hn.my/gitman.
Notes
First, the work tree (/var/www/www.example.org above) must
be writable by the user who runs the hook (or the user needs
sudo access to run git checkout -f, or something similar).
Also, the work tree does not need to correspond exactly
to your DocumentRoot. Your repository may represent only
a subdirectory of it, or even contain it as a subdirectory.
In the work tree, you will need to set the environment
variable GIT_DIR to the path to website.git before you can
run any git commands (e.g. git status).
Setting receive.denycurrentbranch to “ignore” on the
server eliminates a warning issued by recent versions of
git when you push an update to a checked-out branch on
the server.
You can push to more than one remote repository by
adding more URLs under the [remote "web"] section in
your .git/config.
35
Combinatorial Applications
of Spacefilling Curves
By John Bartholdi
36 PROGRAMMING
Figure 2: A TSP tour of 15,112 cities in Germany. This tour was Figure 3: All the points of a triangulated irregular network can be
induced by the Sierpinski spacefilling curve in less than a second indexed continuously by finding a Hamiltonian path or circuit of
and is about 1/3 again as long as the shortest possible. the triangles and filling each with a suitably-oriented spacefilling
curve.
The spacefilling curve heuristic (SFC) has many advan- The spacefilling curve heuristic has been used in many
tages, if you are willing to accept solutions that are about applications, including:
25% longer than optimum (expected, for random point • To build a routing system for Meals-on-Wheels in Fulton
sets). These advantages include: County (Atlanta, GA), which delivers hundreds of meals
• The SFC algorithm is fast. It is essentially sorting, and so daily to those too ill or old to shop for themselves. We
it requires only O(n log n) effort to construct a tour of built this on two rolodex card files.
n points and only O(log n) effort to update the solution • To route blood delivery by the American Red Cross to
by adding or removing points. hospitals in the Atlanta metropolitan area.
• The SFC heuristic does not need explicit distances • To target a space-based laser for the Strategic Defense
between points and so there is no need to compute or Initiative (commonly known as the “Star Wars” program).
measure these, as most other heuristics must. This application was communicated to us by scientists
• The algorithm is parallelizable. In comparison, the com- from TRW Systems, an SDI contractor, who chose the
parable algorithm, Nearest Neighbor, is apparently not spacefilling curve heuristic over alternatives because it
parallelizable. was well-analyzed, parallelizable, and could run on a
computer that was boostable to orbit.
• The length of links in the SFC tour of random points
is expected to be small and of small variance, so that • To control a pen-plotter for the drawing of maps. (M.
(1/k)-th of the stops account for about (1/k)-th of the Iri and co-workers at the University of Tokyo showed
travel time. This means that an SFC tour can easily be how it could be used to reduce drawing time for large
converted to tours for k vehicles simply by partitioning road maps by routing the pen efficiently. They gave an
the SFC route into k contiguous pieces. example in which drawing time was reduced from 10
hours to 1/2 hour.)
37
The idea of routing by spacefilling curve has subsequently Loren Platzman, Bill Nulty, Paul Goldsman, and I have
been incorporated into the ARC/Info Geographical Informa- extended some of these ideas in several directions:
tion System, the CAPS Logistics Toolkit of Baan Systems, • The vertex adjancency dual of a triangulated irregular
and other commercial systems managing 2-dimensional data. network has a Hamiltonian cycle [hn.my/hamiltonian]
A summary of the ideas, minus technical details but by J. Bartholdi and P. Goldsman. This appeared in slightly
with pointers to technical literature, may be found in my revised form in Operations.Research Letters 32: 304-308
class notes, A routing system based on spacefilling curves (2004). The ideas here have been very nicely summarized
[hn.my/mow, pdf format, 22 pages]. To accompany this is and illustrated with a Java applet [hn.my/perouz] by
a table of Sierpinski indices of the points of a 100 x 100 Perouz Taslakian.
grid [hn.my/tbl, pdf format, 22 pages], with which you can
• Multiresolution indexing of triangulated irregular net-
set up your own routing system in an afternoon. Techni-
works [hn.my/tins] by J. Bartholdi and P. Goldsman,
cal details about algorithm performance, along with cita-
IEEE Transactions on Visualization and Computer Graphics
tions to related work, may be found in “Spacefilling curves
10(3):1-12 (May/June 2004)
and the planar travelling salesman problem” with L. K.
Platzman, Journal of the Association for Computing Machinery • Continuous indexing of hierarchical subdivisions of the
36(4):719-737 (1989). globe [hn.my/hglobec] by J. Bartholdi and P. Goldsman.
It is interesting to compare this lightweight heuristic This appeared in slightly revised form in Int. J. Geographi-
with a heavy-duty optimization package, such as the one cal Information Science 15(6):489-522 (2001).
developed by D. Applegate, R. Bixby, V. Chvatal, and W. • Vertex-labelling algorithms for the Hilbert spacefilling
Cook. Their TSP package is a tour-de-force of mathematical curve [hn.my/hilbert] by J. Bartholdi and P. Goldsman.
optimization technology and it has been used to solve a trav- This appeared in slightly revised form in Software —
eling salesman problem for 15,112 cities in Germany. This is Practice and Experience 31:395-408 (2000). A clever
the largest non-trivial problem for which a proven optimal adaptation for use in wavelet image compression appears
solution has been generated. Applegate et al. describe the here [hn.my/wavelet].
computational resources used:
• Robust Multidimensional Searching with Spacefilling
The computation was carried out on a network of 110 Curves by J. Bartholdi and W. Nulty, Proceedings of the
processors located at Rice University and at Princeton Uni- Sixth International Symposium on Spatial Data Handling,
versity. The total computer time used in the computation Edinburgh, Scotland, September 1994.
was 22.6 years, scaled to a Compaq EV6 Alpha proces-
• Design of efficient bin-numbering schemes for warehouses
sor running at 500 MHz. The optimal tour has length
[hn.my/binscheme] by J. Bartholdi and L. Platzman,
1,573,084 in the units used in TSPLIB; this translates to a
Material Flow 4:247-254 (1988). Shows how to create
trip of approximately 66,000 kilometers through Germany.
short order-picking routes by numbering bins according
For comparison, Paul Goldsman used the spacefilling to a spacefilling curve. n
curve heuristic to solve the same instance. Our solution
was about 34% longer (Figure 2). At a leisurely 600 km John Bartholdi is a professor in the School of Industrial and Systems
of travel per day this means the time to drive our solution Engineering at Georgia Tech.
would be about 147 days versus 110 days for the solution
of Bixby, Chvatal, and Cook. But our computation took less Reprinted with permission of the original author. First appeared in hn.my/space.
38 PROGRAMMING
DP Zoo Tour
Someone told me it’s all happening at the zoo...
By Edward Z. Yang
39
Here’s a nice boxy one for finding the longest shared The lovely word wrapping problem, a variant of which
subsequence of two strings. Each cell represents the longest lies at the heart of the Knuth TeX word wrapping algorithm,
shared subsequence of the first string up to x and the second takes advantage of some extra information to bound the
string up to y. I’ll let the reader count the cells and arrows number of cells one has to look back at. (The TeX algorithm
and verify the complexity is correct. does a global optimization, so the complexity would be O(n2)
instead.) Each cell represents the optimal word wrapping
of all the words up to that point.
40 PROGRAMMING
Commentary
By Peter scott (pjscott)
HACKER JOBS
Senior Developer
youDevise, Ltd. (https://dev.youdevise.com)
London, England
60-person agile financial software company in London committed to learning and quality (dojos, TDD, continuous
integration, exploratory testing). Under 10 revenue-affecting production bugs last year. Release every 2 weeks. Mainly
Java, also Groovy, Scala; no prior knowledge of any language needed.
To Apply: Send CV to jobs@youdevise.com.
41
Dream. Design. Print.
MagCloud, the revolutionary new self-publishing web service
by HP, is changing the way ideas, stories, and images find
their way into peoples’ hands in a printed magazine format.
Simply upload a PDF of your content, set your selling price, and
HP MagCloud takes care of the rest—processing payments,
printing magazines on demand, and shipping orders to loca-
tions around the world. All magazine formatted publications
are printed to order using HP Indigo technology, so they not
only look fantastic but there’s no waste or overruns, reducing
the impact on the environment.