## Thursday, July 9, 2020

### A Graphical Analysis of Women's Tops Sold on Goodwill's Website

I set up a script that collected information on listings for more than four million women's shirts for sale through Goodwill's website, going back to mid-2014. The information is deeply flawed—a Goodwill online auction is very different from a Goodwill store—but we can get an idea of how thrift store offerings have changed through the years. There's more info on data collection method below.

## Wednesday, July 1, 2020

### Using AWS S3 Glacier Deep Archive For Personal Backups

I've been using AWS S3 for personal backups, and it's working well.  The hardest part of doing anything in AWS is that you have no idea what it will cost until you actually do it; they are masters of nickle and dime charging.  With that in mind, I wanted to wait until I had a few months of solid data before reporting on how it's been working for me.

If you know me, this may surprise you, but my backup strategy is a bit complex.  However, the relevant part for this post is that my documents folder is about 16 GB and I'm keeping a full backup of that, with daily diffs, for about $0.02 a month. Costs I did a post estimating the costs last year, and the result has lined up with that. Here is the relevant part of my AWS bill for May 2020 (June looks to be the same, but isn't complete yet): There are also some regular S3 line items, since I believe the file list is stored there even when the files are in Deep Archive. However, I'm far below the cost thresholds there. Process I have a local documents folder on my SSD, that gets backed up to a network version nightly via an rsync script. Folders that are no longer being updated (eg, my school folder) I will delete from my local version and just keep on the network version. Every month I create a full zip of my local documents folder and upload to S3. Then every day I create a zip of just the files that have changed in the last 40 days. I chose 40 days to to provide some overlap. You could be more clever and just get files that changed since the first of the month, but I wanted to keep the process simple due to how important it is. I also do a yearly backup of the full network version of this folder, which has a lot of stuff that hasn't changed in years in it. The result is that I could do a full recovery by pulling the most recent monthly backup and then the most recent daily backup, and replacing the files in the monthly with the newer versions from the daily. I'd also have to pull the most recent yearly, and extract that to a separate location. This feels like a pretty simple recovery, all things considered. Scripts The full backup: And the diff backup: If you want to adapt these scripts it should be pretty straightforward. You'll have to have 7zip installed and have the command line aws client set up. Create a nice long random password and store it in the password file. Make sure you have a system for retrieving that password if you lose everything. There's a feature to warn if the compressed file is larger than expected, since that will cost money. The numbers are arbitrary, and work for me, you'd have to adjust them. Also if you want to get the emailed warnings you'll have to set up mail and change the email address. If you do want to use S3 Deep Archive for backups I really recommend reading my previous post, because there are a lot of caveats. I highly encourage you to combine your files into a single file, because that will reduce the per file costs dramatically. Also, note there is nothing here to delete these backups. If all you care about is being able to restore the current version, then you can delete any but the newest version. Keeping them all gives you the ability to restore at any point in time. If you do delete them, keep in mind there is a limit to how fast you can delete things on Deep Archive. Epilogue I realize there are easier, free-er, and arguable better solutions out there for personal backups. That's it, I don't have a 'but,'. If you're reading this blog, this should not be a surprise. Now that I have real data, I'm thinking about backing up some of my harder to find media here too. I estimate 1 TB should cost about$12 per year in any of the cheapest regions.

## Saturday, April 4, 2020

An idea I've had for a while is a password generator where you take a master password, an optional per site password, and the site domain name, combine and hash them to get a unique password for any site.

This system has a unique benefit over traditional password managers in that you can't lose your passwords.  Even if all your electronics were destroyed and you woke up naked in China tomorrow you could get your passwords just by using an online version of the tool (or failing that, manually doing the steps yourself with a hash generator).

However, the system has a unique drawback of not remembering what the password requirements are.  Some sites require special characters, some don't allow them, some require more than 10 characters, some allow for a max of 8.  It would be easy to translate your hash into whatever set of requirements you have, but you still need to either remember that, or store it somewhere else.

Today I discovered this idea has been implemented, a lot.  It's called a stateless password manager, or a deterministic password manager.  Two examples are:

https://lesspass.com/#/

And here is an article discussing the flaws in this system:

## Tuesday, March 24, 2020

### Social Distancing Scoreboard

According to the World Health Organization and the CDC, social distancing is currently the most effective way to slow the spread of COVID-19. We created this interactive Scoreboard, updated daily, to empower organizations to measure and understand the efficacy of social distancing initiatives at the local level.

