Category: Development

  • Swift Coding Puzzles #2 – Balanced Brackets

    This is part of a series of coding puzzles inspired by the #CodingPuzzle tag/puzzles originally curated and shared by Ali Spittel. This is my approach to solving those puzzles in Swift. If you have any comments or answers you want to share, post them below! I’d love to read them.


    Puzzle #2

    Given strings of brackets, determine whether each sequence of brackets is balanced.

    When would you come across a situation like this? Well, if you ever write a source editor, you might come across something like this. As most programming languages use brackets to denote context, functions, and other divisions, we’ve probably all come across a situation where we forgot to close something off.

    For the sake of this exercise, let’s define what brackets mean. In this case, it’ll be three sets of characters: ( ) , [ ] , and { } . The first character we’ll call the “open bracket” and the latter the “close bracket”.

    So, what makes a balanced sequence?

    1. A matched pair of brackets.
    2. Any nested brackets must also be matched pairs.

    An example of some balanced sequences include: () , [(){}] , {([()])}

    An example of some imbalanced sequences include: (() , [([)]] , {([)]}

    If any of those become unpaired, then the entire sequence is considered imbalanced. If you’ve ever created a class in Swift and forgot to close a brace when defining functions, you’ll know what that is.

    By the above definitions, we can thus determine that in a balanced sequence:

    1. It has an even number of brackets
    2. An open bracket will never meet a close bracket of a different type
    3. A closed bracket will never appear before its corresponding open bracket

    That said, here’s how I approached the problem.

    First, I defined what each of the brackets were.

    let brackets: [Character: Character] = [
        "[":"]",
        "(":")",
        "{":"}"
    ]
    var openBrackets: [Character] { return Array(brackets.keys) as! [Character] }
    var closeBrackets: [Character] { return Array(brackets.values) as! [Character] }

    Using a dictionary, I’ll be able to easily look up the close bracket for a given open bracket.

    Next, let’s look at my function to solve this.

    func isBalanced(_ string: String) -> Bool {
        if string.count % 2 != 0 { return false }
        var stack: [Character] = []
        for character in string {
            if closeBrackets.contains(character) {
                if stack.isEmpty {
                    return false
                } else {
                    let indexOfLastCharacter = stack.endIndex - 1
                    let lastCharacterOnStack = stack[indexOfLastCharacter]
                    if character == brackets[lastCharacterOnStack] {
                        stack.removeLast()
                    } else {
                        return false
                    }
                }
            }
            if openBrackets.contains(character) {
                stack.append(character)
            }
        }
        
        return stack.isEmpty
    }

    First, if the string has an odd number of characters, we automatically fail it. This is in line with point number 1 above.

    I then declare a variable to temporarily hold brackets. This stack will be used in the following loop.

    Next, we go through each character of the string. Our first check is whether the character is a close bracket or not. If it is, and our stack is empty, it means we’re encountering a close bracket before its open bracket counterpart. We thus return false. If the stack isn’t empty, we check if the last character on the stack is an open counterpart of this close bracket. If it is, we remove the open bracket from the stack. Otherwise, we return false.

    If it’s not a close bracket, we’re likely looking at an open bracket. Those automatically get added to the stack.

    This loop functions for all characters in the string. Afterwards, our return is whether or not the stack is empty. If it’s not empty, it meant we had more open brackets than closed brackets, and while the earlier catches may not have produced a return, it technically is an unbalanced bracket set.

    Here are a few sample calls to this function and their outputs.

    isBalanced("()") // True
    isBalanced("[]") // True
    isBalanced("][") // False
    isBalanced("[][") // False
    isBalanced("()()") // True
    isBalanced("[(){}]") // True
    isBalanced("{{[()()][]}}") // True
    isBalanced("[]()({)}") // False
    isBalanced("(((") // False

    I had initially hoped to tackle this with recursion, but I found the above solution to be easier to follow and much easier to manage.

    Did you have a different solution? Is there something I could improve with my Swift code? I’d love to hear from you!

  • Swift Coding Puzzles #1 – Simple Pig Latin

    I’ve been following Ali Spittel‘s #CodingPuzzle challenges. While I’ve read most of them, I haven’t actually done them.  But each of them would be a fun little exercise. So, I figured I’d go back and tackle each of them in Swift.

    Before I start, a note: There are always multiple ways to tackle coding challenges. This is just my approach to it. If there are better/more optimal ways of doing it, please comment and share your solutions! I’d love to see them. This is as much a way for me to share what I’ve done as it is for me to learn from how others see problems and want to solve them.

    That said, here is the first puzzle:

    Puzzle #1 – Simple Pig Latin

    “Move the first letter of each word to the end of it, then add “ay” to the end of the word. Leave punctuation marks untouched.”

    If this was just taking a sentence without punctuation, this would be a lot easier. You could split the array, modify the words, and rebuild the sentence. But keeping punctuation untouched adds a bit of a challenge.

    Being me, I also wanted to make sure that this would handle if someone inadvertently misses a space after some punctuation. (No, this likely doesn’t handle apostrophes properly, so contractions will probably not be correct; but I’m no native Pig Latin speaker to know.) So I may have put a little too much thought into this.

    First, I wanted to make a function that modifies a word into its proper Pig Latin form.

    /// Takes a word and makes it Pig Latinized
    func pigLatin(word: String) -> String {
        var newWord = word
        let startIndex = newWord.startIndex
        let firstCharacter = newWord[startIndex]
        newWord.append(firstCharacter)
        newWord.append("ay")
        newWord.remove(at: startIndex)
        return newWord
    }

    With this function, I can now pass in parts of a sentence as needed. With that done, now I just need to get the words to pass in.

    I could have split the array based on space, but that wouldn’t necessarily preserve punctuation. So I instead opted to go through the string character-by-character and parsing words that are found.

    func simplePigLatin(_ text: String) -> String {
        let characterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters)
        var piggyText = ""
        var temporaryWord = ""
        for (index, character) in text.enumerated() {
            let scalar = character.unicodeScalars.first!
            if characterSet.contains(scalar) || index == text.count - 1 {
                if temporaryWord.count > 0 {
                    let pigLatinWord = pigLatin(word: temporaryWord)
                    piggyText.append(pigLatinWord)
                    temporaryWord = ""
                }
                
                // Append any punctuation or white space
                if characterSet.contains(scalar) {
                    piggyText.append(character)
                }
            } else {
                // Append letter to temporary word
                temporaryWord.append(character)
            }
        }
        
        return piggyText
    }

    I go through each character and, if it’s a letter, I add it to a temporary word. If I hit a non-letter (punctuation or whitespace) or the end of the string, I take that temporary word, modify it for authentic Pig Latin, and append it to the return string.

    With all of that, here are some sample outputs:

    let word = simplePigLatin("I wish I could speak in Pig Latin; I really do!")
    print(word) // Iay ishway Iay ouldcay peaksay niay igPay atinLay; Iay eallyray oday!
    
    let contractions = simplePigLatin("I've got day-to-day issues.")
    print(contractions) // Iay'evay otgay ayday-otay-ayday ssuesiay.
    
    let badSpacing = simplePigLatin("I forgot,this is not where commas,go")
    print(badSpacing) // Iay orgotfay,histay siay otnay hereway ommascay,ogay

    So that’s how you can do Pig Latin in Swift. No, it’s not perfect. There are other cases that aren’t dealt with, such as how to handle words starting with vowels or ‘qu’. But I’m no linguist.

  • Managing Time for Side Projects

    I’m quickly coming up on my two year anniversary at my day job. I’ve learned quite a lot in my professional experience as an iOS developer. But one unfortunate side effect of doing something that I love during the day: it’s hard to find the time and motivation needed to work on my app projects, even when the desire is there.

    Max’s tweet was originally about trying to work too much. But I felt inspired to address some of the issues as to why I feel I don’t work enough, whether or not that’s true.

    The Problem(s)

    Here are a few of the issues I’ve found myself facing:

    • Too Many Ideas – My mind seems to come up with new side projects at least once a month. Of course, there’s no way for me to complete (or even start) many of these. But this has been happening for a while. I still have a file in Evernote with about 6 years of app and service ideas. I want to work on one, but I sometimes get distracted with my list and lose focus on what is achievable.
    • Wrong Project Scope – For the ideas that I am able to actually work on, I find myself dreaming up massive plans. ‘Maybe I’ll completely rewrite X!‘ ‘I could do Y like this, but if I do it like this, it’ll be future proof and everything!‘ What was going to be a simple project that I could enjoy working on becomes a large project that might as well take my full time.
    • Too Little Time – I know what you’re going to say. “Isn’t that the whole point of this post?” Well, yes. But it’s worth mentioning. It’s hard to work on side projects when you spend time playing games or watching TV.  If you’ve set aside time for yourself, you are in control of what happens with that time. And that doesn’t always mean those desired projects get a share of it.Nor does that take into account responsibilities you might have if you’re a husband or father and the time you need to spend with your family.

    The Solutions(?)

    Before I had my current job, I did a lot of my development work on the side. Sometimes I even found some time during the lulls of the day to get a little bit of work done. But now, I have to try other things.

    A few things I’ve ultimately realized:

    • I have to make up my mind. Some work I’ve done on my projects lately has stalled because I can’t make up my mind on what to do. In one example, I’m considering using Realm as a data store. I use Realm at work. It’s something I’m fairly comfortable with. But then I think that I could use this time to try working with Core Data again. Or maybe I’ll just stick to using SQLite directly but use a new library. Soon, I’m stuck in this cycle of each direction being one to consider, but I end up doing nothing but considering choices and don’t end up going any one way. So I’ve started telling myself, as my own boss on these projects, that I have to make a choice, stick with it, and move on.
    • I don’t have to be perfect. Similar to the last point, these projects exist for me and me alone. While I am particular about the quality of my own work, I am not going to be pushing these through any kind of code review. So I can let some things slide. If anything, it gives me things I can address with future releases. But ultimately, I don’t need to perfect something before I release it. So long as it works, I can be content.
    • I have to know what I’m doing. I’ve been a fan of Asana for several years. While it was great for my day jobs, I started using it over a year ago for my side projects.  It doesn’t need to be as complicated as my day job (with Epics, Work Requests, and Iteration planning), but I do need to have some idea for what I want my deliverables to be. Setting that for my various projects, including reasonable feature sets for various stages of release, is helping me to make progress.
    • I need a long term plan. I decided earlier this year to go overboard and plan out my 2018 project goals. I’ve got quarterly release goals (mostly Alpha and Beta releases), planned App Store releases, and a general idea of what I would like to accomplish this year. All of it is set up to be achievable but not overwhelming. So no, I’m not launching 6 new apps this year. Yes, I’m hoping to have at least 1 app update and 1 new app on the App Store by December. ((I said it was achievable. I didn’t say it was impressive.))

    Overall, I’m not getting as much done with my side app projects as I’d like. But as I am a developer during the day, that takes a lot of my developer energy. And lastly, I have to balance my interest in side projects with my family, which has my ultimate priority. Thankfully, it’s kept me from being a workaholic. ((As much as I love to work.))

    In my case, I just have to accept the reality: I can’t do what I once could. But that’s okay. ((I started this blog post shortly after Max’s initial tweet, and that was 4 days ago. Shows you how my time is allocated.))

  • Countr, my first app on the App Store

    It’s been many months since I last talked about app development. I’m a bit disappointed with myself, personally, and how much I haven’t shared. It’s been a fun experience as I’ve dived into Objective-C, Xcode, and learning how to develop things on my own. Since then, iOS 8 was previewed (and since launched), Swift was introduced as a new programming language, and more APIs and development tool updates have happened across the Apple ecosystem.

    Well, I’ll be writing more thoughts about the development process soon. But first, I wanted to talk about the first app I’ve developed through to launch. That is Countr, a simple app to quickly take a count. I had wanted an app to help me take a count when I’m at certain meetings or assemblies. I feel this app does this excellently.

    While the app was released in late August, I only just now announced it. Moving to Arizona took up a lot of time. Go figure.

    Countr not only helped me learn the development process, but I got a nice overview of the app release process. I’m very grateful for the update to iTunesConnect, which has made it a much more attractive experience when checking on the status of my app.

    In upcoming posts, I’ll talk about developing Countr, developing for iOS in general, and some other things that I thought were pretty cool.

    I want to thank the few friends that helped beta test Countr before release. I got a lot of good feedback and, while it is a simple app, the others that I’m working on are not as simple. I made sure to use the same process with Countr that I would expect with a larger, complex application. It’s been insightful, and I’m ready to release more apps later this year.

    Countr is available for free on the App Store.

  • My Adventures In App Development (Part 1: The Beginning)

    My Adventures In App Development (Part 1: The Beginning)

    I hate saying that I’m relatively new to app development, but I am. I had originally moved into the Apple ecosystem in 2009 with somewhat of a desire to develop applications. At the time, however, I was spending most of my development time on websites. App development seemed like a much more daunting task.

    Over the years, I would occasionally open up Xcode with the intent of creating some kind of basic iPhone app. Each time, though, it seemed like such a different beast than what I was used to. (The MVC model wasn’t a stranger to me, but I didn’t have a lot of experience with it at the time.) I’d add in a few buttons and views, type up some code, but I couldn’t get myself to really dive into it.

    One thing I’ve come to really love using since I first got my first iPhone in 2009 is Evernote. I use it to store notes about almost anything, from guitar tab to food recipes. For a while now, I’ve also stored different ideas that come into my head. As I put more and more ideas down in writing, I was able to get a better idea of what I wanted to do.

    Two breakthroughs helped me to really push forward in app development, however. The first was making use of video tutorials online, especially on iTunes U, that helped me to really learn and understand Objective-C and iOS app development. Finding an iOS development course is a big plus, as it is just like being in a class where you are taught how to develop for the iPhone and iPad. It definitely beats just reading documentation and following along in a book.

    Second was the latest iOS release, iOS 7. As soon as I saw the new look and feel of iOS unveiled at WWDC, as well as reading about the new APIs built into the release, I became excited for development again. In fact, I hadn’t felt this excited about it before.

    It was with iOS 7 that my interest was aflame again. Since June, I’ve been pushing forward and working on several ideas. I’ve not been so excited about iPhone app development as I am now. I have a few projects on the burners and, as they get closer to release, I’ll start sharing some information about them, either here or via my business site (which will be updated soon). I’ll also document my travels as I learn more about Objective-C, Xcode, and developing for the iPhone, iPad, and Mac.

  • [C#] Using Nini .NET Configuration Library

    [C#] Using Nini .NET Configuration Library

    When developing a desktop application, there will be times when you want to store settings for your program. A database is one option, but on Windows, you might just wish to have your settings stored in an INI file. One way to work with an INI file in C# is with the Nini Library. This makes it quite easy to read from and write to an INI file.

    Let’s get started.

    After installing the library, we’ll need to set our namespace.

    using Nini.Config;

    What will our INI file look like? Something like this:

    ;conf.ini
    [Options]
    Zipped = 0
    Filename = test.txt

    For my application, I decided to make a class devoted to the configuration file. So, let’s define that and a few other variables.

    public class OurConfig
    {
    string NL = Environment.NewLine; // New line character
    private string configFile = "conf.ini"; // Our INI file
    
    IConfigSource config; // Instance of our config
    
    }

    Now that we have our variables declared, let’s create a couple of useful methods.

    public void set_is_zip(int zipped)
    {
    config.Configs["Options"].Set("Zipped", zipped);
    }
    
    public void set_filename(string fname)
    {
    config.Configs["Options"].Set("Filename", fname);
    }

    These two methods will update the INI file with new settings, should we change them in our program. Of course, if we make these changes, they need to be saved. Thankfully, we can declare something in our constructor (which we will write a little later) that will auto-save our changes as we make them.

    config.AutoSave = true;

    Now, let’s create a pair of methods to return the data. This will be useful in our program when we need to use these settings.

    public int return_is_zip()
    {
    return config.Configs["Options"].Get("Zipped");
    }
    
    public string return_filename()
    {
    return config.Configs["Options"].Get("Filename");
    }

    With these methods, we now have a basic class for handling a configuration file. All that is left is our constructor.

    But before we get to the constructor, there is something else I created. What if our INI file doesn’t exist? I decided that I would make a function to create a default INI file, should the old one not exist anymore. This is also useful if we want to distribute our program without an INI file.

    private void fill_new_ini()
    {
    // Put default values into the INI file
    // Essentially, we're writing a blank file, so this is fairly simple
    string toWrite = ";conf.ini" + NL
    + "[Options]" + NL
    + "Zipped = 0" + NL
    + "Filename = test.txt" + NL;
    
    System.IO.File.WriteAllText(@"conf.ini", toWrite);
    }

    We can do a check when we initialize our class that will check to see whether or not this file exists. If not, we’ll create it so we can work with it.

    That makes this our constructor:

    public OurConfig()
    {
    // Initialize the INI file if it doesn't exist
    try
    {
    configFile = new IniConfigSource("conf.ini");
    }
    catch (Exception ex)
    {
    // Write default values into it
    fill_new_ini();
    configFile = new IniConfigSource("conf.ini");
    }
    
    configFile.AutoSave = true; // Auto save config file as we make changes
    
    }

    Our whole class thus looks like this:

    using Nini.Config;
    
    public class OurConfig
    {
    string NL = Environment.NewLine; // New line character
    private string configFile = "conf.ini"; // Our INI file
    
    IConfigSource config; // Instance of our config
    
    public OurConfig()
    {
    // Initialize the INI file if it doesn't exist
    try
    {
    configFile = new IniConfigSource("conf.ini");
    }
    catch (Exception ex)
    {
    // Write default values into it
    fill_new_ini();
    configFile = new IniConfigSource("conf.ini");
    }
    configFile.AutoSave = true; // Auto save config file as we make changes
    }
    
    private void fill_new_ini()
    {
    // Put default values into the INI file
    // Essentially, we're writing a blank file, so this is fairly simple
    string toWrite = ";conf.ini" + NL
    + "[Options]" + NL
    + "Zipped = 0" + CL
    + "Filename = test.txt" + CL;
    System.IO.File.WriteAllText(@"conf.ini", toWrite);
    
    }
    
    public void set_is_zip(int zipped)
    {
    config.Configs["Options"].Set("Zipped", zipped);
    }
    
    public void set_filename(string fname)
    {
    config.Configs["Options"].Set("Filename", fname);
    }
    
    public int return_is_zip()
    {
    return config.Configs["Options"].Get("Zipped");
    }
    
    public string return_filename()
    {
    return config.Configs["Options"].Get("Filename");
    }
    
    } // End OurConfig

    That’s how simple it can be to work with your own INI files in C#.

    Did you find this useful? Let me know in the comments!