Update: I put this in the mail on Tuesday and got cancellation confirmation less than 48 hours later.
Also, your mileage may vary, some locations are a little more of a stickler about certified mail, but you should get a confirmation from the location within a few days if they’ve accepted.
I needed to cancel Planet Fitness in the middle of the COVID-19 pandemic and I really didn’t want to be showing up at a gym in person right now (time and unnecessary risk) just to cancel.
I called up my local Planet Fitness and was told I could either come in in person *or* send a [yes, snail mail] letter to the Planet Fitness I signed up at.
So, I’ve thrown together a cheap template to help you include everything you need to cancel (it’s just name, date of birth, and signature, according to the person on the phone.)
You can download the doc I put together at: Planet Fitness Cancellation Word Doc template
When working on an established Rails project, we noticed that trailing spaces weren’t getting trimmed off. Discussion ensued about whether to do data cleanup and then someone noticed that the
where method in Rails didn’t care about the spaces. Not having seen this in my PostgreSQL days, I was assuming that there was some magic happening in either the Rails codebase or the MySQL adapter. So I went to the underlying DB: No, searching for
column='hi' found values where the column value was actually
All MySQL collations are of type
PAD SPACE. This means that all
TEXTvalues are compared without regard to any trailing spaces. “Comparison” in this context does not include the
LIKEpattern-matching operator, for which trailing spaces are significant.
Of course, I’m using MySQL 8.0 and so is the app. So I dug into the collation, setting up the following table:
mysql> select concat('"', thing, '"'), unthing from surelynot; +-------------------------+---------+ | concat('"', thing, '"') | unthing | +-------------------------+---------+ | "hi " | what | | " hi " | what2 | | " hi" | what3 | | "hi" | what4 | +-------------------------+---------+ 4 rows in set (0.02 sec)
Setting the collation to MySQL 8.x’s default, I get one row for
mysql> alter table surelynot convert to character set utf8mb4 collate utf8mb4_0900_ai_ci; Query OK, 4 rows affected (0.16 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> select concat('"', thing, '"'), unthing from surelynot where thing = 'hi'; +-------------------------+---------+ | concat('"', thing, '"') | unthing | +-------------------------+---------+ | "hi" | what4 | +-------------------------+---------+ 1 row in set (0.05 sec)
However, using the latin1 or latin2 collation that was on the other database, I get two results for
'hi', one for the exact match, and one for the right-padded. Note that left-padding has no impact on the results:
mysql> select concat('"', thing, '"'), unthing from surelynot where thing = 'hi'; +-------------------------+---------+ | concat('"', thing, '"') | unthing | +-------------------------+---------+ | "hi " | what | | "hi" | what4 | +-------------------------+---------+ 2 rows in set (0.00 sec)
ucs2_general_ci also has this property as does the
utf8_general_ci collation. Ultimately, only the default
utf8mb4_0900_ai_ci paid attention to right padded spaces when looking for string equality in the where clause.
In a project using
actionpack-xml_parser, and implementing a modified version of Catching Invalid JSON Parse Errors with Rack Middleware to also handle XML errors, an upgrade to Rails 6 broke the handling of the
ParseError. Interestingly enough, JSON was being handled as expected.
TL;DR: The short answer to this is that
config/initializers/wrap_parameters.rb only had
json mentioned as a format. This can be remedied in the initializer or on a per controller basis. The entire app fix was just adding
:xml to the initializer:
ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json, :xml] end
In looking through the stack traces/call stack for where the parse error occurs (
ActionDispatch::Http::Parameters#parse_formatted_parameters) using the
caller array in the gem source and backtrace in the
rescue, I was able to catch that
ActionController::Metal::ParamsWrapper#_wrapper_enabled? was called for JSON, but not for XML. Ultimately, I was able to track down the difference to
ActionController::Metal::ParamsWrapper#_wrapper_formats?, which was only returning
[:json], which led to the
wrap_parameters functionality in Rails.
At the beginning of the pandemic last year, I wasn’t dealing well with it. The scare TP and *everything else* phase hit a little hard on top of all of the other panic. So I smoked a brisket. Here’s the general procedure:
Equipment / supplies
- Oklahoma Joe’s Longhorn Black Triple-Function Combo Grill
- Oak wood chunks (Amazon affiliate link)
- Lump charcoal
- Propane for finishing
- ThermoPro wireless remote digital meat thermometer (affiliate link) for monitoring after putting on grill
- Heavy duty aluminum for wrapping post smoking
- An old cookie sheet that you don’t care to stain
- 1/4 c packed brown sugar
- 2 tbsp smoked paprika
- 2 tbsp sea salt
- 1 tbsp garlic powder
- 1 tsp onion powder
- 1 tbsp chili powder
- 1 tsp black pepper
I had better luck with brisket from Sam’s Club than Costco, but this was at the early phases of the pandemic, so that might have been part of the problem. 10 lb brisket, good marbling and a fairly trim layer of fat on one side.
40% oak wood and 60% charcoal aiming for 250-275℉ on the hood thermometer. I let the oak wood burn fuel for the fire with whatever smoke it produced. I laid the brisket fat side up at the other end of the charcoal grill chamber from the smoker box and maintained charcoal/wood fire for 5 hours.
Low grill indirect heat
After about 5 hours, I’d gotten as much smoke as I wanted, so I put the brisket on an old cookie sheet and wrapped fairly tightly with heavy duty aluminum foil and put in the propane grill chamber opposite the burner that was lit as low as it would burn. At this point I stuck in the digital thermometer and monitored for 195℉. Once it hit target temperature, I brought it inside and let it cool a bit (mostly to make sure everything else is ready).
I know it will be blasphemy to most, but you can carve up extra thick slices (~1 inch thick) and freeze, for later slow warming in the toaster oven.
I decided to switch to my Vortex Race 3 TKL for a more programming-centric job from the Vortex Tab 90M that felt a little better for email and spreadsheets. The Race 3 has Cherry MX Silent Reds vs. the Vortex Tab 90M’s Cherry MX Silent Blacks.
A couple of things that were a little bit difficult to follow were:
- How to set up the Race 3 for Mac (it had been used on a Windows PC most recently and never really used on a Mac). This Reddit thread gives some suggestions on how to optimize that.
- How to program the LEDs (for just basic effects):
The LED programming was fairly simple once I understood it (see here for a copy of the manual). The cool LED effects when you type are accessible by pressing the Pn key + one of the ‘1’ through ‘5’ keys. ‘4’ and ‘5’ have multiple effects:
Pn + ‘4’ cycles different “display single color LED mode”s which means that the interactive LED effects appear in context with your
- [no effect?]
- Interactive mode – keys light up as you type.
- Flash vortex mode – keys pulse around the keyboard originating from your keystrokes
- Aurora mode – keys pulse in color around the keyboard originating from your keystrokes
Pn + ‘5’ cycles different “Display full color LED mode”s which means “display on all the keys regardless of context”:
- [no effect]
- Full key light mode – just 100% on
- Breath mode – keyboard pulses
- Vortex mode – RGBs cycle in different phases with each other.
- Rain drop mode – random drops of “color” appear on the keys
Pn + X – brightness down for the above effects
Pn + V – brightness up for the above effects
Pn + [< key] and Pn + [> key] are LED speed up and down.
It’s been a little over 1 month since my AWS Certified Solutions Architect – Associate (SAA-C02) exam. After finishing the Solutions Architect Associate exam, I immediately registered for the Developer Associate exam, which I took yesterday and passed.
I took a practice exam (through Linux Academy) shortly after passing the SAA exam, having actually gone through most of a Developer Associate training course. DO NOT DO THIS UNLESS YOU ARE READY TO DIVE DEEP INTO ANYTHING YOU MISSED. I managed to get about 72% on the practice exam, which is essentially a passing score so I let myself lose focus over the holidays.
Next mistake was going through a couple of versions of the course (30 hours each) instead of just using the practice test results to read the white papers, FAQs, and AWS service pages I needed to review. (Linux Academy/aCloudGuru courses provide links to associated AWS reference for this.)
Foundations in SAA
I highly recommend getting the Solutions Architect – Associate first. It covers a good breadth of topics that will give you a solid foundation. I recommend the Linux Academy courses that have labs that you can walk through via a transcript just to traverse all the areas you need to know.
Differences from SAA
All of the AWS Code* services factor into a significant chunk of the DVA exam. If you have solid experience with docker, k8s, and git, you’ll probably have a better than 50% chance on questions about services that you didn’t look into, but there are also things that are about the “AWS way” or the “way that AWS services push you to do things” that I shook my head at. (Physical team organization? Wat?)
- Learn how to set up X-Ray on the various compute environments.
- Create and deploy a Serverless Application Model project and dig into the configuration files for it.
- 0 bytes is the minimum object size, 100 MB is the recommended threshold to use multipart upload to S3, 5GB it is required, 5TB is the object size limit.
- View Protocol Policy in CloudFront (https/http)
- Bucket policies for enforcing server side encryption
- Learn supported platforms for CodeDeploy
- Learn lifecycle hooks for CodeDeploy (just look at the diagrams a few times)
- Learn which services trigger Lambda asynchronously and synchronously
- Lambda requires dependency packaging, and CPU is controlled by RAM allocation.
- Dead letter queues
- Lambda, by definition, does not do in-place deploy (because in-place requires a tangible server)
Use How to get old versions of macOS to download an installer for OS X Yosemite while running on Yosemite. Run the installer and it will install the full installer to /Applications/Install OS X Yosemite.app
Use the command line from How to create a bootable installer for macOS substitution El\ Capitan for Yosemite in the El Capitan instructions.
Hold down option while powering on the Mac to get the option to boot from USB Recovery.
So far, the key interest for me have been the potential drastic improvement in battery life. I’m almost willing to sacrifice a bit of short term productivity to get there. I don’t know that the experiences sound any worse that trying to get my favorite development environments productive on Windows or a non-Debian flavor of Linux:
JetBrains and Xcode-centric perspective (11/23/2020):
Rubyist perspective (11/25/2020):
macOS 11 Big Sur compatibility on Apple Silicon · Issue #7857 · Homebrew/brew · GitHub (closed as of 12/26/2020):
Rails’ DHH’s own experience (12/28/2020):
I tried to cancel Humble Choice a couple of months ago, after getting sucked in to a membership a few months ago, but either I didn’t complete the cancellation, or I didn’t have enough time to completely follow-through. I had a little bit of a challenge finding the cancellation link this time, so I wrote it up here just in case anyone else experienced the frustration. No idea if it works on mobile, I went to the desktop this time to make sure that I could see the entire menu.
- Manage Your Plan
- Scroll down to [Cancel Your Subscription] button
- Scroll down to [Cancel My Membership]
- Select a reason and [Cancel My Membership]
- Click [Cancel My Membership] on the popup.
So we have a battery hungry front door lock that requires 4-AA batteries to power. I noticed that the Sunbeam batteries purchased from Dollar Tree (3 pack for $1, or $1.33 per replacement) were getting replaced every month or so, so I was curious if that was normal as well as how much I was really paying for them.
Tracking in a spreadsheet, the Sunbeam batteries lasted from 23 to 36 days, with an average of 28.8 days. At $1.33 per replacement / 28.8 days… that door cost 4.61¢ per day with the Sunbeam batteries.
Thinking maybe I could do better, I bought a 96 pack of EnviroMAX Batteries (affiliate link) on Woot (but for 25¢ each instead of being similar in price to the Sunbeam… so it was $1 per replacement instead of the $1.42 at the current moment for that link.) The batteries lasted 13-25 days, with a generous average of 21 days, or about 4.7¢ per day… The last replacements were more like 2 weeks and I stopped tracking them, but there were sets in the middle that made it 3 weeks or better, but it was horribly inconsistent.
I just bought a large pack of Kirkland batteries, so I’ll be sure to track the performance of those and see how it lines up with the other batteries.
I’ve been tracking the Sylvania 60W 2700K Equivalent A29 (affiliate link) vs. the AmazonBasics 60W Soft White Non-Dimmable (affiliate link) over the past year and a half after noticing that I was replacing bulbs a lot. With 40+ bulbs in the house, it’s not as uncommon as I would have initially expected to be replacing a bulb on any given day.
I have a limited amount of data so far, but definitely have an apples to apples (same socket in same fixture) comparison, and it looks like the Amazon Basics bulb lasted 242 days vs. the Sylvania’s 308. While I have no other apples-to-apples comparisons, the remaining Sylvania bulbs have lasted at least ten months.
The above links have a 24-pack of AmazonBasics at $27.99, or 0.48¢ per day vs. the Sylvania at $22.88, or 0.31¢ per day.