Hiking Group: Lättich

Lättich towards Blickensdorf

20 March 2019
7.7 km, 160 m ascent, 1h20m, 2°C
It’s been about two and a half months since my last Tuesday group hike. Some of the absences were due to scheduling conflicts, but mostly it was because I chose to go skiing instead. This was a nice easy hike to get back into shape for more hiking this Spring.

This was a pleasant fast walk through farm fields and woods. No high mountains or spectacular views, but good enough and relatively close to home.

Route map from my watch:

Lattich Map

Markdown CV

About a month ago I decided I ought to dust off my CV and get it updated. My CV is a Pages document, and it always seems like my CV is 90% formatting and 10% content, which drives me crazy. I’m a developer; I believe in interoperability, open file formats, and of course making my life easier. It seems like I ought to be able to write my CV in Markdown or something and host it online instead of printing it out or having to email it to people.

(Apropos of being a developer: instead of simply updating my CV, I spend more time figuring out a “solution” to theoretically make updating my CV in the future easier.)

I did some Googling and came across this project to publish your CV in Markdown via GitHub Pages. This would let me have my CV in Markdown and have version control. 🎉🎉🎉🤣

So I forked the repo, rewrote my CV in Markdown, updated it with what I’ve been doing for the past 5 years, and published it on GitHub Pages. Then I put a top-level menu link to it on this website.

I’m not satisfied with the current formatting, but that’s just a CSS file I can adjust (but probably never will). I’m also not satisfied with the content (I think I need to improve the descriptions of the roles I’ve played in various projects). But overall I’m happy with it¹ for the following reasons:

      • Updated content
      • Markdown format
      • Hosted online (with link from front page of my website)
      • Version control

¹Never conflate being satisfied with being happy

How to add an Obj-C bridging header to a Swift framework target in Xcode 10

You can’t, but here’s how you work around it. (Xcode 10.1 generates a compile error if you try to specify an Objective-C bridging header for a framework target.)

  1. Select the header file(s) you wish to bridge, and in the Target Membership section of the File Inspector, check to include it in your framework and then mark it as Public in the dropdown that appears.
  2. Include the header file(s) in the main header file of your framework.
#import <MySDK/MyHeaderFile.h>

Source: Stack Overflow (naturally!)

(This was the first time I’d ever seen the Public / Private / Project dropdown under Target Membership. I guess it’s only for headers, which you don’t typically manually include in a target.)

How to check whether a Core Data store needs migration

When using Core Data I typically rely on automatic lightweight migration to upgrade the persistent store to the latest model version. Today I needed to determine whether the store was migrated.

Creating my persistent store by calling addPersistentStoreWithType:configuration:URL:options:error: with the options to automatically kick off lightweight migration succeeds as long as a migration is possible, but doesn’t indicate when a migration has occurred.

I could just call addPersistentStoreWithType:configuration:URL:options:error: without the migration options, and if that throws an error, then I know I need to migrate. But it turns out there’s a more efficient way to check: simply call isConfiguration:compatibleWithStoreMetadata: on the object model before attempting to open the store.

code snippet:

let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL, options: nil)

if !objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata) {
    needsMigration = true
}

Reading: Initiating the Migration Process

My First Twitter Bot

I love Twitter bots. My favorite used to be the @iaminigomontoya bot that would reply to anyone tweeting the word “inconceivable”. 🤣

I’m also a fan of the @LegoSpaceBot (no real surprise there), which tweets pictures of old LEGO Space sets from the 70’s, 80’s, and 90’s.

These are for the most part exactly the sets that I have been building for my LEGO Space Project for the past two years. So it turns out that I have built and taken photos of most of the sets that @LegoSpaceBot tweets about. I thought it would be fun to make a bot that sort of trolled the @LegoSpaceBot by quote retweeting (almost) every post with my photo of the built set together with a short comment.

After a bit of Googling I decided that I would write and host my bot at Glitch.com. I needed to create a new Twitter account (@LEGOSpaceBotBot) and to sign up for the developer program. Glitch has multiple Twitter bot templates to choose from and lets you get started quickly by “remixing” one of their templates. I started with a template that tweeted random photos, but I also looked at templates that responded to other accounts. I would need both: to be able to search for tweets and to be able to post images.

JavaScript is … interesting. After working in Swift for the past year and a half, it’s quite the change. JS developers: respect.

The basic bot idea was to look at tweets from @LegoSpaceBot, find those which mention specific sets (some posts are of catalog pages), parse out the set number, and check to see whether I have a photo of that set. If it finds a match, then quote retweet that post with the photo and a random message. If no match is found then quote retweet with a different random message.

To avoid having to do too much work, I want it to keep track of the most recent tweet that it has successfully processed. This is written to a simple text file. I also wanted to make sure it only responds to the most recent tweet even if it has been offline for a period of time. (I wanted to make sure it didn’t accidentally respond to @LegoSpaceBot’s entire backlog of 8k+ tweets…)