https://www.unacast.com/covid19/social-distancing-scoreboard

## Sunday, March 15, 2020

### How do they actually work?

Instead of transmitting a counter, just send an alternating pulse.  It doesn't have to be very fast, a MHz would be enough.  Then your reflected pulse is the same wave, but delayed slightly.  You only care about measuring the difference in time of the leading and falling edges of the two waves, or delta.  This means you can just compare the two waves using an XOR gate, which is just a fancy way of saying "tell me whenever these waves are different".

Here's an example

Where the top red line is the original signal, and the second blue line is the reflected version.  Then the third green line is the XORed delta of the two.

When you measure something slightly further away the reflected wave gets more delayed and the delta version gets a longer pulse.

### Are logic gates fast enough?

Logic gates like these are cheaper and faster than the circuitry you'd need for a timer.  However, they still aren't quite fast enough for the precision we see in these tools.  Luckily though, a delay doesn't really impact the measurement.  As long as it's a consistent delay on both the rising and falling edges of the two waves.

All you end up with is a slightly offset delta signal.

### Who will measure the measurer?

It might seem like we're back to square one here, with the need to precisely measure the time of that pulse, but we actually just need take the average of that signal.  There are a variety of ways we can do this, but as a proof of concept, imagine the delta signal is charging a capacitor, which is simultaneously being drained by a constant resistor.  You'd end up with a level of charge in the capacitor which would translate into what percentage of time the delta single is high.

Now, all you have to do is measure the charge in the capacitor and turn that into a measurement you display.  Let's review what we need:
• Laser transmitter and optical sensor.
• MHz clock to turn laser on and off.
• XOR circuit to compare the two transmitted and received signals.
• A capacitor and resistor circuit to find average of the digital signal.
• A way to measure the charge in the capacitor.
• Something to take that measurement and convert it into the distance.
• A display.

## Wednesday, August 14, 2019

### nandgame.com

Build a computer out of NAND gates in stages.  This is essentially a game version of my post about how computers work.

http://nandgame.com/

## Sunday, July 7, 2019

### Social Science Research Network

I've been into reading random papers from SSRN lately.  There's some really good stuff on there, like the paper I mentioned in my last post.

https://hq.ssrn.com/rankings/Ranking_display.cfm?TRN_gID=10

## Sunday, June 30, 2019

### The law of small numbers

I was listening to a podcast when I heard about an interesting probability result in the same vein as the Monty Hall Problem.  The new problem is this: Flip a coin 100 times and record the results.  Now pick random flips in the set and see if the next 3 flips are all heads; if so we call this a streak.  Repeat until you find a streak of 3.  Now what is the probability that the 4th flip is also heads?  Is it 50% like we would expect?  It turns out to be closer to 46%, which is not very far from 50%, but is also a clear trend.

You can download the paper here, and I recommend you read through the introduction, which is pretty easy to follow.  I think does a good job of explaining what is going on.  Since no one will do that, here is a table from the paper which helps give some intuition.

This represents every possible outcome from flipping a coin 3 times and looking for a 'streak' of 1 heads.  There are eight total possible outcomes, all equally likely.   In the first two, the streak of 1 heads never happens, or happens on the last flip where there is no following flip to look at.  Those are thrown away and ignored.  In the other six possible outcomes we do get a streak, at least once, and earlier than the last flip.  The underlined flips represent the possible candidates for the flip that is following a streak.  If we pick the preceding streak, then the underlined flips will be the one we are trying to predict.  In three out of the six outcomes with a streak, the following flip will not be heads.  In two out of the six outcomes the following flip will always be heads.  And in the remaining possible outcome it could be either head or tails with 50/50 probability depending on which streak you pick.

If you list out all the possible outcomes from any combination of streak length and total flips, you can see that some number of the heads flips are 'consumed' by the streaks themselves.  Those flips can never be following a streak, because they are part of the streak needed to define the streak.  On the other hand, the tails have no restrictions, they are all available to occur in the flip immediately following a streak.  There are simply more tails available to go in the candidate position.  The effect gets smaller as you decrease the streak length or increase the total number of flips in a set.

I found this very surprising, so I wanted to test it out.  I wrote a Ruby script to simulate various coin flips and look for streaks of different lengths, and output the results.  I then decided to rewrite it in a compiled language so it would be faster.  I decided to try out Go, as I've never used it before and I was hoping for something with a bit more syntactic sugar than C.

