In Defense of Bubble Sort

Bubble sort is an algorithm with a very bad reputation. Robert Sedgwick, in Algorithms in C, notes that bubble sort is “an elementary sorting method” and “it does much more work” than it needs to. Donald Knuth is much more harsh when he states “the bubble sort seems to have nothing to recommend it, except a catchy name…” in the Art of Computer Programming.

Like a an actor valued only for his good looks bubble sort is an algorithm an enterprising coder should probably not admire.

Why is bubble sort so bad? Why does decent computer society advise young and impressionable software engineers avoid it? Why am I devoting a whole blog post to the ugliest sorting algorithms?

TIL: You can learn more from the flawed than you can from the flawless.

I’m not going to tell you why bubble sort is so bad. But before you google it why not try to figure out on your own?

The truth is that modern programmers don’t usually implement any standard sorting routines on the job—even the good ones! Generally there exists a collection class or library that is well written and well tested. If you have a mentor she will tell you not to bother with your own interpretations of the standard body of algorithms. That problem as been solved.

However, I think you’re missing out. Knowing now to implement well known algorithms can help you understand when to use them, what their strengths and weaknesses are, and how to talk about them. Like in a job interview.

Bubble sort is a great place to start. In order to understand why it’s so bad you have to understand big O notation, how algorithms are classified, and how the ordering of input data impacts the performance of an algorithm.

It’s my opinion that bubble sort is only the most terribad sorting method in the platonic world of absolute randomly unordered data. Bubble sort is actually very appropriate for error detection or for data that is already mostly sorted. You know, the kind of data that you are likely to run into in real life.

// Bubble sort

func bubble(inputList:[Int]) -> [Int] {
    var l = inputList
    var t = 0
    var swapped = false
    
    repeat {
        swapped = false
        for var i = 1; i < l.count; i++ {
            if l[i-1] > l[i] {
                t = l[i-1]
                l[i-1] = l[i]
                l[i] = t
                swapped = true
            }
        }
    } while swapped
    return l

}

var results: [Int]

var randomList = [5,2,7,8,1,9,0,3,4,6]
results = bubble(randomList)

var orderedList = [0,1,2,3,4,5,6,7,8,9]
results = bubble(orderedList)

var semiorderList = [0,1,2,3,4,9,6,8,5,7]
results = bubble(semiorderList)

First Day of the Year

Welcome to 2016 day one. Imagine if on today we could accurately predict what will happen in 2016? We could write a blog post with predictions and then gloat when they all come true!

Here are some of the outcomes I would like to be able to predict:

  • Which movie will win best picture?
  • Which candidates will win the democratic and republican nominations and from there win the Whitehouse?
  • Which football team will win the Super Bowl and which baseball team will win the World Series?
  • Which stocks should be bought and which should be sold?

But it’s hard to predict questions like these for several reasons. We don’t have all the facts and we don’t know how to rank the facts we do have. The facts can and most likely will change. And even if we have everything we need to make an accurate prediction, it would still only be a probability and even if an outcome is 99.999% likely to happen there is still a slim chance, 0.0001%, that it won’t happen.

One approach to predictions is to use the wisdom of the commons and just ask people what they think. This how opinion polls work. The problem here is that much of the time people don’t know their own opinions and how a question is asked creates bias towards an answer. Not to mention that people just change their minds over time which makes for stale predictions.

Another approach is to use the wisdom of the market and create a marketplace where people can bet on outcomes. This is really what the stock market is. The prices of Apple, Microsoft, or Alphabet shares aren’t a valuation of what those companies are worth today but what they will be worth at some point in the future. Sadly, the stock market has a spotty record at predicting the future health and success of a company.

And you can always ask an expert, usually the least accurate way to make a prediction, what she thinks is going to happen. There are enough experts out there that one or two, out of hundreds or thousands, ends up getting lucky and predicting accurate outcomes. There’s a movie out now about how 3-4 people predicted the mortgage crisis of 2008. Sometimes even if you know the future other people are not going to listen. They can’t! They are too invested in the present to make the changes needed to avoid catastrophe. And a thousand years from now we might lean that the financial meltdown in 2008 prevented a worse outcome!

