Keyboard Shortcuts

  • Workflows

Prologue: PSA

The Control key plays a fundamental role in a lot of shortcuts but it resides in a position that requires people to stretch their tendons. Not good if you want to avoid RSI issues! Instead, you can map the Caps Lock to the Control key, which is really straightforward on the Mac.



Keyboard shortcuts are a big part of my workflow since minimizing mouse-keyboard switching saves a lot of time and fatigue. Here’s a list of the shortcuts I find the most useful.

Text fields

Control-F
Move cursor forward one character
Control-B
Move cursor backward one character
Control-P
Move cursor up one character
Control-N
Move cursor down one character
Control-A
Move cursor to beginning of line
Control-E
Move cursor to end of line
Control-K
Delete entire line after cursor
Control-O
Insert new line after cursor

Sublime Text 3

Command-D
Selects entire word at cursor. Really useful for quickly selecting and deleting a word. (Keep pressing to expand selection to next occurrence.)
Command-K [U/L]
Converts selected text to Upper / Lower case
Command-T <file name>
Quickly open a file by name
Control-1
Selects the first group. You can also use 2, 3, … if you have more groups
Control-Tab
Alternates between last used tab (like a stack)
Control-G <line number>
Go to line number. Very useful for navigating to somewhere far away without using the mouse
Control-Minus
Jumps back to previous cursor position. Great if used in combination with above. You can use Ctrl-Shift-Minus to jump forward
Control-T
If you have multiple selections, this shortcut will “rotate” the selection round-robin style. (If you have two selections it swaps them)
Control-Shift-J
Reveal current file in sidebar. I remapped this to be the same as the default shortcut combination in Xcode
Control-R
Switches to matching header/implementation file. This was a lot easier to press compared to the default Command-Option-Up

Finder

See the Instructions below for setting up these custom shortcuts.

Command-Shift-1
Open terminal at selected folder. Unfortunately this requires actually selecting a folder. If anyone knows how to do this without selecting please let me know!
Command-Shift-2
Create a ZIP archive of selected files.

Xcode

The first three shortcuts are very useful complements to each other:

Command-Shift-J
Show current finder in sidebar
Command-Shift-C
Move cursor to console area
Command-J
Move cursor to code editor
Command-Control-R
Continue running (when stopped at breakpoint)
Command-Shift-O
Open Quickly any file. (Vastly improved to add emacs support in Xcode 9!)

Custom shortcuts:

Option-Shift-S
Select iPhone SE simulator as destination
Option-Shift-6
Select iPhone 6 simulator as destination
Option-Shift-J
Select my iPhone as destination

Instructions

Above: Mapping Caps Lock to Control
Above: There's a lot of built-in services!
Above: Compress (AKA Archive files)

Course Evaluations - Winter 2017

  • University

I wanted to jot down my thoughts about taking 6 courses while working part-time. There’s the saying that “marks don’t matter” which I think has some truth. However some courses are quite foundational and important in software development, and these courses do matter. The saying applies more to courses that are subjective or depends on the specific context, or where the real-world practice is actually nothing like the theory taught in class. There’s no consistent method to measure students’ performance because there are too many factors in the real-world to write down in a two hour exam.

Bu 423 - Options, Futures, and Swaps

I’ve always been interested in learning about how to trade stocks as a form of passive income. This course gave me a better sense of the connection between stocks and options, as well as how financial institutions make their money (seriously, right?). The most interesting realization for me was how Principal-Protected Notes work.

Bu 481 - Policy 1

This is my favourite business course by far for a couple of reasons. It consists primarily of real-world cases which provided a more practical learning compared to previous courses. This also makes it more engaging because these cases illustrated the decisions that companies actually had to figure out.

CS 350 - Operating Systems

This course is the culmination of the two pre-requisites on computer CPU architecture and basic compilers. For me this course eliminated the mystery of what operating systems actually do. It allowed me to understand things like what does it mean for 64-bit processors to have 4 levels of page tables (and some security implications), or reading through the reverse-engineered specs of APFS designed for modern SSD’s. Well then, time to re-read objc.io Concurrency :).

CS 370 - Numerical Computation

Before taking this course I didn’t think open-book exams existed in university math courses! I didn’t know what to expect - would the exam be a lot of theory since anyone can lookup all the proofs? Well, turns out it was fairly similar to other courses where questions are mostly based off of assignments.

This course covered a whole range of topics. My favourites in order are 1) details of how Google PageRank works, 2) creating splines, and 3) Fourier transforms. An honorable mention goes to LU Decomposition because I thought it was a good example how pre-computing an expensive result can be worth it in the long-run.

CS 486 - Artificial Intelligence

I have to admit I should have put more effort into this course. The main reason was my loathing of stats - I like the power of the concepts but I’m terrible when it comes to theory. The programming assignments would have been a lot more fun if I started on them earlier. This course gave me a better understanding of how the “intuitive” algorithms that we think up actually works and cleared away some of the mystery behind how to write and train programs with data. The “Utility function” was a common theme in AI, which made sense since there needed to be a canonical way of measuring the value of an outcome. It also shows how stats is used pretty much everywhere. Guess people are going to start bringing their own poker AI to casinos now?

