Archive for the ‘Demoing and Teaching’ Category

Teaching collections: shifting paradigms and breaking rules

Just because some things look alike and may act alike at some level, doesn’t mean that they should be taught at the same time, under a unified umbrella of learning. Consider bagels and donuts. They are both toroids . You can layer several instances onto a stick for storage or serving. You can cut them both in half. If you have no taste or sanity, you can place custard — or, cream cheese, salmon, onions, and capers — interchangeably between the two sides of either item.

Despite these common API surfaces, their use-cases, edge conditions, and recipes share little overlap. Conformance to ToroidFoodstuff does not correlate with each preparation of dough, the cooking process, or the serving and accoutrements associated with either food.

So why do we always have to lump arrays, sets, and dictionaries into a single lesson on collections?

A new language learner has little interest in traversing dictionaries, although it’s possible, or taking a set’s prefix, which is also allowed. Nor are new learners always prepared to take on optionals, the core return value for dictionary lookups, early in the language learning process.

I’ve recently spent some time helping to outline an introductory sequence for Swift learning. I pitched eliminating collections as a single topic unto itself. I want to reject superficial similarity and build language skills by introducing simple, achievable tasks that provide measurable and important wins early in the learning process.

Take arrays. They can store numbers and strings and more. You can grow them, shrink them, slice them. They have a count. They have indexes.  Arrays are perfectly matched with iteration in general and for-in loops in particular. Arrays and for-in iteration work hand-in-hand. So why not learn them together?

The answer is generally that arrays belong with collections and for loops belongs within a larger set of iteration topics. Ask yourself whether new coders actually need while and repeat-while loops in their initial approach to the language? How often in normal Swift coding do you reach for those two for simple reasons in simple code?

I’m not saying while-loops shouldn’t be taught. I’m trying to figure out what sequence of incremental learning provides new Swift developers with the most coherent set of basic tools they need to express themselves and expand their understanding over time.

Every classroom minute spent mastering while is a minute that could expand and practice for. Introductory lessons should focus on the core terms and patterns most commonly used in the workplace. Expressive language vocabulary can always be expanded through practice and engagement. Classroom minutes represent the restricted path.

Dictionaries, I argue, should be taught late. Every lookup is tied directly to optionals, a dictionary’s native return type. And optionals are quite a conceptually heavy topic. Dictionaries are the perfect pairing.  The type is a natural source of optional output, and an opportunity to discuss nil-coalescing and default fallbacks.

From there, you can pull in failable initializers, and optional chaining.  Dictionaries also lend themselves to advanced concepts like (key, value)-based for-in loop tuples, the key-value basics of Codable, and how custom structs relate to key-value coding, not to mention the entire conversation about nil, errors, try?, and more.

As for sets, well, I love sets and use sets, but are sets even appropriate for new learners outside of some sense of “completionism” learning? Should they be taught only because they’re one of the “big three” collection types? I’d argue that people should learn sets when they are already proficient in core language basics, not in the most introductory setting.

For example, you can tie sets into a lesson on view touches. Just because they’re a collection doesn’t mean that the newest students have to learn every collection right away, just as they don’t need to learn NSDictionary, NSArray, and AnyObject, and so forth, in the first days or weeks of exposure to Swift.

Trying to structure a plan to create a solid foundation of incremental learning is a challenging task for any non-trivial topic. When it comes to Swift and Cocoa/Cocoa Touch with its vast range of potential interests, ask the questions: “What core concepts and patterns best reward the language learner with immediate benefit?”, “What grouping conventions should be tossed overboard to better focus on the skills with highest returns?”, and “What critical paths allow learners to proceed towards measurable skills and performance with the least overhead?”

Justify each topic with an answer that’s not “it’s covered that way in the Swift Programming Language book”, especially when working with new learners versus developers moving into the language with existing programming experience. And even when teaching more experienced students, let the daily realities they’re trying to move towards mold the curriculum of what you choose to teach.

The best learners teach themselves. The best curriculum sets them up to do so.

Preparing to teach/demo

Normally I use a separate account to present talks and demos but I’ve recently taken up a more regular instruction gig and in doing so, it’s too inconvenient to move from my main account. My main account is where all my development tools and code are a few clicks and keystrokes away. The demo one is very safe for public presentation but also very distant from my workflow.

To address this, I’ve built a demo-setup utility in Swift. I thought I’d share some of the features and approaches. A lot of these were non-trivial to track down in terms of time and I thought having them in one place could be useful to some of you reading my blog.

If you have others to share, please let me know.

Desktop Wallpaper

I use Backdrop from Apps from Outer Space to cover my normal desktop with a plain and  boring background. Set up preferences in the app and then use open /Applications/Backdrop.app / killall Backdrop to toggle. It covers your wall paper without having to set it back to your favorite picture each time you enter and leave demo mode.

Do Not Disturb

Automate DND with AppleScript. I grabbed code off the web, letting me enable and disable do not disturb mode. (Make sure to enable Script Editor in Accessibility so they’ll run: Settings > Security & Privacy > Accessibility > Allow the apps below to control your computer.)

I didn’t make these pretty or write the osascript stuff into my code. They’re just two scripts in ~/bin right now. At some point, time allowing, I’ll unify these into a single script or app but as they work for now, shrug:

Desktop Icons

I keep a lot of work on my desktop that I’d prefer not to share. It’s easy to hide and show my desktop icons with a simple defaults command:

defaults write com.apple.finder CreateDesktop false; killall Finder"

Substitute true for false to re-enable.

Keyboard Maestro Macros

I not only quit email (killall Mail) but I also disable my Keyboard Maestro shortcut so I don’t accidentally re-launch it from muscle memory.

osascript -e 'tell application "Keyboard Maestro" to setMacroEnable "8E84EF4C-13F8-41AB-85EC-44AF70A52909" without enable'

Grab the unique identifiers for troublesome shortcuts from the files stored in ~/Library/Application\ Support/Keyboard\ Maestro. Use with and without enable to automate the macros off and then back on.

Safari History

No one wants their personal browsing history to pop up during demos in Safari as part of auto-completion suggestions. (Imagine, if you will, typing “s”, and having all your sloth sites listed as possible completions. Or, heaven forfend, things worth than sloth sites.)

If you use iCloud bookmarks, you can disable iCloud, remove your history and bookmarks files from ~/Library/Safari, and relaunch Safari (open /Applications/Safari.app). To re-enable, restart iCloud and wait for the data to sync back to your Mac.

I automated file deletion (actually, moving the files to another location) once iCloud is off and after quitting Safari (killall Safari). However, I didn’t automate enabling/disabling iCloud Safari bookmark sync from the command line. Instead, I used open 'x-apple.systempreferences:com.apple.preference.icloud' to get me to the right place for a single check mark toggle.

I hide my favorites bar:

defaults write com.apple.Safari ShowFavoritesBar-v2 false

Use true instead of false to restore.

You may want to limit Autofill and Search options (Safari > Preferences > Autofill and Search). I didn’t as they don’t really impact my presentations. I’m okay with Safari providing Search Engine-supplied suggestions, especially when searching for tech topics, as for me these are features not bugs.

System Calls

Here’s my ancient code to perform system calls to execute all the setup and teardown without using system(). Although lightly updated, I haven’t spent a lot of time improving something that works. If you have better solutions, please let me know:

extension NSString {
  /// Trim output
  var trimmed: String {
    return self.trimmingCharacters(in: .whitespacesAndNewlines)
  }
}

/// Execute a command as a shell script
@discardableResult
func perform( _ command: String) -> [String] {
  let task = Process()
  (task.launchPath, task.arguments) = ("/bin/sh", ["-c", command])

  let pipe = Pipe()
  task.standardOutput = pipe
  task.launch()
  
  let data = pipe.fileHandleForReading.readDataToEndOfFile()
  task.waitUntilExit()

  if let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)?.trimmed {
    return output.components(separatedBy: "\n")
  }
  
  // Something went wrong
  print(task.terminationStatus); return []
}