Alan Kay and Abraham Lincoln both said “The best way to predict the future is to create/invent it.”

Given the difficulties involved in making accurate and reliable predictions and the nature of probability it best not to focus on guessing the future. IT is a more productive activity to help bring about the future that you want happen. Both Kay and Lincoln were pretty smart guys!

So here are some of the things I’d like to make happen in 2016…

  • I’d like the Internet to go faster so I’m going to do my best to speed up the performance of websites, mobile apps, and services I’m responsible for. Waiting for resources to load is killing all of us. We don’t need new tools and frameworks to speed up the Internet. We just need to do our jobs better!
  • I’d like there to be less misinformation and more accurate information available on the Internet so I’m going to encourage thoughtful, civil, responsible people to blog and post more. Maybe that will crowd out some of the noise.
  • I’d like more people to enjoy Math and Science and coding so I’m going to be more an advocate of learning Calculus in middle age, keeping up with Science at any age, and learning to code from non-Computer Science backgrounds. (I love music, novels, and movies but Geometry and Algorithms deserve appreciation too!)

I predict these tasks will be tough but I’ll make some progress—especially since a whole lot of other people are working toward the same goals.

 

Last Day of the Year

It’s December 31st 2015 and the so-called last day of the year. It sounds so final. 2015 is over and done with. If I had anything that had to be done in 2015 and didn’t get done, well, It’s game over.

But really it’s not the last day of anything important. Sure, it’s the last day of the 2015 tax year. And I’m sure there are some other legal entities that officially expire at midnight today. But these are just temporary rules we set up to police ourselves and not laws of Nature.

Nature has cycles and repetition and patterns but not calendars or tax schedules. And Nature’s cycles are much more sophisticated than our rules and regulations can model. None of our human calendar systems really fit the orbit of the Earth around the Sun or the revolutions of the Earth around its axis or even the orbit of the Moon around the earth. The tradition of ending and starting the year in the middle of Winter is an cultural one. It pre-dates the Romans but for our culture the Romans were the core influence. In celebrating New Year’s Eve we’re celebrating a Roman tradition that includes a tribute to Julius Ceaser and the two-faced god Janus. The Romans felt remorse about killing Ceaser so they kept his calendar and voted him into a god on January 1st.

So what does the last day of the year really mean for you and I? Is it something we should take seriously? Is it just an excuse to have a party at midnight? Probably.

Personally I believe the last day of anything (years, sprints, baseball seasons) is good for two important functions: First, for better or worse, it forces us to pause. Take a break. Spend time with friends and family and ourselves. Taking a breather is a great idea in a 24/7 society. When I was a kid TV networks shut down overnight. Even if you wanted to watch TV all night you could not. You have to take a break. We don’t have that tradition any more. Cable TV and the Internet never go offline (on purpose).

Second, for very good reasons, the last day of anything forces us to reflect. Did we get done everything we wanted to accomplish? I hoped to lose 100 pounds in 2015. That didn’t happen. Maybe I need to change my strategy? Maybe I need to change the goal? These are all good questions.

If I could share some advice for a happy and healthy 2016, this is what I would advise: Take frequent breaks. Spend more time alone. Reflect on the impact of your actions and your enthusiasms on others. Don’t take things too seriously. Before you hit submit on that blog post, tweet or facebook message pause and reflect.

Happy New Year!

Identity used to sign executable no longer valid

The last thing I wanted to do on a Sunday morning is write a blog post about an an Xcode executable problem. What I had planned to do is test my most recent Swift 2.0 SpriteKit game on my iPad and iPhone. Last night I got a “Identity used to sign the executable is no longer valid” error when attempting to run my code on a real device. Since it was around midnight I took the message a notification that bedtime had arrived. Besides, a quick search on StackOverflow would surely solve the problem and if I got on SO now I would be up all night nosing around.