https://github.com/StephenWetzel/coin-flips-go

Here are the results of a bunch of combinations of streak lengths and numbers of flips from the Go program:
Looking for a streak of length  1 in    10 total flips. Performed 10000 rounds, and   9973 were successful, found 45.29% continued the streak.
Looking for a streak of length  1 in   100 total flips. Performed 10000 rounds, and  10000 were successful, found 49.43% continued the streak.
Looking for a streak of length  1 in  1000 total flips. Performed 10000 rounds, and  10000 were successful, found 49.91% continued the streak.
Looking for a streak of length  2 in    10 total flips. Performed 10000 rounds, and   8203 were successful, found 38.16% continued the streak.
Looking for a streak of length  2 in   100 total flips. Performed 10000 rounds, and  10000 were successful, found 47.72% continued the streak.
Looking for a streak of length  2 in  1000 total flips. Performed 10000 rounds, and  10000 were successful, found 50.15% continued the streak.
Looking for a streak of length  3 in    10 total flips. Performed 10000 rounds, and   4797 were successful, found 34.88% continued the streak.
Looking for a streak of length  3 in   100 total flips. Performed 10000 rounds, and   9995 were successful, found 45.84% continued the streak.
Looking for a streak of length  3 in  1000 total flips. Performed 10000 rounds, and  10000 were successful, found 49.78% continued the streak.
Looking for a streak of length  4 in    10 total flips. Performed 10000 rounds, and   2152 were successful, found 35.83% continued the streak.
Looking for a streak of length  4 in   100 total flips. Performed 10000 rounds, and   9637 were successful, found 40.61% continued the streak.
Looking for a streak of length  4 in  1000 total flips. Performed 10000 rounds, and  10000 were successful, found 49.21% continued the streak.
Looking for a streak of length  5 in    10 total flips. Performed 10000 rounds, and    985 were successful, found 37.36% continued the streak.
Looking for a streak of length  5 in   100 total flips. Performed 10000 rounds, and   7860 were successful, found 38.66% continued the streak.
Looking for a streak of length  5 in  1000 total flips. Performed 10000 rounds, and  10000 were successful, found 48.91% continued the streak.
Looking for a streak of length  6 in    10 total flips. Performed 10000 rounds, and    388 were successful, found 35.82% continued the streak.
Looking for a streak of length  6 in   100 total flips. Performed 10000 rounds, and   5190 were successful, found 35.24% continued the streak.
Looking for a streak of length  6 in  1000 total flips. Performed 10000 rounds, and   9996 were successful, found 46.68% continued the streak.
Looking for a streak of length  7 in    10 total flips. Performed 10000 rounds, and    140 were successful, found 40.71% continued the streak.
Looking for a streak of length  7 in   100 total flips. Performed 10000 rounds, and   2997 were successful, found 33.83% continued the streak.
Looking for a streak of length  7 in  1000 total flips. Performed 10000 rounds, and   9761 were successful, found 42.40% continued the streak.
Looking for a streak of length  8 in    10 total flips. Performed 10000 rounds, and     52 were successful, found 36.54% continued the streak.
Looking for a streak of length  8 in   100 total flips. Performed 10000 rounds, and   1634 were successful, found 33.60% continued the streak.
Looking for a streak of length  8 in  1000 total flips. Performed 10000 rounds, and   8365 were successful, found 38.27% continued the streak.
Looking for a streak of length  9 in    10 total flips. Performed 10000 rounds, and     17 were successful, found 47.06% continued the streak.
Looking for a streak of length  9 in   100 total flips. Performed 10000 rounds, and    784 were successful, found 33.04% continued the streak.
Looking for a streak of length  9 in  1000 total flips. Performed 10000 rounds, and   6037 were successful, found 35.80% continued the streak.
Looking for a streak of length 10 in    10 total flips. Performed 10000 rounds, and      0 were successful, found NaN% continued the streak.
Looking for a streak of length 10 in   100 total flips. Performed 10000 rounds, and    381 were successful, found 30.71% continued the streak.
Looking for a streak of length 10 in  1000 total flips. Performed 10000 rounds, and   3615 were successful, found 33.91% continued the streak.

## Tuesday, April 30, 2019

### Should You Time The Market?

