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.

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.

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 3- Printing Quotes

The purpose of this exercise is to display a quote and prompt the user for the person who said the quote. If the quote is correct, you output the answer and the speaker.

I think the stated goals for this exercise assume that you are using a language like Haskell that does not have strong user interface component. I adapted the requirements somewhat for iOS.

The UI elements I need for this exercise are a label asking who said the quote, a text view to hold the quote, a text field to accept the answer, a button to submit the answer, and another text view to display the response.

What you start off seeing when you launch the app.

What you start off seeing when you launch the app.

I briefly thought about how to create a label that would allow for multiple lines of text, when I remembered the best object for that is a text field.

I tried to make the layout adapt to different lengths of quotes. I thought if I just pinned my elements under one another but did not specify the height of each element that it could expand and contract according to how long the quote was. This does not quite work. The text field is stuck at one size and height. If the text is longer than the text field, the element adopts a scroll view to expose the hidden text.

It might be possible to use programmable constraints to get the effect I would like. I am interested in figuring this out in the future, but I will leave that challenge for another time.

There are a few challenges associated with this exercise:

  • Display a quote
  • Check the user input to see if there is an answer
  • If there is an answer, is the answer correct?
  • Customize the output depending on what the user submitted

Like the previous exercises, there are three different possible outputs. Unlike the previous examples, the three are not all connected. If there is no answer, then you have one output. If there is an answer, then you have to process it further to see if it is the correct answer.

I wanted to hard code as little in this application as possible. It was indicated that later in the book we will revisit this application and refactor it to pull multiple quotes and authors from a data structure. I could set the quote and the answer in the view controller, but then if the requirements change and it’s possible that there are more than one quote, I will have to change things. I want this to be set up for that possibility and I want the entire application to be testable, which means moving anything that is not view controller code into a helper functions class.

Since I believe I will later need to have access to multiple quotes, the first function I created was one to return the quote:

func quoteText() -> String {
    return "You can lead a horticulture, but you cannot make her think."
}

Right now we only have one quote, but in the future the requirements may change where we may possibly have more and this can be refactored to determine what that is without having to change any code in the view controller.

Next I want to determine if the response is correct or not. Since the answer is going to be used in multiple places and won’t be passed in from the UI, I made the answer a global variable.

Incorrect response.

Incorrect response.

I need to pass in the response from the user and check it against this answer. It is either correct or incorrect, which means we are returning a Bool:

let answer = "Dorothy Parker"

func isTheAnswerCorrect(response:String) -> Bool {
    if response == answer {
        return true
    } else {
        return false
    }
}

Depending upon whether the response is correct or not, the output string will change. If the answer is correct, we output a congratulatory message. If not, then we let the user know they were incorrect:

func responseOutput(isResponseCorrect:Bool, response:String) -> String {
    if isResponseCorrect == true {
        return "Correct! (response) said (quoteText())"
    } else {
        return "Sorry, (response) did not say that. Try again."
    }
}

Again, I want to future proof this function by not hard coding anything that might change. I am using the response as an interpolated String in both output messages because it will be the same either way. There’s no reason to hard code the correct response, thus making it more difficult to go back and change later.

Correct response

Correct response

So far we’re assuming that the user has entered a response. If they did not enter a response, I would like to handle that contingency as well.

I need to not only check to see if there are no characters in the string, but also to have an output message for the user if it is empty. I want this string to be optional because it is probable that there will be a response and I want this to be a fail-safe:

func isResponseEmpty(response:String) -> String? {
    if response.characters.count == 0 {
        return "Please enter a response!"
    } else {
        return nil
    }
}

Empty Response

Empty Response

My Helper Functions file is now complete. Each piece is small and testable. Now I need to put these pieces together to complete my functionality in the view controller:

@IBAction func answerQuestion(sender: AnyObject) {
    let response = answerTextField.text
        
    if let noResponse = isResponseEmpty(response!) {
        responseTextView.text = noResponse
    } else {
        let checkResponse = isTheAnswerCorrect(response!)
        responseTextView.text = responseOutput(checkResponse, response: response!)
    }
}

I need to pull in the response from the user and store it in a variable.

Since the failsafe for no response is an optional, I need to wrap it in an if-let statement. This puzzled me for a while because I kept getting a compiler error when I did this initially because I had an optional that was not unwrapped. I knew I didn’t want to force unwrap the return value from isResponseEmpty() because most of the time it would be nil. At that point I realized I was using response rather than response! The value from the text field is always presented as an optional. In the first exercise I realized that when you don’t enter anything in the text field, it doesn’t return nil, it just returns an empty string, so I knew it was safe to force unwrap the response.