This morning I got the same message and found a post on SO that started  four years ago with two pages of answers: The identity used to sign the executable is no longer valid. It’s been viewed 66K times and covers many ancient versions of Xcode. The top answer simply said to restart Xcode. Indeed, restarting, rebooting, or re-installing is always a great answer! So I tried the first two (restarting Xcode and rebooting all my devices) but no joy. And it’s a cheap answer. 99% of computer problems are temporarily solved by powering down and up the server or device but the root cause sits like a malignant elf in the machine, biding it’s time, ready to strike again.

So I figured it out. My problem, in any case.

Last week I was giving a talk at SUNY Buffalo (shout out to Prof. Hartloff). It’s just far enough away from NYC that I had to stay overnight. I took a MacBook Pro that I don’t ordinarily use for development. When I was working on my new game and testing it my iPad and iPhone (to get actual frame rates and the feel of touching the screen) Xcode discovered that I didn’t have an iOS development certificate on that MacBook and asked me if I wanted to revoke my current cert or copy it over from another machine. Since I didn’t have it I said revoke. Xcode did what ever it does and created me a new iOS dev cert associated with that particular MacBook Pro.

Note to Apple: There has to be a better way for Apple certified developers to manage their certificates in this age of clouds and connectivity. Can’t these certs reside on Infinite Loop server?

Enough backstory!

If you get the dreaded “Identity used to sign executable no longer valid” error and restarting your Xcode doesn’t work here are the steps that should fix it for good.

Go to your Apple developer account certificate overview and read carefully and completely about how to manually manage certs and provision devices. Once you understand what you need to do it’s relatively simple.

  1. Revoke and delete all the could certs and profiles of devices you no longer own that have build up over the years. Clean it all up.
  2. Then, following the instructions from Apple recreate your iOS development and distribution certificates.
  3. Re-provision your iOS devices.
  4. Download your certs and provisioning files and reinstall them into your Mac’s keychain.
  5. Clean and build your app.
  6. Now it should run on the iOS devices you’ve provisioned nicely.

Note to You: Xcode is no longer managing your certs and profiles. But that’s OK. It was doing a bad job anyway.

Post Script

Why didn’t I post this info to Stack Overflow? Because this is a pretty radical solution, not without risk. SO, for better or worse, has been come the place for copy and paste solutions that have not aged gracefully over time. Don’t get me wrong–I love Stack Overflow, recommend it, and use it all the time. But sometimes it’s not safe to post an answer to a problem that requires reading comprehension.

Lucky for you and me, my unpopular blog post will probably be the last item in your search for solutions to apple certification problems.

Quick Thoughts Apple Watch Sport, AppleTV, Magic Trackpad 2, iPad Pro

This year I had a lot of Apple product to buy. Other than buying a new iPhone every couple of years the rest of my Apple gear didn’t need updating. iMac, MacBooks, and iPads got a little faster, a little thinner, and a little more expensive but not so much that I really needed break down and acquire new ones. Being an Apple fan is an expensive hobby so it was kind of nice to have nothing new to buy. But then came 2015 and all these new toys!

Apple Watch Sport

Positives: I wear it and use it every day! I like the calendar, messaging, and fitness notifications. The iPhone and Apple Watch are very well integrated. It’s great to respond to messages and phone calls without taking out my phone. (I feel a little silly talking like Dick Tracy to my wrist.) I did like the game LifeLine (which is well integrated as a text adventure game) for a little while. I have a nice collection of wrist bands.

Negatives: I’ve turned off 90% of app notifications. None of the 3rd party apps, expect HipChat, have been useful. There is a lag when accessing some apps that makes me impatient. Charging the watch with the disk is a little weird. The sport wristbands bothered my skin so I’ve switched to an inexpensive leather band. I’d like to see more games like LifeLine.

AppleTV

Positives: The whole family loves it. Crossy Road was a big hit and the first time we’ve gathered in front of the TV to play a game since before the kids graduated from High School. The user experience is excellent. Apple Music and Photo on the big screen are awesome. AppleTV is our go to Netflix, Hulu, and HBO Go tool. I want to write an a game for it!

Negatives: I don’t have a 4K TV but I’m worried that AppleTV doesn’t support 4K. (Is that irrational FOMO?) Most of the AppleTV apps are not exciting us. The remote is hard to deal with except when playing a game.