https://ofdollarsanddata.com/even-god-couldnt-beat-dollar-cost-averaging/
You have 2 investment strategies to choose from.
1. Dollar-cost averaging (DCA):  You invest $100 (inflation-adjusted) every month for all 40 years. 2. Buy the Dip: You save$100 (inflation-adjusted) each month and only buy when the market is in a dip.  A “dip” is defined as anytime when the market is not at an all-time high.  But, I am going to make this second strategy even better.  Not only will you buy the dip, but I am going to make you omniscient (i.e. “God”) about when you buy.  You will know exactly when the market is at the absolute bottom between any two all-time highs.  This will ensure that when you do buy the dip, it is always at the lowest possible price.

## Friday, March 15, 2019

### Everything Smarthome

This is a long, but enjoyable article in broken Russian-English about everything smarthome in 2019.

https://vas3k.com/blog/dumbass_home/

## Wednesday, February 27, 2019

Dropbox has a password strength estimator called zxcvbn that I like a lot.  It estimates entropy in your password by looking for dictionary or password list leak matches.  It's long bothered me when sites estimate password strength purely based on complexity.  These sites say a password like Password!1 is much more secure than one like zbuwcramudbpvreorkno (a score of 72% vs 21% respectively).  I discuss this in more detail in my How to be secure online post.

However, a while ago Dropbox changed their algorithm to favor length over resistance to dictionary attacks.  There is some logic in their decision, but I really feel like something is lost by not having the old algorithm.  So, I made a demo comparing the two so you can find passwords both algorithms agree are strong.  At the same time, I finally hooked up this domain I bought a while ago to my github pages site.

## Friday, November 16, 2018

### Invisibly inserting usernames into text with Zero-Width Characters

https://www.umpox.com/zero-width-detection/
Zero-width characters are invisible, ‘non-printing’ characters that are not displayed by the majority of applications. F​or exam​ple, I’ve ins​erted 10 ze​ro-width spa​ces in​to thi​s sentence, c​an you tel​​l? (Hint: paste the sentence into Diff Checker to see the locations of the characters!). These characters can be used to ‘fingerprint’ text for certain users.

## Sunday, November 4, 2018

### The FBI of the National Park Service

https://www.outsideonline.com/2353856/national-park-service-investigative-services-branch
Last August, I traveled to Yosemite National Park to meet up with Shott’s colleague, ISB special agent Jeff Sullivan, an affable, self-deprecating, 35-year veteran of the Park Service. Sullivan has played a role in investigating nearly every major crime and mystery that’s taken place in Yosemite over the past quarter-century, which made him the ideal guide for a tour of the shadowy side of America’s fifth most visited national park. See that grassy expanse, dotted with wildflowers? That’s where park visitors discovered the skull of a still-unidentified young woman, a murder claimed by the prolific serial killer Henry Lee Lucas. That lush meadow? Once, someone found a dead bear there, its head neatly severed from its body. (The ISB sent the bear’s remains to the park’s wildlife lab in Oregon, hoping to discover clues about who’d poached it. The lab called back a few weeks later: The poacher you’re looking for is a mountain lion.)
Sullivan and I drove up to Glacier Point, where he told me about the rockslide in 1996 that killed one and injured at least 11. The dust cloud it kicked up was so massive it blocked out the sun; until Sullivan arrived on the scene, he’d been sure there would be dozens of casualties. Next to us, a bored teenager flung a water bottle into the abyss. Watching it fall seemed to cause Sullivan physical pain. He leaned in close and flashed his badge at the kid. “Don’t throw water bottles,” he said quietly.

## Monday, October 22, 2018

### How to set up Raspberry Pis without a keyboard, mouse, or monitor

There are plenty of guides out there about how to set up headless Raspberry Pis, but they get out of date quickly, and I do this often enough that I'm constantly searching for up to date ones.  So for my own benefit here's my documentation of the process.

Put your SD card in your computer and use lsblk to identify which drive your SD card is. Be careful, if you use the wrong drive below you will overwrite your main hard drive.

Use dd to copy the date over.  They constantly recommend you use the program Etcher, but I've never had it work successfully.  The command is sudo dd bs=4M if=2018-10-09-raspbian-stretch-lite.img of=/dev/sde conv=fsync status=progress

Your card should have 2 partitions, open the boot partition and add an empty file called ssh to enable ssh, and create a file called wpa_supllicant.conf to configure wifi.  The contents of the file are this:



country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
psk=abcdef1234567890
key_mgmt=WPA-PSK
}

You can either put your actual password in there as the psk, or use the tool wpa_passphrase to convert your password into a hash that will also work.

Put the card in the Pi, boot it up, and it should connect to your network and you should be able to ssh in with username pi and password raspberry.  Note that you need to boot once for it to expand the filesystem.

You should put your public key in ~/.ssh/authorized_keys and turn off password ssh access.  You should also run sudo raspi-config once you ssh in, and update with sudo apt update && sudo apt upgrade

## Saturday, October 6, 2018

### Blockchain Technology Overview

https://nvlpubs.nist.gov/nistpubs/ir/2018/NIST.IR.8202.pdf

NIST just published a good overview of blockchain technologies.  Very thorough, yet digestible for non-technical readers.
Blockchains are tamper evident and tamper resistant digital ledgers implemented in a distributed fashion (i.e., without a central repository) and usually without a central authority (i.e., a bank, company, or government). At their basic level, they enable a community of users to record transactions in a shared ledger within that community, such that under normal operation of the blockchain network no transaction can be changed once published. This document provides a high-level technical overview of blockchain technology. The purpose is to help readers understand how blockchain technology works.

Let’s see… I generated a meeting, got a Google Meet phone number, and all subsequent phone numbers are also from the same carrier. Let me call and see if I get the Google Meet greeting to confirm. Bingo! For countries like Australia and Spain, Google Meet phone numbers are assigned in batches that are sequential. I can generate a meeting myself and just check the subsequent phone numbers to obtain more Google Meet numbers. You can use them to join/find meetings in the US as the phone numbers from other countries are not specific to meetings in that country, they are global.

10 seconds per call, 3 PINs at a time, 10,000 PINs to try. It would take about 9 hours to cover all PIN combinations making one call at a time. Because Twilio is designed to make calls at scale, we can make hundreds of calls at the same time making the process much faster. The script fires so many calls that the line will be busy sometimes. Not a problem! The script will detect failed calls and simply retry. Actually, Twilio notifies of failed calls immediately using webhooks making the script very efficient handling calls that did not go through.

## Friday, February 16, 2018

### The “hydrogen economy” may be a thing after all.

https://www.vox.com/energy-and-environment/2018/2/16/16926950/hydrogen-fuel-technology-economy-hytech-storage
The first product, scheduled to debut in April, is the key to everything else.
It’s called Internal Combustion Assistance (ICA), a modification to internal combustion engines that enables them to substantially increase their fuel efficiency and reduce their air pollution. It does this by adding tiny amounts of gaseous hydrogen and oxygen to the fuel just before it is combusted in the engine’s cylinders. The HHO mix lends intensity to the combustion, allowing the fuel to burn more completely, generating more oomph and less pollution.
The ICA system can technically work on any internal combustion engine, but to begin with, HyTech is targeting the dirtiest engines with the fastest return on investment, namely diesel engines — in vehicles like trucks, delivery vans, buses, and forklifts, but also big, stationary diesel generators, which still provide backup (and even primary) power by the millions across the world.

## Monday, January 29, 2018

I've long maintained that the only sites that really need strong passwords are emails (because they let you reset other passwords) and financial sites.  I've memorized long random passwords for those sites, and I have a few similar passwords I use for the rest of things.  I've never been too concerned about sharing passwords between other sites, because I literally don't care about the security of those accounts.

That being said, sites are increasingly instituting arbitrary restrictions that are intended to make things more secure.  This means I need variations of my common passwords for every permutation of rules, and then variations of those for when I'm required to change them.  Having to try all these permutations has finally made me break down and start using a password manager.

It's probably no surprise I didn't just go with LastPass, and not just because of my general aversion to the most popular choices, but as I've heard the company they are owned by is shady.

There are a lot of password managers, but if you're looking for open source, and managing your own password file, the clear choice is KeePass.  However, as is an open source tradition, you can't just go with KeePass; you have to follow the forks, to find the version that is currently up to date and being maintained.  That version is KeePassXC.

If you go with KeePassXC you'll have a client on every device you want to use it with.  Then you'll have a password file, which is the encrypted file holding all your passwords.  In theory if your master password for that file is long and secure you won't need to worry about keeping that file too safe (don't post it publicly).  I'd recommend getting to at least centuries on the 10k/second tier of zxcvbn.