Econ 250 - Macroeconomics

I’m thankful that I also selected an easier course this term. Most of the early chapters were a review of basic economic concepts. With this being an online course, the weekly quizzes, although only 1% each, were very helpful in forcing me to keep up with the content. I think having a basic understanding of economics is one of the most useful subjects as it provides the foundational knowledge to evaluate business decisions and the general economy.

What Are Principal-Protected Notes?

  • Finance

I heard that some banks offer you these “safe” investments when you sign up, but what are they really? Essentially, at maturity, it guarantees that you will receive the amount you invested in, plus some non-negative amount depending on how well the market performs. For example if you invest $1000 for one year, you might receive $1050 or $1100, but nothing less than $1000.

But I thought investing was risky?

You might be thinking: How is it possible that both 1) the initial investment is protected, and 2) the bank makes money, at the same time? The short answer is: There is the risk that inflation is eating your investment.

Here’s what this security is actually made up of: The bank buys a zero-coupon bond and some options, and keeps the remainder as commission. The zero-coupon bond guarantees the principle at maturity, while the options provide the chance of additional returns. Zero-coupons will always cost less to purchase than the principle. The remainder of the initial investment is used to buy options or kept by the bank as commission. Notice that this is a fixed-pie, where banks have the incentive to keep more as commission.

Is it worth it?

The returns of this strategy is largely dependent on the current interest rates. A high interest rate means that the zero-coupon bond is less expensive to purchase, which leaves more money available to buy options. However a higher interest rate might reduce returns of the market in the long-term, limiting the potential upsides of this strategy. On the other hand, a lower interest rate increases the cost of the zero-coupon, leaving less money to buy the leveraged options. And don’t forget - the bank will take a cut of your investment as commission! Now you might be thinking, I will just create this strategy by buying bonds and options myself right? Well that might actually cost more in commissions because that requires two transactions. So in most cases it might actually be better choose a different strategy!

Prototyping with UISliders

  • iOS SDK

Sometimes when prototyping designs, it just comes down to trial and error. Wouldn’t it be great if this can be done without recompiling?

UISlider to the rescue

I created a utility class to setup and attach a UISlider to adjust the constants of a NSLayoutConstraint.

Example 1

let constraint = topView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20))
SliderFactory.main.addSlider(named: "Top", for: constraint, minValue: 20, maxValue: 64)
Example 1
Click to play

Example 2

Here’s a slightly more complicated example.

let adjustableConstraints = [
  ("top", topView.topAnchor.constraint(equalTo: view.topAnchor, constant: 64)),
  ("left", topView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 12)),
  ("right", topView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -12)),
  ("height", topView.heightAnchor.constraint(equalToConstant: 53.0)),
  ("between", bottomView.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 20)),
]
for (name, constraint) in adjustableConstraints {
  NSLayoutConstraint.activate([constraint])
  let min = constraint.constant - 50
  let max = constraint.constant + 50
  SliderFactory.main.addSlider(named: name, for: constraint, minValue: min, maxValue: max)
}
Example 2
Click to play

Example 3

It’s also possible to prototype other types of designs such as a parametric drawings. This is accomplished by passing in a pointer to the variable of interest and adding a callback to redraw.

Example 3
Click to play

Things to explore

These are just a few examples of what is possible with using sliders to dynamically modify variables at runtime. Some other ideas I plan on exploring:

  • Tapping a view brings up sliders specific to the constraints of that view
  • Run an iPhone app inside an iPad with side controls to adjust individual properties

I’d be curious if you have other suggestions. You can find the full source here.

External Dependencies

I make an app that provides a convenient way to check your PRESTO card balance. I started working on this as a side project over a year ago and released it early this year. There is no API available so I had to resort to scraping the data. And of course it would change at the least convenient time.

I planned to make my app free as a promotion during 🇨🇦 Thanksgiving - an impromptu decision probably influenced by a podcast I was listening earlier. The next day I began to do some simple marketing. Thankfully a colleague notified me that the PRESTO website was down before I caused too much damage.

Since the upgrade was going to take place from Friday - Monday, it would mean that my app would stop working for 4 days! It was after the holiday that I discovered that the existing app would not function due to the website changes. At this point I wished I had built some facility for my app to dynamically show a message to users.

Worse, I was in the middle of another project and could not immediately jump on to update the app. This led to some bad reviews which I expected. Most apps either have no reviews, or terrible ones when things go south. It takes a lot for a user to spend time leaving a positive note, but that’s something I’m still aiming for.

The most difficult challenge I faced was really a giant snowball. I had actually migrated to Swift 3 about a week after GM but I put it on hold due to some issues with ATS (before the website was upgraded). Another gotcha was that Swift 3 changed the way that implicitly unwrapped optionals work when converting to strings. But the real problem was testing the migration. I wanted to be real safe that the upgrade would work but I couldn’t download the App Store build because I had taken it down. I also couldn’t make a dev build of the production version because it was Swift 2.2 code, which cannot be loaded on my iOS 10 device.

In the end I did a few tests and opted to just ship it because the production version wasn’t working anyway. Luckily everything went well!

A major point of failure is depending on other services but it’s the reality of current apps. Well, at least the new website supports forward secrecy.