CodeIsTheEnd
When explaining it to some coworkers, I stumbled on a fairly intuitive explanation: "I've run farther before, and I've run faster before, but I've never run _this_ far, _this fast."
There was some pushback about why not just call it a PR (personal record), but I would only use that term for fixed distances (1mi, 5k, 10k, etc.) or a consistent route that I've run many times before. Nobody would say "I set my 7.40 mile PR today." More importantly, it misses the comparison to all farther (and faster) runs—it's not exciting to set a 5k PR just because you've barely run that distance before, and the pace is actually slower that a 10k you've done.
(Had a Pareto run of 7.40 miles @ 6:28/mi last week!)
I looked at the snow one and almost expected snowdrifts to start accumulating.
[alias]
lg = log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -n 15
Which I took from this Stack Overflow post:
https://stackoverflow.com/questions/1057564/pretty-git-branc...Berenjak’s Interactive Website
So if you're looking for a sports alternative, https://plaintextsports.com (which I made) works great! All the scores, play-by-play, box scores, standings, and schedules, but just no news stories. Blazing fast.
(No, it's not technically "Content-Type: text/plain", it uses HTML and CSS. Yes, I know it's not necessarily easier to read; it's an aesthetic. Yes, this is shameless self-promotion.)
A lot of people have requested that I make a progressive web app for https://plaintextsports.com. I've looked into it, but it fundamentally doesn't work, because it caches the home page. My website doesn't load any data via JavaScript; it just relies on the HTML page updating every 30 seconds, so when the home page is cached, the website just stops working.
I don't want this service worker nonsense. In most cases offline access isn't useful; people want the live scores. (It'd be moderately useful for viewing schedules offline, but I think most people use it for live scores.) I just want the website to show up as its own app in the app switcher, and basically nothing else to change: I still want the swipe-to-go-back gesture to still work. I still want the address bar with the manual refresh button. But I can't do that.
It's frustrating that they've provided a way to make a certain style of websites into first-class apps, but it doesn't work for the most basic websites!!
Side note: this is partially a the-best-way-to-get-a-question-answered-on-the-internet-is-to-say-something-wrong post. If there's a way to make it a PWA and not have all the pages heavily cached, please let me know! I would love to be wrong on this. (Unfortunately my noprocast just triggered though, so I won't be able to edit this post or respond for the next three hours.)
https://plaintextsports.com/premier-league/2022-2023/clubs/l...
The challenge is that these pages are really labor intensive, because I want to show relevant information for whatever league is happening, e.g., group stage points, leg of Champions League matches, and it's really difficult to figure out how to fit everything in just 45 columns.
I complained about it in this tweet: https://twitter.com/CodeIsTheEnd/status/1569489636900347904
I got sick of waiting for ESPN to load so I made a site with the goal of providing immediate access to what people actually care about: sports scores.
It's pretty fully featured at this point, supporting the NFL, NBA, MLB, NHL, MLS, Premier League and Champions League, college basketball and college football, WNBA, NWSL, and the World Cup. And for a lot of leagues it has full schedules and standings as well.
It actually was really popular in South Africa during the World Cup when a "super-app" that points users to sites that don't use a lot of data linked to it.
The site is served off of S3 (which is cheap), but there's a job running on an AWS server that's fetching the data for all the games and republishing pages to S3. It's using Ruby and is making a lot of network requests, so it's definitely not super efficient. I need a least a couple virtual CPUs, so it ends up costing ~$60 a month. I could definitely reduce that number, but the trouble just isn't worth it to me right now.
I don't want to make money on it. It's been difficult enough to get people to use it; getting people to pay for it would be even hard. At this point I feel like I've gotten everything I've wanted from the project. (An eye-opening experience into the marketing world; a website that I use every day.)
I try to limit how much I work on it now to mostly just maintenance work. I'd rather work on other stuff. If I started making money that'd just be a number to obsess over, and, honestly, it's never going to make enough money to replace my salary as a software engineer.
It works in Chrome, but unfortunately not in the standalone Slack client. (Maybe an argument for switching to the web version?)
(Uh, does anyone know how I select all (previously C-a) or search (previously C-f) in Chrome now??)
EDIT: Looks like C-/ functions as select all, still looking for a find replacement.
EDIT #2: Oh, silly me, as long as I'm not focused on an input, C-f still works.
Once you get used to using these shortcuts that means you can compose and edit text anywhere without ever moving your hands.
I recently switched to using Linux full time for my job and it KILLS me that these shortcuts aren’t available outside of the terminal. I try to navigate to a search suggestion in Chrome using C-n and accidentally open three new windows. I try to add a sentence at the start of Slack message using C-a and accidentally highlight everything and delete it. I try to move my cursor up to edit a previous line using C-p and end up brining up a print dialogue. It’s breaking the muscle memory of my most basic interactions with the computer, and it sucks.
- 2 stolen bike seats (one by 4th and King, one in the Mission)
- 1 entire bike stolen (left out in the Castro overnight)
- 1 rear wheel stolen (in a parking garage by the SF Symphony)
- 1 seat post clamp (literally just the clamp they had to remove the seat, take off the clamp, then put the seat back; during a 30 minute piano lesson in the Mission)
But that doesn't included the most egregious thing that I ever witnessed: I was running up to Twin Peaks on a Saturday morning, and right around noon, in the mini parking lot between the actual two peaks, with dozens of people milling about, heard someone break a car window while there was someone in the vehicle and grab a bag. A woman was seated in the passenger seat and they broke the rear driver-side window. Within seconds a car pulled up with no license plates, the guy jumped in and they sped off.
This is useful for schemas that use a denormalized tenant id across multiple tables, as might be common in a multi-tenant application:
CREATE TABLE tenants (id serial PRIMARY KEY);
CREATE TABLE users (
tenant_id int REFERENCES tenants ON DELETE CASCADE,
id serial,
PRIMARY KEY (tenant_id, id),
);
CREATE TABLE posts (
tenant_id int REFERENCES tenants ON DELETE CASCADE,
id serial,
author_id int,
PRIMARY KEY (tenant_id, id),
FOREIGN KEY (tenant_id, author_id)
REFERENCES users ON DELETE SET NULL
);
This schema has a problem. When you delete a user, it will try to set both the tenant_id and author_id columns on the posts table to NULL: INSERT INTO tenants VALUES (1);
INSERT INTO users VALUES (1, 101);
INSERT INTO posts VALUES (1, 201, 101);
DELETE FROM users WHERE id = 101;
ERROR: null value in column "tenant_id" violates not-null constraint
DETAIL: Failing row contains (null, 201, null).
When we delete a user, we really only want to clear the author_id column in the posts table, and we want to leave the tenant_id column untouched. The feature I added is a small syntax extension to support doing exactly this. You can provide an explicit column list to the ON DELETE SET NULL / ON DELETE SET DEFAULT actions: CREATE TABLE posts (
tenant_id int REFERENCES tenants ON DELETE CASCADE,
id serial,
author_id int,
PRIMARY KEY (tenant_id, id),
FOREIGN KEY (tenant_id, author_id)
-- Clear only author_id, not tenant_id
REFERENCES users ON DELETE SET NULL (author_id)
-- ^^^^^^^^^^^
);
I initially encountered this problem while converting a database to use composite primary keys in preparation for migrating to Citus [2], and it required adding custom triggers for every single foreign key we created. Now it can be handled entirely by Postgres![1]: https://www.postgresql.org/message-id/flat/CACqFVBZQyMYJV%3D...
[1]: https://plaintextsports.com/all/2022-08-24/
Using GROUP BY CUBE(a, b, c, ...) creates GROUP BY expressions for every element in the power set of {a, b, c, ...}, so GROUP BY CUBE(a, b) does separate GROUP BYs for (a, b), (a), (b) and ().
It's like SQL's version of a pivot table, returning aggregations of data filtered along multiple dimensions, and then also the aggregations of those aggregations.
It seems like it's well supported by Postgres [1], SQL Server [2] and Oracle [3], but MySQL only has partial support for ROLLUP with a different syntax [4].
[1]: https://www.postgresql.org/docs/current/queries-table-expres...
[2]: https://docs.microsoft.com/en-us/sql/t-sql/queries/select-gr...
[3]: https://oracle-base.com/articles/misc/rollup-cube-grouping-f...
[4]: https://dev.mysql.com/doc/refman/8.0/en/group-by-modifiers.h...
The Tanforan Shell Edition
Supported extensions on AWS RDS: https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLRelea...
Supported extensions on Google Cloud SQL: https://cloud.google.com/sql/docs/postgres/extensions
Supported extensions on Azure Database: https://docs.microsoft.com/en-us/azure/postgresql/single-ser...
Brachistochrone Curve
https://www.newyorker.com/magazine/1992/03/02/the-mountains-...
https://news.ycombinator.com/item?id=30956775 (368 points, 124 comments)
On my to-do list is making a personalized page where you can select exactly which teams you want to follow, something closer to what dpeck wants, but I've been having trouble finding the time...
There are a couple other copy variants as well:
I'm a big fan of Ruby, and feel like I know the language pretty well, but, my goodness, I don't know how I've never come across this one before. THIS is something that feels like magic!!
[1]> 3.method(:days).source_location
=> [".../lib/active_support/core_ext/numeric/time.rb", 37]
[2]> puts 3.method(:days).comment
# Returns a Duration instance matching the number of days provided.
#
# 2.days # => 2 days
=> nil
[3]> puts 3.method(:days).source
def days
ActiveSupport::Duration.days(self)
end
=> nil
https://ruby-doc.org/core-3.1.1/Method.htmlMy apologies to Wilfred.