Magic Trackpad 2

Positives: No more environment killing batteries required. The force touch feature is cool for previewing web pages from links. It bigger and more comfortable for gestures.

Negatives: I keep forgetting to use force touch.

iPad Pro

Positives: For me the iPad Pro is the break out hit of Apple’s current product line. The Smart Keyboard is not terrible and the Apple Pencil is amazing. I like to draw and it’s the best drawing experience I have experienced (and I have tried just about every tablet and stylus, including the Cintiq). For work the iPad Pro is 75% of a laptop replacement. It turns out for email, word process, presentations, spread sheets, messaging, and web browsing, I don’t need a complete desktop operating system in my lap–Spit View is enough. The screen is as book as my MacBook Air with higher resolution. Reading ebooks and PDFs is a pleasure. And watching movies and TV is like having a personal cinematic experience with surround sound at my hand. It’s simpler and feels faster than the Surface Pro or Chromebook. The Apple and Microsoft App for the iPad Pro work well. Byword, Coda, Procreate, Graphic, and Assembly are creative iPad Pro apps I recommend. I’ve never wanted to develop an iPad app before (iPhone was all that mattered to me as a dev).

Negatives: It’s big (but not heavy). I wish I could fold it in half. I want the keyboard to light up. I want a place to put the pen when I’ve not using it. Old iPad apps look ridiculous on the iPad Pro. Not all app support the split view feature. The Smart Keyboard doesn’t work well with developer websites like Cloud9 and CodePen. The Facebook iPad is stale. I’m afraid that charging the pencil in the iPad Pro’s power port will break it’s lightning connector off!

It’s a great time to be an Apple fan and an Apple developer. There are still plenty of problems with the Apple ecosystem. Apple News is slow and poorly designed. The App store has discovery, spam, and monetization problems. The Safari browser needs to catch up to Chrome. But Swift is the best programming language since SmallTalk and now opened source. So there’s that. It all evens out.

Four Tips for Xcode Storyboard Users


Apple’s Xcode Storyboard is both your best friend and your worst enemy when it comes to developing state-of-the-art iOS, Mac OS X, tvOS, and watchOS apps. Sometimes, what would be really hard, like associating a function with a gesture is quick and easy. Sometimes, what should be easy, like toggling a property, requires hunting down a checkbox in an inspector that only shows up with the proper object selected.

Below are three common problems with Xcode Storyboards and what works for me to resolve them. Xcode Storyboard evolves with every release: these tips work for Xcode 7.1.1.

1. Is your Storyboard rendering as XML source code and not graphics?

Screen Shot 2015-11-23 at 9.56.10 AM

Somehow, someway Xcode magically switches the view of a storyboard from Interface Builder – Storyboard to Source Code. No matter, just secondary-click on the name of the storyboard in the Project Navigator and select Open As -> Interface Builder – Storyboard.

What is an Interface Builder? Back when the Mac OS X was the NextStep OS Interface Builder was a developer tool for creating views. This ancient app lives on the deep sub-basement of Xcode and sometimes unexpectedly appears.

2. Is your app blank in the simulator?

Screen Shot 2015-11-23 at 8.57.25 PM

It might be that you need to select your main view controller in Main.storyboard and set the “Is Initial View Controller” checkbox in the Attributes Inspector.

This usually happens when you have deleted the default view controller on a storyboard. You know, when you want to start over.

If the default storyboard is still around you can drag the Storyboard Entry Point arrow from the original view controller to point to your main view controller.

3. Having a hard time control-dragging between UI objects and the Document Outline?

Screen Shot 2015-11-23 at 9.13.06 PM

You’re not alone! You can use the Connections Inspector to drag-create connections without holding down the control key.

In the inspector just drag from the circle to the controller that you want to your UI object connected with.

Make sure you have the correct UI object on the storyboard and/or in the Document Outline selected so you connect the right things together.

4. Auto layout constraint values driving you batty?

Screen Shot 2015-11-23 at 9.14.46 PM

Setting up constraints is one of the most unintuitive parts of Xcode’s storyboards. Part of the problem is there a several ways to do it and Xcode doesn’t always seem to do what you ask it to do. Don’t worry! You can use the Document Outline to selection each individual constraint and adjust it’s values in the Size Inspector.

Generally I use the Align or Pin menus to initially set the auto layout constrains for an UI object.

Then I use the Resolve Auto Layout Issues menu to make the UI object conform to the initial constraint values with Update Frames.

Finally, since the UI object always looks weird I select each constraint in the Document Outline, adjust it in the Size Inspect, or delete it and start over.

There you go Xcoders! If I thinking of anything else I’ll update this post!

Fun with Core Graphics and Swift Part 2

Screen Shot 2015-11-09 at 9.24.06 PM

Hey, you have 10 minuets, don’t you?

Then you can add pinch and rotate gestures to our fake-genigraphics app. I didn’t realize it would be this easy. But sometimes Apple’s developer tools engineering team does something amazing–and gesture recognizers are super amazing.

A good way to start is to read the UIGestureRecognizer Tutorial on Ray Wenderlich’s website. I’ve said good things about Ray before. I don’t know him. However, Ray and his team of technical authors just have a way of spelling things out 100 times more clearly than Apple’s developer documentation.

After you’ve read the tutorial open up ViewController.swift in the fake-genigraphics project. Delete the boilerplate code in the ViewController class and replace it with the following code (from the tutorial):

    @IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) {
        if let view = recognizer.view {
            view.transform = CGAffineTransformScale(view.transform,
                recognizer.scale, recognizer.scale)
            recognizer.scale = 1
        }
    }
    
    @IBAction func handleRotate(recognizer : UIRotationGestureRecognizer) {
        if let view = recognizer.view {
            view.transform = CGAffineTransformRotate(view.transform, recognizer.rotation)
            recognizer.rotation = 0
        }
    }

Each of these functions is decorated with the @IBAction tag. That means we’re going to hook them up to events from our project’s Main.storyboard. This part still vexes me. I want to do everything in code and not use drag and drop to wire up events with functions (and properties with variables). Especially since I am left handed and to do a key part of the drag and drop I have to use the control key which only exists on the left side of my nifty Apple Magic Keypad.

Enough whining. Time to drag and drop!

Open up your Main.storyboard in the fake-genigraphics project. In the Object Library on the right find the section near the bottom with all the gesture recognizers. Drag a Pinch Gesture Recognizer out from the library and drop it on the BackgroundView in the storyboard. Now for the hard part: In the Document Outline on the left control-drag the Pinch Gesture Recognizer entry up and drop it on the ViewController entry. On the pop-up menu that suddenly appears choose Sent Actions Handle Pinch. (So weird).

Do these same steps again with the Rotation Gesture Recognizer. What you are doing is connecting events from the gesture recognizers to the functions in the ViewController marked with @IBAction.

Guess What? You’re done! Run your app in the simulator and on your iPhone or iPad. You can now zoom in and out and rotate the Background View like a pro. Notice how responsive and smooth the animation is. Alas there seems to be limits on how far you can zoom out. And you can’t rotate and zoom at the same time. I have trouble with rotating with my left hand. I’m convinced that nobody at Apple is left handled!

Fun with Core Graphics and Swift

Screen Shot 2015-11-07 at 12.15.12 AM

A long time ago in a galaxy far, far away… I was a computer graphics artist. Specifically I was a Genigraphics
console operator. I worked the night shift creating illustrations and slides with vector graphics for big corporations. This was the early 1980s and fast, cheap personal computers with color graphics had not quite been invented yet. Later when I learned to program the Apple Macintosh I had a head start–I had created hundreds of vector images using computer graphic primitives by hand! The ability to draw lines, circles, and rectangles with code blew my mind.

I’m thinking it would be fun to do some graphics exercises with Swift and Apple’s Core Graphics. Maybe recreate some of those Genigraphics images from 30 years ago. Somewhere in the basement I have a box of 35mm slides and 8″ floppy disks. Probably not readable but I should be able to create a few images from memory. Genigraphics was the ancient ancestor of PowerPoint and Keynote. Every element in an illustration or on a slide had to be created from a graphic primitive. A gradient color fill was created with 30 or 40 overlapping rectangles, each with an incrementally different color.  And remember all the primitives were created by a human hand!

One of the most time consuming effects involved creating a grid for a background. It involved much duplicating, aligning, and counting.

So let’s create a clunky Genigraphcis grid in Swift using Core Graphics and display it in a UIView on and iOS device!

Launch Xcode and create a new iOS single view application. Make sure you choose Swift as the language. It doesn’t matter what you call your app. Run the new blank app just to make sure Xcode did it’s job.

Kill the app and go back to Xcode. Create a new iOS Cocoa Touch Class source file. Call it BackgroundView and make it a subclass of UIView. Go to your main.storyboard and select the View in your View Controller. In the Identity Inspector set the class of the View to BackgroundView.

Run the app again just make sure it builds and then kill it and return to Xcode.

Select BackgroundView.swift. You should see a drawRect function provided by Apple. Delete all the comments so it’s ready for some grid code…

override func drawRect(rect: CGRect) {

}

This function is called whenever iOS needs to paint your view on the screen. The rect is the area that needs to be painted. The first time drawRect is called the rect is the same size as your view. Later on when drawRect is called the rect is just the area of the view that needs to be updated. So I get the view width and height from the bounds. I’m also assuming the origin (left, top corner) is always 0,0. Add the following code to your drawRect function so you can get the the bounds width and height and compare it to the rect (technically called the “dirty rect” because that is the part of the view that needs to redrawn).

        let viewWidth:CGFloat = self.bounds.width
        print("viewWidth \(viewWidth)")
        print("rect.size.width \(rect.size.width)")
        
        let viewHight:CGFloat = self.bounds.height
        print("viewHight \(viewHight)")
        print("rect.size.height \(rect.size.height)")

I like to define all my important variables together near the top of my functions because I always know where to find them. Swift let’s you declare and define variable throughout the code. (I only use that freedom for unimportant “throw away” variables that are used inside loops and other control structures.)

Add the code to define your gridlines starting points, lengths, and line width.

        let x1:CGFloat = 0.0
        let x2:CGFloat = viewWidth
        
        let y1:CGFloat = 0.0
        let y2:CGFloat = viewHight

Core Graphics likes all your coordinates to be CGFloats. Since the resolution of an iOS device can be just about anything size these coordinates represent an idealize space as points. On a high resolution iOS device, like an iPhone 6s Plus you’re going to get 3 pixels for every point. My iPhone 6 Plus has a resolution of 1242 × 2208 but Core Graphics gives me 414 × 736 to work with. I’m just going to live with that for now.

I want a nice square grid so I use the either the viewWidth or viewHeight (which ever is smaller) divided 15 as the length of a grid cell.

        let cellLength:CGFloat = min(viewHight, viewWidth) / 15
        print("rowHeight \(cellLength)")

Now it’s time to set the style of our lines: color and width. As I recall Genigraphics only had 64 colors or maybe 128. I’ll figure that out next weekend. In the meantime I choose blue with a width of 2.

        let lineWidth:CGFloat = 2.0
        
        let context = UIGraphicsGetCurrentContext()
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        
        let components: [CGFloat] = [0.0, 0.0, 1.0, 1.0]
        let color = CGColorCreate(colorSpace, components)
        
        CGContextSetLineWidth(context, lineWidth)
        CGContextSetStrokeColorWithColor(context, color)

Wow! That’s a lot of code just to set the color and line width. It’s a little complicated because Core Graphics is context-based. You have to get the current graphics context and modify it to draw. In the code above I’m also creating a color the hard way via a color space and RGBA (Red Green Blue Alpha) color values. All this work will let me have a fine degree of control of the color of the gridlines later on.

Finally, I’m going to draw my horizontal and vertical gridlines!

        // draw horizontal lines
        var i:CGFloat = 0.0
        repeat {
          
            CGContextMoveToPoint(context, x1, cellLength + i)
            CGContextAddLineToPoint(context, x2, cellLength + i)
            
            i = i + cellLength
            
        } while i < rect.height - cellLength
        
        
        // draw vertical lines
        var j:CGFloat = 0.0
        repeat {
            
            CGContextMoveToPoint(context, cellLength + j, y1)
            CGContextAddLineToPoint(context, cellLength + j, y2)
            
            j = j + cellLength
            
        } while j < rect.width - cellLength

I’m just fooling around at this point so I don’t know if two repeat loops is the most efficient way to draw a grid. Right now I’m just happy to see a grid show up. I’ll optimize it later–if needed! To draw my lines I start at 0 and draw each line a cellLengh apart. CoreGraphics is a bit like Logo’s turtle graphics: I have to add drawing commands to the context, building up the image step by step behind the scenes.

If you run the code that this you will see nothing! Go ahead… I dare you!

That’s because you need to tell the graphics context to blast your drawing commands from the context on to the view. One line of code does it.

        CGContextStrokePath(context)

If you have been typing along you now have a custom UIView that draws a grid properly no matter now you hold your iPhone.

If you want to see the grid on your storyboard add

@IBDesignable

just above the class declaration. But be careful! Buggy Core Graphics rendering can freeze up Xcode. (It happened to me while writing this code.) I keep @IBDesignable commented out until I know my drawing code is working.

You can find all the code on GitHub.

Next week I’ll add some more complex drawing in the OG Genigraphics style. This is a good start for your own explorations. Have fun and don’t worry! You can’t blow up your computer by writing code.

The Desktop Strikes Back

Darth vs Obi Wan

I was surprised and delighted by Microsoft’s introduction of the Surface Pro 4 and and Surface Book. I have a feeling that Microsoft is doing something really interesting: Bringing back the general purpose personal computer. Wait, wait, I know what you are thinking! It’s all about the phones and pads and the Internet of things! I get it! I’m not some old guy pining for the days when PC were king and 640K RAM was a luxury. Well, actually, I am that old guy. But I have not personally coded a desktop app, native or web, since 2010. Everything thing I do for work or play is meant for mobile devices. I’m usually the guy in the conference room saying “We need to focus on Mobile!” and “kids today don’t even know what a desktop is.”

But Microsoft and some of the recent changes to Mac OS X in El Capitan are making me think there is some life yet left in the PC.

While Apple is targeting coffee shop-consumers by making MacBooks  lighter but less powerful or targeting highly specialized markets with high-resolution workstations, Microsoft has reminded me that there is a vast middle in this market. And that middle is still mostly using desktops that run Windows. There hasn’t been growth in the middle for a while but then again there hasn’t been much product to spur growth.

Every year I want to buy a new phone. I swear have every iPhone model in a drawer starting with number 3. But buying a new computer is something I do only when I absolutely must. There just isn’t any reason to upgrade a contemporary desktop or laptop. And looking at where Apple and Dell and other PC manufacturers were going it seemed to me that PC were just getting specialized. The middle ground was a nomad’s land of crappy plastic slow PC encircled by ultra-lights and gaming rigs.

A while back I bought a Surface Pro 3 with it’s pen, keyboard cover, and Windows OS. I found it… interesting. A had to pair it with an Apple Wireless Bluetooth Keyboard to get a decent typing experience. And Windows 10 is still a little rough. Ok, Windows 10 is a lot rough. And confusing. But it getting better.

I feel a great nostalgia for all things from the original Bill Gates/Steve Jobs era. I will probably end up acquiring a Surface Pro 4 or a Surface Book. I’m pretty sure either of those products will not displace my iMac 5K as my go-to general purpose computer for coding, blogging, podcast editing, and cartooning. (Everything else I do, I do on my iPhone.)

But heck, I want Microsoft to win here and bring the PC back to the forefront of the consumer electronics revolution. So here are five suggestions or tips for MS that would have me running to the Microsoft Store as if they were selling Tesla Model Xs at a deep discount!

Tip 1: Really rethink Windows and the UX of a desktop operating system.