I started out with an array of 8 phrases that would be chosen randomly to accompany each post. After the same phrase was randomly chosen for the second and third posts, I realized that I needed something a bit more advanced than just simply random. Fortunately, the author of the @LegoSpaceBot already solved this problem and has a good discussion of the issue here. The basic gist is to split the array into two halves and shuffle through one half before shuffling through the other half. That guarantees a minimum distance of N/2 between any repeats. So for my array of 8 phrases, any given phrase would be at least 4 tweets apart. (Obviously I need more phrases.) I adapted my randomizing method from the code here. This solution relies on being able to seed the randomizer, which to my surprise JavaScript.Math does not handle by default! Fortunately there’s an answer for that too and you can add seed functionality by including seedrandom.js from here.

En fin, I hereby present the LEGO Space Build Bot.

Hiking Group: Gottschalkenberg

Gottschalkenberg Bellevue

8 January 2019
5km, 150m ascent, 1h30m, 0°C

The first snowshoe hike of the season (and my first snowshoe hike ever). Snowshoes were one of my Christmas gifts this year. The weather was pretty miserable: foggy, windy, snowing wet snow, and it felt colder than just freezing. Nevertheless it was still a fun hike and a successful first outing on showshoes for me.

Snow shoes

We did a simple out and back hike from Raten, past Gottschalkenberg to Bellevue (supposedly the view point but it was fogged in). This hike could have been a loop around Gottschalkenberg, but due to the weather we decided to just retrace our steps to Raten. (Returning was easier because the snow was already tramped down.)

Gottschalkenberg Hike

Route:

Gottschalkenberg Route

Hiking Group: Week 12 (Canceled)

Rigi Kaltbad
Rigi Kaltbad in better weather
Weggis to Rigi Kaltbad

4 December 2018

Today we were planning to hike up to Rigi Kaltbad (where there’s a spa) from Weggis, which is a town on Lake Luzern. I’ve taken the cable car down from Rigi Kaltbad to Weggis several times, but I’ve never done the walk in either direction. This hike is supposed to be about 6km long but with 1km ascent, so it’s quite steep. This would make it the second most difficult hike of the season so far after the Stanserhorn. It was canceled due to rain and thunderstorms. We’ll try again next week if the weather improves.

Hiking Group: Week 11

Status: 2018-12-03 11.54.18

Immensee Hike

27 November 2018
7km, 190m ascent, 1h:30m
This was one of the shortest hikes we’ve done: a double loop hike around a wooded peninsula on Lake Zug. The outer loop was at lake level, and then we ascended to make a smaller inner loop higher up on the hill that occupies the peninsula.

The weather was not good (2°C and rainy), and consequently we had fewer hikers than normal. Still it was a pretty hike, and the distance was right for the weather, especially considering the slippery roots on the trail.

Group photo

More pics here.

Route map from my watch:
Week 11 Map

On the drive home my car GPS decided to route me through 20 km of tiny one-lane farmer roads up and over the Zugerberg. Up on the mountains it was snowing and not always plowed. I think I must have accidentally told the GPS to avoid highways. Thank goodness for winter tires and 4wd. It was very pretty though.

Status: 2018-11-27 14.19.04

Hiking Group: Week 10

Status: 2018-12-03 11.38.21

Sihl River Loop

20 November 2018
11.3km, 190m ascent, 2h:30m
This was a very pretty, mostly flat hike. We made sort of an elongated figure-eight by walking along both sides of the Sihl River and crossing three different bridges.

The weather was literally freezing (0°C), but I never felt cold during the hike. We only saw a dusting of snow in a few places.

Group Photo

More pics here.

Apple Watch with the hiking workout continues to be a good hiking companion.

Route map from my watch:
Week 10 Map

Hiking Group: Week 9

Ägerisee

Ägerital Panoramaweg

13 November 2018
13.7 km, 320m ascent, 2h:50m
This was my first hike in over a month, so I was glad that it was close to home and that it was relatively easy (compared to say, the Stanserhorn). I walked to and from the meeting point for the hike, which added another 2.6 km of walking to my day, although I must admit that at the end I half-regretted my decision not to drive.

There was not a lot of ascending, but there was more than enough to make me sweat. The day was gray and chilly, around 9°C, but I was soon down to shorts and a t-shirt regardless. It was a pretty hike despite the gray skies: farm fields then up the hill and along part of the Panorama trail with views of the lake before descending to the lake and heading back along the shore.

Week 9 Group Photo

I think this was the longest hike we’ve done thus far (even before adding in the extra walking to/from the start point). My legs were definitely tired and my feet were sore by the end of it.

Route map from my watch:
Week 9 Map