Jeff Kaufman's Writing
https://www.jefftk.com/p
Jeff Kaufman's Writing from post 1598 backen-us/p/slack-tool-predictSlack tool: predict
https://www.jefftk.com/p/slack-tool-predict
lwfeedpredicttech17 Mar 2017 08:00:00 EST<p><span>
I wrote a Slack tool that implements a </span>
<a href="http://www.rationality.org/">CFAR</a>-style prediction market:
<p>
</p>
<pre>
/predict create rain-2017-03-18 "it will rain tomorrow" tomorrow 40%
/predict rain-2017-03-18 70%
/predict rain-2017-03-18 80%
/predict resolve rain-2017-03-18 true
</pre>
<p>
A contract is some proposition that isn't known now, but will be known
later, at which point it can be resolved true or false. When you create
a contract, you give some details about how you'll resolve it, a time
when it will close and stop taking new predictions, and some "house
odds". These odds try and start the predicting in a reasonable place,
so no one gets a big windfall from noticing things first.
</p>
<p>
When the market closes, people earn points in proportion to how much
they improved the group consensus. [1] This isn't a traditional
prediction market in the sense of having buyers and sellers. The
downside is that it offers windfall profits to the first person to react
to news, but the upside is that anyone can make a prediction at any time
without needing to have a counterparty.
</p>
<p>
The code is <a href="https://github.com/waveremit/predictions">on
github</a>. I've been using heroku to host it, but it can run
anywhere. If you're having trouble adding it to slack let me know.
</p>
<p>
<br>
[1] Specifically, you get (or lose) points in proportion to the log of the
ratio of your prediction to the one before. So if you predict 60%, I
predict 70%, and it's resolved true, then I earn <tt>log(70/60)</tt>
points. If it's resolved false we recast these predictions as if they
were predicting the opposite, so 30% and 40%, and I earn (lose)
<tt>log(30/40)</tt> points.
</p>
<p><i>Comment via: <a href="https://plus.google.com/103013777355236494008/posts/7GzNk3PKfxL">google plus</a>, <a href="https://www.facebook.com/jefftk/posts/855206911372">facebook</a></i></p>
/p/diving-into-a-floating-point-bugDiving into a floating point bug
https://www.jefftk.com/p/diving-into-a-floating-point-bug
lwfeedtech02 Mar 2017 08:00:00 EST<p><span>
Yesterday I refactored some python code that effectively changed:
</span>
<pre>
floor(n * (100 / 101))
</pre>
into:
<pre>
floor(n * Decimal(100/101))
</pre>
For most integers this doesn't change anything, but for multiples of
101 it gives you different answers:
<pre>
floor(101 * (100 / 101)) -> 100
floor(101 * Decimal(100/101)) -> 99
</pre>
In python2, however, both give 100:
<pre>
floor(101 * (100.0 / 101)) -> 100
floor(101 * Decimal(100.0/101)) -> 100
</pre>
What's going on? First, what's the difference between python2 and
python3 here? One of the changes not listed in
<a href="https://docs.python.org/3.0/whatsnew/3.0.html">What's New In
Python 3.0</a> is that
<tt>floor</tt> now returns an
<tt>int</tt>
instead of a
<tt>float</tt>:
<ul>
<li>
<a href="https://docs.python.org/2/library/math.html#math.floor">2.x</a>:
Return the floor of <tt>x</tt> as a <tt>float</tt>, the largest
integer value less than or equal to <tt>x</tt>.
</li>
<li>
<a href="https://docs.python.org/3/library/math.html#math.floor">3.x</a>:
Return the floor of <tt>x</tt>, the largest integer less than or equal
to <tt>x</tt>. If <tt>x</tt> is not a <tt>float</tt>, delegates to
<tt>x.__floor__()</tt>, which should return an <tt>Integral</tt>
value.
</li>
</ul>
Since these are positive numbers, we can use
<tt>int()</tt> instead of
<tt>floor()</tt> and now python2 and python3 give the same result:
<pre>
2.x: int(101 * Decimal(100.0/101)) -> 99
3.x: int(101 * Decimal(100/101)) -> 99
</pre>
The root of the problem is that
<tt>100/101</tt> is a repeating decimal,
<tt>0.99009900...</tt>, and so can't be represented
exactly as a
<tt>Decimal</tt> or a
<tt>float</tt>. To store it as a
<tt>Decimal</tt> python defaults to 28 decimal digits and rounds it:
<pre>
> D(100)/D(101)
Decimal('0.9900990099009900990099009901')
</pre>
Storing it as a
<tt>float</tt> is more complicated. Python uses the
platform's hardware support, which is
<a href="https://en.wikipedia.org/wiki/IEEE_floating_point">IEEE 754</a>
floating point bascially everywhere, and it gets converted to a binary
fraction with 53 bits for the numerator and a power of two for the
denominator:
<pre>
1114752383012499 / 2**50
</pre>
Python is aware that there are many numbers for which this is the
closest possible floating point approximation, and so to be friendly
it selectes the shortest decimal representation when printing it:
<pre>
> 100/101
0.9900990099009901
</pre>
<p>
Now we have all the pieces to see why <tt>101*Decimal(100/101)</tt> is
less than <tt>101*(100/101)</tt>, and, critically, why one is just under
100 while the other is exactly 100.
</p>
<p>
In the <tt>Decimal</tt> case python first divides 100 by 101 and gets
<tt>1114752383012499 / 2**50</tt>. Then it takes the closest
representable <tt>Decimal</tt> to that number, which is
<tt>Decimal('0.99009900990099009021605525049380958080291748046875')</tt>.
That's 50 bits of precision because <tt>Decimal</tt> tries to track
and preseve precision in its calculations, and 53 bits of precision is
50 decimal digits of precision. [<a name="update-2017-03-02"></a><b>Update 2017-03-02</b>: this is
wrong: 53 bits of precision much less than 50 decimal digits. I'm not
sure why <tt>Decimal</tt> is doing this.] All of the digits starting with
<tt>02160...</tt> are just noise, but <tt>Decimal</tt> has no way
of knowing that. Then when we multiply by <tt>101</tt> we get
<tt>Decimal('99.999...58030')</tt>, because our <tt>Decimal</tt>
version of the <tt>float</tt> was slightly less than true
<tt>100/101</tt>.
</p>
<p>
On the other hand, when python gets <tt>101 * (100/101)</tt> it stays
in IEEE 754 land. It multiplies <tt>101</tt> by <tt>1114752383012499
/ 2**50</tt>, and the closest <tt>float</tt> to that is exactly
<tt>100</tt>.
</p>
<p>
I ran into this bug because I had been trying to break a large change into
two behavior-preserving changes, first switching some code to use
<tt>Decimal</tt> and then switching the rest. To fix the bug, I
combined the two changes into one, so that we switched from using
<tt>float</tt> and <tt>int</tt> to using <tt>Decimal</tt> throughout
this module.
</p>
<p><i>Comment via: <a href="https://plus.google.com/103013777355236494008/posts/eyY9LQBXwCr">google plus</a>, <a href="https://www.facebook.com/jefftk/posts/851537469962">facebook</a>, <a href="https://news.ycombinator.com/item?id=13774742">hacker news</a></i></p>
/p/housing-without-street-parkingHousing Without Street Parking
https://www.jefftk.com/p/housing-without-street-parking
housingideaslwfeed28 Feb 2017 08:00:00 EST<p><span>
One of the major reasons existing residents often oppose adding more
housing is that as more people move in it gets harder to find
on-street parking. [1] This gives us things like requirements that there
be at least one off-street parking place per unit, or just
prohibitions on building out. What if, in places like Somerville
where all parking is already by-permit-only, we added a new category of
housing unit, one that didn't come with any rights to street parking?
</span>
<p>
The requirements for building these would be lower, and they would
end up renting somewhat more cheaply. I know a lot of people who
don't own cars and walk / bike / taxi / take public transit
everywhere, who I think would be happy to rent units classified this
way.
</p>
<p>
Almost everything else about cities can scale with more money, and
when you build new units you get more in property taxes. The main
thing that doesn't scale is space, and by allowing more people without
further dividing the space we should be able to make everyone happy?
</p>
<p>
<br>
[1] For example, my alderman's most recent monthly letter contains:
</p>
<blockquote>
"21 Cherry Street — 6 units. The developer wants to bulk up the building and add many bedrooms without additional parking. The neighbors are opposed and have urged the developer to scale down the plans. ...
<p>
39 Murdock Street — 3 units. The developer is expanding a small single family with less than 1,000 square feet into a large 3-family with 10 bedrooms and almost 6,000 square feet. Neighbors are concerned about parking issues."
</p>
</blockquote>
<p><i>Comment via: <a href="https://plus.google.com/103013777355236494008/posts/f5KhutoE6WZ">google plus</a>, <a href="https://www.facebook.com/jefftk/posts/851221093982">facebook</a></i></p>
/p/early-exercise-and-83bEarly Exercise and 83b
https://www.jefftk.com/p/early-exercise-and-83b
lwfeedmoneystartuptaxes16 Feb 2017 08:00:00 EST<p><span>
</span>
<i>This is a post where I'm trying to figure out what I should do from
a tax perspective. I'm not that knowlegable about taxes, but I still
have to make a tax-relevant choice. So please read this as "Jeff
writes down what he's currently thinking about how to make this
decision" and not "Jeff tells me how to decide whether to early
exercise."</i>
<p>
<a name="update-2017-03-07"></a><b>Update 2017-03-07</b>: Ben Kuhn has a much better post, <a href="http://www.benkuhn.net/options">Stock options are really
complicated</a>. Go read that instead.
</p>
<p>
<a name="update-2017-02-17"></a><b>Update 2017-02-17</b>: The modelling in this post is wrong to the
point of not being useful. I had thought that the reason to exercise
early was to get capital gains treatment on options, but <a href="https://en.wikipedia.org/wiki/Incentive_stock_option">ISOs</a>
already have this if you're careful with them. The reason to exercise
early is the <a href="https://en.wikipedia.org/wiki/Alternative_minimum_tax">alternative
minumum tax</a>.
</p>
<p>
I <a href="https://www.jefftk.com/p/leaving-google-joining-wave">recently</a> started at a
startup, and as is typical part of my compensation is in the form of
stock options vesting over four years. I have two choices about how
to handle this:
</p>
<p>
</p>
<ul>
<li><p>The default option is to do nothing. When I want to sell, I pay
the strike price to convert the options into stock ("exercise them"),
and pay taxes on their growth.
</p></li>
<li><p>Alternately I pay the strike price now to convert the options into
stock (even thought they haven't vested yet) and file an 83b election.
When I want to sell, I pay taxes on their growth.
</p></li>
</ul>
At first glance this seems kind of counterproductive: why would I want
to pay the strike price now, instead of waiting until I exercise? The
thing is, there are two different tax rates involved. If I exercise
the shares now and file an 83b, then I pay no tax now (I effectively
just bought some stock at fair market value) and when I eventually do
sell the shares I'm taxed at the long-term capital gains rate. If
instead I don't do anything, then when I eventually exercise and sell
the shares [1] I pay (much higher) regular income tax on their growth.
<p>
On the other hand, the company might not succeed. Then I'll have paid
thousands of dollars to buy shares that aren't worth anything. Or I
might leave the company before four years have passed, giving up
thousands of dollars of stock that I've paid for but hasn't vested. I
don't expect either of these to happen, but the outside view suggests
something like a 50% chance.
</p>
<p>
So, what does this look like financially? Let's say there's a 25%
chance of the company doing really well and exiting for $1B in five
years, a 25% chance of $300M, and a 50% chance of failure. How much
money do I have in five years?
</p>
<p>
</p>
<ul>
<li><p>Early exercise: I pay $25k in strike price now, which if
borrowed at 5% is comparable to $30k five years out. In five years I
have a 25% chance of my stock being worth $1.5M, a 25% chance of it
being worth $0.5M, and a 50% chance of it being worth $0. IRS says I
have long term capital gains of $475k, I pay $95k in taxes. After
taxes I have $375k.
</p></li>
<li><p>Default: I do nothing now. If the company fails I also do
nothing. If it succeeds, five years from now I pay the $25k
strike price, immediately sell the stock, and have regular income of
$975 taxed at 35%. After taxes I have (50%) $0 or ($50%) $634k, which
is $317k.
</p></li>
</ul>
<p>
So, with that model I should early-exerise. But this ignores
donations! Donations do two things:
</p>
<ul>
<li><p>If I early exercise, I would be donating appreciated stock,
which has very good tax treatment. I donate the stock, but don't ever
pay tax on it. Additionally, I can deduct it from my federal income
taxes (up to 30% of AGI). So if I slowly donated off the stock,
taking a deduction as I went, I not only wouldn't ever pay tax on the
gains, but I would reduce my regular taxes. This is complicated and
extends the time horizon, so I'm just going to model this as if I
donate all the stock. So I donate (50%) $0 or (50%) $1M, which after
accounting for the strike price with interest is $470k.
</p></li>
<li><p>If I do nothing, then if the company succeeds I'm donating
some of the proceeds and so not taxed on them. I take in $975k,
donate 50%, so $488k, pay 35% taxes on the rest leaving me with $316k.
Ignoring the donated-kept distinction, and accounting for the strike
price, this is $779. So this is either (50%) $0 or (50%) $779k, which
is $390k.
</p></li>
</ul>
<p>
Ignoring donations, I come out ahead by $58k by early exercising,
while counting donations I'm ahead by $80k.
</p>
<p>
Of course, the real tricky part here is the model of how much the
company is going to be worth. The company might be more likely than
50% to fail, but it also might be worth as much as, say, Western
Union, at $10B. I'm not great at handling tax details, but I'm really
not good at valuing companies! Not early exercising is in some sense
the 'safer' choice, but of course so would have been staying at Google.
</p>
<p>
<br>
[1] The options have a ten-year exercise period, so there's nothing
that would push me to exercise the options without immediately selling
them.
</p>
<p><i>Comment via: <a href="https://plus.google.com/103013777355236494008/posts/7jXFYQYv4BL">google plus</a>, <a href="https://www.facebook.com/jefftk/posts/848628654252">facebook</a></i></p>
/p/carcassonne-for-kidsCarcassonne For Kids
https://www.jefftk.com/p/carcassonne-for-kids
gameskidslwfeed13 Feb 2017 08:00:00 EST<p><span>
Standard Carcassone is too complicated before about age 9, but if you
adjust the rules (substantially) it can be a lot of fun with much
younger kids. Stages of play:
</span>
<p>
</p>
<ol>
<li>You just take turns playing tiles, and edges don't matter.
</li>
<li>Still just playing tiles, but now edges do matter.
</li>
<li>When you play a city tile, you can put a person on it, and when
the city completes you get the person back.
</li>
<li>Same with roads.
</li>
<li>Same with monastaries.
</li>
<li>Start counting points and having a winner.
</li>
<li>Add farms
</li>
</ol>
<p>
I've been playing stage #1 with Lily (nearly three years old) a lot
lately, I've played stage #2 with a five year old, and stage #3 with a
six year old. The exact rules don't matter that much, the important
thing is to have fun and to teach the idea of playing a game that has
rules you need to follow. For example, Lily wanted to play with the
meeple as well, so we play that every time you put down a tile you
also have to put a person on it.
</p>
<p>
<img src="https://www.jefftk.com/carcassone-kids.jpg" width="550" height="359" class="mobile-fullwidth" style="max-width:100.0vw; max-height:65.3vw;" srcset="https://www.jefftk.com/carcassone-kids.jpg 550w,https://www.jefftk.com/carcassone-kids-2x.jpg 1100w">
</p>
<p>
There's also a version of Carcassone <a href="https://en.wikipedia.org/wiki/The_Kids_of_Carcassonne">specifically
aimed at kids</a> but I think using the normal tiles with simpler
rules makes more sense—why buy another game, and one that can't
become more interesting as the kid gets older?
</p>
<p>
(This would work with other games as well. For example, with Dominion you
could play with just money, trying to be the first to buy a Gold.
Then you add in victory points, then one additional card at a time as
they seem ready.)
</p>
<p>
<i>Follow-up: <a href="https://www.jefftk.com/p/simplifying-board-games">Simplifying Board Games</a></i>
</p>
<p><i>Comment via: <a href="https://plus.google.com/103013777355236494008/posts/SrCNKfu6TGn">google plus</a>, <a href="https://www.facebook.com/jefftk/posts/847211090062">facebook</a></i></p>