Index
created
2024-02-18
modified
2025-11-08
About
I am a software developer at [Apple](http://apple.com). I'm from Minnesota. I graduated from [RPI](http://rpi.edu) in 2012. I am a strong advocate of Internet Independence.You can contact me at [peter@haj.as](mailto:peter@haj.as).# TalksI feel very fortunate to be able to speak publicly about things I am passionate about. Below is a collection of talks I’ve been a part of.- 2025 - [What's new in SwiftUI](https://developer.apple.com/videos/play/wwdc2025/256)- 2018 - [Adding Delight to your iOS App](https://developer.apple.com/videos/play/wwdc2018/233)- 2016 - [A Peek at 3D Touch](https://developer.apple.com/videos/play/wwdc2016/228/) - [What’s New in UICollectionView in iOS 10](https://developer.apple.com/videos/play/wwdc2016/219/)- 2015 - [Getting Started With Multitasking on iPad in iOS 9](https://asciiwwdc.com/2015/sessions/205) *(video unavailable)*- 2014 - [A Look Inside Presentation Controllers](https://asciiwwdc.com/2014/sessions/228) *(video unavailable)*- 2013 - [Advanced Text Layout and Effects with TextKit](https://developer.apple.com/videos/play/wwdc2013/220/)# PaperIn college, I was lucky to co-author a paper with my research advisor and friend [Moorthy](http://cs.rpi.edu/~moorthy/). It's about Yelp reviews. You can read it [here](https://arxiv.org/abs/1407.1443).
Site Info
This site is a TiddlyWiki - a living interconnected hypertext document that organically grows as I add to it. This site is not a blog.I keep a "main" TiddlyWiki file for all my public and private things. Some special scripts ingest this and turn it into the website you're seeing now.For notes on how the old page worked, check Old Site Info.
Now
* Designing the 3D version of this wiki (see 3D Scene)* Teaching myself about [zellij](https://zellij.dev)* Watching Movies and rating them* Odd-job home repairs using strange parts and methods* Homelab setup
3D Scene
Experience this wiki... in 3D!(also works on Apple Vision Pro)Undefined widget 'phajas.3d.scene'
Notable People
Notable people I have taken photos with.
*
* [John Voorhees](https://johnvoorhees.co/) 2025
*
* [Gary Stern](https://en.wikipedia.org/wiki/Stern_Pinball) 2023
*
* [Merlin Mann](https://en.wikipedia.org/wiki/Merlin_Mann) 2020
*
* [John Roderick](https://en.wikipedia.org/wiki/John_Roderick_(musician)) 2020
*
* [Redfoo](https://en.wikipedia.org/wiki/Redfoo) 2017
*
* [Merlin Mann](https://en.wikipedia.org/wiki/Merlin_Mann) 2016
*
* [Will Wiesenfeld](https://en.wikipedia.org/wiki/Baths_(musician)) 2016
*
* [Justin Pierre](https://en.wikipedia.org/wiki/Justin_Pierre) 2010
*
* [Richard Stallman](https://en.wikipedia.org/wiki/Richard_stallman) 2008
Aesthetic
My inspiration. I like the look or feeling of these.
Cool Sites
This is a list of cool sites that you should check out, un-alphabetized- [buzzert.net](https://buzzert.net)- [max.town](https://max.town)- [vivekseth.com](https://vivekseth.com)- [zanneth.com](http://zanneth.com)Do you want your site on this list? Email me.
2025-10-27 Optimizing sleep around Claude Code
[This article](https://mattwie.se/no-sleep-till-agi) is very cyberpunk:> What if I sleep like a sailor in order to maximize my Claude usage limit?> So I did.> And so far, it's worked. Depending on how I use Claude (or how Claude uses me?) I run out of tokens on the Pro plan in 1 - 3 hours. This typically gives me time for a nap that's about 2 or 3 hours, which is enough to even get a little bit of REM sleep.Planning sleep around the AI. What a time to be alive!
2025-10-27 First Kid (film)
Clsssic feel-good 1990s film. I really liked some of the retro UI and chat programs. Sinbad was funny and likable.
2025-10-20 Little Giants (film)
This movie was sweet. A classic underdog sports tale, with Rick Moranis and Ed O'Neill. This movie had classic 90's optimism.
2025-10-19 Live Stream From the Namib Desert
Cool [video stream I found](https://www.youtube.com/watch?v=ydYDqZQpim8) on Hacker News:
2025-10-17 Thanks, Claude Code
I'm really busy in my day-to-day life, and my attention for free-time projects is more scarce now than it was a few years ago. This is due to very positive changes in my life.I love programming, and I'm happy that a tool like Claude Code exists. What's fascinating about this tool is I'm not using it to _replace_ the work I'd do usually, but I'm using it to do _more_ than I would usually. Just like a stool can help you reach a higher area, and a car lets you drive to further places, claude lets me reach further out and try new things. Writing demo experiences for ancient game consoles, updating my neovim config, and writing new shell scripts for me.It's not all hype, but it's not all nothing either.
2025-10-14 The Invention of Lying
This movie was cute, but a little bit on the nose.Ricky Gervais and Jennifer Gardner are great actors, and it was fun to see Louis C.K. in a film.But I still couldn't get over how insincere and raunchy this film was.
2025-10-10 Tron: Ares (film)
This movie was so-so. Not many of the characters were likable, and there were a few too many (there were several characters with 1-2 lines, which could have been done by a more main character filling approximately the same role).The visuals were great, especially when Jared Leto's character enters the 1980's themed area. The skin tones and 3D aniamtion were perfect, and even the stuttered animation of him getting into the light cycle. I really enjoyed that touch.Movie is a very low 3 for me. Soundtrack was so-so - I dig Nine Inch Nails, but nothing beats Daft Punk for me.
2025-10-09 Universal Soldier (film)
Interesting movie. It was a bit too gory for me, but I enjoyed the plot and the techno soldiers. It's cool they were able to get Val and Dolph in the same film.This concludes my "Soldier" movie run (alongside Soldier (film) and Small Soldiers (film)).
2025-09-27 Windy City Heat (film)
This movie was wild. Almost like it was from another dimension. Recommended by a good friend, this movie follows some friends on an epic prank - convincing a friend for _more than a year_ that they're starring in a fake film.The movie's worth it alone for the scene where they're going to the premier. It was hilarious.
2025-09-12 Daylight (film)
This was a fun disaster movie. Sylvester Stallone is great as usual, and the plot was interesting. It was a bit more emotional than I would have hoped.
2025-09-08 Wolfs (film)
This was a pretty good movie. Reminded me of a heist movie or other films with competence as a core theme.
2025-09-04 The Big Bus (film)
I recently saw this film with some very good friends. The Big Bus is about a big bus that's going across America, from New York City to Denver.This movie was great! It was hilarious and had good set pieces. It reminded me a lot of "Airplane". I am going to watch it again (making this a 5 - check out the Ratings system if you have questions).I was really tired while watching this movie, but still enjoyed it.
2025-08-30 Soldier (film)
This was a fun action movie, but it had a somewhat boring story. The plotline was predictable (my friends guessed it very accurately). It was still fun, and takes place in the Blade Runner universe!
2025-08-27 "Don't forget to subscribe"
A quote from [@tomgara](http://farside.link/twitter.com/tomgara) in [a tweet](https://farside.link/twitter.com/tomgara/status/860938163526799362)> My friend's toddler babbled "don't forget to subscribe" as he was put to bed. Kid watches so much YouTube he thought it means "goodbye"
2025-08-25 Small Soldiers (film)
This movie was great! Awesome casting. Phil Hartman's scene with his new big screen TV is a highlight - "no no, it's the chroma, the skin tone is all off".
2025-08-25 The Long Kiss Goodnight (film)
I couldn't finish this. Samuel L Jackson was great, but the writing was abysmal and the pacing was glacial. I was really hoping this would be better!
2025-08-16 Camera buttons in the sidebar
As I wrote about in TiddlyWiki Lightning Talk, I have a sidebar on my Mac that renders part of my wiki. It's a bespoke "heads up display" (it'd be fun to turn this into a plugin some day) that lets me keep an eye on things. I use it for the time, date, weather, weather radar, calendar, a handy place to launch shortcuts, some widgets, etc.I've long had a preview of some cameras around my house there. I made some enhancements to this today with $:/phajas/macros/mpv_button. Now I have buttons for the cameras. They look the same as regular previews, but when I click them, they open the camera feed in mpv.
2025-08-16 The trend of external displays
It seems like there's a recent trend of external displays for mobile phones or handheld gaming consoles. I was not aware of this trend until the last few days, so I thought I would write about it.First, a colleague sent me [this neat Mac mini project](https://www.yankodesign.com/2025/05/05/diy-portable-mac-mini-uses-off-the-shelf-parts-no-soldering-required/) with an external wide format display.Second I saw [this post by Lon Seidman](https://blog.lon.tv/2025/08/16/a-company-tried-to-bribe-their-way-out-of-a-negative-review-the-d-deng-scam/) talking about how a seller on Amazon tried to pressure him into leaving a positive review. The product was an external display for a phone for selfies.Finally, I saw [this video from Retro Game Corps](https://www.youtube.com/watch?v=CL6wJuwrgPI) that shows off an external display for a handheld game player.Kinda neat!
2025-08-06 The Impact of CD-ROM
I grew up alongside the personal computer. During my childhood, there was huge excitement over CD-ROM.CD-ROM offered dramatically more storage than before. It let you purchase huge media archives and libraries, and store them on very inexpensive-to-produce media. We had a copy of [Encarta](https://en.wikipedia.org/wiki/Encarta) on CD, and my dad had [Dark Forces](https://en.wikipedia.org/wiki/Star_Wars:_Dark_Forces). I remember it seeming like an explosive change. Recently, I quantified it, and verified my feeling.To investigate this, I made a table of every five years starting in 1985 and went in 5 year increments. I researched modem bandwidth (commonly called "speed"), internal storage size, and removable storage size that was common at each of these points. I couldn't find citations for all of these, but I have anecdotal experience - we had dial-up in 2000, and 512GB SD cards were not uncommon in 2020.| Year | Speed Min (bps) | Speed Max (bps) | Internal Min (MB) | Internal Max (MB) | Removable Min (MB) | Removable Max (MB) | Removable Details | Modem Speed Citation | Storage Citation | Removable Citation || —— | -----------—— | -----------—— | -------------—— | ------------—— | --------------—— | --------------—— | -------------—— | ----------------------------------------------------------------------------------------------------------------------—— | ---------------------------------------------------------------------------------------------------—— | ----------------------------------------------------------------------—— || 1985 | 1200 | 2400 | 10 | 20 | 0.360 | 1.2 | 5.25” Floppy | [here](https://www.techradar.com/news/internet/getting-connected-a-history-of-modems-657479) | [here](https://en.wikipedia.org/wiki/History_of_hard_disk_drives) | [here](https://en.wikipedia.org/wiki/Floppy_disk) || 1990 | 2400 | 9600 | 40 | 80 | 1.44 | 1.44 | 3.5” Floppy | [here](https://www.techradar.com/news/internet/getting-connected-a-history-of-modems-657479) | [here](https://www.pingdom.com/blog/amazing-facts-and-figures-about-the-evolution-of-hard-disk-drives/) | [here](https://en.wikipedia.org/wiki/Floppy_disk) || 1995 | 14400 | 28800 | 500 | 1000 | 650 | 650 | CD ROM | [here](https://www.auvik.com/franklyit/blog/history-of-the-modem/) | [here](https://www.relativelyinteresting.com/comparing-todays-computers-to-1995s/) | [here](https://en.wikipedia.org/wiki/CD-ROM) || 2000 | 56000 | 56000 | 10000 | 20000 | 4700 | 4700 | DVD ROM | My life | [here](https://itstillworks.com/specifications-gateway-2000-computer-7699939.html) | [here](https://en.wikipedia.org/wiki/DVD) || 2005 | 1000000 | 2000000 | 80000 | 200000 | 8500 | 8500 | DL-DVD ROM | [here](https://www.gwsmedia.com/articles/how-internet-system-requirements-have-changed) | [here](https://forums.tomshardware.com/threads/average-hard-drive-in-2005.2210228/) | [here](https://en.wikipedia.org/wiki/DVD) || 2010 | 10000000 | 25000000 | 500000 | 1000000 | 25000 | 50000 | Blu-Ray | [here](https://www.ooma.com/blog/average-us-internet-speeds-over-time/) | [here](https://en.wikipedia.org/wiki/History_of_hard_disk_drives) | [here](https://en.wikipedia.org/wiki/Blu-ray) || 2015 | 25000000 | 100000000 | 1000000 | 2000000 | 64000 | 128000 | SD Card | [here](https://www.pewresearch.org/internet/fact-sheet/internet-broadband/) | [here](https://en.wikipedia.org/wiki/SD_card) | [here](https://en.wikipedia.org/wiki/SD_card) || 2020 | 100000000 | 300000000 | 1000000 | 4000000 | 256000 | 512000 | SD Card | [here](https://www.fcc.gov/reports-research/reports/measuring-broadband-america/measuring-fixed-broadband-eleventh-report) | [here](https://hexus.net/tech/news/storage/147428-ssd-units-sold-surpassed-hdds-2020-333m-vs-260m/) | My life || 2025 | 300000000 | 500000000 | 2000000 | 8000000 | 512000 | 1024000 | SD Card | [here](https://www.highspeedinternet.com/resources/internet-facts-statistics) | [here](https://www.mordorintelligence.com/industry-reports/solid-state-drive-market) | [here](https://trendsandbargains.com/blog/the-best-microsd-cards-in-2025/) |It's interesting to see the exponential way that computers have improved in 40 years just by seeing how these values grow. I computed averages for each year to get a sense of what the modem bandwidth, internal storage, and removable storage was.I wanted to compare the growth of all three, to assess my memory of CD-ROM. I computed and graphed the logarithm of those averages to show the relative differences. Look how huge the jump was for CD-ROM between 1990 and 1995 (the bottom burnt orange line).CD-ROM is the most transformative step-change in storage or bandwidth since the introduction of the personal computer. In just a few years, we went from 1.44MB floppies to 650MB compact discs - a 450x increase. This led to a renaissance for educational and entertainment material. To draw a comparison to the modern day, this would be like getting ~345TB SD Cards or 2250TB internal disks by 2030.
2025-08-05 Failed Adventures and Sign Modifications
The latest [Van Neistat](https://www.youtube.com/watch?v=mXlZ3GFf3PI) video (I won't ruin the punchline) reminded me very much of Richard Ankrom's [Guerrilla Public Service](https://www.youtube.com/watch?v=Clgl63CWOkM) (previously on 2024-08-01 - Link Log - a year and three days ago!). Modifying signs is really cool.
2025-07-23 The Luckiest Man in America
Another too-slow stream-optimized film. Second screen, unfortunately. The plot line in the "back office" stretched on forever, and characters' roles were not explained. David Strathairn was a highlight in this film.
2025-07-23 Starship Troopers
This movie was fun and had some great one-liners. Some of the action went on a bit long. The effects were cheesy, but I liked it.
2025-07-07 The Accountant 2 (film)
Well, sorry past Peter. The sequel was much worse than the original. The plot was winding and didn't make much sense - the motivation of the villains was unclear, the production value was lower, and Ben Affleck's voice change was very distracting (compared to the first film).
2025-06-29 Flight Risk (film)
Eh. These movies made for streaming move so much slower - they are designed for people to watch while on their phone. Characters do something and then act it out, or a shot is anticipated for a very long time.Wahlberg was a good creep, but the dialog and pacing did not match. I thought Matt Damon was creepier in *Interstellar*, and he was in it for less time.
2025-06-29 Behind Enemy Lines
Great movie. Classic 90s action, with a nice patriotic element. Owen Wilson and Gene Hackman are a great pair.Some people recommended this to me for Air April 2025. It was a very good recommendation.
2025-06-21 2025-06-21 - Happy summer solstice
Happy summer solstice - the longest day of the year in the northern hemisphere! Today the sun rose around 5:30AM. which is more than 90 minutes earlier than when it will rise at the winter solstice.
2025-06-19 Modems and Tokens
In the 1980s, modems were slow. 300 baud - that's about 300 *bits* per second (half a percent of a 56K modem!). But they had some practical utility at that slow speed. Even at a glacial 300 baud, they were about the [speed of a human's reading](https://www.vintagecomputing.com/index.php/archives/161/the-dial-up-bbs-revisited). Throughout the 1980s, speeds got faster, and were [more than 30 times faster](https://courses.cs.washington.edu/courses/cse490h1/19wi/exhibit/bbs.html) by 1987.My first memory of being "online" was on a family trip, using either a 14.4kbps or 28kbps US Robotics modem. [Dial-up hiss and all](https://www.youtube.com/watch?v=gsNaR6FRuO0). At these advanced speeds - 50 to 100 times faster than the early BBS modems - I could do more! Load images, play RuneScape, read game guides on GameFAQs. My current gigabit internet connection - more than three million times faster than those early modems - lets me stream high definition movies, have rich telepresence video calls, and play massive multiplayer high-fidelity games.Current large language models are a bit faster than human reading speed - I find Claude and ChatGPT to be around ~3x-5x my reading speed.Imagine we can grow compute capacity at the same exponential rate we grew transmission capacity, just like the fiber rollouts of the late 1990s and early 2000s. What happens when the models are 50x faster? Or 3,000,000x? What's the RuneScape, GameFAQs, and video calling of LLM-land? Sounds cool.
2025-06-19 2025-06-19
Good morning:* I've been preparing more for my upcoming excursion (more on this later). I wrote a script and had WindSurf help me do it. I'm not sure I was "vibe coding", but it was really effortless to write alongside the model.* Cleaned up the hard drive this morning. My machine's been running out of swap, so I needed to get rid of some junk.* I did a total desk "reconfigure" the other day, removing everything and putting it back. I'm happy I no longer have wires dragging down, and I've removed a lot of [kipple](https://www.urbandictionary.com/define.php?term=kipple) from my desk.
2025-06-03 The Public Domain Review
One of my favorite websites, and a great feed to subscribe to, is the [Public Domain Review](https://publicdomainreview.org/). This website features curated collections of works that are in the public domain in United States copyright.For example, check out [these lithographs of thermal springs in Yellowstone](https://publicdomainreview.org/collection/yellowstone-thermal-springs/). Isn't this great? A really neat resource.
2025-05-30 2025-05-30
* I had a nice trip to the Bay for work. I got to see some good friends and catch up.* I've been working on becoming a carnivore for an upcoming endeavor - I've been eating only meat, cheese, and eggs for about 2 weeks. Cravings for carbs are gone, so I only crave steak, bacon, and ground beef now.* I have been having fun playing with tool-use models in my free time, and seeing how I can stitch some local models together for some automated computing.
2025-05-30 Frantic (film)
I watched this film because it is featured in the Barenaked Ladies song "One Week":> Like Harrison Ford, I'm getting FranticIt was good! A fun thriller, with some exciting turns. The soundtrack is really good. Harrison Ford is a versatile actor.This was a good plane movie - it built slow, and it was fun to get into the groove. I would recommend this film.
2025-05-26 Wag the Dog (film)
This movie was really good! An entertaining look behind what makes up "news" in modern day America. The casting was great (Willie Nelson plays a charicature of himself).
2025-05-15 Screenshot Conf
[Cool conference that happened recently](https://cristobal.arquipelago.org/writing/screenshot.html).> When thinking about media that can survive millenia, I'm more confident in visual diagrams than in any kind of digital file format that depends on a working decoder to be visualized. The Rosetta Stone, through visually paired symbols, transmitted distant languages in a redundant format that could be deciphered in the far future with minimal context.I hope they post videos.
2025-05-14 Secret Mall Apartment
This movie was interesting. I was loosely familiar with the story (reminds me a bit of Guerilla Public Service, check the 2024-08-01 - Link Log).I wanted to hear more details about the space and what getting caught was like. I think the movie got caught up in social commentary. The story was well-told.Michael Townsend is an inspirational figure, and it was cool to hear about the philanthropy of the whole group throughout the film.
2025-05-08 Broken Arrow
The last movie of Air April 2025. Good cast, director, music, and some sharp dialogue. Unfortunately, this movie was just OK. It lost it for me at the ~75% mark. The film didn't ever have a chance to take a breath - the entire latter 65% of the film is one prolonged action sequence.The props were cheesy, but I didn't mind. I wished I could hear more from Delroy Lindo's character.
2025-04-25 Trying a Continuous Glucose Monitor
I recently tried a Continuous Glucose Monitor and wore it for 15 days. It was a [FreeStyle Libre 3](https://www.freestyle.abbott/us-en/products/freestyle-libre-3.html). I was trying it for fun; to learn more about myself and how productive my body's insulin response is.The insertion process wasn't too painful, but it is inserting a small needle into your arm. I inserted mine a bit above the midway point between my shoulder and elbow, so it was covered by a t-shirt. The sensor has an adhesive that kept it on reliably for the 15 day period. I showered and exercised normally.The device is low-power bluetooth and disposable. It's paired over NFC, which felt futuristic (holding my phone to the back of my arm). You pair the device with an app, but you need to use a different app if you want historical data. This means both need to be installed. You cannot export the data - no CSV, no HealthKit.I was happy to learn that my body has a great insulin response to glucose. I noticed that even after having some thing really sugary, my body responded quickly and recovered my glucose levels by administering insulin. Here's an overlapping day graph (midnight to midnight) for the sensor duration. You can see I was able to maintain my glucose within healthy levels:I recommend trying one of these sensors! A note if you want to try for yourself: Unfortunately, a monitor like this is supposed to be prescribed by a doctor.
2025-04-18 Stealth (film)
I thought this was a fun mid-2000's action movie. Good effects, good casting, and an interesting enough plot.The coolest character was Dr. Orbit. He had an awesome computer setup.Third film in Air April 2025.
2025-04-17 Flight of the Phoenix (film)
This is a remake, but I never saw the original. I really liked this movie! It was exciting and interesting. A great disaster / survival film.Dennis Quaid and Tyrese Gibson are a good pair, and Hugh Laurie actually plays a Brit.The second movie in Air April 2025.
2025-04-17 Air America (film)
The casting was great in this film, but even Mel Gibson and Robert Downey Jr. couldn't rescue it.Almost couldn't finish this one.The first movie in Air April 2025, where I watch movies about airplanes.
2025-04-12 Not Like the Movies
> If it's not like the movies> > That's how it should be*Not Like the Movies*, Katy Perry—Fiction can have a profound effect on people. Stories aren't just idle amusement - they cause emotional and physiological responses. The [brain can't tell fact from fiction](https://nautil.us/most-of-the-mind-cant-tell-fact-from-fiction-237537/). This is empirically observable - people cry at movies, or feel heartwarmed by books.Fiction can also distort your memory of real events that you experienced. The film [Dog Day Afternoon](https://en.wikipedia.org/wiki/Dog_Day_Afternoon) is based off of a true attempted bank robbery. One of the real bank robbers, [John Wojtowicz](https://en.wikipedia.org/wiki/John_Wojtowicz) (portrayed by Pacino), saw the movie after it came out. The short film [The Third Memory](https://www.imdb.com/title/tt0396251/) shows that his memory has been _altered_ by the fiction. He can't help but pantomime things from the film, and he has a manufactured memory about Nixon's role on the robbery.Movies retcon things all the time, which can exploit this property of human psychology. Did the [Chappaquiddick incident](https://en.wikipedia.org/wiki/Chappaquiddick_incident) match what happened in the film [Chappaquiddick](https://en.wikipedia.org/wiki/Chappaquiddick_(film))? I wasn't alive, but I can't think of the event without thinking of the film. The line gets blurrier for fiction that is *sort of* based off of real events (whether explicitly or implicitly).Popular fiction unfortunately creates circumstances where there are objectively good and bad characters. Harry Potter's good, Voldemort is bad, and "The Dark Side" is self explanatory. This also happens for "historical retellings", painting characters as good or bad. Most people and situations in real life are in the gray. There are not often objective "good" and "bad" sides to a conflict.I'm not against fiction - I have reviewed many fictional movies on this site - but I am against emotional and manipulative fiction. For movies, I prefer lighthearted ones limited emotional impact rather than fake retellings (or half-retellings) of real events meant to emotionally manipulate me.
2025-04-09 DEC Alpha Server Music Video
Highest+Availability+Internet+ServiceI really dig the narration and music.
2025-04-05 OpenRA - FOSS Command and Conquer
My brother recently started playing [Command and Conquer](https://en.wikipedia.org/wiki/Command_%26_Conquer_(1995_video_game)). I wanted to play with him, and found [OpenRA](https://www.openra.net).OpenRA is a FOSS implementation of the CnC engine (including other games, like Dune 2000). It runs on macOS, Linux, and Windows. There are also lots of fun enhancements, like the [Combined Arms](https://www.moddb.com/mods/command-conquer-combined-arms) mod.I never played Command and Conquer (I was more of a WarCraft / StarCraft player), but it's fun to play this with folks over LAN or the web. I recommend you check it out. Email me if you want to play together some time.
2025-04-03 Jodorowsky's Dune (Film)
This is the best movie I've seen this year.Jodorowsky's ill-fated Dune film adaptation was in some ways a boondoggle. It spent more than $1 million (in 1970's dollars) in pre-production alone, and was theorized to be 14 hours in length. Jodorowsky convinced Salvador Dalí, Orson Welles, and Mick Jagger to be in the movie. He also assembled the "dream team" of effects folks - Giger (his first time working in film), O'Bannon, Chris Foss, and Giraud ("Mœbius") - who all later worked on Alien.This is a great look at Jodorowsky the director and his efforts to make the greatest film of all time.
2025-03-30 Welcome to Mooseport (film)
A 2004 film about a mayoral election in a small town, and the last film Gene Hackman starred in.This movie felt very pre-9/11. Optimistic popcorn film. I was surprised to see Rip Torn in this movie.
2025-03-27 Dreaming in Code (2007)
This was a fun book about Mitch Kapor's successor to Agenda, "Chandler". Kapor founded Lotus. Chandler's an interesting kind of software that blends many types of personal information together. Scott Rosenberg does a great job covering the history of software (mentioning Engelbart's NLS and demo), along with the trials of organized software development.I found this bug through Joe Armstrong's [post about TiddlyWiki and Chandler](https://joearms.github.io/#2018-12-26%20Fun%20with%20the%20TiddlyWiki).If you know me IRL, ask to borrow this book! I'd happily lend it to you.
2025-03-22 Avatar: The Way of Water (film)
Ugh. This movie is really mediocre.I enjoyed the first one, as the human technology was cool. This one had some cool parts (like the spider robots), but most of it was making you feel guilty about the death of the space whales. I rooted for the humans in the first one, and I couldn't help but do the same in this one. They harvest eternal youth from the space whales.I could see myself watching Avatar 1 again, but I don't think I'd ever watch Avatar 2 again.
2025-03-15 The Commuter (film)
Really awesome movie by the director of Carry On (film), Run All Night, and Unknown (film).This movie was most similar to Carry On, and I thought that it was a better version of that movie. Neeson's a great actor, and Vera Farmiga is a perfect fit for the Joanna character.A good mystery, with some unbelievable action. Not quite as unbelievable as Carry On's car chase scene.
2025-03-11 Sprite Zero Sugar Chill (Cherry Lime)
Another soda from my sister in law (in addition to 7up Tropical). This soda tastes "cold" - due to an additive that the Coca Cola company adds to the soda. I think this is a cool, futuristic touch.The can design is OK. The blue accenting gives the "Chill" text a two-toned appearance, but it ends abruptly next to the barcode on the side of the can.
2025-03-11 7up Tropical
My sister-in-law brought me a can of this recently. I found it tasty, and fruity, but maybe a bit too "thick" on the carbonation. A nice reprieve from other sodas (or a good "cold one" to crack at the end of the day), but not a soda I'd enjoy on a regular basis.The can design is great. It's fun and reminds me of a vacation.
2025-03-02 Privacy-Preserving Redirection with Farside
A tip I use daily is to use [Farside](https://farside.link/) to browse privacy-preserving mirrors of popular sites. This is really easy to use - you prepend the link you're going to with https://farside.link/, for example:https://farside.link/reddit.com/r/whateverorhttps://farside.link/x.com/whoeverOn my Mac, I have a clipboard watcher that automatically does this for me when I copy text containing a link. On my other devices, a Siri Shortcut (trigged from a menu in my Action Button) does the conversion and opens it on Safari.
2025-02-26 Watson Grinding Chemical Safety Video
I enjoy these videos from the Chemical Safety and Hazard Investigation Board. They're informative and explain failures in systems and how to prevent them. They're well animated, even if you're not familiar with chemical safety (I'm not).The [latest video](https://www.youtube.com/watch?v=CFVUSDzHL8A) on the [Watson Griding incident in 2020](https://en.wikipedia.org/wiki/2020_Houston_explosion) is a good example.
2025-02-18 Body of Lies (2008)
Pretty good! I enjoyed this one. DiCaprio and Crow(e?) are great actors and do this well. I like how Crow is always hooked up to an earpiece, this reminds me of the early 2000s and Bluetooth headphones and earpieces.
2025-02-17 The Pentagon Wars (1998)
This was a funny movie about government waste, a relevant topic these days. I thought the acting was really good, and the story was believable. Turns out the story is true - the real protagonist served as an advisor on this film. Viola Davis and Cary Elwes were a good pair, and I'm always game for a John McGinley movie.
2025-02-14 Tufte on iPhone
[Late 2008 video from Edward Tufte on iPhone](https://www.youtube.com/watch?v=YslQ2625TR4). I haven't heard Tufte speak before, but he has some insightful commentary:> After an image is selected, the entire screen becomes content. No computer administrative debris at all.> To clarify, add detail [...] Clutter and overload are not an attribute of information, they are failures of design. If the information is in chaos, don't start throwing out information. Instead, fix the design.
2025-02-11 Turning Soldiers into Superheroes
[Exciting update](https://palmerluckey.com/turning-soldiers-into-superheroes/) from Palmer Luckey's Anduril:> As of today, Anduril Industries is taking the reins of the largest project of its kind in history: the United States Army’s Integrated Visual Augmentation System (IVAS) program.> Superman doesn’t use menus – he just sees and does> Whatever you are imagining, however crazy you imagine I am, multiply it by ten and then do it again. I am back, and I am only getting started.
2025-02-07 The future belongs to idea guys who can just do things
From [this post](https://ghuntley.com/dothings/) (thanks [Simon](https://simonwillison.net/2025/Feb/6/the-future-belongs-to-idea-guys-who-can-just-do-things/#atom-everything)):> It's been a good 43 years of software development as usual but it's time to go up another layer of abstraction as we have in the past - from hand rolling assembler to higher level compilers.> If you’re a high agency person, there’s never been a better time to be aliveI couldn't agree more. There are fewer boundaries today for high agency people than there have been in history. Writing personal projects with Claude and Cursor has shown me that the path forward is bright for those who seize it.
2025-02-04 Powered by TiddlyWiki
Less than a year after moving to Hugo, I'm trying a new system for this website. It's now a [TiddlyWiki](https://tiddlywiki.com).Using some scripts on a podman container running on my webserver, I can update this page *just by editing my Wiki* on any of my devices. Neat!
2024-12-01 Wild Wild West
This movie was really fun! I thought it was lighthearted, and had some really cool effects from the late 90s. It's hard to imagine this movie getting made - another Will Smith movie where he has a song with the same title.I'm a sucker for giant robot spiders.
2024-11-29 FarCry (film)
This movie stunk. The action was hard to believe, and many scenes were dubbed. I stopped watching halfway through.
2024-11-24 Jupiter Ascending
I could not finish this movie. It was just _boring_. Channing Tatum was underused, and Mila Kunis' dialogue was poorly written. I was excited about watching this after hearing them talk it up on [Blank Check](https://www.blankcheckpod.com).
2024-11-15 Now is the most important time to write
I'm part of the way through [this interview with Gwern](https://www.dwarkeshpatel.com/p/gwern-branwen) which has this awesome (and scary) part. It's basically "now is the important time to write" if you want your ideas captured by the LLMs:> If you aren't writing, you're kind of abdicating the future or abdicating your role in it. If you think it's enough to just be a good citizen to vote for your favorite politician, you know, to pick up litter and recycle, the future doesn't care about you. This is a major way to keep your contributions to the future nonzero:> I think far more than ever before. If there are values you have, which are not expressed yet in text, and if there are things that you like or want, if they aren't reflected online, then to the AI they basically don't exist. And that is dangerously close to "won't exist."I found this profound. Now *is* the most important time to write. Get a Website and write, indeed. Thanks gwern.(transcribed, of course, with [Whisper](https://github.com/ggerganov/whisper.cpp)).
2024-10-06 Noise (film)
This movie was OK. I really enjoyed the beginning - the narration and cinematography were great. It really fell off in the middle - I did not care about the protagonist's strange relationships, and found the scenes with them pretty lengthy and boring. The movie really picked up at the end.If the movie didn't have the middle segment, it'd be a 4.
2024-10-06 Blue Streak
This movie was great. Martin Lawrence is a great physical comedian. I enjoyed the plot, music, and action. "It's like that".
2024-10-02 TiddlyWiki Can Generate RSS Feeds
Here's something new I learned - [TiddlyWiki](https://tiddlywiki.com) can [generate RSS feeds](https://talk.tiddlywiki.org/t/has-anyone-generated-an-rss-feed-from-tiddlywiki/966). With some small modifications or changes to Saq's plugin, you can generate custom feeds for your site using a shell script (or a [post-update hook](https://github.com/peterhajas/peterhajas.com/blob/master/playbooks/service_tiddlywiki.yml#L17)). This can be a great way of powering your blog or other site through TiddlyWiki.
2024-08-29 Sorcerer (film)
This movie was *amazing*. Excellent music (from Tangerine Dream, [check it out](https://www.youtube.com/playlist?list=PLVC1hw9RLnoetJfeEKTWQdm50wXVN39NV)), the cast was great, and the plot was exciting.I think it's interesting that it is compared so much to Star Wars, as they came out around the same time. Where Star Wars is monotonous, predictable, and cliché, Sorcerer is different. It's subtle, nuanced, and has characters with depth. Are any of them bad? Are any of them *good*? I feel like you can see yourself in them - they feel more human.I think this is in my "top 5" movies of all time.
2024-08-26 The Sentinel (film)
This movie was fun, but not amazing. I really liked all the MacGyver stuff with hotwiring the phone. Michael Douglas is a great actor, and Kiefer Sutherland has a very gritty voice in the film.
2024-08-24 The Contender (film)
Gosh this movie was boring. People talking in offices, and eating (so much eating). The President is so concerned with legacy in a hypocritical way (the good of the country versus the good of his "swan song"). Jeff Bridges as president is constantly ordering food - I can't tell if this is supposed to be a bit or not?Also, the first scene with Christian Slater (outside a building in DC) has some obvious speck on the lens. I am surprised they went with that take.This exchange between the President and an aide made me laugh:> Did we get him a gift?> Yes sir, you did. A leatherbound "Don Quixote"> Great great, a metaphorical gift. He'll be trying to figure out why I got him that for years.Gary Oldman got into an argument with the director over politically motivated edits to the film, which I thought was interesting.
2024-08-23 Deterrence (film)
This was a really interesting movie. It's a "bottle episode" - the entire film takes place in one setting, a sleepy diner in Colorado.Kevin Pollak plays a believable president - I was impressed with his portrayal. The plot is interesting, but I won't spoil it here. I found this movie as its director (Rod Lurie) also directed The Last Castle.
2024-08-23 Unfrosted
I watched this movie with my mom. I thought it was _fine_, but nothing to write home about. The jokes were very 2006-era (pre-Superbad), and many characters and jokes were just for a bit. The cast was amazing, and I can't believe all the actors that Seinfeld convinced to be in it.
2024-08-18 The Last Castle
This movie is *so* good. Robert Redford is a very believable Army general, and Delroy Lindo plays his role well (I only wish we would have seen his reaction at the end). I was surprised to see James Gandolfini as a warden (and not a crime boss).
2024-08-16 National Treasure
I think I last saw this movie *when it came out* in theaters.I liked this movie. It was a bit campy, and a very "comfy" film. Lots of great lines ("I'm going to steal the Declaration of Independence"), and a fun cast. I forgot that Jon Voight and Sean Bean were in this movie.I would watch this movie again. It was fun.
2024-08-15 The Nice Guys
This movie stunk. It had degeneracy, a not-great plot, and was generally unenjoyable. I was surprised about that given the cast. I would not recommend this to anyone.
2024-08-14 The Accountant
Fun movie with some good action and an interesting story. I predicted some of what was going to happen, but it was still entertaining. Excited to see the sequel - I would recommend this movie.
2024-08-12 Deceptive Practice: The Mysteries and Mentors of Ricky Jay
Interesting film about a great close up magician and the people who inspired him.I was most taken with how *everything* in Ricky's life revolves around magic. His youth, his fun, his employment.There's a younger protege of Ricky - Michael - who shares an anecdote about a magician that he was touring with. He was older, and Michael had gone out on the town. When he came back to the hotel, the magician was in the dark on his bed and dong a card trick with a deck of cards in the air. I loved this story - what a great commitment to your craft!Heard about this through Merlin Mann on a podcast.
2024-08-06 JFK
Really great movie from Oliver Stone. Tommy Lee Jones is *excellent*. Kevin Costner also stood out. This type of historical drama is really exciting. I watched the 3.5hr Director's Cut, which was very good and interesting.
2024-08-01 Gleaming the Cube
Fun movie about skateboarders in Los Angeles and a mysterious death. Christian Slater was a great skater (and looks so young), and I see Richard Herd as a darker version of his role as Wilhelm in Seinfeld.I enjoyed the music in the film, the ambient synth and darker atmospheres.
2024-07-26 The Rock 1996
Great action movie - an absolute classic. Nicolas Cage plays a very Nicolas Cage character. Sean Connery is a great escaped convict, and I especially liked John McGinley (one of my favorite actors - I didn't know he was in this one).
2024-07-23 The Beekeeper
Enjoyable action movie with Jason Statham. I enjoyed the plot - a guy wronged by a tech support scam - and found it entertaining and surprisingly deep.I am not sure I would watch it again, but I would recommend this movie to others.
2024-06-19 Per-Tiddler Custom CSS Styling
I really enjoy how extensible TiddlyWiki is. You can easily modify the tool to suit your need.One thing I found myself doing with my notes is wanting to style tags or tiddlers individually. For example, all tiddlers tagged "Public" show up with a faint green hue to remind myself that they're public and readable by anyone. Tiddlers tagged "phajas" (generally all my "personal" or meta tiddlers) get an orange top line.Rather than do this manually with stylesheet tiddlers, I wrote a utility tiddler that handles this **automatically**. Here it is:
\whitespace trim<$list filter="[is[tiddler]]"><$list filter="[<currentTiddler>fields[]prefix[css]!suffix[css]]" variable="field"><$letCSSPROP={{{ [<field>search-replace[css-],[]] }}}VALUE={{{ [<currentTiddler>get<field>] }}}>[data-tiddler-title="<<currentTiddler>>"] { <<CSSPROP>> : <<VALUE>>;}.tc-tagged-<<currentTiddler>> { <<CSSPROP>> : <<VALUE>>;}</$let></$list></$list>(put this in a Tiddler tagged $:/tags/Stylesheet).In any tiddler or tag where you want custom styling, add a css- prefixed field with the value. For example, adding this to a Tag tiddler:css-background-color: {{!!color}}33will add a partially translucent background matching that tag's color. Notice how we can transclude the color field. You can also impress your friends by adding:css-font-family: Papyrusto a tiddler to give it some swanky styling.
2024-06-19 Taking Care of Business
I discovered this movie in a search on Wikipedia for the term "Filofax". The [Filofax](https://en.wikipedia.org/wiki/Filofax) is a personal organizer binder (an oldschool [hipster PDA](https://www.43folders.com/2004/09/03/introducing-the-hipster-pda)). The core plot of this film is a businessman losing his Filofax to an escaped convict (played by James Belushi) who lives the high life.I found this movie to be fun - an 80s comedy that hit all the notes. It was wild to see Gates McFadden and John de Lancie in a movie together (outside of Star Trek: The Next Generation).This movie also showed me the expansive Filofax community. There are [Filofax blogs](https://philofaxy.blogspot.com), YouTube videos, and more. I think that the film licensed the brand - it was called "Filofax" in its UK release (Filofax is a UK company).
2024-04-03 ISO 8601 - The Superior Date Format
I *really like* ISO 8601. When I was in school, we learned the MM/DD/YYYY date formatting scheme:04/03/2024This is a strange choice. It's written out of order in terms of the size of each date component (medium, small, large). The DD/MM/YYYY system is slightly better:03/04/2024Unfortunately, it's confusing with the MM/DD/YYYY system (is that April 3rd, or March 4th?) and in the wrong order (it goes small, medium, large). And what's with the slashes?[ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) solves all this. An ISO 8601 date looks like this:2024-04-03There's no ambiguity here. It's large, medium, small. There are no pesky slashes to mess with your file naming scheme. You can alphabetically sort a list of them trivially to order ascending or descending, too.
2024-02-13 Treadmill
Early last year, I got a treadmill[^thisone] that I can easily roll under my desk.The treadmill is great. When I'm feeling ambitious, I wake up a few hours earlier (it helps to go to bed a few hours earlier) and hop on the treadmill. I throw on my headphones to stream [soma.fm's "The Trip"](https://somafm.com/thetrip/).Then I use the computer. I program, write in my wiki, or surf the web. Soon, 2 hours has elapsed and I've burned 600 active calories.[^thisone]: [This is the treadmill](https://www.amazon.com/RHYTHM-FUN-Treadmill-Folding-Portable/dp/B07V7F8QYK) I got. No endorsement besides "It still works 11 months later after moderate use".
2024-02-13 Predator
A classic action film. Arnold Schwarzenegger stars alongside the late Carl Weathers. I didn't know that Arnold's famous "get to the chopper" line was from this film. The effects weren't terrible, and it kept mostly away from jump scares. The "Predator vision" thermal effects were cool.I learned that Kevin Peter Hall, who portrayed the Predator, could not see in the suit and had to memorize where he was walking.
2024-01-27 Bye, Nitter
I read today that [Nitter](https://github.com/zedeus/nitter) is [going offline](https://nitter.d420.de/) due to changes at The X Platform blocking the service.This is unfortunate. Nitter is a pillar of an alternate internet, not powered and funded by surveillance and megabytes of scripts. I like it so much that I have a [clipboard watcher](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/link_replace.lua) on my computer (and a Shortcut on my phone / pad) to do replacement so I can use a Nitter instance.I'll miss Nitter. Thanks for all the fast pageloads and low distraction. I've removed nitter from the Internet Independence page.
2023-12-31 New People Page (and belated Merry Christmas)
I have added a new page of notable people I have taken photos with.Also, I am a bit late, but Merry Christmas to my readers! I hope you had a wonderful celebration.
2023-12-22 The Simulation Hypothesis and Entropy
[buzzert recently shared](https://buzzert.net/posts/2023-12-20-you-are-living-in-a-computer-simulation/) some thoughts on the [Simulation Hypothesis](https://en.wikipedia.org/wiki/Simulation_hypothesis). I'd like to expand on this, and offer another reason why our reality may exist.The Simulation Hypothesis is frustratingly likely. I am confident that we will one day simulate our ancestors (and have already done so in crude ways with computer games). If that's possible, it's very likely that we're not the first simulated reality. We're probably thousands of realities deep. It's simulations all the way down.I hate claims that are not falsifiable. They're impossible to argue against. There are many "scientific" claims about our planet that are not falsifiable due to the lack of a second earth. Perhaps one day we can run simulations of "second earth" scenarios to prove or disprove these claims[^1]. It seems like the simulation hypothesis *is* falsifiable (we've unintentionally tried to falsify it). If I were trying to prove we didn't live in a simulation, I'd look for attributes I would expect of a base reality:* Determinism, instead of floating-point-style phenomena that [changes based on whether it is observed](https://en.wikipedia.org/wiki/Copenhagen_interpretation).* Unbounded interactions with reality, rather than [arbitrary upper limits on some interactions](https://en.wikipedia.org/wiki/Speed_of_light).I would not want us to prove we live in a simulation. Causing an exception to be thrown, or bumping our universe's ranking in some parent reality's version of top, would draw attention. Some parent reality human (PRH) sysadmin in parent reality may restart the process or run garbage collection. It's possible this already happened in the past and led to cataclysmic events (such as the Great Flood).I think our simulation was built as a way to escape entropy for the PRHs. Entropy is the anticlimactic end to the material universe. It's a lukewarm heat death of nebulas of nothing - the cosmos idling a bit above 0 kelvin. If the PRHs' computers are fast enough, they can simulate reality (at a less-accurate resolution) faster than real-time. This would let them escape the inevitability of entropy. The PRHs can buy themselves time - in a less-accurate representation of the universe - by placing themselves in our reality. They would need to exist in our reality to outrun entropy and perpetuate their existence. Perhaps the PRHs are the "UAP" phenomena.Thanks for reading. If you found this interesting, please write about your thoughts on the Simulation Hypothesis.[^1]: Perhaps our reality helps examine claims in parent reality.
2023-11-27 The Manchurian Candidate
My Denzel kick continues. Great movie. Creepy and well acted. Denzel Washington plays his role perfectly as Marco. Meryl Streep is a terrifying combination of 21st century American Deep State politicians. I only wish Jon Voight and Jeffrey Wright were onscreen for longer.Tina Sinatra co-produced this movie, which provides continuity with the original. Marco and Shaw's characters are also largely reused.
2023-11-04 The Taking of Pelham 1 2 3
This is the third and most recent film of the same title and rough storyline. Great action movie with Denzel Washington and John Travolta. The action was well paced, and the NYC subway system is a great set to have a hostage negotiation film. Travolta feels like a loose cannon, and Denzel's character is very believable. There's a scene near the end where Turturro gives Denzel a thumbs up that felt a _bit_ cheesy (I laughed).The directory, Tony Scott, directed *another* train movie also starring Denzel Washington that came out less than 18 months later ("Unstoppable").
2023-07-30 Matchstick Men
An excellent movie about an obsessive-compuslive con-man. The soundtrack and cinematography are great. Nicolas Cage and Sam Rockwell are a great pair.No trivia about this one, other than it was directed by Ridley Scott.
2023-07-29 Being There (1979)
A film about a simpleton who climbs the social through metaphor and platitudes. Peter Sellars is excellent in it, and the film has great pacing. This movie was very funny. The humor is witty and well-timed. Melvyn Douglas plays a great dying aristocrat.Fun trivia I learned about this movie: there's an outtake of Sellars shown during the credits that he disliked being in the film. He thought he lost the Oscar due to its inclusion.
2023-07-25 Taking a Break from Logging Food and Drinks
I have written a lot about logging food and drinks. I've decided to take a break.Logging food and drink no longer causes me joy. I don't do analytics on the data, and it feels like a burden to be using my phone so much. I'd obsess about the calories eaten, and hoard them like a resource. I also started to find it to be unfulfilling and futile. Will I still be logging food if I make it to 50? I don't think my life is defined by a CSV file (well, at least not one I've got write permissions to).If anyone's interested, I'd be happy to share CSV files of ~5 years of food and drink logging. Send me an email if you'd like this data.
2023-07-21 Coke Zero Ultimate
I love trying new sodas. My wife recently found [Coca-Cola® Zero Sugar Ultimate](https://us.coca-cola.com/products/coke-creations/league-of-legends-ultimate-limited-edition-soda-zero-sugar) at the store. It's good! It tastes like a bit of a berry-infused Coca-Cola Zero (but definitely not like any of Coca-Cola's cherry flavors). The marketing for this product centers around it being the "+XP" flavor.It kind of tastes like gaining experience points in a game. It's nice to enjoy a product featuring aspartame in the aftermath of a declaration about [how bad it may be for you](https://www.who.int/news/item/14-07-2023-aspartame-hazard-and-risk-assessment-results-released). I think this really *does* make it the "Ultimate" Coca-Cola Zero Sugar.I look forward to more Coke Creations products!
2023-07-18 Safe
Haunting film about a woman who descends into madness due to an "environmental illness". I found the film haunting. The long shots really added to the suspense and eerie feeling. Carol feels so distant and alone. I loved the 90's aesthetic and furniture.Fun trivia I learned about this movie: the director intentionally kept the shots wide to increase the emotional distance from the characters.A friend pointed out that this has strange parallels to modern psychosomatic ailments.
2023-07-14 Coding Machines
This is a short story I read in college. I highly recommend reading it. [Here's the link](https://www.teamten.com/lawrence/writings/coding-machines/).I lost the link more than 10 years ago, and have thought about it occasionally ever since. I'm happy to have found it again.
2023-07-10 Excel Forensics and Soft Science Research
I love stories about Microsoft Excel, especially when they involve scientific misconduct. From [Data Colada](http://datacolada.org/109) (via [Bruce Schneier](https://www.schneier.com/blog/archives/2023/06/excel-data-forensics.html)):> Two different people independently faked data for two different studies in a paper about dishonesty.They found evidence *in the Excel document*:> A little known fact about Excel files is that they are literal zip files, bundles of smaller files that Excel combines to produce a single spreadsheet...> CalcChain tells Excel in which order to carry out the calculations in the spreadsheet...> Analyses of calcChain for the 5 other out-of-sequence observations similarly support the hypothesis that an analyst (manually) moved observations from one condition to the other. Click the links below to see themI am suspicious of modern published research in "soft" fields like these. A social psychologist and 269 co-authors repeated studies where they were unable to replicate [more than half](https://www.science.org/doi/10.1126/science.aac4716?siteid=sci&keytype=ref&ijkey=1xgFoCnpLswpk) of the results from 98 papers found in psychology journals. The rates of hypothesis acceptance in "softer" fields [is unsurprisingly higher than in other disciplines](https://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0010068&type=printable).
2023-07-09 Heist
This was a great movie. Entertaining and engaging, the plot had some great Oceans-esque misdirection. Gene Hackman is a convincing about-to-retire thief. Delroy Lindo gave a great performance. Sam Rockwell does a great job as the deadbeat nephew of Danny Devito (this was a hard casting choice to believe). My favorite character was Ricky Jay's - he cleans up messes (even if that means jumping in front of cars).Fun trivia I learned about this movie: the director (David Mamet) cast his wife (Rebecca Pidgeon, who is great in the roll) in it.
2023-07-08 Main Characters and NPCs
Being a main character is where someone leads their life as though they're the main character in a story. This is good when it lets someone feel agency and autonomy in their life. It's a solution to being an NPC - a non-player character. An NPC is even worse than a main character. They go through life on auto-pilot, and talking with them feels like a closed dialog tree with an NPC in a game. "Main character" is generally considered an insult. It applies to the outspoken and interesting, but also jerks - the kinds of people who talk during a movie, play music in public places, or yell at waitstaff. "NPC" is also an insult - it's like you're an automaton with no agency.It's interesting that our society considers main character an insult. If you are too confident, you need to stop and stay in your lane. But not too much - you don't want to be an NPC. This encourages you to be happy with being in the middle of the pack - not too outspoken, but not too docile.More people could stand to be proactive main characters rather than coasting at the tip of the personality curve. The most interesting people *are* the main characters.
2023-07-08 Moving to Hugo
I've switched this blog to use [hugo](https://gohugo.io/). I got frustrated with my existing static site generator, and wanted something easier to extend.This took an evening to do. I wrote a fun macro to port all my old PT-dates into nicely formatted ones, redid the frontmatter, and updated the CSS. The site should be functional - please let me know if you find any dead links.I apologize to existing readers whose RSS feed may have duplicate posts.
2022-12-18 Peterometer
I've written a few times on this site about the Peterometer, my name for a quantified-self dashboard.Over the recent Thanksgiving holiday, I worked on [a new version of the Peterometer](/peterometer/) that I'm ready to share.# InspirationThe site is themed after the visuals in the 2013 film [Oblivion](https://en.wikipedia.org/wiki/Oblivion_(2013_film)), which is a great movie with excellent futuristic UI (and music). I found [a page](https://gmunk.com/OBLIVION-GFX) by one of the visual artists explaining how they built the UI for the movie. I like the clean lines, simple colors, and graphs. I used this as inspiration for building the website itself - a cool futuristic font, a neat color palette, and 3D graphics animating in a subtle way.I got feedback from friends and family - thanks to [James](https://buzzert.net) and [Charles](http://zanneth.com) for pushing me to use a consistent palette, and thanks to my sister for pointing out that my previously chosen palette was ugly.I listened to the [TRON: Legacy soundtrack](https://en.wikipedia.org/wiki/Tron:_Legacy_(soundtrack)) while working on this site.# The DataI log a lot of data about myself:* Health data automatically through my watch, which I've worn since April 2015* Food, which I have logged since March 2019* Hydration, which I have logged since December 2018It's not hard or irritating for me to log when I eat or drink, and it makes me more mindful of what I *do* end up ingesting.The site is populated by the [Health Auto Export](https://www.healthexportapp.com) app, which runs in the background on my phone. It takes my HealthKit database and periodically slurps up the last 7 days of data and sends it to the website. I like this because I don't have to think about the site at all - I just log data like I normally do, and it shows up on the Peterometer after a few days. I like that the Peterometer fits seamlessly into habits I've already built.# The SiteI use the [Three.js](https://threejs.org) library for rendering the 3D data. I wrote some code to line up Three.js objects with DOM elements, which made it easy to use flexbox to position the elements of the site. The site is responsive to window size changes.# Next StepsI have a 3D scan of my body that I'd like to add to the page. I wish I could use a tool like ffmpeg to downsize the model, make it low-poly, and put it on the site. If you know how to do this, email me!I would also like to have a display in my home dedicated to showing this information. It would be nice to see this as a kind of "Peter Health Dashboard" throughout the day, and it may end up influencing my behavior.
2022-07-15 Avoiding Ads
I hate ads. I don't like watching them, I don't like seeing them, and I don't like hearing them. The attention economy is very sad and I want no part of it. "Ethical ads" are about as oxymoronic as "healthy cigarettes". A [friend](https://buzzert.net) recently told me that advertising [reduces activity in the decision-making parts of your brain](https://www.sciencedaily.com/releases/2011/09/110920163318.htm).Funnily enough, the more visual ads are, the easier they are to avoid. Here is how I avoid most advertisements.# Avoiding Audio AdsThis one is easiest to set up. Most podcatchers support a different "Skip Forward" and "Skip Backward" duration. Everyone I know who listens to podcasts has these set to "Skip forward 30 seconds" and "Skip backward 15 seconds". Each time you hear the start of an ad about a great new mattress (that the hosts only ever have in their guest room), or a non-FDA approved CBD vendor, you skip forward 30 seconds. You keep pressing this until the show - the thing you're there to listen to - comes back on, and then you back up by 15 seconds until you're between the ad and the show.Usually this means you're still subject to "thanks to our friends at wherever" narration, perhaps with a coupon code, but it's better than listening to the whole ad.# Avoiding Web AdsThis one takes a bit more effort, depending on how far you want to go. I use ad blockers (extensions that run on your device) to block web ads. These involve filters or rules to omit content from webpages before it is rendered (or in some cases fetched). I use 12+ of these on my devices.I also run [pihole](https://pi-hole.net) on a computer in my house, and route all my internet traffic through it. This filters out content before devices fetch it by blocking the domain name resolution of advertising and analytics. This accounts for a shockingly high 8% of all domain queries on my network.# Avoiding Video AdsThis one takes the most effort to configure, but it's well worth the setup time. I love web video, but hate the ads that hosting providers and content creators sprinkle in their videos. For avoiding ads that the site inserts (usually for vacation rentals and car insurance), I use yt-dlp. This program downloads a video to your local computer, and you never need to see the pre-roll / mid-roll ads the hosting provider inserts.To avoid ads that content creators place in the middle of their videos (for VPN services and wallets, usually), I use the –sponsorblock-remove flag of yt-dlp. There's a community-maintained database of ad segments of videos called [SponsorBlock](https://sponsor.ajay.app). The –sponsorblock-remove flag hits this database, finds the time codes for the ad segments, and then *stitches them out of the video file*. This feature is awesome, and there's a [list of the different types](https://wiki.sponsor.ajay.app/w/Guidelines) of video segments that SponsorBlock can stitch out.I've mapped my invocation of yt-dlp to a simple hotkey, so with one keypress I can download and watch (ad free!) any video link in my clipboard.—I hope this article was helpful for avoiding ads in your day-to-day life. These techniques help me move through the cloud of engagement metrics and sketchy tracking, and towards a place where I own my time and attention.
2022-06-02 The Recursive Power of TiddlyWiki
I recently learned about [TiddlyWiki](https://tiddlywiki.com). It's wiki software that you run on your computer.There are lots of these "second brain" pieces of software - Notion, Obsidian, vimwiki. But TiddlyWiki has some special tricks up its sleeve that I think put it into a league of its own. There are two components of it that I find so intriguing.# It includes its own viewer and editorIf I were using vimwiki (which I used to, heavily!), I'd store all my files on my computer (like in ~/.vimwiki, which I had symlinked to my NextCloud instance). But I'd need a way to view and edit those files. I used vim and Marked 2. TiddlyWiki is a self-contained HTML file. It has everything in it - the editor, the viewer, a filesystem implementation, but it's all saved to one HTML file. This is very novel - it's the ultimate portability. I can sync one file to copy my entire database, viewing experience and all. I can make copies of to back it up or try new things.# It is built in itselfThis TiddlyWiki's superpower. It is a tool that is built inside of itself. Besides a small kernel of core functionality, the rest of the system is represented as "tiddlers" - individual notes / files. The sidebar menu, the story list of tiddlers, the editor toolbar, *all of this* is represented as Tiddlers. This makes it very easy to add new functionality to these views. For example, I added an Emoji picker and indicator to all my Tiddlers in a few minutes. This can be done with the embedded powerful template language. TiddlyWiki supports key-value storage (called "fields") on tiddlers, enabling you to make your own taxonomy and relationships.To help you wrap your mind around this concept, here are things that are _just tiddlers_ in TiddlyWiki:- the menus and user interface- the stylesheets that customize the UI- the user settings (metrics, themes, behaviors)- the state of the wiki, like open tiddlers- plugins, which can contain JavaScript, CSS, and tiddlers- keyboard shortcuts, including the ability to make your ownMuch of this UI comes from use of tags, which is just another field on a tiddler. This lets you put things into the system easily. If you want a new item in the sidebar, just tag it with $:/tags/SideBarSegment. If you want something new in the view for each tiddler, tag it with $:/tags/ViewTemplate.
I found this software a few days ago, and I've already become enamored with it. I think this site might eventually become a TiddlyWiki.As they say in their [Discover](https://tiddlywiki.com/static/Discover%2520TiddlyWiki.html) page:> You've never seen anything like TiddlyWikiI agree - I recommend you [go play with it](https://tiddlywiki.com)!
2022-05-21 Declarative Home Automation
My home is powered by [Home Assistant](https://www.home-assistant.io), which is a great software package for running a smart home. In this post, I'll talk about how I'm automating my home *declaratively* rather than using an "if-this-then-that" approach.# Lighting The PatioWe have lights on our patio. I want them on if:- it's after sunset and before 9:00PM*or*- the patio door was opened within the last 3 minutes at night (if I'm going outside, or letting the dogs out)## The Classic Model: "If-This-Then-That"If you did an "if-this-then-that" approach, you might have rules like:- if it's after sunset but before 9:00PM, turn the lights on- if the back door opens while the sun is below the horizon, turn the lights on for 3 minutesWhile these rules sound simple, they have edge cases that will bite you when the cases fight each other. Imagine I'm letting the dogs out at 8:59PM. Following the above rules:1. Door opens at 8:59PM, and the lights turn on2. 9:00PM comes, and the lights turn off3. I'm out in the dark!You could solve this by introducing more state. You might add a "lights on due to time" and "lights on due to door opening" state to bookkeep when to perform actions of the automation. But what if we add another rule? For example: if the back camera detects a person or dog, turn the lights on for three minutes.Adding additional "what am I doing" state makes the complexity explode for state bookkeeping.## A Declarative Model: "Should" StateIn my smart home, I take all this input state and derive a "should be" state out of it. The patio light automation has just one rule:- If the patio lights *should* be on, then turn them on. Otherwise turn them off.I define these "should be" states with simple boolean logic in a [template binary sensor](https://www.home-assistant.io/integrations/template/). Here's the one for my patio lights: template: - binary_sensor: - name: "Patio Lights Should Be On" delay_off: minutes: 3 state: > {% set before9 = now().hour < 21 %} {% set doorOpen = states('binary_sensor.patio_door') == 'on' %} {% set night = is_state('binary_sensor.night', 'on') %} {% set people = is_state('binary_sensor.patio_person_motion', 'on') %} {% set dog = is_state('binary_sensor.patio_dog_motion', 'on') %} I have a simple [blueprint](https://www.home-assistant.io/docs/automation/using_blueprints/), binary_sensor_entity, that manages these automations for me: blueprint: name: Binary Sensor to Entity description: Tie a binary sensor (likely from a template) to an entity state domain: automation input: source_sensor: name: Source Sensor description: This sensor will be used to drive the entity selector: entity: domain: binary_sensor target_entity: name: Target Entity description: The entity to be driven by the sensor selector: entity: variables: source_sensor: !input source_sensor trigger: - platform: state entity_id: !input source_sensor action: - service: > {% if is_state(source_sensor, "on") %} homeassistant.turn_on {% else %} homeassistant.turn_off {% endif %} entity_id: !input target_entityThis makes the patio lights automation very simple: automation: - alias: Lights - Patio - Primary use_blueprint: path: binary_sensor_entity.yaml input: source_sensor: binary_sensor.patio_lights_should_be_on target_entity: switch.patio_shelly_channel_1My entire home is driven this way. I think this is easier to understand and extend than the classic way of doing Home Assistant automations. I also prefer it over [Node-RED](https://nodered.org), although I still use Node-RED for some tasks in my home (this may be a subject of a future post).I like how well this addresses the edge case described above, and how easy it is to experiment with new states driving the "should be" sensors. I tried keeping the lights on during severe weather (I have since removed this), and it only took one change to the "should be" sensor for the patio lights. These sensors are also really easy to debug - you can view them in the History section of Home Assistant.Please feel free to drop me a line if you have any feedback on this post. Thanks for reading!
2022-02-27 Pokémon Map Generator
[The generator is available on my website here](/pokemon_mapgen).I recently took a week long vacation. I love working on recreational programming projects during a vacation. It's a great chance to try programming in a space I am less familiar with.This vacation, I worked on something I've wanted for a long time: a Pokémon map generator! I've always been interested in the maps in the Game Boy Pokémon games (read more about parsing the data format and visualizing the map connections. There was something magical about exploring these areas, pouring over towns in strategy guides, and designing my own maps on paper.# Generated MapsI love looking at the maps you can generate with this. Here are a few of them that stood out to me:A Town with a CaveShop by the SeaSkyscraper By a LabMountain RouteThe Super Nintendo Room# The AlgorithmIn addition to letting you visualize maps from Pokémon Red and Blue, this site also lets you generate your own maps using a (naive) [Markov](https://en.wikipedia.org/wiki/Markov_chain)-style approach.Here's how it works:- I wrote a small python program to gather data from the [pokered repository](https://github.com/pret/pokered) in JSON format. It scrapes out the built-in maps and their metadata, the blocksets, and the tilesets.- When you click "Generate", we find all the maps in Pokémon that have the tileset you chose.- For each of these maps, we record their blocks and what blocks neighbor them. For example, if block 77 in OVERWORLD has block 12 north of it in a map, we record this. I also record the frequency that these blocks occur, but this is not currently used in map generation. These neighbors are stored in a dictionary.- Starting from the top-left, we choose a random block that is known to be used by maps with this tileset. These are just the keys for the above neighbors dictionary.- We then fill the map from left to right, top to bottom, trying to find blocks that can fit in with the constraints of the already built map. If the map is unsatisfiable, it's thrown out and we attempt again (up to 2000 iterations - and we may sometimes never find a solution). This is part of the generation algorithm that I'd like to improve and get feedback on.- Once the map is complete, we render it using the techniques described below.Note that it has bugs! I'd recommend not getting larger than 8x8 for most tilesets. Some tilesets are missing, like "DOJO" and "REDS_HOUSE".# Rendering MapsTo render both built-in and generated maps, the site uses a similar mechanism to my Emoji-based approach (although much faster than rendering all that unicode!). It parses the tileset and blocksets, and renders them using [
2021-08-01 My Custom Stream Deck Toolkit
Last September, I bought an [Elgato Stream Deck XL](https://www.elgato.com/en/stream-deck-xl). It's a USB input device with 32 programmable buttons, each with an individual display. I think the target market is video game streamers, who use it to switch cameras, control lighting, play sound effects, and do [star wipe transitions](https://www.youtube.com/watch?v=72bUheqRE5o). I don't stream video games, but I've found myself using the Stream Deck frequently with my computer. This post shows what I'm doing with it and how I built it.# Hammerspoon and hs.streamdeckI don't use the Elgato Stream Deck software. Instead, I use [Hammerspoon](https://www.hammerspoon.org), the amazing macOS customization tool I've had for years on my systems. You configure it with Lua files, and there is a module for using the Stream Deck called [hs.streamdeck](https://www.hammerspoon.org/docs/hs.streamdeck.html). This module lets you:- run a callback when a Stream Deck is connected or disconnected- react to button press-down and press-up events- assign images to buttons- set brightness# My Stream Deck Toolkit
Using the Hammerspoon support, I built a declarative toolkit for populating the Stream Deck as part of my [dotfiles](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck.lua). I define buttons [as Lua tables with simple properties like image and onClick callbacks](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/about.md). My toolkit also supports navigation stacks, scrolling, and "panels" - buttons where X and Y on the grid are important (like in the number pad and clone window buttons below). This toolkit lets me write buttons very easily, and experiment with new functionality quickly. Making it easy to iterate was essential to my success with this project. For example, the button to lock my computer is a few lines of Lua: lockButton = { ['name'] = 'Lock', ['image'] = streamdeck_imageFromText('🔒'), ['onClick'] = function() hs.caffeinate.lockScreen() end }(lock emoji added for clarity - I use the lock.fill symbol from SF Symbols on my system)# My ButtonsHere are the buttons I use in my personal configuration at home:- [Weather](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/weather.lua): loads weather from [wttr.in](https://wttr.in) (and shows a few more places when tapped)- Calendar [Peek](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/peek.lua): shows today's date and acts as a way to "peek" at my calendar. These peek buttons have some *very useful* behavior which I am proud of: - when *pressed*, they will show Calendar if it is not frontmost, or hide it if it is frontmost - when *held*, they will show Calendar _only while held_, hiding it when released These make it really easy to check my Calendar during a meeting, or quickly see what my next day looks like.- Reeder Peek: peeks at Reeder, my feed reader- [Lock](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/lock.lua): locks my Mac when pressed- [Audio](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/audio_devices.lua): shows my connected output and input devices. This helps when switching between audio devices during meetings. These buttons also show a little bar indicating the selected device's current volume (dimmed if it does not support volume) - [Media Controls](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/itunes.lua): Skips tracks. I don't use these very much- [App Switcher](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/app_switcher.lua): Pushes a grid of open apps onto the navigation stack. Each of these buttons act as peek buttons for that app- [Window switcher](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/window_switcher.lua): Pushes a grid of open windows, with snapshots and app icons, onto the navigation stack. Pushing one of these makes that window frontmost- [Home Assistant](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/home_assistant.lua): Pushes a grid of all my Home Assistant entities onto the navigation stack. This lets me control lights, switches, scenes, run scripts, etc.- [Numpad](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/numpad.lua): Pushes a panel which is a software number pad / calculator for the currently foreground app - [Window Clone](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/window_clone.lua): Pushes a grid of open windows onto the navigation stack. Selecting one pushes a panel-based live-updating version of it on the Stream Deck. This can be handy for keeping an eye on something, and lets the Stream Deck act as a slow-updating external display for a window - [Function Keys](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/function_keys.lua): Pushes a grid of software F-keys, going from F1 to F20 - Office Regular, Office Mood, Office Off: Each of these act as shortcuts to activate a specific Home Assistant scene in my office- [Shortcuts](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/shortcuts.lua): Pushes a grid of my Shortcut folders onto the navigation stack. From these, I can pick a Shortcut and run it from the Stream Deck- [Camera 1, Camera 2, Dash Close](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/camera.lua): Shows a camera feed from an external camera on my "dash" display in my office (a subject of a future post). The "dash close" button lets me close any open windows on my dash display- [Shelf A, B, and C](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/shelf.lua): lets me store anything on the clipboard into a scratch buffer and later recall it by pressing the button. Holding the button clears that bufferThe colored buttons at the bottom are [nonce buttons](https://github.com/peterhajas/dotfiles/blob/master/hammerspoon/.hammerspoon/streamdeck/nonce.lua). They show a random color and cycle between it at an interval, because it looks cool.If you like what you see, or if you end up using my toolkit, please write me an email!
2021-05-29 Just Married
2021-05-06 Detecting Whether I'm in Bed or Not
# Some BackgroundI've been learning about and using [Home Assistant](https://www.home-assistant.io) for the past few months. It's an open source home automation platform, but it can be turned into much more. It's kind of like your own personal "if-this-happens, do-that" service.At the core of the system are *entities*, which represent stuff the system knows about. Entities are prefixed with their *type*, for example person.peter_hajas, light.bedside_table, sensor.patio_temperature, or sun.sun. Home Assistant supports a suite of user-authored entities for sensors (things that feed the system data), commands (actions triggered by the system), and semantic devices (like "covers", Home Assistant's catchall for garage doors, sun shades, etc.).# Building the SensorOne of the platforms for a binary sensor (determines if something is true or false) is the [Bayesian](https://www.home-assistant.io/integrations/bayesian/) binary sensor. This lets you use [Bayes' theorem](https://en.wikipedia.org/wiki/Bayes%27_theorem) to combine observations into a sensor value.While spending some time at my home alone recently, I wanted to play with automations keyed off of whether or not I was in bed. This could be used to shut off lights and turn off appliances. I've read about some of the [bed occupancy sensors](https://everythingsmarthome.co.uk/howto/building-a-bed-occupancy-sensor-for-home-assistant/) you can build, but I wanted to see how far Bayesian sensing could get me.Here's my "am I at home in bed" binary_sensor: # Am I at home in bed? - platform: bayesian name: "peter_in_bed" prior: 0.33 probability_threshold: 0.9 observations: - entity_id: "person.peter_hajas" prob_given_true: 0.5 platform: "state" to_state: "home" - entity_id: "sensor.phajas_phone_battery_state" prob_given_true: 0.75 prob_given_false: 0.05 platform: "state" to_state: "Charging" - entity_id: "sun.sun" prob_given_true: 0.75 platform: "state" to_state: "below_horizon" - entity_id: "binary_sensor.orion_active" prob_given_true: 0.4 platform: "state" to_state: "off"These sensors are written in YAML. You describe a prior (at any given time, how likely is it this is true?), an optional threshold (only be true if the chance is above the threshold), and observations. These observations are in terms of entities or Home Assistant templates. Here's a breakdown of this sensor:- There's a 33% chance I'm in bed, represented by the prior. This assumes I spend 8 hours in bed.- I only want the sensor to trigger when the sensor is at least 90% confident. It'd be annoying if it activated at a lower threshold. This is set in probability_threshold.- If I'm at home, there's a 50% chance of me being asleep (this is a bit less true while working from home, but tracks for a typical commute schedule).- If my phone is charging, there's a 75% chance I'm asleep. I usually only charge at night, so if I'm unplugged, there's only a 5% chance of me being in bed.- If the sun is below the horizon, there's a 75% chance that I'm in bed.- If my workstation (Orion) is not active, there's a 40% chance that I'm in bed.# How Well Does it Work?I'd say it works pretty well. Some observations:- It's awesome to throw the phone on the nightstand charging pad and have everything shut off.- It stinks when I charge my phone at night and everything turns off. I might need to play with the probabilities (if my machine is logged in, there's basically a 0% chance I'm in bed, for example) or add other sensing (did another room recently see motion?) to help in this case.- I have yet to try it with multiple users :-). My wife (yes, wife! More on this in a future post) would need her own version of this sensor to enable turning lights off, otherwise I could leave her in the dark.
2020-12-30 Pre-Victorian Revival Reading
A thought that has stuck with me is this passage from [*The Diamond Age*](https://www.penguinrandomhouse.com/books/172835/the-diamond-age-by-neal-stephenson/):> One of the insights of the Victorian Revival was that it was not necessarily a good thing for everyone to read a completely different newspaper in the morning; so the higher one rose in the society, the more similar one's Times became to one's peers'.I think about this a lot when it comes to [the news](http://www.aaronsw.com/weblog/hatethenews). In the Stephenson *Diamond Age*-sense, I strive to read like the pre-Victorian Revival (or lower-status) folks.Thanks to the power of feeds, I have tailored my reading experience exactly to my liking. As I read more, I end up collecting feeds of people's writing I find interesting (from friend recommendations, Hacker News, and other sources). Each time I discover a new feed, I do a deep dive on the page contents to come up to speed. As I get more feeds, I find myself reading aggregators less, and other sites more.I find myself less inclined to habitually check for the next piece of information. This leaves more time for creative pursuits, spending time with my family and friends, and critical thinking.If you're willing to change your habits, I've found that this manner of reading can be very fulfilling.
2020-12-29 December 2020 Links
Here are the links I found this month:[Occupational Portraits](https://rarehistoricalphotos.com/tintype-occupational-portraits-19th-century/) - people posing with their tools[The Semantic Future of the Web](https://stackoverflow.blog/2020/12/10/the-semantic-future-of-the-web/?cb=1)[Cameras and Lenses](https://ciechanow.ski/cameras-and-lenses/) - Bartosz never fails to teach very effectively[Read the Olds](https://www.robrhinehart.com/read-the-olds/) - good advice[0 A.D. A free, open-source game of ancient warfare](https://play0ad.com) - I was impressed by the performance on older machines
2020-11-29 November 2020 Links
Here are some neat links I found this month:[Shooting Through Things](http://games.moria.org.uk/doom/research/shooting-through-things) - why do some shots in DOOM not land?[Origins of the youtube-dl project](https://rg3.name/202011071352.html) - the history behind one of my favorite pieces of software[Should we stop?](http://blog.spencermounta.in/2020/should-we-stop/index.html) - a wonderful piece on software[The Web's Grain](https://frankchimero.com/blog/2015/the-webs-grain/)[NeXT Timeline](http://www.kevra.org/TheBestOfNext/Timeline/TImeline.html)[Vegans More Likely To Break Bones Than Meat Eaters, Study Finds](https://www.newsweek.com/vegans-more-likely-break-bones-meat-eaters-study-finds-1549425)[Testing for divisibility by 19](https://blog.plover.com/math/divisibility-by-19.html)
2020-09-15 Balzac and Coffee
From Balzac's "[The Pleasures and Pains of Coffee](http://blissbat.net/balzac.html)":> Coffee affects the diaphragm and the plexus of the stomach, from which it reaches the brain by barely perceptible radiations that escape complete analysis; that aside, we may surmise that our primary nervous flux conducts an electricity emitted by coffee when we drink it. Coffee's power changes over time. Rossini has personally experienced some of these effects as, of course, have I. "Coffee," Rossini told me, "is an affair of fifteen or twenty days; just the right amount of time, fortunately, to write an opera." This is true. But the length of time during which one can enjoy the benefits of coffee can be extended.This is a great essay with some vivid descriptions of coffee from 1830.
2020-09-08 September 2020 Site Updates
I've made a few updates to the site that I wanted to write about:1. There is a new Internet Independence section which has some helpful tips for being more independent online.2. I added a Cool Sites page with links to cool sites. Please check it out. If you operate a site that is cool, email me and I will consider adding it.3. I made a [Pix](/notes/index.php) site with a feed of photos that I update occasionally.I hope you like these changes to the site.
2020-08-23 Get a Website
There's never been a better time to get a website!Rather than speaking your mind through a centralized service, you can get your own place on the internet to share. It's much better to have your own platform for expressing yourself and sharing your passions.1. Get Hosted Hosting is inexpensive. A simple web host can cost you less than $80 US per year. You could also use a free service like [GitHub Pages](https://pages.github.com), but I feel most comfortable with a service I'm paying for. Be sure to check the terms of use for the service before using it. It's important to understand specifically what could cause the provider to deny you service.2. Make Your Site Webpages are written in HTML and styled with CSS. While this may seem daunting if you've never written code before, it's easy to get started. Mozilla has [some good resources](https://developer.mozilla.org/en-US/docs/Learn) for learning web development. You can follow along and have a simple page up quickly.3. Do Your Thing This is the fun part! Share your passion with the world, start writing about your thoughts, ideas, and interests. Writing is really hard work (something I'm trying to work on) and having a website can be a good way to work on this important skill. I've discovered that I feel the best about my writing when I'm writing _for myself_. Writing the type of stuff *I would like to read*. This is better than whatever will get the most points on an aggregator or social site.Now is a _great_ time to get a website! If you make your own site, please write to me.
2020-08-22 Checking food expiration with StillTasty
I love websites that are great expressions of the medium. Many of my favorites do one thing well. One of my favorite sites is [www.stilltasty.com](https://www.stilltasty.com). It has a simple purpose:> How long will your favorite food or beverage stay safe and tasty? What's the best way to store it?For packaged foods, manufacturers often put expiration dates on them, but [how do they know the _exact date_](https://www.youtube.com/watch?v=qguDBXXOsWw)?I use this site while shopping or preparing meals. Here are some sample links:- [How long can you keep bananas in the freezer?](https://www.stilltasty.com/fooditems/index/16451)?- What's the preservation time for [shelf stable almond milk](https://www.stilltasty.com/Fooditems/index/19075) versus the [refrigerated version](https://www.stilltasty.com/Fooditems/index/19067)?
2020-08-09 The McDonaldland Multiverse
Do you know about [McDonaldland](https://en.wikipedia.org/wiki/McDonaldland)? It's the fantastical world of fictional characters created by McDonald's. Ronald McDonald, Grimace, Birdie, the Hamburglar, etc. These were staple characters in the 80s and 90s.I recently wondered: *how large is the McDonaldland universe?* Let's explore this question.Ronald McDonald was in advertisements with a lot of popular characters to promote the McDonald's restaurant. A notable one was [this ad](https://www.youtube.com/watch?v=CClLVbJHZZU) where Ronald and Grimace run into Mario, from Super Mario Brothers. This means Mario, Peach, and the Mushroom Kingdom are *in the McDonaldland universe*. Pretty cool! Let's see how deep this goes.Mario is a very popular character, and has appeared in games with many other characters. For example, Mario's presence in the [Mario & Sonic at the Olympic Games](https://en.wikipedia.org/wiki/Mario_%26_Sonic_at_the_Olympic_Games) series. This means the characters of Sonic are also in McDonaldland.Sonic is also very popular. In 2013, he appeared in the ["Worlds Collide" Archie comic](https://archiesonic.fandom.com/wiki/Worlds_Collide). This involved a crossover with the Capcom character, [Mega Man](https://en.wikipedia.org/wiki/Mega_Man). This means that Mega Man also resides in McDonaldland.Capcom pursued some ambitious games with their characters. A popular title was 1998's [Marvel vs. Capcom: Clash of Super Heroes](https://en.wikipedia.org/wiki/Marvel_vs._Capcom:_Clash_of_Super_Heroes) where Capcom characters (including the Blue Bomber, Mega Man) appeared alongside Marvel superheroes. All of the Marvel characters (Iron Man, Rogue, Wolverine, etc.) are part of McDonaldland.Marvel characters haven't just appeared in crossovers with their own properties. There were two comics where the characters of the Marvel universe also met with the crew of the Enterprise from both [the original series in "Star Trek/X-Men"](https://en.wikipedia.org/wiki/Star_Trek/X-Men) and [the Next Generation in "Planet X"](https://en.wikipedia.org/wiki/Planet_X_(Star_Trek)). All of Star Fleet exists in McDonaldland.The Star Trek characters were in many films, books, and comics. An important one for the McDonaldland continuity was the ["Star Trek/Green Lantern"](https://en.wikipedia.org/wiki/Star_Trek/Green_Lantern) series. This involved the crew of the Enterprise meeting the Green Lantern. Unsurprisingly, the DC Comics characters also exist in McDonaldland.Superman has fought a lot of tough enemies. One of the most difficult was published in the year 2000. He battled against [The Terminator in "Superman vs. The Terminator: Death to the Future"](https://en.wikipedia.org/wiki/Superman_vs._The_Terminator:_Death_to_the_Future). Obviously, Sarah Connor and the Terminator are also from McDonaldland.There were other comics featuring The Terminator. One put him in the middle of a triangle against two other battling foes in [Aliens versus Predator versus The Terminator](https://en.wikipedia.org/wiki/Aliens_versus_Predator_versus_The_Terminator). This means the characters of "Alien" (Ripley, Peter Weyland, the alien, and others) are in McDonaldland.The Alien franchise didn't just feature in the popular films, but also video games. An important title was 2015's [Mortal Kombat X](https://en.wikipedia.org/wiki/Mortal_Kombat_X). Here, you could play as Alien and fight Freddy from "A Nightmare on Elm Street". Freddy Krueger also exists in McDonaldland.Freddy Krueger also appeared in [Mortal Kombat (9)](https://en.wikipedia.org/wiki/Mortal_Kombat_(2011_video_game)) alongside some other characters. The roster included Kratos from God of War, another resident of McDonaldland.The McDonaldland Multiverse (also called the McDonaldland / Mario / Sonic / Mega Man / Marvel / Star Trek / DC / Terminator / Alien / Nightmare on Elm Street / God of War Multiverse) is an expansive one. To help visualize it, I prepared this DOT file which you can see here:
Click the image above to see it full-size
2020-08-03 Parsing Pokémon Red and Blue Maps
I previously wrote about visualizing the connections between maps in Pokémon Red and Blue.Next, I wanted to explore how the game's maps work in more detail. I couldn't find any documentation about how to read the map data. I spent some time understanding the format which I want to document here for anyone else looking to parse maps. Special thanks to the folks on the "pret" Discord channel whose comments I studied in an effort to understand the map format.—A quick note: the [pokered](https://github.com/pret/pokered) repository has changed since I wrote this post, and the graphics are now always in png format. As a result, you'll *need to generate the 2bpp files yourself to follow these steps. Thankfully, running make in the pokered root will generate these using rgbgfx from the [RGBDS](https://rgbds.gbdev.io) project. Here's a sample invocation: rgbgfx -o gfx/tilesets/overworld.2bpp gfx/tilesets/overworld.png—## Starting in Pallet TownWe'll use the game's starting area, Pallet Town, as an example. If you haven't played Pokémon Red and Blue, it looks like this:
This image was captured from an emulator running a compiled version of pokered
In the [pokered](https://github.com/pret/pokered) repository, individual city, route, and interior maps are stored in the maps directory as .blk files. Within the Pokémon map editing community these are known as "blockfiles".Here's Pallet Town's blockfile in hex: 524F5252 4F0B5052 52504E01 38390101 3839014D 4E083C3D 01083C3D 014D4E01 01010101 0101014D 4E017756 010C0D0E 014D4E01 74740110 3A00014D 4E010101 01775677 314D4E0A 1D1E3174 740A314D 500A6564 61616161 614FSomehow, these 90 *bytes* are what the game needs to render the starting town. But how?Pallet Town measures 20 squares wide by 18 squares tall (where a "square" is the size of the player character). Surely there must be a 20x18-element grid that tells the game "blank space, left side of house, grass, water, etc.", right? But 20 x 18 = 360. If these 90 bytes were used to encode this information, that would mean we'd be allocating 4 "squares" of information per byte, which would only allow for 2 bits-per square. This would restrict us to 4 types of squares for the game. There are more types of tiles in Pokémon maps than 4 - you can see the variety used in Pallet Town above - so we'll have to look deeper.## A Look at TilesetsThe pokered repository also contains a directory of tilesets, which is our first clue about how this system works. These are stored in gfx/tilesets. Each tileset is represented twice - a jpeg image and a 2bpp file. There are 19 of these tilesets for use cases like "house", "gym", "forest", and "overworld". Here's what overworld.jpeg looks like:In the game, you move the player character around a grid of squares. These tilesets are *not* stored in squares. Notice that each 8x8 pixel tile measures exactly *half* the width and height of an in-game 16x16 pixel square. Here's a version of the tileset above where I've drawn dividers between the tiles:For example, the infamous log (pillar? column?) that borders in-game areas is spread across 4 tiles. To save space and increase possibilities, each in-game square is made up of 4 tiles in a grid. This allows for creative combination of them to make more interesting maps.The 2bpp file is what's actually compiled into the game. This represents our tileset image data, which is stored in "2 bits per pixel" format. This matches the color support of the [original GameBoy](https://en.wikipedia.org/wiki/Game_Boy) which can only support 4 shades of gray. These are stored as 00 for white, 01 for light-gray, 10 for dark-gray, and 11 for black. These pixels are packed in 64 pixel tiles, and they are represented in a top-left coordinate system. This means the first pixel read is at (0, 0) at the top left of the tile, and the last pixel read is at (7, 7) at the bottom right of the tile.Unusually, these tile pixels are spread across bytes. So these two bytes: 00000000 11111111would *not* lead to pixels of 00 00 00 00 11 11 11 11. Instead, you'd take each bit in the first byte and combine it with the bit at its same index in the *next* byte. This example would yield 01 01 01 01 01 01 01 01. This is counter-intuitive but essential to parsing the tilesets.Because it's in the overworld, Pallet Town uses the overworld tileset. You can find this information in Pallet Town's header file in data/maps/headers/PalletTown.asm which lists it as OVERWORLD: map_header PalletTown, PALLET_TOWN, OVERWORLD, NORTH | SOUTH## Blocksets to the RescueWe still don't have nearly enough information to reconstitute a map. I got stuck here for a while. The bytes from the map blk files can't be offsets into the tileset - they're not big enough to store that data. There must be something else.I grep'd around in the pokered repository looking for what could be missing. I found a file that held the key to understanding how these maps are stored - the blockset.These blockset files live in the gfx/blocksets directory. Each tileset has its own blockset. For example, the overworld tileset has its own overworld.bst file in this directory. These are essential for properly parsing the map.Because the GameBoy is so resource constrained, the game reduces common tile combinations into "blocksets" (also sometimes called "metatiles" in the map editing community). A blockset file contains "blocks" - 4x4 tile combinations that are used in-game. Each block contains 16 bytes, where each one is an offset into the tiles from the 2bpp tileset. These are also stored with a top-left coordinate system, and are stored contiguously - block-by-block - and referenced by index.## Putting it TogetherFor me, figuring out blocksets was the missing link for understanding the end-to-end flow. We said earlier that our map, Pallet Town, measured 90 bytes despite being 20 squares wide by 18 squares tall. This is because map bytes are *block* references. So Pallet Town measures 10 blocks wide by 9 blocks tall. You can find these dimensions inside of the constants/map_constants.asm file, where they are represented as height, width for each map: mapconst PALLET_TOWN, 9, 10 ; $00Putting these parts together:1. Find its tileset in its header (stored at data/maps/headers/2. Read the tileset in as a 2 bits per pixel format file. Pixels are spread across neighboring bytes. Tiles are stored as 8x8 pixels, and read in from top-left to bottom-right. A square is represented by 2x2 tiles3. Read in the blockset, 16 bytes at a time. Each 16 byte unit is a block. These blocks measure 4x4 tiles - each byte is an index into the tileset read above. Blocksets are also read from top-left to bottom-right. Blocks measure 2x2 squares4. Read in the map file. Each byte in the map file is an index into the blockset for the block to show at that location. Maps are also read from top-left to bottom-right## Rendering MapsWhile working through this, I wrote a small program to follow the above steps and print out maps to STDOUT. Because there's no Unicode character for white / light gray / dark gray / black, I used some emoji (⬜ / 🔳 / 🔲 / ⬛) to achieve a similar look.Here's my program rendering Pallet Town with these emoji.This was a fun learning opportunity! I have a few ideas for fun projects to do with map parsing and tilesets in the future.
2020-07-04 Office Space features an N64
In the film Office Space, there's a great montage to ["Damn It Feels Good To Be A Gangsta"](https://music.apple.com/us/album/damn-it-feels-good-to-be-a-gangsta/710128784?i=710130888). There's a version of that montage [here](https://www.youtube.com/watch?v=I1L8l3LrzLA).There's something interesting in this montage, around [the 1:04 mark](https://youtu.be/I1L8l3LrzLA?t=64). Near the right side of the screen:It's a Nintendo 64!Right at the edge of the frame is part of a cartridge. Because of cropping, we can't tell what game is in the console in the standard-definition version of the film.Very thankfully, in the [widescreen version of the movie](https://tv.apple.com/us/movie/office-space/umc.cmc.6jlilk9yf1ozlv281w6rnw5pu), we can more clearly see what Game Pak is in the console:Let's enhance a bit more:It's Mario Kart 64!As we see later on in the film, the controller is plugged into Player 4's port:
2020-04-14 Visualizing Pokémon Red and Blue Connections
I love Pokémon. My fascination with the series began with the original games released in the US, Pokémon Red and Blue (I had the Blue version).In the past few years, people have been disassembling Pokémon games. You can check these out for Pokémon [Red and Blue](https://github.com/pret/pokered), [Crystal](https://github.com/pret/pokecrystal), [Emerald](https://github.com/pret/pokeemerald), and others. It's really cool to be able to compile and build a game that was such a huge part of my youth.I thought it would be fun to play with this source code, viewing these games through a new lens. A few months ago, I discovered [Graphviz](https://www.graphviz.org), a software package for rendering graphs written in the [Dot language](https://en.wikipedia.org/wiki/DOT_(graph_description_language)). Dot is a very simple language, and it's easy to filter data into its format. Graphviz includes some command line tools that can render dot files to nice human-readable output. Let's see how we can use Graphviz to visualize Pokémon Red and Blue.Inside of pokered, there's a data directory with a mapHeaders subdirectory inside. mapHeaders includes metadata about every overworld map in the game. This includes the connections between maps. For example, here is the metadata for Route 10: $ cat Route10.asm Route10_h: db OVERWORLD ; tileset db ROUTE_10_HEIGHT, ROUTE_10_WIDTH ; dimensions (y, x) dw Route10_Blocks ; blocks dw Route10_TextPointers ; texts dw Route10_Script ; scripts db SOUTH | WEST ; connections SOUTH_MAP_CONNECTION ROUTE_10, LAVENDER_TOWN, 0, 0, LavenderTown_Blocks WEST_MAP_CONNECTION ROUTE_10, ROUTE_9, 0, 0, Route9_Blocks dw Route10_Object ; objectsSo south of Route 10 is Lavender Town, and west is Route 9. We can use this connection data and some simple uses of grep and awk to generate Dot code representing these connections. The following commands are all run from /data/mapHeaders in the pokered repository. First, we use grep to see the connections: $ grep -R "MAP_CONNECTION" ./ .PewterCity.asm: SOUTH_MAP_CONNECTION PEWTER_CITY, ROUTE_2, 5, 0, Route2_Blocks .PewterCity.asm: EAST_MAP_CONNECTION PEWTER_CITY, ROUTE_3, 4, 0, Route3_Blocks ...Next, let's pipe that to awk to print the endpoints of that connection: $ grep -R "MAP_CONNECTION" ./ | awk -F" " '{ print $3 $4; }' PEWTER_CITY,ROUTE_2, PEWTER_CITY,ROUTE_3, ...We can use a second awk invocation to print these as Dot edges: $ grep -R "MAP_CONNECTION" ./ | awk -F" " '{ print $3 $4; }' | awk -F"," '{ print $1" – "$2 }' PEWTER_CITY – ROUTE_2 PEWTER_CITY – ROUTE_3 ...Undirected Dot edges are represented with the two nodes and a – between them.We can represent a strict (one connection between nodes) graph (non-directed, as these are bidirectional connections) by wrapping all these connections in a strict graph {}: strict graph { PEWTER_CITY – ROUTE_2 PEWTER_CITY – ROUTE_3 ...We can add two other options (overlap=false to avoid edge overlap and splines=true to use splines for edges) to get a better looking graph. Here's my pokemon_rb_towns_and_routes.dot generated from the above steps: strict graph { overlap=false; splines=true; PEWTER_CITY – ROUTE_2 PEWTER_CITY – ROUTE_3 CELADON_CITY – ROUTE_16 CELADON_CITY – ROUTE_7 ROUTE_9 – CERULEAN_CITY ROUTE_9 – ROUTE_10 ROUTE_8 – SAFFRON_CITY ROUTE_8 – LAVENDER_TOWN ROUTE_21 – PALLET_TOWN ROUTE_21 – CINNABAR_ISLAND ROUTE_20 – CINNABAR_ISLAND ROUTE_20 – ROUTE_19 ROUTE_22 – ROUTE_23 ROUTE_22 – VIRIDIAN_CITY PALLET_TOWN – ROUTE_1 PALLET_TOWN – ROUTE_21 ROUTE_23 – INDIGO_PLATEAU ROUTE_23 – ROUTE_22 VERMILION_CITY – ROUTE_6 VERMILION_CITY – ROUTE_11 ROUTE_24 – CERULEAN_CITY ROUTE_24 – ROUTE_25 ROUTE_18 – ROUTE_17 ROUTE_18 – FUCHSIA_CITY ROUTE_19 – FUCHSIA_CITY ROUTE_19 – ROUTE_20 ROUTE_25 – ROUTE_24 LAVENDER_TOWN – ROUTE_10 LAVENDER_TOWN – ROUTE_12 LAVENDER_TOWN – ROUTE_8 ROUTE_14 – ROUTE_15 ROUTE_14 – ROUTE_13 ROUTE_15 – FUCHSIA_CITY ROUTE_15 – ROUTE_14 ROUTE_17 – ROUTE_16 ROUTE_17 – ROUTE_18 ROUTE_16 – ROUTE_17 ROUTE_16 – CELADON_CITY ROUTE_12 – LAVENDER_TOWN ROUTE_12 – ROUTE_13 ROUTE_12 – ROUTE_11 ROUTE_13 – ROUTE_12 ROUTE_13 – ROUTE_14 ROUTE_11 – VERMILION_CITY ROUTE_11 – ROUTE_12 CERULEAN_CITY – ROUTE_24 CERULEAN_CITY – ROUTE_5 CERULEAN_CITY – ROUTE_4 CERULEAN_CITY – ROUTE_9 ROUTE_10 – LAVENDER_TOWN ROUTE_10 – ROUTE_9 ROUTE_5 – CERULEAN_CITY ROUTE_5 – SAFFRON_CITY FUCHSIA_CITY – ROUTE_19 FUCHSIA_CITY – ROUTE_18 FUCHSIA_CITY – ROUTE_15 SAFFRON_CITY – ROUTE_5 SAFFRON_CITY – ROUTE_6 SAFFRON_CITY – ROUTE_7 SAFFRON_CITY – ROUTE_8 ROUTE_4 – ROUTE_3 ROUTE_4 – CERULEAN_CITY ROUTE_6 – SAFFRON_CITY ROUTE_6 – VERMILION_CITY VIRIDIAN_CITY – ROUTE_2 VIRIDIAN_CITY – ROUTE_1 VIRIDIAN_CITY – ROUTE_22 INDIGO_PLATEAU – ROUTE_23 ROUTE_7 – CELADON_CITY ROUTE_7 – SAFFRON_CITY ROUTE_3 – ROUTE_4 ROUTE_3 – PEWTER_CITY ROUTE_2 – PEWTER_CITY ROUTE_2 – VIRIDIAN_CITY CINNABAR_ISLAND – ROUTE_21 CINNABAR_ISLAND – ROUTE_20 ROUTE_1 – VIRIDIAN_CITY ROUTE_1 – PALLET_TOWN }We can use a simple invocation of neato to produce a PDF file with: neato -Tpdf pokemon_rb_towns_and_routes.dot > pokemon_rb_towns_and_routes.pdfCheck it out:PDF file hereOK, so towns and routes are cool. Can we augment this file to include buildings, tunnels, and rooms? There are warp and warp_to markers in the files in /data/mapObjects. For example, let's look at SaffronCity.asm: $ cat data/mapObjects/SaffronCity.asm SaffronCity_Object: db $f ; border block db 8 ; warps warp 7, 5, 0, COPYCATS_HOUSE_1F warp 26, 3, 0, FIGHTING_DOJO warp 34, 3, 0, SAFFRON_GYM warp 13, 11, 0, SAFFRON_PIDGEY_HOUSE warp 25, 11, 0, SAFFRON_MART warp 18, 21, 0, SILPH_CO_1F warp 9, 29, 0, SAFFRON_POKECENTER warp 29, 29, 0, MR_PSYCHICS_HOUSE ... ; warp-to warp_to 7, 5, SAFFRON_CITY_WIDTH ; COPYCATS_HOUSE_1F warp_to 26, 3, SAFFRON_CITY_WIDTH ; FIGHTING_DOJO warp_to 34, 3, SAFFRON_CITY_WIDTH ; SAFFRON_GYM warp_to 13, 11, SAFFRON_CITY_WIDTH ; SAFFRON_PIDGEY_HOUSE warp_to 25, 11, SAFFRON_CITY_WIDTH ; SAFFRON_MART warp_to 18, 21, SAFFRON_CITY_WIDTH ; SILPH_CO_1F warp_to 9, 29, SAFFRON_CITY_WIDTH ; SAFFRON_POKECENTER warp_to 29, 29, SAFFRON_CITY_WIDTH ; MR_PSYCHICS_HOUSE ...(These _WIDTH suffixes seem to indicate the coordinates are inside of the width of the map. We'll clean them up later.)So, if we parse out the warp_to statements, we should be able to get a more complete view of the game's locations and how they connect. Let's start with a simple grep to find all the warp_to statements (run from /data/mapObjects): grep -R "warp_to " ./ .RocketHideoutB4F.asm: warp_to 19, 10, ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_B3F .RocketHideoutB4F.asm: warp_to 24, 15, ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_ELEVATOR .RocketHideoutB4F.asm: warp_to 25, 15, ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_ELEVATOR ...Next, pipe to awk to find the endpoints of the warp: $ grep -R "warp_to " ./ | awk -F"," '{ print $3; }' ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_B3F ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_ELEVATOR ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_ELEVATOR CELADON_MART_3F_WIDTH ; CELADON_MART_4F CELADON_MART_3F_WIDTH ; CELADON_MART_2F CELADON_MART_3F_WIDTH ; CELADON_MART_ELEVATOR BRUNOS_ROOM_WIDTH ; LORELEIS_ROOM BRUNOS_ROOM_WIDTH ; LORELEIS_ROOM BRUNOS_ROOM_WIDTH ; AGATHAS_ROOM BRUNOS_ROOM_WIDTH ; AGATHAS_ROOM BIKE_SHOP_WIDTH ...This is close, but includes some warps that appear to point to themselves (like BIKE_SHOP_WIDTH above). No problem - we can only print lines with ; in them using grep: $ grep -R "warp_to " ./ | awk -F"," '{ print $3; }' | grep ";" ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_B3F ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_ELEVATOR ROCKET_HIDEOUT_B4F_WIDTH ; ROCKET_HIDEOUT_ELEVATOR CELADON_MART_3F_WIDTH ; CELADON_MART_4F CELADON_MART_3F_WIDTH ; CELADON_MART_2F CELADON_MART_3F_WIDTH ; CELADON_MART_ELEVATOR ...OK, almost done. Next, let's strip out the _WIDTH text and put in edge connections: $ grep -R "warp_to " ./ | awk -F"," '{ print $3; }' | grep ";" | sed -e "s/_WIDTH" | sed -e "s/;/–/" ROCKET_HIDEOUT_B4F – ROCKET_HIDEOUT_B3F ROCKET_HIDEOUT_B4F – ROCKET_HIDEOUT_ELEVATOR ROCKET_HIDEOUT_B4F – ROCKET_HIDEOUT_ELEVATOR CELADON_MART_3F – CELADON_MART_4F CELADON_MART_3F – CELADON_MART_2F CELADON_MART_3F – CELADON_MART_ELEVATOR ...(note the leading space here - not a big deal for the Graphviz tools)Now, we'll put this all into a pokemon_rb_all.dot file (along with the connections from pokemon_rb_towns_and_routes.dot) to make a graph of all of the locations in Pokémon Red and Blue. For this invocation, I also used neato: neato -Tpdf pokemon_rb_all.dot > pokemon_rb_all.pdfThis graph is so cool! Check it out:PDF file here, dot file hereThere are so many sections of this graph with interesting details, like Victory Road leading into the Indigo Plateau and Elite Four:Or the maze-like Silph Company building:I think it's really cool how easy it is to use simple tools to see these games from a new angle. I hope to look at other aspects of these games sometime in the future.
2020-03-30 February Trip to Death Valley
In February, I had the opportunity to go on a trip to [Death Valley National Park](https://en.m.wikipedia.org/wiki/Death_Valley_National_Park) with some friends. It was an awesome time! Here’s what happened:# GearI was lucky enough to go to REI with one of my buddies, a camping veteran, before the trip. He was also the organizer of our trip to Death Valley. At REI, I secured some supplies, including essentials (sleeping bag, freeze-dried food), things I thought were unnecessary but ended up being very useful (utensils, sleeping pad), and things I had no idea you needed or wanted on a camping trip (pillow, chair). It helps to go with people who are experienced!# The Trip OutWe left at an early 5AM towards our destination. The Death Valley area is a good 6-7 hours from the Bay Area. The drive was pretty, complete with an early morning coffee pit stop in Gilroy. Onwards...# Campsite One: The Trona PinnaclesWe arrived in our first campsite: the [Trona Pinnacles](https://en.m.wikipedia.org/wiki/Trona_Pinnacles). This area looks like another planet:In fact, it’s been used for just that in movie and TV sets (Star Trek V was filmed here). It was also the setting for [Lady Gaga’s latest video](https://m.youtube.com/watch?v=5L6xyaeiV58).This is also where fighter jets do test flights, which is really cool to see up close:The area is part of [California’s BLM lands](https://en.wikipedia.org/wiki/Bureau_of_Land_Management). This made it a great spot for camping and for a fire.Along with some Ardbeg, I enjoyed some a delicious freeze dried meal: chili macaroni and cheese with beef.# Campsite Two: In The ParkAfter a nice oatmeal and some instant coffee, we pushed off to [Trona, CA](https://en.wikipedia.org/wiki/Trona,_San_Bernardino_County,_California) to stock up on some snacks and get gas. Trona is an industrial town in the middle of nowhere. My fiancé and I fell in love with it on our first visit. They mine borax and salt. I love this note from the [Trona High School Wikipedia page](https://en.wikipedia.org/wiki/Trona_High_School):> Until several years ago an annual game was played against Boron High School. Referred to as the Borax Bowl by some, the game was a matchup of two mining towns that are world leaders in producing potash and borax, minerals used in a number of products.While in Trona, we saw a motorcycle group with a dog that rode along. Cool!We took off to enter Death Valley. Rather than entering through the visitor center from California, we took a side route. We saw some amazing sites on the way in to the park:I even saw an abandoned mineshaft - cool!We then arrived at our next camp site. We set up our tents, and imbibed and ate.The night was a bit windy, but the tent I was loaned stood up just fine after some rocks were placed inside.# Campsite Three: Echo CanyonWe awoke, had some breakfast, and pushed off. We stopped off at some abandoned campgrounds and checked out a cool natural spring:We headed off to [Beatty, NV](https://en.wikipedia.org/wiki/Beatty,_Nevada) for a stop at a diner:We had to make a game-time decision about where to stay on this third night. We had thought of staying that night in a canyon, but the park was experiencing snow (in a desert no less):I was *really* hoping we would not have to call off our trip a day early. We decided to stay the night - I was happy we did - and headed off to Echo Canyon.Inside the canyon, we found a nice campsite against some rocks:We pitched our tents, and had dinner for the evening.As the night wore on, the wind picked up more and more. I awoke at around 4 in the morning to the wall of the tent covering my body, pushed by a strong wind. I figured I wouldn’t suffocate (I was getting barraged by oxygen), so I went back to bed.# The Trip BackThe next morning, after our customary breakfast, we packed up and headed back to civilization. We saw some beautiful views on our way out:We stopped at a truck stop for some food. I had a Double Quarter Pounder with Cheese - it was delicious.All in all, a great trip! I hope to get back soon.
2020-01-29 Peterometer Chapter 2: Counting Raw Eggs
*This is the second in the Peterometer series. The first can be found here.*After I felt comfortable tracking hydration, I wanted to introduce other metrics tracking into my life. I've been tracking the food I've eaten since March 2019. With less than a week of downtime, I've tracked **everything I've eaten** since that time.I track my food in the [LoseIt](https://loseit.com/) app. I usually log the food right after eating it, and I really enjoy seeing how many calories I've eaten that day.In the past year, I've also become *really* into eating raw eggs. I enjoy them on starchy foods, like ramen or rice. Kind of like my own version of [tamago kake gohan](https://en.wikipedia.org/wiki/Tamago_kake_gohan). In a given week, I'll end up eating a few meals with raw eggs.But how many raw eggs? Let's find out!# Exporting LoseIt DataLoseIt lets you export the food you've eaten on a weekly basis from their website. These export as a CSV file, which is perfect for processing and backup. If you're a Premium member, go to your "Insights" tab on the website and then look for "Weekly Summary" and "Export to spreadsheet". I export my data every 2 or 3 weeks, and collect it all in a folder on my machine. These files are numbered based on their starting day since January 1 2000: $ ls WeeklySummary6637.csv WeeklySummary6644.csv WeeklySummary6651.csv WeeklySummary6658.csv WeeklySummary6665.csv WeeklySummary6672.csv WeeklySummary6679.csv ...# Generating a master food CSVI wrote a simple shell script to combine all these summaries, remove workouts (I track these separately), and then generate a master combine.csv file with all my food in one place: #!/bin/sh # delete the combine file rm combine.csv # concatenate all the csvs, sorting echo "Date,Name,Type,Quantity,Units,Calories,Fat (g),Protein (g),Carbohydrates (g),Saturated Fat (g),Sugars (g),Fiber (g),Cholesterol (mg),Sodium (mg)" > combine.csv cat *.csv | grep -v "Calorie Burn" | grep -v "Date,Name" | grep -v "HealthKit" | sort >> combine.csvWith this, we can cat out the combined CSV file to see the food I've eaten: $ cat combine.csv Date,Name,Type,Quantity,Units,Calories,Fat (g),Protein (g),Carbohydrates (g),Saturated Fat (g),Sugars (g),Fiber (g),Cholesterol (mg),Sodium (mg) 01/01/2020,"Sandwich, Sub, JJ Gargantuan",Lunch,1.5,Each,"1,656",82.50,108,124.50,22.50,n/a,7.50,268.50,5121 01/01/2020,Cookie,Snacks,4.0,Servings,144,12,4,72,6,32,0,0,230 ...(this example highlights a problem with my use of sort in the script: 01/01/2020 sorts alphabetically before 12/01/2019)# Analyzing the food I've eatenWe can use some simple utilities to query the file. For example, how many food entries have I logged? $ cat combine.csv | wc -l 3984Wow! That's a lot of food. This averages to around 12 entries per day.We can grep for other data, like how many burritos I've had. $ cat combine.csv | grep -i burrito | wc -l 38I've eaten a burrito every 9 days or so.# Counting raw eggsBut **how many raw eggs** have I eaten? I usually log these when I eat *actual raw eggs* (when I cook an egg dish on the stove without oil I will also count it as raw eggs). Let's grep the CSV file: $ cat combine.csv |grep -i egg 01/02/2020,Egg raw,Dinner,2.0,Servings,140,9.60,12.60,0.80,3.20,n/a,n/a,372,142 01/02/2020,Scrambled Eggs,Breakfast,1.0,Each,91,7,6,1,2,0.80,0,169,88 ...This grep picked up anything with "egg" in the title, like scrambled eggs. We only want to look for raw eggs - it's simple enough to do that by modifying our grep invocation. But keep in mind the header line of combine.csv: Date,Name,Type,Quantity,...The fourth column is the *quantity*. This is how many raw eggs I actually ate. So we really want to sum that column.We can print the fourth column with a bit of awk: $ cat combine.csv |grep -i egg |grep -i raw | awk -F, '{ print $4; }' 2.0 2.0 2.0 2.0 2.0 ...and sum it with a bit more: $ cat combine.csv |grep -i egg |grep -i raw | awk -F, '{ eggs+=$4; } END { print eggs; } ' 276.75(yes, I did eat non-whole portions of eggs some days)276.75 raw eggs. That's nearly two dozen dozen raw eggs!# Raw egg consumption based on day of the weekAs a fun visualization, I wanted to see if I ate raw eggs more on a particular day of the week. I did this using some simple categorization in Numbers:Wow! Based on this, I had way fewer raw eggs on Fridays. Tuesdays and Thursdays are lighter weekdays for raw egg consumption.# Looking forward to more food analysisCounting raw egg was a fun test of the data I've been gathering for the past 10 months. I'm really excited about the other visualizations and analysis I can do on the food that I've eaten.
2020-01-04 The Platform Master
Watched [this documentary about Ulillillia](https://www.youtube.com/watch?v=QFLJEIrfx9U), the internet figure. It follows him and the small town of Minot, ND in the aftermath of the [2011 Souris River Flood](https://en.wikipedia.org/wiki/2011_Souris_River_flood). Despite it being from 2012, it was released at the end of 2019.While the film moved at a slower pace, I found some of Ulillillia's quotes from it interesting. In the documentary, Ulillillia lives with his parents:> There's very little I can do, so I don't get much enjoyment ... I definitely wish I could travel more, or see the world ... it's like I can't get out of the cage[According to this wiki page](https://ulillillia.fandom.com/wiki/Ulillillia), he has since gotten a driver's license and moved out of his parent's home to Florida.
2019-12-21 Upgrading a Nintendo Switch SD card
I own a Nintendo Switch console. Because I don't want physical games cluttering my home, I get all my games digitally. I recently started running out of room and needed a new SD card to hold my games. This path ended up being circuitous, taking me through fake flash storage, the Switch's file structure, and its operating system's treatment of Unix file attributes.# A new cardI purchased a Samsung 512GB SD card from Amazon for $65. I'm shocked at how cheap SD cards are now. This replaced my old 128GB card.Here's the old card:And here's the new card:Flash memory has never been more popular. Unfortunately, there has been a recent rise of **fake flash** memory. These are USB keys, SD cards, and solid state disks that masquerade as a larger capacity, but will lose your data or fail to read / write properly.After my new card arrived, I wanted to check its authenticity. Is this a real 512GB SD card? Or a fake?# The f3 tool[f3](http://oss.digirati.com.br/f3/) is a tool to verify the authenticity of flash memory. It stands for "Fight Flash Fraud" or "Fight Fake Flash". From the site:> I started this project when I bought a 32GB microSDHC card for my Android phone back in 2010, and found out that this card always fails when one fills it up.I installed it on my Mac with brew install f3. This installed two binaries: f3write and f3read.f3write writes contiguous 1GB files to your card until it has exhausted its space. It will also report on the write speed for this operation. You use it by running it on the path you want to write to. It will report progress when running: $ f3write /Volumes/test F3 write 7.2 Copyright (C) 2010 Digirati Internet LTDA. This is free software; see the source for copying conditions. Free space: 476.69 GB Creating file 1.h2w ... OK! Creating file 2.h2w ... OK! ... Creating file 476.h2w ... OK! Creating file 477.h2w ... OK! Free space: 1.38 MB Average writing speed: 77.17 MB/sMy card got 77MB/s, which comes out to about 2 hours of write time (this is about how long it felt). After doing the write step, you can run f3read to verify that the files made it there successfully: $ f3read /Volumes/test F3 read 7.2 Copyright (C) 2010 Digirati Internet LTDA. This is free software; see the source for copying conditions. SECTORS ok/corrupted/changed/overwritten Validating file 1.h2w ... 2097152/ 0/ 0/ 0 Validating file 2.h2w ... 2097152/ 0/ 0/ 0 ... Validating file 476.h2w ... 2097152/ 0/ 0/ 0 Validating file 477.h2w ... 1432983/ 0/ 0/ 0 Data OK: 476.68 GB (999677335 sectors) Data LOST: 0.00 Byte (0 sectors) Corrupted: 0.00 Byte (0 sectors) Slightly changed: 0.00 Byte (0 sectors) Overwritten: 0.00 Byte (0 sectors) Average reading speed: 71.12 MB/sThis will read each of the 1GB files created by f3write, verifying they did not experience any data loss. This will also report on your card's read speed. Mine was 71MB/s, which also felt like around 2 hours.Cool, a real SD card that works! Next step: move my games over.# Switch SD file structurePlugging my old SD card into my machine, diskutil reports an NTFS filesystem: $ diskutil list /dev/disk3 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *127.9 GB disk3 1: Windows_NTFS 127.8 GB disk3s1The hierarchy on the card (named "Untitled") has a single "Nintendo" folder on it. What's in there? $ tree Nintendo Nintendo/ ├── Album │ ├── 2017 │ ├── 2018 │ └── 2019 ├── Contents │ ├── placehld │ ├── private │ ├── private1 │ └── registered ├── save └── saveMeta 829 directories, 688 files(heavily truncated)So, it looks like:- Album, which includes all my screenshots and video recordings arranged by year- Content, which has some subdirectories: - placehld, which has some empty directories - likely placeholders given the filename - private, a 16B file which looks like it contains a key - private1, a 32B file which looks like it contains a different key - registered, which appears to contain all the gamesI've used the majority of the card's 128GB space: $ du -skh /Volumes/Untitled 111G /Volumes/Untitled# Formatting the cardNext step was to insert the 512GB card into the Switch and ask it to format. This process took about 3 seconds, then the console rebooted itself. I verified that the card was now NTFS: $ diskutil list /dev/disk3 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *512.1 GB disk3 1: Windows_NTFS 512.0 GB disk3s1# Backing up the cardI don't have two SD card slots on my machine, so I'll need to copy the data first to my computer, then onto the card. We can use rsync to do this: $ mkdir nintendo_backup $ rsync -avz /Volumes/Untitled nintendo_backup/I used rsync in archive mode by passing the -a flag, which according to man rsync will:> ...ensure that symbolic links, devices, attributes, permissions, ownerships, etc. are preserved...Perfect! I also passed -v for verbose, and -z to use compression as the files are moved.# Restoring to the new cardNow it's time to restore to the new card. After unmounting the smaller card and inserting the new card, it's a simple matter of rsyncing the files back: rsync -avz nintendo_backup/Untitled/ /Volumes/Untitled# Trying it outWith the rsync step done, we can test out the card:It doesn't work! The Switch responds with error 2016-0247 and is unable to access the cardI then tried copying the contents of nintendo_backup over the rsync'd backup files with Finder. Perhaps the rsync step missed something? Or my machine fell asleep?Nope, same error. I tried the original card to verify my Switch was still functional. The original card works fine.# Debugging the issueSo, we've got a new SD card that the Switch won't see:- it was formatted by the Switch's software, so any secret partitions or files should be there- it contains an rsync archive copy of the games and media from the original card- the Switch read the card successfully when formatting it, but hasn't since the restore succeededThe [Nintendo support site](https://en-americas-support.nintendo.com/app/answers/detail/a_id/27595/) seems to suggest similar steps to those I followed:> - Open Windows Explorer (for PC) and access the microSD card.> - Highlight the data and drag it to the desktop.> - If you are moving your content to a new microSD card, be sure to first format the new card per our recommendations.> - Once the new card has been formatted, continue with the instructions below.> - Eject the first microSD card, then insert the second microSD card into the slot or reader/writer.> - Using Windows Explorer access the microSD card again.> - Drag the data from the desktop to the new microSD card, then insert the new microSD card into the Nintendo Switch console.Although it does contain this strange warning:> Important: This process may not be able to copy the microSD card contents correctly in environments other than Windows (such as Mac).# A fixTurns out I was missing the archive attribute on the card. Simply running sudo chflags -R arch /Volumes/Untitled to fix up the Archive attribute fixed the issue (I also did a sudo dot_clean -mn on the directory). Phew! Look at all that space:# Why did this break?I'm not totally sure. My hunch is that an archive attribute on the files was confusing the Switch's SD card parsing. It looks like the Nintendo Switch's OS is not Unix-derived, but rather an [evolution of the 3DS OS](https://en.wikipedia.org/wiki/Nintendo_Switch_system_software). It's possible that some file attributes from Unix may have confused the Switch.
2019-03-08 Peterometer Chapter 1: Tracking Hydration
*This is the first in a series of posts I hope to write about building tools for "Peterometer", a way to visualize stats I've collected about myself.*# Inspiration for PeterometerI've long been inspired by people who build beautiful visualizations of their gathered metrics. For example, Nicholas Felton's annual reports. Here is an example [from his 2007 report](http://feltron.com/FAR07.html):[The first page of Nicholas Felton's 2007 annual report](http://feltron.com/images/FAR07/03.jpg)I think this format of visualization is *really* cool. It's easy to glance at while being information-dense.Another cool example is Anand Sharma's [April Zero](http://aprilzero.com), which is now an app called [Gyroscope](http://gyrosco.pe):[An image of Gyroscope](https://cdn-images-1.medium.com/max/1200/1*4bB_yEzM7Yt_Nme-rQLkzg.png)He has some great posts about his creative process [here](https://blog.gyrosco.pe/the-making-of-april-zero-877612ca3d24) and [here](https://blog.gyrosco.pe/the-making-of-april-zero-part-2-9fee331e2043). The Iron Man-style HUD influence shines through in the finished product.These visualizations are really cool ways to show stats gathered about your life. I've recently been getting more into tracking my day-to-day life, and experimenting with visualization techniques to showcase this data.# Hydration TrackingSince December 2018, I've been tracking my hydration every day. Every time I finish drinking something, I log the type of drink it was, and how much of it I drank. I log the data using the [WaterMinder](http://waterminder.com) app on my watch and phone. WaterMinder lets you have saved drinks, which is really helpful if you drink the same thing often (my Nalgene, a cup of coffee from the machine at work, etc.)# Some VisualizationsWaterMinder lets you export your data in CSV format. With a [little bit of Python](https://github.com/peterhajas/peterometer/blob/master/hydration/waterminder_parse.py), we can parse this into a ["stream" stacked area chart](http://leebyron.com/streamgraph/) to show how I hydrate myself:This chart is a bit tough to read due to data density. The legend is sorted in descending order of consumption. By the numbers, this is:Drink | fluid oz. |–— | –— |Water | 4159.7 |Coffee | 1482.7 |Soda | 826.9 |Sports Drink | 761.9 |Tea | 751.4 |Smoothie | 398.0 |Carbonated Water | 381.4 |Energy Drink | 273.6 |Beer | 225.0 |Protein Shake | 162.0 |Liquor | 130.0 |Juice | 94.0 |Coconut Water | 81.6 |Milk | 55.1 |Wine | 17.6 |Hot Chocolate | 15.0 |**Total** | **9815.9** |Using the chart and table there are some interesting takeaways:- I drink a lot of coffee. Almost 44 liters during this period!- There's coconut water consumption in late December - I had this while skiing- In early February, there are a few days with only water, smoothies, and some soda. This corresponds to when I had my wisdom teeth removed- I have energy drinks on the same day as protein shakes. This matches reality - I have a pre-workout energy drink and protein shake on days that I lift- I seldom have beer, but I have more beer than I have protein shakes- I infrequently have wine and liquor. This is good! - You can see wine consumption during the New Years period - Most liquor consumption was during vacations
2019-01-21 Analyzing My Dog's DNA
Dogs are awesome. Since March of 2014, I've owned a little dog named Riker:I adopted her from the Humane Society in Milpitas. She was 8 weeks old. She recently had her fifth birthday. Happy birthday Riker! I love her very much.Anyways, when I got her, I was curious about what type of dog she was. She looks like a chihuahua, but has some features that don't match the traditional chihuahua:- Curled, fluffy tail- Gradient-banded coat near her front legs- Sheds *mountains* of fur- Generally pleasant demeanorI thought she might have been part [Shiba Inu](https://en.wikipedia.org/wiki/Shiba_Inu). These dogs are adorable and have the curled tail and gradient-banded coat. Here's one from Wikipedia:[A shiba inu dog outside on grass](https://upload.wikimedia.org/wikipedia/commons/6/6b/Taka_Shiba.jpg)Doesn't this dog look like Riker? With the tail and banded coat? I thought so too.Whenever other people asked me about Riker, I would tell them she's "part chihuahua, part shiba inu". They believed me, but I didn't have any proof.# Enter EmbarkA good friend of mine told me about a service where you can get your dog's DNA analyzed. It's called [EmbarkVet](https://www.talkable.com/x/Qnraz2) (disclaimer: this is a referral link). Embark gives your dog a breed report, health analysis, and some cool genetic information. It's like 23andMe for your dog.I signed up for the service. A few days later they sent me a DNA swab kit. It's like an oversized q-tip. After sticking this in Riker's cheeks for 30 seconds or so (she wasn't happy about this, but I told her it was for science), I packed the kit in the return shipping and sent it off.Over the next few weeks, Embark notified me as the analysis progressed. After 3 weeks or so, my pressing question was answered: they told me what type of dog she was!# Less than 50% chihuahuaTo my absolute amazement, Riker is not even mostly chihuahua! The results confirm that **Riker is a pomeranian**! The full breakdown is:- 50% [Pomeranian](https://en.wikipedia.org/wiki/Pomeranian_(dog)) (this accounts for the curved tail, banded coat, shedding, and how she's nice to be around)- 32.5% [Chihuahua](https://en.wikipedia.org/wiki/Chihuahua_(dog))- 6.9% [Miniature Pinscher](https://en.wikipedia.org/wiki/Miniature_Pinscher) (no relation to the [larger dog](https://en.wikipedia.org/wiki/Dobermann))- 10.6% "Supermutt" (small amounts of DNA from other dogs, including [Cocker Spaniel](https://en.wikipedia.org/wiki/Cocker_Spaniel))I also learned that she has 1.5% "Wolfiness", which indicates ancient wolf genes that have survived through to modern domesticated dogs. Cool!***Note:*** I am not a trained biologist. Regrettably, I spent much of my college biology course playing [Pokémon Crystal](https://en.wikipedia.org/wiki/Pokémon_Crystal), although I do remember some parts of the genetics sections.# A family treeEmbark also determines haplotypes, which means they can tell what genes of Riker's came from which parents. This lets them generate a family tree:This means Riker's parents were a chihuahua mix and a purebred pomeranian.# Analyzing my dog's DNABesides finally being able to see my dog's genetic history, I was *super* happy that I could download the raw genetic data. When I unzipped the file, I was left with two text files: riker.tfam 75B riker.tped 6.7MB(I renamed them for brevity)I searched for information on these file types. They both seem to be related to the free [PLINK](https://www.cog-genomics.org/plink2) genetics software package.If we download PLINK and run it on these files, we get: $ plink –tfile riker Processing .tped file... 77% Error: Invalid chromosome code '27' on line 166046 of .tped file. (This is disallowed for humans. Check if the problem is with your data, or if you forgot to define a different chromosome set with e.g. –chr-set.)This is pretty cool! PLINK defaults to human DNA. This file is from a dog, not a person. Looking through the plink –help file, we can see that they have support for lots of species: –cow/–dog/–horse/–mouse/–rice/–sheep : Shortcuts for those species.(I wonder why rice is so interesting to the software...)Anyways, let's run it with the –dog flag: $ plink –dog –tfile riker Processing .tped file... done. plink.bed + plink.bim + plink.fam written.PLINK wrote these files to the same directory: $ ls plink.bed plink.bim plink.fam plink.log riker.tfam riker.tpedThese look to be PLINK metadata files that the software uses to do its processing.We can use PLINK to do some interesting sounding genetic computations. For example, if we run it with the –homozyg flag, we can see homozygosity reports. According to Wikipedia (I must have been in [Johto](https://en.wikipedia.org/wiki/Pokémon_universe#Johto) during this part of biology), [zygosity](https://en.wikipedia.org/wiki/Zygosity) is "the degree of similarity of the alleles for a trait in an organism". Running it produces: $ plink –dog –tfile riker –homozyg 1 dog (0 males, 1 female) loaded from .fam. –homozyg: Scan complete, found 27 ROH. Results saved to plink.hom + plink.hom.indiv + plink.hom.summary .The software knows that the dog is female, which is pretty cool. The files it generated seem to indicate the degree of homozygosity for her individual genes. Neat!If we run with the –het flag, we can see inbreeding coefficients. The file it produces show this: O(HOM) E(HOM) N(NM) F 0 3.051e+04 61022 -1From [this helpful documentation](http://zzz.bwh.harvard.edu/plink/ibdibs.shtml) I found online: O(HOM) Observed number of homozygotes E(HOM) Expected number of homozygotes N(NM) Number of non-missing genotypes F F inbreeding coefficient estimate-1 looks like it indicates a sampling error or contamination according to the docs:> The estimate of F can sometimes be negative. Often this will just reflect random sampling error, but a result that is strongly negative (i.e. an individual has fewer homozygotes than one would expect by chance at the genome-wide level) can reflect other factors, e.g. sample contamination events perhaps.We can also use the software to find what parts of the genotyping are missing with the –missing flag. From this, I was able to gather that Riker only has a missing SNP rate of 0.0009034 (less than 1%). I *think* this means that Riker's DNA in this sample is over 99% complete. Cool!I may make Riker's DNA available online some day for others to do genetic analysis.Anyways, I thought this was a fun exercise into how genetic data is stored and processed. It's really cool that there is open source software to analyze this data. Thanks for reading!
2019-01-06 Live Markdown previews from vim
*This is more of a technical post*This site is written using [Markdown](https://daringfireball.net/projects/markdown/), which:> allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML)It's a common technique for writing blogs, as it lets the author write text in the text editor of their choice.I write this page in vim, which is a command line text editor. I love vim for many reasons that are outside the scope of this post. I've been using it as my primary editor for almost 5 years. I wanted a good solution for writing Markdown in vim.Because vim is a command line editor, it makes it tougher to use it to write rich text. In a GUI program, rich text can be rendered inline and as-you-edit. A command line tool can show you the formatting you have applied to text, but it does not give you an accurate rendering of how your content will look as you edit it.I wanted to continue to use vim to edit my blog posts (I find vim plugins for other editors to be a worse approximation than "I can't believe it's not butter"). This post is about how I solved this problem.# A Markdown preview appOn macOS, you can get apps to render Markdown in a window. One that I like a lot is [Marked](http://marked2app.com), which automatically refreshes its preview when the Markdown file changes. This means you can open a .md file in Marked and get live updates *as you change it*. This can be used with any editor, including vim. The flow is something like:- touch or :e the file you want to write- Open Marked- Open the file in MarkedAs you save to it with :w, the preview will be auto-refreshed. I like this, but wanted to open it with a single key combination.# Adding Marked to vimWe can write a vim function to help us with this. Something like this: function OpenInMarked2() " Open the file in Marked here endfunction## Running a shell command from vimWe can use ! to run a command from our function. Technically, this is the filter command. From :help !:> !{motion}{filter} Filter {motion} text lines through the external program {filter}.You can try this in your vim. Just run :!pwd, and you should be presented with your shell and your current working directory. Below it, vim helpfully tells us "Press ENTER or type command to continue".This is great! Using this and the macOS open command, we can at least *launch* Marked 2 with something like this: !open -a Marked\ 2.appBut what about opening the current file? vim lets us use % from Ex commands as a stand-in for the path to the current file. So we can do something like: !echo %to see the current file. We can use this with open to open the current file in vim: !open -a Marked\ 2.app %This is the body of our OpenInMarked2 function: function OpenInMarked2() !open -a Marked\ 2.app % endfunctionOnce we have this function, we can call it with the Ex call command, like this: :call OpenInMarked2()This will open the current file in Marked, but will leave us at the shell with "Press ENTER or type command to continue" there. We still have to press enter before we can edit the file live.## Defining a mappingWe can use a vim mapping to call the function for us. A mapping lets us take a key combination and map it to a command. For the key combination, I like to use , which is a user-controlled modifier in vim. This means that _ is wide open for use in your .vimrc. For my leader key, I use , (comma), as it's near the other modifiers on a US keyboard. For leader mappings, I like a mnemonic key combination, as it makes it easier to remember.A good choice for this mapping, which is applicable for **M**arkdown and for opening **M**arked, is m. Our mapping to call the function might look like this: nmap m :call OpenInMarked2()Here's a decoder ring for what these commands mean:- nmap means a mapping that exists in vim's normal mode- means the mapping will not be echoed on the command line- m is the mapping we've picked for this particular command- :call will call a particular function- OpenInMarked2() is the name of the function we'd like to callIf you add this mapping and function to your .vimrc, you'll see that it works *kind of*. You have to hit enter to get the command to actually run, and then after doing so you're left at the shell, so you need to hit enter **again** before returning to the editor.## Hitting enter twiceWe can add a press of the enter key to our mapping using . This acts as though the user has pressed the carriage return. We'll add two of them, as we need one to run the function and another to return to the editor. Our mapping now looks like this: nmap m :call OpenInMarked2()
which is the mapping you'll find in my [.vimrc](https://github.com/peterhajas/dotfiles/blob/master/vim/.vimrc).
I hope you found this post helpful. I have been using OpenInMarked2 to help me write Markdown for 2 years now, and I think it's a cool example of how to extend vim to fit your needs.
2018-12-31 New Site, Who Dis?
This is the first post on my new website! You're reading this on the *brand new* [peterhajas.com](http://peterhajas.com). Let's break it down.# A (not so new) domainIt's worth noting that this page is also hosted on [peter.haj.as](http://peter.haj.as). I have had this domain from American Samoa for some time. I love the idea of domains that are people's names with no added alphanumeric characters, and this one fits the bill for me.# My own static site generator - what could possibly go wrong?My old page was powered by [Hyde](https://github.com/hyde/hyde). While this project provides a lot of flexibility, I felt that I was not using all of its features. I wanted something dead-simple that could enable me to write more. As a result, I [wrote my own](https://github.com/peterhajas/peterhajas.com).This site is still statically-generated from Markdown, but it's now done with a Bash script with only one dependency (a markdown binary). This makes it easier to set up on a new machine. It also lets me really understand how the site works.The site generates quickly, and it's been a great learning opportunity! For example, I learned how to format dates using date (see [here](https://github.com/peterhajas/peterhajas.com/blob/master/build#L44)). I'm still learning (I don't know web layout very well, for example) but I think it's better to jump in with both feet when learning something new.The site is missing some stuff (like RSS support), but I plan to iterate on it over time.# Hopefully I'll write moreAll of this is for naught if I don't actually *use the damn thing* to write and think out loud.I hadn't updated my old webpage in **over 6 years**. There's so much that has happened in that time that I want to write about, like:- I have a dog!- Living in the Bay Area- My obsession with [dotfiles](https://github.com/peterhajas/dotfiles)- Music that I'm listening to- Trips I've gone on- Pictures I've takenFingers crossed I'll write about these things in the (near) future on this page.