After I check to verify that there is not an empty string, I need to check to see if the answer is correct. I run the isTheAnswerCorrect() function and pass that value into the responseOutput() function. That function returns a string and that string is set to the response text view.

I ran the code and it appears to work properly. Just to make sure, I went ahead and wrote a unit test for each function in the Helper Functions file. Since each function is small and does a very specific unit of work, it doesn’t take too long to verify each possible output.

Conclusion

I suppose it’s possible that I have overengineered this application. Some of the functions are probably overkill for the requirements as they are now, but I wanted to make this flexible for if those requirements change.

I probably could have shoved all my programming logic into one function, but I really like having everything spelled out and having each function do one small thing. When I was taking classes with Eric Knapp, he said that if you are talking about a function’s job and your description includes “It does this AND…” then you need another function. Each function should do one thing. I like this philosophy and I have been trying to implement it in my own code.

A link to this project can be found here.

Exercises For Programmers: Exercise Two – Counting Characters

This is the second exercise in Brian Hogan’s book Exercises for Programmers. My solution for this exercise is on GitHub.

Since this is still relatively early in the book, we are still dealing with some simple concepts. This exercise is about asking for a string, repeating it back to the user, and telling the user how many characters are in the string.

countCharactersSuccess

This was supposed to be the first exercise where you set up a user interface, but I jumped the gun on that by setting one up with the first exercise.

The only changes between the first exercise and the second were that there was going to be another label to output the number of characters and that I needed to count the characters in the string.

I was able to complete this far more quickly than the first exercise because most of the road blocks I encountered with the first exercise were solved for the second. I already knew how to set up my auto layout. I remembered how to get the text from the UITextField. I already had most of my set up for the processing I needed to do for the labels.

Failure condition. Need to set both labels, including making sure the second label is an empty string.

Failure condition. Need to set both labels, including making sure the second label is an empty string.

I started out thinking that because I had two labels I needed to create two separate functions. I initially made a variable out of the text field input and passed that into my two functions. Then I thought more critically about it.

I was passing the same information into both functions and doing the same “if-else if-else” statement:

func yourInputString(input:String) -> String {
    
    if input.characters.count == 0 {
        return "You need to enter a string!"
    } else if Int(input) != nil {
        return "Please enter letters and not numbers!"
    } else {
        return "Your input string: (input)"
    }
    
}

func numberOfCharactersInString(input:String) -> String {
    
    if input.characters.count == 0 {
        return ""
    } else if Int(input) != nil {
        return ""
    } else {
        return "(input.uppercaseString) has (input.characters.count) characters."
    }
    
}

That is a lot of repeated code. There is probably a better way to consolidate this.

One of the things Brad and I talked about with Swift having an advantage over Objective-C is that it can return more than one thing. One reason that the NSError stuff is so screwy is because you can’t return more than one thing. You have to pass a pointer to the location in memory for the error because you can’t simply return the error.

I realized that I could cut down on a lot of code by simply returning a tuple that contained both label strings. This cut down on code in both my helper functions and in my main View Controller because I only had to call one function and then assign the result from that function to the labels in the UI.

func inputStringAndCharacterCount(input:String) -> (String, String) {
    
    let yourInputString:String
    let numberOfCharactersString:String
    
    if input.characters.count == 0 {
        yourInputString = "You need to enter a string!"
        numberOfCharactersString = ""
    } else if Int(input) != nil {
        yourInputString = "Please enter letters and not numbers!"
        numberOfCharactersString = ""
    } else {
        yourInputString = "Your input string: (input)"
        numberOfCharactersString = "(input.uppercaseString) has (input.characters.count) characters."
    }
    
    return (yourInputString, numberOfCharactersString)
}

I am finding this iterative approach of starting with something simple then adding complexity is a really good way to approach programming. You take lessons you learned doing something simple and you apply them as you do more and more complicated things.

Writing unit tests also forces you to think in ways to make it as easy as possible for yourself to be able to separate out as much functionality as possible in a way for it to be testable.

When Brad was telling me initially about using tuples I didn’t get how he came up with the solution. It was obvious once I saw it, but I didn’t get how he came up with it. I get it now. When I was writing my code and saw that I was repeating myself a lot, it forced me to think more critically about how I could make my code better.

I am happy I am doing these exercises because I don’t feel I get to code as much as I should. I am now seeing that coding things for myself helps me to learn things better than just being told what to do by someone who learned the way I am learning now.

We can read all the books we want to on clean code and so forth, but you really learn by doing and making mistakes and going back to refactor. I think a lot of people never go back and refactor and that is unfortunate for them. They are missing out on a great learning opportunity.

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.