This felt like it was going to be the hardest part, but it turned out to be the easiest.  Certainly, the biggest convenience of LastPass is that someone else manages the password file for you.  A lot of people use Dropbox to sync the KeePass file, and I was ok with this (as the file is encrypted so you aren't really trusting Dropbox with anything), but I hate the idea of installing Dropbox's bloated, always running, client on every device.

Luckily I found Syncthing.  Which is essentially an open source, bit torrent based, version of Dropbox.  You install it on all your machines and then point it to the folder you want to share and it keeps it synced.  My biggest issue was having to enable discovery on every device so that they would share the list of devices they are sharing with too.  This makes sense to have turned off if you were sharing with other people, but if you're only using it in a closed personal ecosystem it's much easier to have it enabled.

I was slightly worried about the password file becoming out of sync, getting written to by two different computers and getting corrupted.  But my mild stress tests have been unable to make this happen.  I've been using this set up for half a year now without issue, so I'm comfortable recommending it.  That being said, Syncthing does allow you to maintain history files (where it keeps the last few versions of the file every time it overwrites it), and I still have that enabled on my PC.

### Browser Integration

KeePassXC uses a protocol called KeePassHTTP to share passwords externally.  This basically just sets up a server and allows http requests for your passwords.  This is risky because there could be external requests.  KeePassXC only allows localhost requests, which should mitigate that risk.  If you're still worried you can disable that and use autotyping where you place the cursor in any text field and the it types the password in that field.

Just searching for "KeePassXC Firefox" or Chrome shows the extensions for either.  I've been happy with both of those, although they do feel like the weakest link.

On Android the app Keepass2Android works well.  If you search for the site in the app it then gives you another keyboard to choose from which only has two buttons "User" and "Pass".  Pressing those fills in that info for the site you have selected.

The closest thing to a problem on the phone is that it takes a few seconds to unlock the file.  This is important though, it should take at least half a second to unlock your password file on a fast PC.  If you make it faster to open, it'll be easier to brute force.

## Thursday, December 28, 2017

### Create fake videos of famous people saying anything you want in real time.

Google has software that can create dynamic audio indistinguishable from a real person (scroll to "Tacotron 2 or Human?" at the bottom):

Combine with this which lets you to put your facial movements on a real person:

## Wednesday, December 20, 2017

Annechino and Cheng spent months researching one city. But not only did Google capture all of their commerical corridors (and several more), it somehow came up with them for thousands of cities across the world. (Even my tiny hometown got a few.)

## Sunday, October 29, 2017

### Designing a Hammock Stand

2017 note: This is a post I wrote in 2013 about a hammock stand I never built.  My plan was to build it first so I could add finished pictures, but I think I'm about ready to give up on my prospects of ever actually building this.

Every night I sleep on, what is essentially, a pile of garbage.  A while back, someone started a thread on reddit about sleeping in a hammock every night.  He had nothing but praise for hammocks and some research showed the internet generally agreed that hammocks were an excellent bed replacement.

I decided I would give it a try.  As I backpack too, I bought an ENO Doublenest that can be used for camping.  Although I have no real plans to do that.

Calculations

Before I could plan a stand for nightly, indoor, hammock use, I had to know what kind of forces it would have to handle.

The hammock's max weight rating is 400 lbs, and since it is probably better for the hammock to fail before the stand I used that as my load.

Each end of the hammock has to support half the load, however, this is not just 200 lbs.  To find out why, and see what the actual tension is we will break the force vector into its x and y components

We don't know the x force, and are trying to find the resultant force.  We do, however, know the angle and the y force.  The y force must be equal to just half the weight supported by the hammock.  This assumes the weight won't get shifted too much to one end.

The ideal hang angle is widely reported to be 30 degrees down from a horizontal.  A preliminary test of mine showed I liked it closer to 45.  Shallower angles increase the stresses, so I planned for 30 degrees.

The forces form a right triangle with all known angles and one known side.  It's a 30-60-90 triangle and the vertical leg is 200 lbs.  This means the horizontal force is 347 lbs and the resultant force on the line is 400 lbs.  To be clear, this means that for a 30 degree hang, each line must support the full weight in the hammock.  If we let the hammock sag more to 45 degrees it reduces the tension on the line to only 283 lbs.

Hanging Possibilities

The guy in the reddit thread said he simply hung his from eye bolts in the wall studs.  I don't have wall studs in the basement, and I wouldn't trust them if I did.  I considered hanging from the 2x8 ceiling joists.  The problem was the height would mean I would need a huge span between the two hang points.  Also, I wouldn't recommend anyone hang perpendicular to the direction of the joists, as this will cause deflection.  It might not seem like it would be a big deal, but it is generally a bad idea to introduce new stresses in directions that structural members were never designed to handle, particularly when they are holding up your house.

After some debate I decided on building a stand.  Since most the force is in the horizontal direction I thought about just hanging from a 4x4 post that I would elevate off the ground with some sort of stands on the ends.  I didn't like this idea since it would be annoying to have the post above me while sleeping, and even more annoying when it failed and crashed down on my face.

In order to deal with the high horizontal load, whatever the hammock is actually hanging from would have to be angled out.  This leads to the classic hammock stand shape of angled arms.

Will 2x4s Work?

I decided to angle my arms out at 60 degrees above the horizontal.  This meant that the hammock would hang between 30 and 15 degrees above the arm (for 30 to 45 degrees below horizontal).  To calculate the stresses in the arm I rotated the axes such that the arm was now vertical.  I then calculated the x and y force vectors in this new rotated orientation.

Drawing out the forces shows the 30 degree hang produces the same force triangle as before, just flipped.  There will be 200 lbs of force perpendicular to the arm, and 347 lbs of force parallel to it.  For the 45 degree hang it shifts to 274 lbs parallel to the arm and just 74 lbs perpendicular to it.  You can see what a significant factor the hang angle is to the forces involved.  If I were actually planning on hanging at 30 degrees I'd probably adjust the arms out further to shift more of the torque to compression.

We now have two forces which means we can see what types of load they produce on the arms.  The parallel force results in a axial compressive load, ie, like a column.  This handy calculator tells me that a 2x4 can support 1000-1500 lbs of compression over 5 unbraced feet, depending on grade.  So axial load shouldn't be a limiting factor.

The perpendicular force will produce moment (torque).  The amount will depend on the arm length, which is not yet known.  An estimate of 4.5 feet gives us 340 ft lbs for the 45 degree hang, and 900 ft lbs for the 30 degree hang.  The above calculator's brother tells me that a 2x4 should be able to handle about 375 ft lbs of bending.  This roughly matches the calculations I did on paper as a sanity check.

So, we can see that for a 30 degree hang a 2x4 wouldn't be enough.  Keep in mind we started with a load of 400 lbs in the hammock, and I'd guess that calculator has a safety margin built in, so I'd guess that a 2x4 would hold, at least for a while.

My Design

I began my design with this simple design.  Reading through the comments and several other sites I changed the design significantly.  A goal of my design was ease of construction with a total lack of tools and experience (which admittedly might impair my ability to judge what is easy to build).

After some concern about the torque in the joint I decided to create something like a half lap joint.  I will layer two 2x4s to make a quasi 4x4 as my horizontal base.  First, however, I will make a 60 degree cut through one of the 2x4s at about 2 feet from the center.  I will cut the other 2x4 at 2 feet from the center in the other direction.  Thus, both 2x4s will have a 60 degree cut, 2 feet from the center, but on opposite sides of the center.  I will then gap the cut enough to fit the 2x4 for the arm in there, and cut the bottom of the arm at 60 degrees to make it flush against the floor.  This means the two arms won't be exactly in line, but rather slightly offset.  Looking at the stand head on, the left edge of one arm will be aligned with the right edge of the other.

The two 2x4s along the base will be wood glued and screwed to form a solid 4x4 like piece.  At the end of the base 4 foot long 2x4s will be screwed into the base, forming an I shape.  They will provide stability.  At this point the design looks similar to the starting design, albeit with major, if subtle, differences.  The last change would be side bracing similar to what people in the comments added.  Each side brace would be about 4 feet long and set up at a 60 degree above horizontal angle.  For no reason I decided to put each brace on opposite sides of the ground 2x4 they connect to.  That changes their length by a bit.  It took me much longer than I care to admit to calculate what that difference would be, finally resorting to just using CAD.

Here are some preliminary CAD drawings I did.  I still plan on testing the hang length a bit more before these are final.  Since I'm well aware that no one could be expected to visualize what I described, and that these drawings don't help much, I won't publish this until I'm ready to follow this post up with a construction post with actual pictures.

In lieu of finished shots I did this render in Tinkercad: