Minuet in G

A few weeks ago I read this article about the right way to practice. The gist of the article is that we as human beings are able to do extraordinary things that we weren’t able to do a hundred years ago. The world record for a marathon a hundred years ago barely qualifies for a competitive marathon now. It isn’t that we have somehow evolved tremendously over the last hundred years. It’s that we’ve gotten better at learning and doing productive practicing.

Part of this resonates with me because of my experience with playing the piano as a kid. I was naturally good at it and no one ever made me practice or showed me a way to practice more effectively.

I progressed to a certain point and would play songs for fun and I just never got any better. I went to college and started taking music theory classes and I got overwhelmed by a bunch of stuff and shut down and just stopped playing.

I was still very interested in music and sound, but I abandoned music as a hobby. I moved out of my parent’s place about seven years ago and never brought my piano with me.

This topic interests me because I am seeing similar patterns of behavior with myself and programming. I am not going to say I feel I had the same aptitude for programming as I had for piano. I always felt incredibly stupid and out of my depth, which ironically is why I got good at it because I worked on it all the time.

I did targeted practice with programming where I would write a difficult piece of code over and over again until somehow my brain would process what it did and I would have an understanding of what the code does.

Unfortunately, there is not a lot of material out there for people who are not beginners. There was a great blog post about why programming is hard. When you’re a beginner, there is a lot of hand holding. There is a multitude of learn to code sites, including the one I used to learn to code, where you get walked through targeted practice that makes you learn better.

Once you get past learning the basics, however, you’re kind of tossed off a cliff to fend for yourself. My observation of the programming community has been that most people plug along until they reach a level of competency that allows them to be employed. We as a community assume that if a person has been programming professionally for 10 years then they must be better than someone who has been programming for three, but that is not necessarily the case. We tend to reach a level of proficiency and we don’t get any better unless we continue to push ourselves to improve.

But how do we do that? How is that measured?

It’s easy to see how you have improved with the piano. If you can tackle and master a difficult piece, then your results speak for themselves. If you aren’t getting any better in spite of hours of practice, then you’re doing something wrong. It isn’t that you have naturally hit your level of expertise, it’s that your not practicing effectively.

I also think that we tend to write off that we, as adults, are capable of learning extraordinary things. This other article talks about how impossible it is to take up chess at a later age because young children have vastly more potential to learn than adults do because their brains are flexible.

My reaction: So what?

I remember being a kid. I had no disciple. If I was good at something I didn’t work really hard at it and if I was bad at something I just avoided it altogether. I sucked at sports and running and I never thought that I could do anything to change that by working at it.

I basically squandered all of my childlike potential to be a super genius because I was stupid and didn’t do stuff. I refuse to believe that I am not capable of pushing myself now to be better than I was a year ago. I would rather believe in the first article about the effect of productive practice than be told that if I don’t start something by the time I am five that I am screwed and will never be great at anything.

So What Does This Have to Do with Minuet in G?

I am at my parent’s place today for Mother’s Day. One of my goals this year is to get my piano moved back to my house.

When you can't find sheet music...

When you can’t find sheet music…

I was curious about trying out this targeted practice thing with something I hadn’t done in a while, which was playing the piano. I was curious about why I never got any better. What did I do wrong besides not practice enough?

I picked Minuet in G because I believe it was written as a learning piece by Bach and I knew it was a relatively short and simple piece of music. I figured it was something I could sit down and get close to mastering in a few hours.

After hacking a solution to try and actually get the music in front of me, I sat down to practice for about an hour.

The first ten minutes of shaking off the rust were kind of demoralizing, but after I had warmed up a bit things got better.

The biggest thing I noticed while I was playing was that my fingers liked to overcomplicate things a lot. In the first half of the piece, the left hand does very little. It basically holds notes for long periods of time and doesn’t need to move around to hit the notes. I noticed that I had a strong urge to reposition my hand constantly even though there was no point in doing so. I would make a lot of mistakes because my hand was positioned in a place where it could not reach the notes.

Then, in the second half of the piece, where the left hand has more to do, my hand could not plan out where it needed to be. It would get very confused and keep hitting wrong notes. I think my brain felt like the only fingers that it had to work with were the thumb and first finger. Using the last two fingers on the hand always feels quite strange to me.

I also noticed that when I was working on the easier parts my brain would get distracted by being bored and I would stop paying attention and then I would make mistakes. This fits into what I remember as a kid. I liked fast pieces with a lot of movement on both hands because I would screw up easier stuff where I didn’t need to do as much because I would get distracted.

After I realized these issues, I was able to fix them. I would practice with the left hand by itself a lot and plan out how to avoid moving my hand as much as possible. I would get distracted and move it and I would force myself to only think about what measure I was currently playing.

By doing these things, I was able to improve much more quickly than I would have if I had just sat down and tried to play over and over again until I didn’t make a mistake.

How Does This Apply to Programming?

I don’t know yet.

I know there has to be some way for me to apply to programming what I did to the piano. I think it’s different in that with piano you know if you’re doing poorly immediately because you get the feedback of wrong notes. It is more difficult to know when you are programming badly because at a certain point you stop getting weird compiler warnings and stuff builds, but it’s not necessarily the best or fastest you can do.

I am going to continue to drive people nuts with my blog posts about the learning process because I find it fascinating and I don’t want to resign myself to the fact that I will never be a great programmer because I didn’t start when I was five. I think I can train myself like chess grandmasters and Olympic athletes can do. I don’t know how yet, but I have faith that it’s possible.

The Fig Tree

I have been doing some soul searching for the last six months or so. I have written on my blog about suffering from some massive burn out. I had reached a point a few months ago where I honestly didn’t think I could cut it as a programmer and thought about leaving the industry to do something easier.

I took some time off to regroup and figure out what I was going to do.

During that time I happened to have a lot of conference talks and trips that I had lined up a long time ago. While the constant travel was exhausting, it was genuinely wonderful to see so many members of the community. I got to see old friends and make some new ones.

I also had a chance to calm down and actually see what life was like if I wasn’t programming every day. Honestly, life without programming really sucks.

When I wrote my first shader program and debugged it I felt like I had come out of a coma. I knew that this was something I could do, but I knew I wasn’t approaching it properly.

I thought the problem was that I was programming too much. It isn’t that I was programming too much. I wasn’t actually programming enough in the right way.

Before when I was having emotional crises I would sit down with a programming book and actually work through the exercises. The summer I couldn’t find an internship my ex-husband lost his job. He was home all the time and that along with another situation lead to me having a nervous breakdown.

I went to a friend of mine, Stephen Anderson, and asked if I could squat at his company for a few days a week so that I would have a calm and quiet place to work. He was very kind and allowed me to work out their office for two months.

During that time, I worked through Chris Adamson’s “Learning Core Audio” book. I would come in, set up my computer, and type through all the exercises in the book. Doing that refreshed my soul and helped me learn a lot and get through that horrible period of my life.

I hit a point where I felt like I was too “advanced” to keep relying on tutorials and I tried to transition over to working on projects. But by that point I was working for people full time and working on various books and projects and sometime never came.

One of my goals in 2016 is to release an app. I quit my work at Ray Wenderlich, withdrew from my book obligations, and I put down the podcast so that I could focus all of my energy on this task. It’s May and I have nothing. So what do I do?

Focus

First thing I need to do: FOCUS!!!

I named this blog post after a quote by Sylvia Plath. The gist of this quote is that there is a woman who is privileged to have many different futures and opportunities. However, she can only choose one. Choosing one means giving up all the others and she can’t decide. As she sits indecisively she loses her opportunities because she waited too long.

This feeling of so many choices and none of them being real is a theme in many things. This theme shows up in the Harry Potter movies as The Mirror of Erised.

One of the things I have never publicly admitted before is that I do Tarot card readings. One of the cards is the seven of cups. This card symbolizes a person looking at many different goals and interests and possibilities but none of them are real because the person in the card hasn’t manifested them yet.

I talk a lot on here about my various interests. I like electronics. I like graphic design. I like audio and graphics programming. I like Swift.

I can’t do everything I want to do.

I talk about wanting to be an audio programmer or a graphics/Metal programmer, but if I am honest with myself I am not those things. I don’t have the right to label myself as such because I am not focused on it.

It feels good to say you want to do something. It feels good to buy books and put on various trappings of a person doing something. But the only way to manifest what you want is to put in the work and just fucking do it.

All of the things I am interested in require deeply focused effort and knowledge. I had a similar revelation when I was learning programming. I spent at least sixty hours a week for over a year just coding. I dropped all of my other hobbies and interests. I would have fights with my ex-husband because he wanted to go to a movie and I didn’t want to be torn away from my screen.

I miss that. I want to get back to that on something. I want there to be something that is so vitally important to me that I focus everything I have on it to the exclusion of all other things.

I had to step back for a while to figure out how to heal myself so that I can go back to being that person and to figure out how to avoid feeling like I did earlier in the year.

Work Efficiently

The biggest thing I can do is work efficiently. I need to avoid doing things that feel like work but aren’t. I need to code a lot. I need to make sure my focus is not fractured.

I also need to learn to disconnect from the keyboard. I am doing better in this regard. I bought a bunch of analog books that have nothing to do with programming. I have (mostly) stopped taking my iPhone with me to the bath tub.

I am deeply sad about abandoning my electronics shop in the basement. This post came about because I saw someone on Twitter posting a picture of their new Raspberry Pi setup and I really wanted to go out and buy a new Pi and a bunch of other stuff to do what they were doing. However, I have done this before. I have a giant nest of electronics components and Arduinos and Pis in the basement that are basically untouched.

I keep telling myself that I can work on it as a hobby. I spoke to my teacher Eric Knapp on Twitter yesterday about setting up a wood working shop in the basement. I have a weird obsession about setting up some kind of shop in the basement because somehow I think that having a non-programming hobby will solve all of my problems and life will feel meaningful again.

It’s all just me running away from reality.

I keep thinking there is some easy answer or escape from how I feel right now and there isn’t. Well, there is, but I don’t like where that route takes me.

If I want to go where I want to be, I need to embrace the hard road. I didn’t prepare myself for it last time and I ran out of food and had to go back home to lick my wounds. I know more now and I think I can do it.

I have to simply my life and just pick something and stick with it. I have to know that it’s going to be a long road and that I can’t let myself be distracted by the new shiny thing. One good and bad thing about programming is that there is not just one right choice to make. Someone who chose to learn something like Node.js isn’t kicking themselves because they didn’t learn Swift. There is a lot of opportunity in the programming world for a lot of people with a lot of various skill sets.

I talk to people who feel like they have to know everything because someone might need them to know PHP or Java or Perl.

You don’t have to do this. In fact, there are better opportunities out there if you specialize in something. I guarantee you there is a job out there for someone with deep knowledge of Perl. Choose your own adventure. Pick a path. Stick to it. Make something. Own it. Stop dreaming and manifest.

Practicing Scales

I have been rather discombobulated over the last several months. I had a number of upheavals in my life. I left a job and started another. I traveled to a new place every other week. I spoke at many conferences.

I have been running ragged for a few months now and I am trying to get myself back into a better mental state. Since I get to stay put for a while, I am trying to figure out a better routine for myself to help me shake off the last of my burnout and to prevent future burn out.

What I Do For a Living

One thing I have been struggling with is making time to code. I know this sounds incredibly stupid considering I am a professional programmer. Don’t I spend at least 40 hours a week coding? Isn’t that what I am being paid for.

Well… not really.

A lot of my job over the last year has been looking at other people’s code and debugging it. Or looking at other people’s code to learn how they did something. Or reading documentation to make a sample project to show how to do something.

I had a few large projects over the last year such as wrapping libXML2 in Swift. This project took between two and three months. The first month, at least, of this project consisted of me staring at code I did not understand and then staring off into space waiting for my brain to compile it. I had panic attacks that it would never click and I would fail and all hope would be lost. Then at some point I woke up in the morning and I understood the code. This happens to me a lot and I find the process quite terrifying. I keep worrying that it won’t all pull together for me this time and I am just living on a prayer.

Regardless, during this compile time, I did not code very much. I didn’t understand the code I was supposed to work with, so I couldn’t write anything. I couldn’t work on a tutorial or something else because it wasn’t what I was supposed to be working on. So I spent a good chunk of time walking around outside with headphones on waiting for my brain to make sense of things.

I don’t like this process.

Right now I want to learn C++. I am interesting in game engine programming, audio programming, and other low level programming that at this point is only being done in C++.

I went on Twitter and asked for some advice for resources. I got these responses:

  • Why are you learning C++? Why not just do it in Swift?
  • You can’t learn from books. You can only learn from projects.

First off, not everything can be done in Swift. It just can’t. It would be nice, but we’re not there yet, so this is a non-starter.

I have written about my personal experiences from not learning from books so it isn’t that I completely disagree with this statement. I just think that there is a happy medium between “learn from books” and “learn from projects.” That medium is the tutorial.

In Defense of Tutorials

I have heard a lot of people talk about learning code from videos and podcasts. They put a podcast on their iPhone or just take the audio track from a WWDC video and throw it on while they go for a jog.

I envy those people.

I know this is ironic from someone who used to do a podcast (and plans to get back to doing so soon, I promise!), but I don’t like listening to podcasts or videos. It drives me crazy. I need something interactive. Listening to someone else talk and not being able to have a back and forth and ask questions makes me completely insane. I have no idea how anyone learns this way.

I went to school for programming twice. The first time I dropped out because I followed the “Just learn from projects” line of advice. I would do a bunch of research into how to do my homework. I would do it once, then I would never do it again. I never learned or retained anything I did. I aced my exams but I had no fucking clue how to code.

It was only when I had the worst job I ever had that I learned to code. I was told that the team lead didn’t know what we were supposed to be doing and so he told all of us to look like we were working. To avoid having a nervous breakdown, I started doing tutorials on Codecademy.

By just typing code forty hours a week, I learned so much more than I had when I spent most of that time thinking about what I was doing. Mindlessly typing code like a monkey for a really long time was a far more effective learning tool than anything else I did.

By typing code a lot, my brain processed how it worked. It didn’t work on the first try. It took doing it three or four times before my brain processed it.

I feel incredibly worried because even though I am a professional programmer I don’t get to code enough hours in a week for me to feel I am still proficient at programming. I keep having good intentions of working through code after work, but I usually am tired and want to cook dinner and take a bath, so it never happens.

I do not want to try to learn C++ by reading the code base for the Unreal Engine. Most of C++ looks alien and terrifying. I can’t just do a project with it because I have no idea how to begin. It’s like telling someone who is interested in architecture to just build a house. You need to have some kind of practice so that you know what the fuck you are doing.

Programming is one of the only skills I have heard of people doing where we don’t emphasize practice. If you want to be a great pianist you have to do scales. A lot. You don’t just do them once and assume you’re done with them. You keep doing them. You keep practicing the pieces you want to play. You don’t become a better piano player by just reading sheet music or listening to recorded songs. You get better by putting fingers to keys. A lot.

What I am Doing About It

I have spent the last year getting more and more depressed by trying to adopt the learning style I see everyone else around me adopting and getting more and more frustrated when it doesn’t work for me.

I had my epiphany about how I learn. I learned programming by doing a lot of tutorials and practicing my coding by just typing code a lot. Just because everyone else around me tells me this isn’t the way to learn doesn’t mean that I have to listen to them. It’s possible my way would work better for them and they’ve never tried it. It’s also likely that we’re all different people and we are all capable of learning differently. I should stop trying to conform myself to another person’s learning style just because they think they are “right.”

One thing I have done since I have tried to establish my routine is I set aside two hours each morning to code. Right now I am working through Beginning C++ Through Game Programming. Each chapter has about half a dozen programs in it that you can either download from their website or you can code yourself. I have been coding each exercise and I am already feeling far less freaked out by C++. Yes, I know how conditional logic works, but just getting used to typing out all the double colons and the semi-colons at the end of each statement is really helping me mentally process how the language feels.

This is one of many things that I have not been assertive about when I go to a job. I feel like working through my scales doesn’t count as part of my job because the code I am working on isn’t production code. But it does help me keep my skills sharp and makes me a more productive worker. I may not tell people that I am doing this, but I do hope to make this a normal part of my routine in the future. I want to be an amazing programmer and you can’t do that if you don’t code. A lot.

Self Destructive Tendencies

I have a problem and I am writing about it because I want to know if anyone else has the same problem.

When I start a new project I get really overwhelmed.

My dream project for the last few years has been to write a synthesizer application. Every time I start to think about writing this application I get incredibly overwhelmed by a lot of things:

  • How much math do I need to know how to do?
  • What kind of synthesizer do I want to write?
  • Oh shit, everything is in C++. How much C++ do I need to know?!
  • Can I use this audio programming book that’s in C++ if everything in it assumes you’re using Windows?
  • How do I do the user interface?
  • How do I fit all these little elements on an iPhone? Can I lay it out differently?
  • Do I need to know OpenGL to do a decent user interface?

So I get super overwhelmed and I sit down to try to figure out one of these things.

I sit down to learn C++ so I can read the book on audio programming.

I figure out that I don’t understand the math and I get freaked out and I try to learn the math.

Then at a certain point I get overwhelmed, feel stupid, and curl up on the floor crying because I am stupid and will never amount to anything and I should just give up on programming because I am a failure and should just go back to working at Target.

This doesn’t just happen with my personal projects. Sometimes this happens at work too.

At my previous job I had to learn a bunch of stuff about network programming. I have never done network programming and I honestly never want to do it ever again. I had people telling me to play with Paw to learn network programming. I don’t know what Paw is supposed to do. If I don’t know what it is doing, how do I play with it? I have no context for anything I am doing, so I wind up in this creepy, paralyzing mental mode where I am grappling with a bunch of unfamiliar terminology that has no context and if I can’t do my job I will get fired and I can’t pay my mortgage and I will be homeless and it makes me curl up on the floor breathing into a brown paper bag.

How do I avoid this?

Learn by Doing

I know from my own personal experience that I learn better by doing.

For a really long time I learned by doing a lot of tutorials. The first time I would do a tutorial I would have the overwhelming paralyzing feeling of not knowing what I was doing, but then I would do the tutorial over and over again a few times until I got the feel for what I was doing.

Back when I was a full time student and had the luxury of time, I could do this 60-80 hours a week. It was kind of magical about how by the third or fourth time I totally understood what I was doing.

Then I went out into the job market and started to mentally feel like I couldn’t do this and have tried to find ways around it. I used to keep trying to do tutorials, but I would only have time to do them once and I would be stuck in the paralyzed overwhelming stage, so I stopped doing that.

The only way to learn and grow is to write code.

You start with a blank project and you ask yourself how to make something work. That gives you the first step you have to take to find your answer.

I know this. I have experienced this. So why does it always take me by surprise when I figure this out for the fortieth time??

Lazy Information Initialization

I noticed I tend to get overstimulated and unfocused when I have to start on something. I tend to shave yaks.

I think that I can read a book on math for 3D graphics programming and learn all about that before I start a project rather than going in and just learning what I need to know to do what I need to do.

I do things that seem like work but aren’t actually productive.

I know on some level that trying to learn this difficult way by reading math books in the bath tub is not helpful and actively causes me mental harm. But I feel guilty if I am not working and I have adopted a lot of destructive behaviors that feel like work and make me feel like I am being productive that are making me less productive.

As I have gotten more and more burned out I have worked harder and harder on these self destructive tendencies because I haven’t known how to break out of them.

I have noticed at most of my jobs there is an implicit feel that working on code that does not directly go into a project is considered wasteful. Saying I am going to set up a sample project to learn a concept sounds unproductive and people would really rather that you work directly on the code base or read documentation. (Except when I worked for Brad. He did this stuff all the time and this is where I got this idea from and I finally started getting it through my thick head.)

In my experience, those things don’t work nearly as effectively.

I am trying to be better about asserting what I need to be a productive programmer even if it’s not what people want to hear. It’s not enough to just say “I need to do these things.” I also have to put them into practice.

And part of putting those into practice is to stop doing these destructive behaviors that make me feel like I am doing something when I am actually destroying my ability to function.

I think it’s important to understand how we learn and to stick to it even when other people don’t want to hear about it. It’s really easy to do a bunch of things that make you feel busy but aren’t getting you anywhere.

I am sick of feeling tired and burned out all the time because I am doing things that I know don’t actually help me. I am trying to figure out how to be a more productive person because my career and my mental health depend on it. This is too important to ignore and wait to resolve itself.

So I am not going to exhaust myself reading programming and math books with no context. I am going to do more sample projects and I will only learn what I need to know to solve a problem with my code. I am not going to expel a lot of energy on something that causes mental friction and generates heat that burns me out. I will only use energy on things that are actively productive. I will be less tired and less hurt this way.

Elementary

I have been taking some time off recently and catching up on some much needed rest. Part of my regime has been finding a bunch of TV shows I have been meaning to watch and going through them.

One of those shows is Elementary. I am a huge Sherlock Holmes addict. The recent versions with Benedict Cumberbatch and Robert Downey Jr. have been interesting, but Jeremey Brett will always be my Sherlock.

Besides updating to modern times, one of the big selling points of Elementary has been gender switching several of the more prominent characters in the Holmes canon, namely the role of Dr. Watson.

I want to talk a bit about something I feel that they did right with this that I would like to see more of in the future.

Mentorship

In the original Holmes stories, Watson is Sherlock’s roommate and side kick. He acts as the reader’s eyes and ears reporting what a “normal” person would see and generally most of the resolutions in the crimes come as a surprise because Watson does not observe what Sherlock does, which makes it difficult to guess what the resolution of the stories will be.

CBS_ELEMENTARY_406_LOGO_IMAGE_702765_640x360In Elementary, Watson starts out as a sober companion for Sherlock, but eventually transitions to being his protégé. He sees potential in her and he helps her cultivate it.

This Watson is a dynamic character. Her skills grow and evolve. This is different than the static Watson character in the original stories who is purposely kept somewhat dumb to allow the reader to enjoy the story.

A lot of this dynamic spoke to me on a personal level.

Programming is a rather new field that is primarily male-dominated. All of my mentors have been men. I often wonder if men ever get to be mentored because there is an inherent social dynamic that seems to make it easier for men to mentor women. Our society assumes that women take a subordinate role and it’s simply easier when you are a woman to approach a man and ask for help and for guidance. This can have a pleasing feeling for both people because the man feels important because he gets to instruct and train a subordinate and the woman feels important because someone she respects and admires has chosen to take time out of their life to pass on knowledge and wisdom to them that they aren’t passing down to anyone else.

When you’re first starting out, this can be a very comfortable and emotionally rewarding relationship. However, like all things, this can’t last.

Partnership

At some point, the protégé starts to bump up against the edges of the relationship. The protégé wants to be acknowledged. They want to have their new skills be recognized and leave the nest and be seen as an equal.

This can make the mentor very uncomfortable. Their entire relationship is predicated upon being the source of knowledge. Once the protégé catches up to the mentor, it can cause a lot of issues.

Elementary-season-3-promo-watson-holmesIt can make the mentor feel very upset because they feel they’ve lost their identity as the person who knows everything. Sometimes the mentor succumbs to the urge to try and cut their protégé down to keep them in the subordinate role because that is where they feel comfortable.

Other times the mentor can become upset that the protégé wants to be seen as an equal. The mentor has spent decades honing their craft and this upstart person wants to be seen as an equal without putting the work in.

This relationship is very reminiscent of a parent/child relationship. At some point you realize your parents don’t know everything. Our relationships with our parents change as we get older because they must. Sometimes our parents cut us down to try and maintain the control over us that they have gotten used to. They want us to succeed, but not too much because it threatens their sense of self worth.

A mentorship relationship is more fragile than a parental relationship because of two reasons. One, our parents will always be our parents. As much as we might argue and fight with them, there is a blood tie that can’t be broken. The second is the one I mention at the beginning of this post, the gender thing.

Professional Respect

One thing that I respect Elementary for is the fact that, as far as I have gotten, there has been no effort to force Sherlock and Watson into a romantic relationship. All of their conflicts have been able to explore the mentor/protégé relationship without having to stoop to the cliche of putting them together in a romantic relationship.

I greatly admire the fact that the writers have been able to craft a compelling story about the mentorship conflict in a completely platonic context.

1355273194905.cachedAs the person who has been in the protégé role, I want my mentors to see me as an equal. I want to show them that they were right in sharing their wisdom with me and I would like to show I can manage on my own without being dependent on them. Joan Watson is similar. She wants to be a detective in her own right.

Sherlock doesn’t want her as an equal. He wants to keep her as a subordinate. They fight over her need to be her own person and not an extension of him.

Both characters have had romantic relationships with other people, so this isn’t a generic, Aspie asexual stereotype. The relationship between Sherlock and Watson is based on professional admiration and respect. Watson gets frustrated when Sherlock won’t give her the professional respect she feels she has earned.

I have found it incredibly compelling to watch this relationship being explored. It’s a painful situation for both Sherlock and Watson. Both of them are right. Both of them have been hurt by their evolving relationship. But it’s a necessary pain for them to experience so both of them can grow and change.

Lessons From Sherlock

I spoke about mentorship at CocoaLove 2015. I wanted to give advice to both mentors and protégés. I want to reiterate some of it now.

If you are a protégé, at some point you need to step out on your own. It’s comfortable and safe to be under the wing of someone with a lot of experience, but at some point you need to succeed or fail on your own. You will stumble a lot, but that is how your mentor learned. They stumbled and have given you advice about how to avoid the same stumbles they took. You will learn best through your own stumbles than you will hearing stories of your mentor’s stumbles.

If you are a mentor, please understand that this is a temporary situation. Don’t become so attached to the idea that you have to know everything that it creates a situation where you lash out at your protégé when they want to be seen as an equal. Your protégé has a lot of affection for you that can quickly turn into a toxic situation if you put them down in an effort to keep them subordinate to you.

The best way for a mentor/protégé relationship to go is if both parties go in wanting the protégé to become independent. If you’re a mentor and your protégé doesn’t seem to want to walk on their own, try to push them to take risks and fall and learn from their experiences.

Above all, remember that part of the reason you both entered into this relationship was because you like and respect one another. Just because your relationship changes as the protégé grows in experience doesn’t mean those feelings go away.

How to Write a Custom Shader Using GPUImage

One of my goals over the last year or so was to do more coding and to specifically do more GLSL programming. You learn best by actually working on projects. I know that, but I have had some trouble making time to do things on my own.

I want to go over my thought process in figuring out a filter I wanted to write, how I was able to utilize the resources available to me, and to hopefully give you an idea about how you can do the same.

You can clone GPUImage here.

Solarize Image Filter

One thing I had trouble with in GPUImage is the fact that it is too comprehensive. I couldn’t think of an image filter that wasn’t in the framework already.

So I started thinking about Photoshop. I remembered there was a goofy filter in Photoshop called Solarize.

Since I knew that Brad was more concerned with things like edge detection and machine vision, I figured that it would not have occurred to him to include a purely artistic filter like that. Sure enough, there was no solarization filter. Jackpot!

After figuring out something that wasn’t there, the next question was how to create one. I initially was going to use this Photoshop tutorial as a jumping off point, but I wondered if there was a better way. I Googled “Solarize Effect Algorithm” and I found this computer science class web page that gave an agnostic description of how the effect works.

What is Solarization?

Solarization is an effect from analog photography. In photography, one important component of a photograph is its exposure time. Photographers used to purposely overexpose their photos to generate this effect. When a negative or a print is overexposed, parts of the image will invert their color. Black will become white, green will become red.

There is a threshold where any part that passes that threshold will receive the effect.

One of the things Brad told me about GPUImage was that many of the filters in GPUImage are composed of many smaller filters. It’s like building blocks. You have a base number of simple effects. These effects can be combined together to generate more and more complex effects.

Looking at the algorithm for solarization, I noticed it requires two things:

  • An adaptive threshold to determine what parts of the image receive the effect
  • An inversion effect on the pixels

I opened up GPUImage to see if there were already filters that do those things. Both of these functions already exist in GPUImage.

Now I needed to figure out how they work so that I could combine them into one, complex filter.

GPUImageColorInvertFilter

Since the color invert filter is the simpler of the two filters, I will be looking at this one first.

Since this is a straightforward filter that does one thing without any variables, there are no publicly facing properties in it’s header file.

Here is the code for the vertex shader that we see in the implementation file:

NSString *const kGPUImageInvertFragmentShaderString = SHADER_STRING
(
 varying highp vec2 textureCoordinate;
 
 uniform sampler2D inputImageTexture;
 
 void main()
 {
    lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    
    gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);
 }
);

These two lines will exist in every vertex shader in GPUImage:

varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;

These lines are the lines where you are bringing in the image that is going to be filtered and the specific pixel that the fragment shader is going to work on.

Let’s look at the rest of this:

void main()
{
   lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
   gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);
}

The first line is simply obtaining the specific RBGA values at the specific pixel that you are currently processing. We need that for the second line of code.

The gl_FragColor is the “return” statement for the fragment shader. We are returning what color the pixel will be. Texture colors are part of a normalized coordinate system where everything exists on a continuum between 0.0 and 1.0. In order to invert the color, we are subtracting the current color from 1.0. If your red value is 0.8, the inverted value would be (1.0 - 0.8), which equals 0.2.

This is a simple and straight forward shader. All of the actual, shader specific logic is in the gl_FragColor line where we are doing the logic to invert the colors.

Now let’s move on to the more complicated shader.

GPUImageLuminanceThresholdFilter

The Luminance Threshold Filter is interesting. It checks the amount of light in the frame and if it is above a certain threshold, the pixel will be white. If it’s below that threshold, the pixel will be black. How do we do this? Let’s find out.

The Luminance Threshold Filter, unlike the color inversion filter, has public facing properties. This means that the header file has some actual code in it that we need to be aware of. Since this one is interactive and depends upon input from the user, we need a way for the shader to interface with the rest of the code:

@interface GPUImageLuminanceThresholdFilter : GPUImageFilter
{
    GLint thresholdUniform;
}

/** Anything above this luminance will be white, and anything below black. Ranges from 0.0 to 1.0, with 0.5 as the default
 */
@property(readwrite, nonatomic) CGFloat threshold; 

@end

Our threshold property will receive input from a slider in the UI that will then set a property we will need to calculate our shader.

NSString *const kGPUImageLuminanceThresholdFragmentShaderString = SHADER_STRING
( 
 varying highp vec2 textureCoordinate;
 
 uniform sampler2D inputImageTexture;
 uniform highp float threshold;
 
 const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);

 void main()
 {
     highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     highp float luminance = dot(textureColor.rgb, W);
     highp float thresholdResult = step(threshold, luminance);
     
     gl_FragColor = vec4(vec3(thresholdResult), textureColor.w);
 }
);

This has a few more components than the color inversion code. Let’s take a look at the new code.

uniform highp float threshold;
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);

The first variable is the value we are receiving from the user for our threshold. We want this to be very accurate because we’re trying to determine whether a pixel should receive an effect or not.

The second line has what looks like a set of “magic numbers.” These numbers are a formula for determining luminance. There are explanations for it here and in the iPhone 3D programming book by Philip Rideout. We will use this constant to map over the current value of the fragment in the next bit of code.

void main()
{
    highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    highp float luminance = dot(textureColor.rgb, W);
    highp float thresholdResult = step(threshold, luminance);
     
    gl_FragColor = vec4(vec3(thresholdResult), textureColor.w);
}

The first line does the same thing as it did in the color inversion filter, so we can safely move on to the next line.

For the luminance variable, we’re encountering our first function that doesn’t exist in C: dot(). dot() takes each red, green, and blue property in our current pixel and multiplies it by the corresponding property in our “magic” formula. These are then added together to generate a float.

I have tried hard to find a good explanation of why dot product exists and what it does. This is the closest thing I can find. One of my goals with this series of blog posts is to take things like dot product where you can explain what it does, but not why you are using it and what functionality it fulfills. For now, hopefully this is enough.

Next up, we have the threshold result. This is where we are doing our only conditional logic in the shader. If you recall, this shader makes a determination if each pixel should be white or black. That determination is being made here.

The step() function evaluates two different floats. If the first number is larger, then the threshold result is 1.0 and that particular pixel is bright enough to pass the threshold requirements. If the second number is larger, then the pixel is too dim to pass the threshold and the result is 0.0.

Finally, we map this result to our “return” statement, the gl_FragColor. If the pixel passed the threshold, then our RGB values are (1.0,1.0,1.0), or white. If it was too dim, the then RGB values are (0.0,0.0,0.0), or black.

GPUImageSolarizeFilter

According to the algorithm that describes the solarization process, you use a luminance threshold to determine if a pixel receives an effect or not. Instead of the effect of making the pixel either white or black, we want to know if the pixel should be left alone or if it’s color should be inverted.

The only line of code that the color inversion filter has that the threshold doesn’t have is a different gl_FragColor:

// Color inversion gl_FragColor
gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);

// Luminance Threshold gl_FragColor
gl_FragColor = vec4(vec3(thresholdResult), textureColor.w);

I am embarrassed to say how long it took me to figure out how to combine these two filters. I thought about this for a long time. I had to think through all of the logic of how the threshold filter works.

The threshold filter either colors a pixel black or white. That is determined in the thresholdResult variable. This means that we still need the result in order to figure out if a pixel receives an effect or not, but how do we modify it?

Look at this part of the gl_FragColor for the color inversion:

(1.0 - textureColor.rgb)

Where else do we see 1.0 being used in the threshold shader? It’s the result of a successful step() function. If it fails, you wind up with 0.0. We need to change the gl_FragColor from the color inversion filter to have the option to return a normal color or an inverted color. If we subtract 0.0 from the texture color, then nothing changes.

This is the final code I came up with to implement my Solarize Shader:

NSString *const kGPUImageSolarizeFragmentShaderString = SHADER_STRING
(
 varying highp vec2 textureCoordinate;
 
 uniform sampler2D inputImageTexture;
 uniform highp float threshold;
 
 const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
 
 void main()
 {
     highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     highp float luminance = dot(textureColor.rgb, W);
     highp float thresholdResult = step(luminance, threshold);
     highp vec3 finalColor = abs(thresholdResult - textureColor.rgb);
     
     gl_FragColor = vec4(finalColor, textureColor.w);
 }
);

This is primarily composed of the same code to create the luminance threshold shader, but instead of mapping each pixel to be either black or white, I am using that result to check to see if I am inverting my colors. If the colors need to be inverted, then the thresholdResult is 1.0 and our formula moves forward as usual. If thresholdResult is 0.0, then our texture color remains the same, except now it is negative, which is why I wrapped it in an abs() function.

Completely solarize shader. Will try to get a better picture later.

Completely solarize shader. Will try to get a better picture later.

Takeaways

One of the big things I keep harping on with this blog the last year or so is that to be a good engineer, you must have an understanding about what you’re trying to accomplish.

Breaking down a shader that you want into an algorithm helps you to tease out what pieces of functionality you need to get the result you want. In a lot of cases, the smaller pieces of functionality are already out there in the world somewhere and you can reuse them to build more complex things.

You also need to be able to read through those shaders to figure out how they work so you can know where the pressure points are to change the code. Since shaders are so small, you can usually take one line at a time and break down what it does. If there is a function being used that you’re unfamiliar with, Google it. You don’t always need to understand all of the why something is being used in order to implement it, such as I did with the dot() function. I was able to have a good enough grasp of what it did to understand why it was needed in my shader which was all I really needed.

This stuff can be intimidating, which is why it’s important to spend some time figuring out why something works and, more importantly, figuring out what YOU want to do with it.

I will be following this post up tomorrow with instructions for how to add a shader to the GPUImage framework, including some other parts of the shader code that I did not go over here.

Exercises for Programmers: Exercise 4- Mad Libs

The fourth exercise in Exercises for Programmers is to create a Mad Lib.

Mad Libs are a game you play when you’re a kid and you’re trying to learn different parts of speech. You name random nouns and verbs to fill in the blanks in a story you can’t see until you are finished.

This project continues with the theme of making the exercises more and more complex as you go along.

This project requires you to ask for four different user inputs and to create a story around them. If any of those inputs is missing, you want to alert the user rather than output a story with half the words missing.

As usual, I have uploaded this project to GitHub.

What this looks like when successful

What this looks like when successful

Data Structures

Since I want to unit test my application, I want to move as much of the programming logic outside of the view controller as possible. I need to grab the four user input responses and I want to pass those into another function.

I thought about making this into an array of strings, but I liked the idea of being able to have keys and values for the user input. I want to be able to tell the user which field they forgot to fill and that is a lot easier when you bundle the name of the field along with the input instead of just counting on things being in the right order. Having an array of random words with no indication about what they represent seemed like a recipe for disaster.

In the @IBAction for the Enter button, I created a dictionary of all of the user input values:

let userInput:[String:String] = [
    "noun":nounTextField.text!,
    "verb":verbTextField.text!,
    "adjective":adjectiveTextField.text!,
    "adverb":adverbTextField.text!
]

Now that I had a data structure and I knew what types were going into it, I could start working on the output logic.

Set up

Set up

To Map(), or not to Map()

One reason I wanted these values to exist in a data structure was because I wanted to use Map().

This seemed like a good time to use Map(). I had to iterate through a data structure, check to see if the input was empty, and if it was I had to do something.

Taking this approach really tripped me up and cost me a lot of time.

When I worked with Brad at SonoPlot, he used protocols and flatmaps to iterate through a collection of data we were writing to and getting from the NSUserDefaults. I thought I would set up a function that returns an optional string that would check each string to see if there was anything in it. If there wasn’t, I could return a nil and filter them out.

func isStringEmpty(input:String) -> String? {
    if input.characters.count != 0 {
        return input
    } else {
        return nil
    }
}

I started to realize this wasn’t really helpful to me. Here is why:

Let’s say my user forgets to specify a verb. I can flatmap my dictionary using this function that will give me an array with three values. I won’t know which value is missing. I can’t tell the user which value they forgot to enter.

I spent a bunch of time trying to figure out how to map my isStringEmpty() function to my dictionary. In order to try and figure out how to optimize this, I wrote it in the most inefficient manner I possibly could so I could see what code I was repeating:

func output(input:[String:String]) -> String {
    
    var outputString = String()
    
    let noun = isStringEmpty(input["noun"]!)
    let verb = isStringEmpty(input["verb"]!)
    let adjective = isStringEmpty(input["adjective"]!)
    let adverb = isStringEmpty(input["adverb"]!)
    
    if noun == nil {
        outputString += "Please enter a noun! 
"
    }
    
    if verb == nil {
        outputString += "Please enter a verb! 
"
    }
    
    if adjective == nil {
        outputString += "Please enter an adjective! 
"
    }
    
    if adverb == nil {
        outputString += "Please enter an adverb! 
"
    }
    
    if noun != nil &&
       verb != nil &&
       adjective != nil &&
       adverb != nil
    {
        outputString = "Do you (verb) your (adjective) (noun) (adverb)?"
    }
    
    return outputString
}

Clearly I am repeating my calls to isStringEmpty() for every input in my UI. This is really inefficient.

I am also constantly checking if something is nil. Since the variable I am checking has the same name as the type of word that I need to tell the user to enter, this could probably be more generic.

I optimized this from that monstrosity to the following:

func output(input:[String:String]) -> String {
    var outputString = String()
    
    for (key, value) in input {
        let checkValue = isStringEmpty(value)
        
        if checkValue.characters.count == nil {
            outputString += "Please enter a (key)! 
"
        }
        
    }
    
    if outputString.characters.count == 0 {
        let noun = input["noun"]!
        let verb = input["verb"]!
        let adjective = input["adjective"]!
        let adverb = input["adverb"]!
        
        outputString = "Do you (verb) your (adjective) (noun) (adverb)?"
    }
    
    return outputString
}

I tried for a bit to use a map() function rather than the for-in loop, but it felt just easier to do it this way. I would still like to get more comfortable using map(), but I also don’t want to create an “If you give a mouse a cookie” problem where I am adding a bunch of garbage to my code to try and force a square peg into a round hole.

If anyone can give me a good explanation about how I could have used map() more efficiently than using for-in I would greatly appreciate it. I have seen it used in other people’s code but I don’t process how I can implement it myself because I have not tried to solve a problem with it yet.

Lastly, I realized that my efforts to cram the flatmap() into the code was causing me to use the isStringEmpty() function even though there really was no point in doing so.

I condensed down all of my programming logic into one function:

func output(input:[String:String]) -> String {
    var outputString = String()
    
    for (key, value) in input {
        
        if value.characters.count == 0 {
            outputString += "Please enter a (key)! 
"
        }
        
    }
    
    if outputString.characters.count == 0 {
        let noun = input["noun"]!
        let verb = input["verb"]!
        let adjective = input["adjective"]!
        let adverb = input["adverb"]!
        
        outputString = "Do you (verb) your (adjective) (noun) (adverb)?"
    }
    
    return outputString
}
Completely empty response

Completely empty response

Limit to User Input Optimization

One thing that bothered me about this project was the fact that I couldn’t procedurally deal with every instance of pulling out the nouns, verbs, etc…

No matter what I do I have to spend four lines of code pulling out the user input and then another four lines doing something with them.

Those lines of code cause me to be bothered because I don’t like hard coding things. I was happy I could do the for-in loop because there could be forty elements or two and either way it was flexible. Having things hard coded isn’t flexible.

However, I do not think there is a way around this in this project. I believe that any time you are doing anything that touches the user interface, there is a limit to how far you can optimize it.

When I was going to write the unit tests, I had the urge to see what would happen if I sent a value that wasn’t noun or verb or if one of those was missing. I know that in this project that is impossible, but it still really bothers me because of how inefficient it feels. It had code smell. I think there is nothing I can do about it, but that won’t keep me from driving myself crazy trying to think of a way around it.

Partially empty response

Partially empty response

Takeaways

Initially, I thought this project would have a lot more programming logic than any other project before this, but it actually had the least amount.

I left my less efficient code in the project to show how much I was able to refactor the project.

I think a major takeaway that I want to bring up is the idea of rewriting your code a lot.

One issue I have had with working with other people on programming projects is that sometimes, as I did here, it’s easier for me to write some really crappy, inefficient code that just works so that I can get a better handle on how to make it better. When I am working on something and someone randomly demands to see what I have so far, it is incredibly upsetting to have to show that I did this really terrible code. There are probably ways around this, but it can be super demoralizing to show the early part of my process to someone when it is something I am still actively working on and trying to make better.

If you are a decent programmer, you will rewrite your code a few times. You will get a better idea about what problems you are trying to solve and how your current approach isn’t what you thought it would be. My final code is about a third of what it was initially because the way I thought I needed to do this was different than the way I actually needed to do it. I could have kept adding more and more junk to the code to try and force it to work, or I could change my perspective on how to approach the problem.

I firmly believe in writing bad code to get the garbage out of your head. Not every line of code needs to be a line from Shakespeare. Writing a lot of bad code helps you figure out how to write better code more quickly.

Exercises For Programmers: Exercise One-Saying Hello

A couple of months ago I bought Exercises for Programmers by my friend Brian Hogan. I was trying to find some mini challenges for myself like I had when I was a student when I would just work on a small, solvable problem.

When I think about programing, I usually get really overwhelmed by thinking about all of the components I need to make a minimum viable product. I start thinking about having to learn everything I have to do in order to put together a whole application. I wind up not doing anything because I feel like I have to learn twenty things before I can start coding rather than just diving in.

I have worked on other people’s projects and been given some rather explicit functionality that I have to have that is divorced from thinking about how to construct an actual program.

When I initially looked through this, I was disappointed because I felt like this was more targeted at people learning programming. There were tip calculators and Hello, World. So I got all sulky and emo teenager and decided this was not for me.

I was wrong.

I am planning to go through each exercise in this book and treat each exercise as a complete project. I am going to write unit tests for all of my code, make sure that the auto layout works, and try to think about what constraints I need rather than just trying to get something that works under specific circumstances.

User Interface and Autolayout

The first exercise in the book is a play on the usual “Hello world!” application. In this, you take user input and you output it to the screen.

To get user input from a user in iOS, you need to set up a bunch of UI elements: a label asking for your name, a text field for your name, a button to enter your name, and another label to display the message.

goodAutoLayout

This is a slightly embarrassing thing for me to admit, but I do not work much with user interface stuff. For the last two years I have worked exclusively on things like unit tests and network programming. The last time I worked a lot with user interfaces was around the time Storyboards were introduced. I have not mastered the Zen of Auto Layout.

Initially, I thought I had all of my elements laid out properly, but they didn’t show up where I wanted them to. I realized I had to go in and figure out a bunch of constraints to see what I wanted to on my screen.

autoLayoutFail

The top and bottom labels were easier because I knew I wanted them to be centered. The button and the text field were harder because I wanted them next to one another and I couldn’t center them the same way I did the labels.

autoLayoutFail2

I thought about giving up and just putting them on their own lines, but that kind of defeats the purpose of doing these exercises. I vaguely remembered that I can line things up by the leading or trailing edge. I liked the text field up with the leading edge of the top label and the button to the trailing edge of the top label. The text field rendered out to be about two characters wide, so I added one more constraint to maintain the spacing between the text field and the button.

HelloDelia

Programming Logic

Now that I have the layout working properly, I needed to think about what my failure cases are. Back when I was a student, I would just pull out whatever was entered in the text field and print it out on the screen. Since I want to write unit tests for this, I needed to put more thought into what would be a “bad” input.

The two that I could think about were either not entering anything at all, or entering in a number.

Since the text field is an optional, I needed to wrap it in an if-let. I thought about using a guard statement, but I didn’t feel like it would work in this case because I didn’t just want the result to be nil if you didn’t enter anything. I wanted to actually do something if it was nil, so I stuck with the if-let.

I thought that if there was nothing in the text field when you clicked on the button that it would be nil, so I had an else statement to state that if you just clicked on the button. That did not work because the text field returns an empty string. So that became a case I needed to check.

The last one was trying to figure out how check if the string contains a number. The ability to check a string for a number has changed a bit over the last two years in Swift. There used to be a toInt() function on the String class, but that was replaced with an initializer on the Int class. You pass a string into the Int initializer and if it can be converted to an int then you will have a value, otherwise, you get a nil.

Testing and Decoupling

I did my own testing on my application and I was able to trigger all three possible string outputs. But I want to get in the habit of writing unit tests for all of my personal applications. When I worked for Brad Larson, the main component of my job was to write unit tests for our code.

One way we were able to do that is because we made things very functional. We had very few classes. We had a lot of stand alone functions that could be tested thoroughly on their own. We created fake hardware objects in code.

That was harder to do with the view controller. I could make a function within the view controller to process the input from the text field, but I couldn’t do things as functionally as I wanted to.

Then I realized I could break my function up. Initially, I had this:

@IBAction func enterName(sender: AnyObject) {
    if let name = nameField.text {

        let myInt: Int? = Int(name)

        if name.characters.count == 0 {
            helloLabel.text = "You need to enter your name"
        } else if myInt != nil {
            helloLabel.text = "You entered numbers, not a name"
        } else {
            helloLabel.text = "Hello (name), how are you?"
        }
    }
}

This coupled the code in such a way that it was impossible to pull that code out and make it testable. Everything in this function was talking to parts of the class, so I couldn’t pull it out and make it stand alone.

So I rethought was I was trying to do. This function needed to do one thing: Set the helloLabel. I was making it do two things. I was also making it determine what the helloLabel was set to.

I realized I could make the output from the text field into a parameter that could be passed into a stand alone function.

I changed that function from what I had to this:

@IBAction func enterName(sender: AnyObject) {
        if let name = nameField.text {
            let nameString:String = nameFunction(name)
            helloLabel.text = nameString
        }
}

func nameFunction(name:String) -> String {
    
    let myInt: Int? = Int(name)
    
    if name.characters.count == 0 {
        return "You need to enter your name"
    } else if myInt != nil {
        return "You entered numbers, not a name"
    } else {
        return "Hello (name), how are you?"
    }
    
}

I pulled the nameFunction out of the View Controller and I put it in a Helper Function file. This function is the only part of this program that I need to unit test and I pulled it out from everything else. This makes testing my programming logic a snap.

    func testLabelOutput() {
        let emptyString = ""
        let numberString = "42"
        let normalString = "Delia"
        
        let firstTest = nameFunction(emptyString)
        let secondTest = nameFunction(numberString)
        let thirdTest = nameFunction(normalString)
        
        XCTAssertEqual(firstTest, "You need to enter your name")
        XCTAssertEqual(secondTest, "You entered numbers, not a name")
        XCTAssertEqual(thirdTest, "Hello (normalString), how are you?")
    }

Conclusions

I am a little embarrassed that this took me longer than I thought it would. I have my name on a few programming books and I “know” this stuff. The Apple ecosystem is an incredibly vast and complex system of knowledge. If you don’t work with something for a while, it takes a while to remember how to do things and shake the cobwebs off.

There are a lot of considerations I put into this exercise that I would not have bothered with when I was a student. I would have been like, why bother making this testable? It works. No one is going to be stupid enough to post numbers and if they do, who cares?

That isn’t a good way to think.

It doesn’t matter what kind of application you are doing. You should try to make everything you code the best that it can be.

This was a good exercise for me to think about this differently than I would have, especially knowing I was going to write unit tests. I rewrote that function a few times and almost thought I couldn’t decouple it until I thought about it for like an hour.

I could have had this working in ten minutes, but the UI would have been screwed up and it would not have been safe.

I am still not happy with the final version of my code, but I feel better about it than I did before. I hope that someone will code review this and tell me how I could have done it better.

All in all, this was a really interesting thought experiment. There are lots of dark corner in my brain of things that I don’t know I don’t know. Shining some light into those corners and airing them out is a good thing to do every once and a while.

I am making a GitHub repository for my exercise if people have any interest in looking them over and comparing notes.

Catch you next time!

Also, if anyone can give me some suggestions about how to get code to format reliably in WordPress I would appreciate it. Sometimes it works and sometimes all of my formatting is gone.

Are you a Developer or an Engineer?

Last month my boss, Daniel Pasco, posted this thought on Twitter:

developerEngineer

Developers focus on making great code.
Engineers focus on making great things.

This really struck a chord with me. I have observed a few behaviors that I didn’t really have any context to express and I feel like this quote sums up a lot of things that trouble me about the programming community.

Hipster Coding

“Nobody goes there anymore. It’s too crowded.”
– Yogi Berra

I went back to school in earnest to learn programming in 2012. I wasn’t sure what I wanted to do, but I knew I wanted to find whatever would work best for me in the long run. I initially went for Java because I knew there was a lot of demand for it, but I didn’t realize there was also a lot of supply and it was difficult to find an entry level Java job because most of them demanded 3-5 years of experience. I couldn’t break through the layers of bureaucracy and I just stopped trying.

I initially got involved with the Ruby community. I knew a lot of people who were active there and it seemed like it was the new up and coming thing.

I would talk to people about how to get into Ruby and I would be asked what open source projects I worked on. I didn’t really understand open source and would ask for help about how to get into open source. Their looks would immediately change to a combination of disdain and pity and they would stop talking to me because I wasn’t a contributor.

I struggled with this a bit trying to break into Ruby, only to discover that all the people who had been doing Ruby had moved on to Clojure. Then they moved on to Haskell. I think they were interested in Swift for a bit, but I have lost track of whatever the new hot language is. Might be Go…

I think a lot of people feel like they missed out on the Gold Rush of the iPhone. I know that I do. By the time I started taking iOS programming classes in 2012, the whole point of having an app out on the store was to use it as a resume builder to find an actual job. We were being prepared for the world as it exists now/over the next few years where there is less contracting and more enterprise development.

I feel a sense of chasing after something that doesn’t exist anymore. We still have the dream of writing a killer app and making mad bank, but that is growing more and more difficult. I feel like any time Apple releases a new piece of hardware, like the Apple Watch or the Apple TV, people feel like they need to immediately mark their territory on it because they think that if they get there first, they can strike gold and move on before everyone else gets there.

This has created a situation where we have platforms that seem to be abandoned by developers because there is something newer and shinier that has come out and everyone wants to be the first one there.

I Have a Screwdriver and Everything is a Screw

My introduction to programming was back in 2008. I was kind of loafing around unemployed because I had no idea what I was doing with my life. My dad would take me to work and I would go and hang out with the weird IT guy. My nickname for this guy was Jesus because he looked like Jesus if Jesus wore a shirt and tie.

He was really into programming and told me that learning programming was a valuable skill. He set me up with a book and a laptop in the corner. He showed me where the Terminal was and taught me how to write code in TextEdit and compile it on the command line.

All of this was done in Perl.

The book he gave me was the Llama O’Reilly book from I think 1998. He told me that the language was stable and didn’t change, so it was okay that the book was old.

I started telling people that I was learning Perl and I got horrified looks from people telling me no one uses it anymore. I was told to learn PHP because that was the future.

I talked to Jesus about that, and he told me not to bother learning PHP because everything that I want to do I can do in Perl. Perl does everything.

Replace “Perl” with “JavaScript” and that is exactly what we have now for a fairly large portion of the programming community.

I am not going to get into an argument about whether JavaScript is “real” code or not. That isn’t the point I am trying to make. JavaScript is a tool. It has its uses. If I want to write a website, I can’t do that in Swift with the Cocoa frameworks.

What worries me is that I see a lot of people treating JavaScript the way my friend Jesus treated Perl. It’s the thing they know, so they want to make it work for every single possible thing that exists.

There was a great blog post I read recently saying that the state of web development is static right now. Large companies like Yahoo are basically rewriting their websites over and over again in whatever the new hot JavaScript framework is.

I think I read recently that someone created a framework on top of JQuery, which is it’s a framework on top of JavaScript. I think someone tried to create a JavaScript framework to do server back end work. It’s a web language! It was designed to do one thing and one thing well. It’s being convoluted into weird, abstract shapes because people don’t want to learn new things.

Fleeting Fame

fleetingFame

“ObjC culture carriers were people who’d been building products for years using it. Swift culture carriers see a chance for fleeting fame.”
– Graham Lee

When Swift first came out, there were a lot of prominent members of the programming community that were incredibly anti-Swift. They had invested 15 years in Objective-C and saw no reason to pick up this goofy new language and get knocked back the the beginning of the board with everyone else.

A lot of us scoffed at these people and told them to get with the program because Swift wasn’t going anywhere.

It’s nearly two years later, and we’re now seeing that a lot of these people have come to terms with the fact that this language isn’t going anywhere.

This doesn’t mean that they are sitting back and figuring out the language. On the contrary. Many of them are just as loud and opinionated about it as they ever were, but now they’re actually trying to use it.

I have noticed a shift in the last six months or so where the people talking about Swift aren’t the early adopters who were coming from Haskell backgrounds who wanted to share their functional programming knowledge. Instead, we’re getting people who feel like they need to have an opinion about Swift to feel important.

Lots of people want to post tirades about how Swift should be done. They don’t want to listen to people who have been working with it for the last few years. That defeats the purpose. They want to be the one who can go and write a convoluted piece of code to break the compiler and have everyone tell them how clever they are.

A lot of the sense of community that I felt back when we had Objective-C has evaporated. Back then, new people could enter the community and have seasoned professionals give them a hand with understanding things. Now, everyone feels like they have to establish themselves as an expert and no one is willing to ask actual questions that would make them better Swift programmers. Their shouting is drowning out everyone else’s thoughts and opinions and making it even more difficult for beginners to actually learn Swift.

How We Should Be Doing Things

I worked for Brad Larson for a year. We spent that year porting a legacy code base from Objective-C to Swift. There were two important reasons for doing this:

  1. The code base was fragile and at a point where we could not go in and add or change anything without breaking it.
  2. There were problems that we had encountered over the years that would not have happened if we wrote the code base in Swift.

There was a point when I was working with Brad where he showed me this crazy code that was full of functional programming stuff. I felt very depressed because I didn’t think I could ever come up with something that interesting or complex. It bothered me, so I kept talking to him about it.

After doing this for a while I figured out the right question: What problem is this code solving?

When he started to tell me about how unsafe our previous code was because of the constraints of Objective-C. He had spent years trying to figure out a better solution for his problem and he understood what needed to be done intimately.

Brad is an engineer. He didn’t set out to use all the new toys in Swift because he was looking for an excuse to use them. He had problems he needed to solve and wanted to find the most elegant way of solving them. That solution just happened to include a lot of functional programming concepts. I think he actually rewrote the code a few times because he realized there was a better way to solve the problem.

Code exists as a tool to solve problems. It isn’t an end in and of itself. You can write the most insane Rube Goldergian piece of code imaginable that will work, but why bother?

Writing an app or an open source framework or anything is a little like adopting a puppy. It’s a long term commitment. I don’t think that the people who released the first apps for the iPhone realized they might be on the hook for supporting them for close to a decade. No one anticipated that.

Now that we have a better understanding of that, it’s important to spend time thinking about what your app will solve and how to maintain it long term when it stops being cute and starts peeing on your floor.

One of my goals this year is to release an app. I have done other projects like books and talks, and as such you can take what I say with as many grains of salt as you want. I have been hesitant to produce anything because I worry about the long term maintenance of what I am doing. I know I should just put something out there and learn from my mistakes. We’ll see.

I want to find one, solid piece of functionality that I want to see out in the world. I want to start with whatever the smallest bit of that is and work out from there. I want to keep the scope small and make sure that each piece works and can be built off of to add functionality.

I know that I want to be an engineer. I want to solve problems. I don’t care if no one buys my app or if it is just a tree that falls in the woods where no one can hear it. I just want to know that designed and implemented something well. The problem I need to solve right now is getting over my fear of fucking up and to just do something.

Minimum Viable iOS Engineer

Parable of the Shrew

My father works at the Botany Department at UW-Madison. When he was a graduate student he worked as a naturalist at a state park in South Carolina. When I was growing up he told me a lot of stories about this park. One story that he told me in particular has stuck with me most of my life. I have been meaning to write a blog post about it, and I feel like now is the time.

One day while he was working at the state park, he found a shrew. A shrew is a small rodent that eats crickets. My dad captured it and took it back to the office with him. He knew it ate crickets, but wasn’t sure how many or how long it had been since the shrew had eaten. He wanted to be safe, so he put the shrew in an empty aquarium with a hundred crickets, figuring that would be enough.

He came back the next morning to find the shrew dead on its back with all four little furry feet in the air. It was surrounded by dead crickets. The shrew was so fixated on killing every cricket in the aquarium that it forgot to eat any of them and it starved to death surrounded by food.

Resist the Temptation to Be the Shrew!

Yesterday Apple had their announcement of the new tvOS, along with a lot of other new toys that made my head spin.

I noticed a lot of people dropping the watchOS stuff to pick up the new tvOS stuff because it was the new thing and they didn’t want to get behind.

I want to say something that is going to make you feel bad. Take a deep breath. Relax. Here goes.

We have reached a point with the platform where we can’t know everything.

When I started programming I figured I would learn a few languages to cover my bases and give me options for when I went looking for a job. I realized that this was a bad tactic so I picked the one I most wanted to work with. I have further specialized to more and more specific areas of Apple development.

Every time that something new and shiny is announced, I feel compelled to learn something about it. I have Ray Wenderlich’s WatchKit by Tutorial on one of my computers and I don’t know if I have ever opened it. I also have their Animations, Core Data, and several years of iOS By Tutorial in a folder on my computer unread. I feel an incredible amount of panic because no sooner do I hear an announcement about something, my Twitter feed explodes with people who have dug into the docs and are sharing what they read. I have barely processed that something new has come out and already people are doing something with it. It gives me tremendous anxiety and makes my head spin.

I have been working myself into a tizzy just trying to keep up with what I am doing at my job. I have not used the iOS frameworks in about a year. I have a book out on iOS development but I don’t use it every day and it’s basically gone from my memory. I know if I had to use it every day I would pick it back up again fairly quickly, but it still disturbs me that I just don’t remember this any more.

I keep feeling like I need to know Core Data and Networking to stay marketable. I have a list of things that I think I need to know because if I don’t know them then I am not a real developer and people will shun me when they find out. This fear leads me to work all the time. I regularly suffer from exhaustion. The last two weekends I spent two days in bed internally screaming at my body for giving up on me because I have deadlines I need to meet and I don’t want to let people down.

I can not continue this way. If you are going through this, you can’t do it either.

This year at 360iDev there were a lot of talks about the death of independent development. We’ve moved beyond the point where you can make an app in your free time on nights and weekends that is going to be a minimum viable product. Believe it or not, this is a good thing.

Back in 2009 when the platform was relatively new, you could know everything. It was possible. The reason it was possible was because the platform was incredibly limited. There were a lot of things you couldn’t do, or couldn’t do easily. Now we are living in an embarrassment of riches where almost everything is possible, which means YOU CAN’T KNOW EVERYTHING!! Stop trying!

What is the Bare Minimum You Need to Know

I celebrated my first work anniversary on Tuesday. Before that I worked at a start up for two months, worked on an OpenGL contract application for three months, coauthored a book, and did over a dozen conference talks. I have a shocking amount and diversity of experience for a developer who has less than two years of experience.

I don’t know Core Data. I don’t remember most of iOS. I haven’t worked with Interface Builder in a year even though I intended to specialize in graphics and design for iOS.

I think that the amount of things you need to know to be a beginning iOS developer is smaller than most people think.

I talk to students at the tech school I attended and all of them think they need to know a lot of stuff. I would argue that you don’t need to know a lot of stuff, but the stuff you do need to know you need to know well.

Here is my list of what I think you absolutely need to know to have an entry-level iOS job:

  • Some fundamental understanding of either Objective-C or Swift. Both of these languages have a lot of unique aspects and I would argue it is important to have enough of a grasp of one of these to understand why you don’t program them like Java or some other language.
  • The MVC design pattern. This is a fundamental pattern that permeates all of iOS. If you do not understand this pattern, you will not write good iOS code. It is vital to understand this.
  • Know how to use the Apple documentation to look up how the frameworks work. You can’t know everything, but you at least need to know how to learn what you need to know.

I think knowing Core Data or Networking or any of the other multitudes of things are nice career embellishments, but I think if you are looking to bring on an entry level person and train them, this is what they need to know.

I don’t know how to do Networking. I have never had to know it for any job I have had. Same with Core Data. I know a lot about things most people never need to use like how to connect to a FireWire camera and how to parse LibXML2. These are things I learned because I needed them for the job I have. If I were looking for another job I am sure knowing Core Data would make me more marketable, but I wanted to find the right job for me rather than being qualified for a lot of jobs that aren’t really a good fit.

I don’t think not knowing how to do NSURLSession or how to make an Apple Watch app makes me an impostor or a bad developer. They haven’t affected my ability to get a job yet and I don’t think they ever will. If I need to learn them for something I am doing, I know enough that I can teach them to myself and if I forget them again, then I wasn’t using them.

I worry about people spending so much time learning “superficial” stuff that lets them build an app but does not teach them how the app works so it can’t be applied to anything else. I think instead of creating an aura of fear at not knowing everything, we focus on what is the essential amount you must know and enable people to learn the things they need to know to specialize or that interest them.

Specialize

At 360iDev last year Saul Mora and I were discussing the possibility of setting up something like a co-op for developers. If you had an app idea where you needed to know something you didn’t know, you could post it on this message board and if someone knew how to do it, you could negotiate working with them on it. I don’t particularly want to learn a bunch of stuff I don’t care about to make something and I would love to work on someone else’s project only doing the things that I want to do.

Like all good ideas that are formed by committee, this got bogged down in a lot of implementation details and forgotten. I still think this is the only way for independent development to move forward.

If you have a group of four people with different technical skills working together, you can put out a really nice app in your spare time. The gold rush is over, but I would hope that some people are involved in app development because they enjoy it and have ideas they want to share with the world.

I feel that Ray Wenderlich has embraced this idea. He has a large team of people working together on the tutorials because it simply got to the point where he couldn’t do it alone. We have a large pool of knowledge and resources and we are able to accomplish more than any one person could. I think he’s a great example of what you can do if you start trying to think cooperatively rather than singularly.

I think we need to move away from the idea of the solitary developer working in their basement over a weekend and move towards the idea of having a team of friends you can work with and share ownership of a product with. Even if the app never earns a dime, the act of working with your friends to make something you are proud of is a goal in and of itself.

So, to everyone feeling shitty because you can’t keep up with the new and shiny, stop it. Go easy on yourself. We’re at a turning point where things are going to be different and you can’t hold yourself to those standards anymore. Focus on the fundamentals and what is important to you and you will be fine. The platform has matured and it’s a good thing.