I know MS got in trouble for removing the Start Menu. But seriously: There is no Start Menu in Mac OS X or iOS because for the most part the whole operating system is the Start Menu. Go back and look at the Xerox Star if you have to. Don’t try to mask complexity with a handful of easy-to-use screens hiding the real OS. When I worked at Apple we had a saying: “Every pixel counts.” It’s clear to me that on Windows some pixels count more than others.

Tip 2: Bring back desk accessories

I know that both Apple and Microsoft have failed at providing consumers with a library of little single-purpose applets that share the desktop with the bigger multipurpose applications. But, as guy who once wrote a mildly popular Yahoo Widget, there is real consumer value in DAs. I think the original Mac OS and PC DOS got it right: Apple’s Desk Accessories and Borland’s Sidekick provided little utility functions that were easy to access, simple to use, and fast to summon and hide. By contrast Apple’s Dashboard Widgets and Microsoft’s Desktop Gadgets were slow and clunky. These decedents of the desk accessory were too ambitious and missed the whole point. I want “info at my finger tips.”

Tip 3: Fix the menu bar or retire it

I was so excited when Mac OS X El Capitan enabled me to hide not only the taskbar but the menu bar as well. I hate the menu bar! It’s usually a dumping ground for every feature of an app randomly arranged. Long ago the menu bar had a formal structure. It was drilled into my head as a young software developer that menu titles were nouns and menu bar items were verbs. If I had a document menu then all the menu items were the operations that could be performed on documents. But right from the get-go both Apple and Microsoft ignored that simple and powerful idea. Almost all Windows and Mac apps have separate “File” and “Document” menus. I know that files are those objects that computer applications store data into but we tell consumers to call those things documents. Everyone is confused. And then there is the universal “Edit” menu which should be called the “Selection” menu. This might seem like small potatoes but I’ve learned trivial details are the stumbling blocks that kill product adoption.

Tip 4: Make the desktop a first class entity

Most flavors of Unix are doing the Desktop right and Apple and Microsoft are starting to get clued in. It should be very easy to set up and arrange windows on a desktop and have them stay that way for eternity. Like really forever and definitely between restarts and system updates. Adobe understands this and gives each of its apps a layout manager that allows artists to personalize and save their workspace. Context is everything. Humans are dumber in unfamiliar contexts and smarter in well known contexts. A desktop is really just a context of virtual objects. I think phones are easier to use, not because they are better designed than PCs, but because they naturally just have one context, one screen, at a time.

Tip 5: A list of five more tips

Bonus round!

  1. Don’t go too far trying to make the desktop UX the same as the mobile UX. They are two different use cases. Shortcut keys, content menus, and over lapping windows are great features and can’t really be replaced by gestures, hard presses, and split screens.
  2. Bring back BASIC or Hypercard or some kind of programming environment intelligent non-computer scientists can utilize to create real apps on their own. It’s not about workflow automation. Do not copy Apple’s lame Automator or evil AppleScript.
  3. Clean up your Windows Store. Be even more picky than Apple. Keep out the spam, copy cats, and useless garbage. But make sure users can continue to download and install non-certified apps. I know it’s risky but it’s also capitalism.
  4. Reactivate Windows third party developer base, not by enabling quick and dirty ports of websites into Windows apps but by continuing to empower and simplify and open Visual Studio. I went to one of the very first Windows developer events in Redmond in the early 90s. I got to shake Bill’s hand. I’m sure he doesn’t remember me but I really wanted to write Windows apps after that.
  5. Continue to revive and refine the general purpose personal computer that is great for everything and works for everybody. I don’t want or need a workstation. I do want to get a lot of work done. Instead of thinking like Apple, think like the Microsoft that re-packaged and made affordable the hoity toity graphical user interface in an open system for schools, small businesses, and nerdy kids.

Even if Microsoft succeeds with the Surface Pro 4 and Surface Book, the PC market will most likely continue to look to Cupertino and Redmond steal marketshare from each other. But unlike smart phones, pads, and household items with embedded microchips, PCs are programable–by users. And that is something worthy of a battle with the Empire.