Archive

Posts

  • Meetings are Broken

    Let me preface this essay by saying that I’m not anti-meeting. I’m against wasting time in meetings. A good meeting is great, but good meetings in the wild are as rare as agile done right.

    Why Meetings are Broken

    No agenda

    No agenda at all is a pretty obvious way a meeting can be broken, but the no agenda meeting can take other forms. A common form I have seen is a standing meeting for a given topic, say Project X. People feel like the meeting has an agenda (“hey, it’s about Project X”), but that’s not an agenda. What if there is nothing to discuss on Project X, then what? How would that be discovered prior to the meeting?

    Off Topic

    Even with an agenda, many times meetings simply veer off topic. People in the meeting use the time to discuss other things that is on the top of their current list. Effectively, they bring their disorganization into the meeting and spread it to every other person in attendance.

    Time Box?

    Time boxing can take a couple forms. There is time boxing the entire meeting and also time boxing each agenda item in the meeting. Ideally time boxing should not be needed. If a meeting is called to make a decision, the meeting should only end when the decision is made. But, time boxing is often used as a way to maintain urgency and keep the meeting from veering off topic.

    Synchronous

    Meetings are by nature synchronous. Every person in the meeting has to be part of that meeting at that moment regardless of what else they could be working on instead. Discussions in a meeting are also in real time. This leads to the topic presenter having an advantage over the other participants during the discussion because the presenter has given more thought to the topic. The other participants then either have to think quickly or can only really offer gut reactions to the topic.

    Late!

    Another obvious one is when people are late. First there is the cost of the meeting itself, but then delaying the meeting even further quickly puts the company in the hole. Five programmers at a fairly low salary can cost the company $40+ for every 10 minutes they are waiting around.

    Lack of Documentation

    This is a big one for me. I take notes in and after the meeting as a way to make sure what was discussed and decided is what happened. Even then, there can still be miscommunication about what was decided by who and why.

    Lack of Intellectual Rigor

    Talk is cheap. It is almost too easy to say something without thinking it through in a meeting. Now, I’m not talking about brain storming sessions to figure something out, but the typical meeting to discuss some agenda item. Writing forces a higher level of intellectual rigor that speaking does not.

    How to Fix the Meeting

    Nothing I’ve stated above is novel, yet companies still continue to have completely wasted meetings. I’m using this series of posts as a way to put some coherence to my thoughts, and will address how to fix meetings in a future post.

  • Effective Note Taking

    Speaking of Notes

    I learned note taking in college. In class I would write copious notes, and then transfer them to my computer as an outline that I could reference later. At the time there were not many tools that could easily input handwriting into the computer, and also make it useful. There were some tools that could scan pages, but they were cumbersome to use.

    Fast forward many years to now, and I am still searching for the perfect note taking device. I tend to bounce back and forth between a notebook, and some note type app on the computer. Both have advantages and disadvantages inherent in the media.

    A paper notebook is the optimal note taking device. I can easily make lists highlight items, and draw lines connecting ideas. I can also quickly draw diagrams or quick app designs. The problem is that unless I’m writing notes, I’m on my computer. Referencing my handwritten notes is a pain, much less easily sharing them. The most serious problem I run into is finding a note from last week or last month.

    It’s usually around the point when searching for a hand written note that I get frustrated, and vow to only take notes on the computer. After bouncing between many apps, the latest version of the Apple Notes.app is what I have settled on. Picking a note app is its own post, so I don’t want to get too far into that here. The general benefits of a notes app are the same. They are searchable, sync through the cloud, and are easy share with others. The big drawback is that they are not really the best way for me to take notes.

    Enter the 11” iPad Pro + Apple Pencil

    Writing on an iPad Pro with the Apple Pencil has a very nice feel. The Apple Pencil has a little less drag than a typical #2 pencil, and more drag than a smooth ballpoint pen. There is little screen lag that I can notice when writing or drawing.

    In the Notes.app, the written notes are OCRed in the background and made searchable. Even my sometimes questionable handwriting is deciphered fairly well. The notes are also synced across all devices.

    I do have some initial complaints:

    • Mixing typed and hand written notes is more cumbersome than it should be. When a hand written note is synced to the computer it can be awkward to start a typed section above.
    • Sharing from the Notes.app to something like Slack does not work. It processes like it is going to work, but then nothing shows up in Slack. For diagrams I have been using Linea Sketch. It is simple enough for a non-artist like me to get diagrams done. It also shares perfectly.
    • I do not like the noise the Apple Pencil makes when it first hits the screen to start writing or drawing. It might just be me, but I have started training myself to bring the pencil down more lightly when writing.

    Even with the shortcomings above, taking notes on the iPad Pro is a huge step forward for my note taking. Now that I have the iPad Pro and Apple Pencil, I plan to take another pass through note taking apps. I’ll update here if anything changes.

  • AWS SFTP Transfer with a Custom Identity Provider

    We were excited when AWS finally announced a hosted SFTP transfer service backed directly by S3. We had looked at other solutions that mounted S3 as a drive, but they always seem to have some random issues. What we had settled on was running an ftp server and then periodically sweeping the uploaded files into S3 for processing.

    The announcement made the setup process look simple, which it was for the specific use case where all users will manage their own ssh certificates. In our case though, users had to be able to upload files with just a username and password. And, ideally, it would be the same username and password they use to work in our other systems.

    According to the documentation for Custom Identity Providers, it should be a simple process of setting up a lambda and API Gateway end point. On a successful authentication, the lambda should return this json back to the SFTP Transfer service.

    {
      "Role": "IAM role with configured S3 permissions",
      "PublicKeys": ["ssh-rsa public-key1", "ssh-rsa public-key2"],
      "Policy": "STS Assume role scope down policy",
      "HomeDirectory": "User's home directory"
    }
    
    • We were not using PublicKeys, so they can be omitted.
    • The users home directory really means the full path, including the bucket name. For example, /sftp-bucket/username

    Role and policy were not so simple. First, read this post about IAM Assume role, and how to setup the basic scope-down policy. The writer does a good job explaining both, so there is no need to rehash the same thing here. But, that post only deals with setting up users that are managed by the SFTP Transfer service and not dealing with a custom identity provider.

    Looking back as the require json response, anyone who has experience with AWS IAM would look at the json above and think Role and Policy require ARNs. It turns out we were only half right. Yes, Role does require an ARN. The role must also have full access to the ftp bucket. The policy is given a set of variables by the SFTP Transfer service, and is applied in real time. In order for this to work, the policy must be passed inline. Let me repeat that, the entire policy must be returned inline from the lambda function.

    We could not find this gotcha in the documentation. There were hints in how scope-down policies are used though. Because they are assumed at usage time and passed variables, they cannot be attached to roles ahead of time. We incorrectly thought that the SFTP Transfer service would look up the policy based on its ARN, and do the replacement then. Instead, it treated the ARN as json which obviously failed and gave the final clue to the issue - a CloudWatch error from the SFTP Transfer service that read invalid json when a user logged in.

    Finally, since we like to manage all our IAM policies through an external tool like Terraform or CloudFormation we did not want a random policy sitting in a lambda function. We went ahead and implemented what we thought the SFTP Transfer service was doing and looked up the policy json using the AWS SDK getPolicy() and getPolicyVersion() functions. This way the policy is managed along with all our other policies, and is dynamically loaded in the lambda with the json returned.

  • Path to Discipline

    About 6 months ago I came across Jocko Willink on Twitter. He is an ex-Navy Seal with a straight forward approach to life and leadership. I do not remember exactly how I stumbled across him, but I immediately consume much of his Twitter feed. His no-nonsense approach to discipline resonated with me.

    After 7 months of working on my personal discipline, my next step is to write more. As someone who typically works in code all day long, the obvious question is why write more instead of code more. There are two reasons:

    • Writing down thoughts is great way to take partial ideas and make them concrete. It forces the writer to work through the idea to a deeper level than otherwise happens with thinking alone. Jeff Bezos even forces this type of communication at Amazon.

    • Written communication is key to any profession no matter the persons current career level. Creating software is almost always a team activity. Creating great software requires effective communication both to the team and to the users.

    To this end, I will start writing in this blog again. My goal is to share some thoughts weekly even though work makes that challenging. But, without a measurable goal it is not a goal. So, here we go.

  • The Case for Adding Scala

    Scala is a language that I have been examining for awhile. Early on the library versioning issues really turned me off, but the seem to have been solved. It’s also a very large language that requires programmer discipline to not abuse. Twitter has been a big proponent of Scala and the Effective Scala document is a great start on how not to abuse the language features.

    This post argues against Scala in large projects or in mixed projects. The points made about tooling and interoperability I think have for the most part been fixed since the post was made in 2010. Intellij works great with Scala and intermingles Scala and Java in the same project without any issue.

    One of the big points that is made in the post against adding Scala is that it raises the bar for someone to contribute to a project. While is does raise the bar, is Scala really the straw that breaks the camel’s back in this case? Any modern Java project is already going to be loaded with Java, Spring, Hibernate at a minimum. I also wouldn’t write any Java without using Guava and the components it provides like immutable collections, predicates and options.  Do those also raise the bar too high for a new contributor?

    The post also argues against multi-language projects. Again, every project is already multi-language. Java, SQL, HQL, HTML, JS, SpEL to name the common ones. Scala appears to get singled out because it can be abused. The problem with that line of logic is that any language can be abused. Project standards are key anytime there is more than one developer.

    So, after some discussion we are including Scala into our Java projects. I view it as an easy way to evaluate if Scala can work for us. I also think (hope) that in the long run Scala can become our language of choice for working on the JVM.

  • Making A Living in the App Store

    TL;DR – Starting a business is hard and most fail.

    The NYC has posted an interesting article about the app store boom.  The article focuses on a couple that bet everything on developing a business around making apps.  While I agree with the articles premise that making a living on the app store is a  very hard thing to do (see Zynga’s collapse), the article failed to mention that any startup is hard.  The majority of startups fail regardless of the industry.

    As someone who has been following the app store for many years the gold rush period has long been over.  Flooding the app store with bad apps is no longer a way to make money.  Users expect apps to be much higher quality than in 2009.  High quality takes time and money to develop.

    Discoverability it hard.  Even if the app is high quality and solves a genuine problem for the user, it may remain impossible to find.  People complain about the app stores discoverability like this is a problem unique to Apple, but it’s not.  Discoverability is hard in any business.  Having a great product is simply not enough.  Potential users must be told about the product.

    One positive for the couple in the article is the husband learned how to write apps.  While the app store gold rush may be over, the app store is not going away.  Users increasingly expect every product to have a corresponding mobile app.  Mobile web works for some products, but users expect a quality that is still hard to reach with todays mobile technology.  As Steve Jobs so famously said about DropBox, apps will increasingly become features of a larger product.  Dropbox on the other hand has turned out differently.

  • Stop SOPA!

    This issue is too important to ignore so I’ve been trying to build a post that explains what SOPA is and why it is not the answer.  Turns out that Tim O’Reilly has recently given an interview about why SOPA isn’t needed and should be stopped.  As a publisher who benefits from copyright, he explains in a clear and concise manner why SOPA is not needed.  Read the full interview at GigaOM.

  • Emacs Org-Mode

    As a vi and vim user I had never come across emacs org-mode until yesterday.  I’ve spent the last couple days fitting it into my project and task workflow and must say that I am really impressed.  Traditionally whenever I have tried to use project management or task tracking software it would always get in the way of how I wanted to do things.  This inevitably would lead me back to a text file list on my desktop, a piece of paper with notes, and recently a google doc that looks a lot like my desktop text file.  Org-mode has opened my eyes to how project management should be done.

    First off, since I’m not an emacs user yet, some of the key binding issues have slowed me down.  Out of the gate I have set up my projects in a simple, and I think, logical fashion.  I’ve read about other people maintaining a single .org file with their entire life in it, but that seems a bit too unwieldy to me.  Perhaps that’s my lack of emacs skills showing through though.

    In my initial setup, I have a .org file for each project.  Projects that are work related are simply named work_.org in addition to a catchall project called work_general.org.  The general project is a place to put quick TODOs that popup out of meetings or conversations that are not really projects.  Overall, it’s a nice easy way to keep everything work related together and grouped by project.  Now, this does mean I have to add each .org file to my .emacs to have it show up in my global TODO list, but that’s actually a good thing since I want my global TODO list to only show work items.

    For my non-work life I have a life.org file.  I keep this file out of the global TODO list and use it stand alone for everything from what needs to be done from things with the house to buying gifts to whatever (“TODO cancel XBOX live subscription” is on there).

    Finally, personal projects have their own file, projects.org.

    The beauty of org-mode is that it’s just text files.  At any point and time while taking notes on a project I can type “TODO” and the line becomes part of the global TODO list.  The list lets me jump right to the TODO line and see the context of the notes that caused the TODO to come about.  Something so simple, yet at the same time completely awesome.

    This is the first time in a long time I’ve been excited about something like project management.  I’m not really surprised that emacs contained org-mode (isn’t emacs it’s own self hosting OS by now?), but at the same time I never thought to look.  The org-mode website mentions converting vi users to emacs.  I can’t say that will happen, but hopefully learning both vi and emacs to a sufficient level will not be like crossing the streams.

  • Resting and Working

    People who write software are using their creativity to solve problems.  I compare it to writing using a very precise language and grammar to express a story to the user.  I came across this video over at the 99%.  In it Tony Schwartz, author of “The Way We’re Working Isn’t Working“, relates athletic performance to creative performance.  One thing athletes have known for years is that the rest between workouts is just as important as the workout itself.  While it seems intuitive that it would work the same way with mental work, many creative professionals skip the rest part in order to squeeze in more work.  This additional work is usually lower quality and eventually the lack of rest becomes detrimental to creativity.
    (It’s a flash player, so if you have flash block on click the whitespace below to make it load.)

  • UITextField Format For Currency Revisited

    Since my first post on formatting a UITextField with proper currency symbols and separators I think I have learned a lot more about objective-c and more importantly the UI components provided by Apple.  In this article I will revisit how to format a UITextField with the correct currency symbol and grouping separators.

    The original goal was to create a text field that would update in real time both with the currency symbol and grouping separators as numbers were typed in.  The first working solution can be found here, but it had some short comings particularly in code complexity.  The main problem was that I was trying to keep the string formatting correct so that I could decode the string to an NSNumber using a currency formatter and then encode the string again to an NSString.  This was needless complicating the code when dealing with inputting characters. The original code:

    //MARK: -
    //MARK: UITextFieldDelegate Implementation
    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range 
                                                          replacementString:(NSString *)string{
     BOOL result = NO; //default to reject
     
     if([string length] == 0){ //backspace
      result = YES;
     }
     else{
      if([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0){
       result = YES;
      }
     }
     
     //here we deal with the UITextField on our own
     if(result){
      //grab a mutable copy of what's currently in the UITextField
      NSMutableString* mstring = [[textField text] mutableCopy];
      if([mstring length] == 0){
       //special case...nothing in the field yet, so set a currency symbol first
       [mstring appendString:[[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol]];
       
       //now append the replacement string
       [mstring appendString:string];
      }
      else{
       //adding a char or deleting?
       if([string length] > 0){
        [mstring insertString:string atIndex:range.location];
       }
       else {
        //delete case - the length of replacement string is zero for a delete
        [mstring deleteCharactersInRange:range];
       }
      }
      
      //to get the grouping separators properly placed
      //first convert the string into a number. The function
      //will ignore any grouping symbols already present -- NOT in iOS4!
      //fix added below - remove locale specific currency separators first
      NSString* localeSeparator = [[NSLocale currentLocale] 
                                     objectForKey:NSLocaleGroupingSeparator];
      NSNumber* number = [currencyFormatter numberFromString:[mstring
                            stringByReplacingOccurrencesOfString:localeSeparator 
                                                      withString:@""]];
      [mstring release];
      
      //now format the number back to the proper currency string
      //and get the grouping separators added in and put it in the UITextField
      [textField setText:[currencyFormatter stringFromNumber:number]];
     }
     
     //always return no since we are manually changing the text field
     return NO;
    }
    

    Instead it was much easier to just strip out the currency symbol and group separators and then use a basic number formatter to turn the string into a NSNumber.  I was able to remove an entire section of code:

     ...
     //here we deal with the UITextField on our own
     if(result){
      //grab a mutable copy of what's currently in the UITextField
      NSMutableString* mstring = [[textField text] mutableCopy];
      if([mstring length] == 0){
       //special case...nothing in the field yet, so set a currency symbol first
       [mstring appendString:[[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol]];
       
       //now append the replacement string
       [mstring appendString:string];
      }
    ...
    

    Finally, take the newly formed NSNumber and run it through the currency formatter to create the desired output.  The entire new method is below:

    //MARK: -
    //MARK: UITextFieldDelegate Implementation
    -(BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
                    replacementString:(NSString *)string{
     BOOL result = NO; //default to reject
     
     if([string length] == 0){ //backspace
      result = YES;
     }
     else{
      if([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0){
       result = YES;
      }
     }
     
     //here we deal with the UITextField on our own
     if(result){
      //grab a mutable copy of what's currently in the UITextField
      NSMutableString* mstring = [[textField text] mutableCopy];
    
            //adding a char or deleting?
            if([string length] > 0){
                [mstring insertString:string atIndex:range.location];
            }
            else {
                //delete case - the length of replacement string is zero for a delete
                [mstring deleteCharactersInRange:range];
            }
            
            //remove any possible symbols so the formatter will work
            NSString* clean_string = [[mstring stringByReplacingOccurrencesOfString:localGroupingSeparator 
                                                                         withString:@""]
                                                   stringByReplacingOccurrencesOfString:localCurrencySymbol 
                                                                             withString:@""];
            
            //clean up mstring since it's no longer needed
            [mstring release];
            
            NSNumber* number = [basicFormatter numberFromString: clean_string];
      
      //now format the number back to the proper currency string
      //and get the grouping separators added in and put it in the UITextField
      [textField setText:[currencyFormatter stringFromNumber:number]];
     }
     
     //always return no since we are manually changing the text field
     return NO;
    }
    

    First thing to notice is the cleanup of the code between lines 19 and 21. There is no more special case, and thus reduced complexity. Line 32 is what allowed the removal of the special case. Instead of trying to work with symbols and groupings they are now ignored completely and removed before being added back in. The variable clean_string will end up a string with only numbers and will be easily parsed into an NSNumber by a basic NSNumberFormatter.

    There are a few class instance variables that need to be set. The init and associated dealloc is below even though they are not necessarily related to the optimizations above.

    //MARK: -
    //MARK: Object Management
    -(id)init{
        if ((self = [super init])){
      NSLocale* locale = [NSLocale currentLocale];
      localCurrencySymbol = [locale objectForKey:NSLocaleCurrencySymbol];
      localGroupingSeparator = [locale objectForKey:NSLocaleGroupingSeparator];
      
      currencyFormatter = [[Formatters currencyFormatterWithNoFraction] retain];
                    basicFormatter = [[Formatters basicFormatter] retain];
      
      //set up the reject character set
      NSMutableCharacterSet *numberSet = [[NSCharacterSet decimalDigitCharacterSet] mutableCopy];
      [numberSet formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
      nonNumberSet = [[numberSet invertedSet] retain];
      [numberSet release];
        }
        return self;
    }
    
    -(void)dealloc {
        [nonNumberSet release];
        [currencyFormatter release];
        [localCurrencySymbol release];
        [localGroupingSeparator release];
        [basicFormatter release];
     
        [super dealloc];
    }
    

    Formatters is a custom class that contains various class methods to return ready to use formatters. In the next article I will show how it is setup. In the meantime two new NSNumberFormatters could have just been declared inline. See the Apple reference documentation for NSNumberFormatter.
    The above improvement cut out some code that was not needed, but most of all made the logic easier to follow.  Instead of having to worry about special cases with currency symbols when inserting new characters, they can now just be ignored.  The formatters do all of the heavy lifting as they should.

  • The Lazy Programmer: Language Selection

    When I was in graduate school one of my fellow students was a C++ fanatic.  To him, every software problem was best solved by C++.  To his credit he probably could solve any problem using C++, but was that really the best use of his time?  By assuming C++ as the best language choice for every problem was he being lazy or simply over working himself?

    The common adage to describe the scenario above is “when all you have is a hammer, every problem looks like a nail.”  Of course you need a hammer because there are a lot of nails in the world, but there are also a lot of other types of problems.  C++ is well suited to a large (and shrinking, depending on who you talk to) problem domain, but is it really best language to use to develop a web site?  How about loading data into a database, parsing text files, or creating CRUD GUI interfaces?

    Each of the problems I listed above have programming languages that fit the problem domain better than any other language.  It may take some time up front to learn a new language, but that time spent is well worth the effort of a simpler to develop to solution.

    The lazy programmer, instead of letting tools drive solutions, lets the solutions drive the tools.

  • Hello World Version 2.0

    What a crazy year.  So the blog kind of fell off as work got really busy along with life.  Now that I have gotten life back to a normal pace I plan to resume writing both the blog and some new iPhone apps.  I have a few ideas kicking around and will be working on them as I have time.

    iAutoCalc is on my list of TODOs that needs to get updated to the iOS 5.  I have ran it under each version of iOS and it appears to be working fine, but the code will not compile on anything past iOS 3 right now.  Thus, some of my older posts on objective-c unable to compile in some instances.  I’m hoping to get it cleaned up soon.

  • What Language To Learn First?

    When looking at various programming forums I see this question over and over. Many responders usually jump in suggesting languages from C to Java to Ruby to Lisp. Well, maybe not Lisp but you get the point. The problem with so quickly answering the above question is that I think the answer is:

    • dependent on the individual
    • learning a SINGLE language should not be the goal

    Personally, I learn by seeing the details. I don’t have any problem working at an abstract level (or with infamous car analogies), but before I’m completely comfortable at any given level I need to see the details of what is going on behind the scenes. An example of my personal learning style comes from my first compsci class in college where Turbo Pascal was used to teach object oriented programming. As an aside, the school soon after moved to Java, but at the time teaching object oriented programming so early on in a curriculum was fairly progressive. A key part to any compsci curriculum is the teaching of pointers. Pointers are generally considered a complicated topic, so instead of just explaining what they were in detail the professor instead built these odd analogies. Today I don’t exactly remember the analogies, but I still remember them more confusing that helpful even after fully understanding pointers. I do recall though that they had something to with houses and phone lines. 🙂

    After struggling for days trying to understand the analogies that were being used I asked one of my professors to explain in detail just what is a pointer. My professor proceeded to draw a diagram on the whiteboard similar to the one in this wiki article, to which I immediately asked, “that’s it?!” All of the methods that my professors to shield me from the details in an effort to help me understand the topic were actually getting in the way of how I learned. I needed to see the details, and at that point my understanding was immediate. Because of my need to see the details in order to understand the whole, I would consider myself a person who learns from the bottom up.

    For a person who learns from the bottom up and wants to take things apart and see the details of how it works before understanding the whole, a language like C is the perfect language to start with. C has a concise, fairly simple syntax and hides very little of what is happening on the hardware underneath.

    Now, contrast this with a person learns from the top down. This person needs to see the entire picture before looking at the details. This person may never look at the details unless they are forced. This person may also be perfectly content to stay at higher levels of abstraction and often doesn’t care what is going on behind the scenes as long as the abstractions work. In essence this person is a top down learner. He wants to understand the entire picture before delving into the details and then only delving as far as absolutely necessary.

    For a top down learner, starting with a language like Ruby is a great choice. Using Ruby, the top down learner can see immediate results and hide a lot of the details of what is going on behind the scenes. The person can learn to create programs early on without being bothered to understand the nuances of what is happening on the computer hardware to make the programs work.

    At this point I want to state that I’m not saying one type of learning is better than the other. In my opinion both types of students need to learn the same languages, but it is important to realize that people have different learning styles that should be accommodated. This brings me to my second point, that the question should not be about what single language to learn first, but what set of languages to learn and in what order.

    I’ve made the case above that some people learn from the bottom up and some from the top down. This does not mean that they should end up learning different languages though, and at some point should be equally proficient in a similar set of languages. A person who learns from the bottom up when it comes to a single language should apply the same strategy to a set of languages. This means that this student should learn C, then a language like Java or C#, and then move onto the higher level languages like Ruby and Python (then onto functional languages, but I consider those beyond the scope of this article). This person ends up applying their single language learning strategy to the larger problem of learning to program in general.

    For the person who learns from a top down approach they would simply flip the order of languages. Start with Ruby, then move to C#, and finally move to C making sure to understand how each level decomposes from the level above or below the current level.

    Whether a student goes from the top down or bottom up, both should pay special attention what each abstraction level brings to the table. Where are the leaks in the abstraction? How are they solved? What problems are best solved by each level of abstraction? What are the shortcomings of each language? Advantages? How are the languages the same and different? By researching and answering questions like these the student will gain a much deeper understanding of all the languages they learn.  Each time the student learns a new language they will see new ideas and concepts in languages they thought they already knew.

    I hope the next time someone asks what programming language to learn first I can point them to this article because the answer isn’t as simple as C/C++/Ruby/Java/Perl/Python/….

  • Objective-C Protocols and Delegates

    My earlier article about building a currency formatter for a UITextField generated a few comments and some confusion about how to use delegates in iPhone programming. In this article/tutorial I hope to clear up any confusion and tie it back to using the the currency formatter with the UITextField.

    What Is A Protocol?

    The Apple documentation on a protocol can be found here. The documentation summarizes that:

    Protocols declare methods that can be implemented by any class. Protocols are useful in at least three situations:

    • To declare methods that others are expected to implement
    • To declare the interface to an object while concealing its class
    • To capture similarities among classes that are not hierarchically related

    The situation that we are interested in is the first one that allows methods to be declared that others are expected to implement. In this situation protocols are very similar to Java and C# interfaces. In our particular case Apples UIKit framework provides a protocol for use with the UITextField. This protocol is conveniently named UITextFieldDelegate. Defined in this protocol are 7 optional methods that a program can implement to change the behavior of a UITextField. Keep in mind that Apple has only provided the skeleton of the method and not any actual implementation. The implementation is left up to the programmer to implement for their specific needs. In our case we only need to implement 2 of the methods.

    So now we have all we need to create a stubbed out version of our UITextFieldDelegate protocol implementation:

    The @interface line is where we tell the compiler that we are implementing the UITextFieldDelegate with this class. Keep in mind that it doesn’t have to be a separate class like here, and could instead be the controller or any other class where you think the delegate methods should be implemented. I like doing a separate class since it makes the delegate easy to reuse and keeps the code modularized.

    Since we have not yet provided any implementation, if we took this above code as is and made it the delegate of a UITextField the text field would work the same way it does without a delegate attached. Since this post is not about the implementation of the currency format delegate I’m going to point readers to my previous post on implementation and move on to how to use the delegate.

    What Is A Delegate?

    Once again the Apple documentation is quite good at explaining delegation. In delegation programming one object (in our case the UITextField) relies on another object (the CurrencyFormatDelegate) to provide a certain set of functionality. As the Apple documentation explains, using delegation programming allows the programmer to customize the behavior of framework objects without having to subclass. In turn this allows the programmer to aggregate multiple delegates into one object and extend the functionality of the existing framework. Now, what does all this mean for the currency formatter? In order to get our delegate to execute at the proper time we have to attach it to our UITextField. Assume that we have already defined and linked a UITextField in Interface Builder and we called it currencyTextField. In the controllers viewDidLoad we just need to assign the CurrencyFormatDelegate our UITextFields delegate property.

    You’ll notice a bit of object management code to make sure that we properly allocate and release the delegate when we are done with it. The key line in all of the controller code is:

    It is here where we tell the text field to user our delegate and call our implementation of the protocol methods.

    I hope that this clears up some of the issues people were having while trying to use my text field currency formatter. The code above should mostly work as is since I took it from a working program and pared it down for the post. If there are any copy and paste issues they shouldn’t be too hard to correct.

    Further Reading

    The delegate pattern is a fundamental object oriented design pattern. If you want to know more about the delegate pattern and design patters in general check out Design Patterns.

  • Are Social Obligation Games Psychological Malware?

    Years ago I played a game called Dark Age of Camelot (DAoC). It was my first foray into the MMORPG genre of video games. While the game had its fun moments where strategy and some thinking was required, many parts of it were very repetitive. Leveling up was one of these boring repetitive tasks that you had to do in order to progress in the game. Players lovingly called this process grinding. Over time I found myself playing the game more and more even though I dreaded logging in. I had become addicted to the game much like Everquest players had become addicted to it in the past. When I stopped playing I tried to figure out why I had played so long.

    I used to think that I was addicted DAoC through classical conditioning. This works by rewarding the player often early on and slowly spacing out the rewards to require more and more time to complete them. Eventually you can get a player to play for days and days in order to accomplish a single task. My friends and I used to jokingly refer to the process as ‘give me the pellet’ referring to science experiments where rats are rewarded with food pellets for completing some mundane task. Something always bothered my about this analysis though. I have played games throughout my life and never had a problem before with playing too much. Was this classical conditioning response on its own enough to keep my playing?

    The other main game mechanic that makes MMOs different from other games is that you play in a persistent world with other people. To accomplish anything worthwhile in these games you generally need to befriend and group with other people on a near constant basis. As you progress in the game the people you group with become more and more important and you start feeling obligated to log in and help your friends that you have made in game. The game plays to an individuals social responsibility to keep people coming back so as not to let down their friends.

    In DAoC and other traditional MMOs I don’t believe this social aspect is a blatant attempt to keep people playing. There really is an underlying game that can be enjoying to play, and I think the social aspects are there as another avenue to make the game more enjoyable. In the last few years though a new category of game has arisen and it turns out that its primary draw is from the social obligation to play.

    Farmville is currently the most popular game in America with between 70 and 80 million people playing through their Facebook accounts. I hesitate to call it a game since it really isn’t much of a game at all. An excerpt from this article best describes why people play Farmville:

    The secret to Farmville’s popularity is neither gameplay nor aesthetics. Farmville is popular because in entangles users in a web of social obligations. When users log into Facebook, they are reminded that their neighbors have sent them gifts, posted bonuses on their walls, and helped with each others’ farms. In turn, they are obligated to return the courtesies. As the French sociologist Marcel Mauss tells us, gifts are never free: they bind the giver and receiver in a loop of reciprocity. It is rude to refuse a gift, and ruder still to not return the kindness.[11] We play Farmville, then, because we are trying to be good to one another. We play Farmville because we are polite, cultivated people.

    Where traditional MMOs addicted geeks with a combination of gameplay, competition, and social obligation, Farmville has dropped all other aspects of game play and ropes in its users by entangling them in a complex network of social obligations. Much like a con man plays to our human nature to generally trust others, Farmville is using our basic nature to be nice to others and reciprocate kindness in order to keep people playing.

    In my mind a couple questions then arise with respect to Farmville and software design in general. First, is it ethical to design software in such a way that it provides little value to users other than locking them into a web of social obligations? I’m guessing many users do not even realize what has occurred when they are planning their day around planting, harvesting, and making sure their friends also do their planting and harvesting. At what point does a game like Farmville cease being a game and become a type of psychological malware for the users players?

    Second, even if people agree that Farmville’s use of social obligations may not be ethical, could there a social benefit in other types of software applications. Software is not written in a vacuum, and without users it is essentially useless. Could adding more social obligations to useful software be beneficial to users by getting users to use the software. Could the introduction of social obligations somehow get users to better maintain their computers by staying up to date with patches and virus software?

    Ultimately while I think Zygna is a company preying on peoples good nature, it does not automatically mean that keeping users through a social obligation is ethically wrong and it must be looked at on a case by case basis.

  • Nothing Happened To Programming – It’s the Problems

    In this blog post (and follow up post) Mike Taylor asks “What happened to programming.” He writes about creating games as a kid and reflects on his excitement about writing compilers. He enjoyed making things. His complaint is that most programming today is just gluing libraries together to create a solution and as he says “I want to make things, not just glue things together.” I agree with him, but not his reasoning.

    I think that every programmer wants to make things, but they also want to solve interesting problems. It’s not the gluing of libraries together that caused programming to change, it’s the sheer number of boring problems that are the cause of Mikes complaints. Nearly every business today can benefit from some sort of custom programming, but that doesn’t mean that it will be interesting or fun to create.

    For me, I have always looked at programming as tool to solve interesting problems. The issue is that getting a job only solving interesting problems is not always easy to do. There are only so many Google type companies in the world. Most jobs involve writing code to create yet another TPS report variation. I view this as boring repetitive work, but for many programmers it’s what pays the bills. I would argue that all of the libraries available actually make this work at least minimally tolerable for most programmers.

    In the end Mike says:

    I understand, I think, how we landed up here. I wish I know how we can get out.

    The way out is to eliminate the boring problems, most likely through a library.

  • Customizing The UITextField Format For Currency

    ** Update! **

    Make sure to read part two of this article to learn about how this solution was optimized.

    When I was building iAutoCalc for the iPhone I was looking for an easy way to validate and format the data as it was entered into a UITextField.  I found plenty of articles to do the validation, but nothing that showed a way to arbitrarily format the field as data was entered.  After tinkering around I came up with a pretty neat method of providing a locale correct format for currency data.  I haven’t played with it anymore yet for other format styles, but I think it could be easily adopted for any format style.

    The exact problem I wanted to solve was to have the user only be allowed to enter numeric data and have that data formatted as a local specific currency with proper grouping separators.  For example, if the user entered 20000 the UITextField would display $20,000.  I also wanted the formatting to happen real time as the user entered the data.

    First we need to create a currency formatter:

    NSNumberFormatter* currencyFormatter = [[[NSNumberFormatter alloc] init] autorelease];
    [currencyFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
    [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [currencyFormatter setMaximumFractionDigits:0];
    [currencyFormatter setLocale:[NSLocale currentLocale]];
    

    The above creates a basic, local specific currency formatter without any decimal places.

    We also need to create a set to help us reject all non-numbers:

    
    //set up the reject character set
    NSMutableCharacterSet *numberSet = [[NSCharacterSet decimalDigitCharacterSet] mutableCopy];
      [numberSet formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
      nonNumberSet = [[numberSet invertedSet] retain];
      [numberSet release];
    

    I create both the currencyFormatter and nonNumberSet in the init function for use in the text change callback method below.

    Now we need a hook into the UITextField that will tell our controller know when the text has been updated. The UITextFieldDelegate does just that by providing the callback method:

    
    -(BOOL)textField:(UITextField *)textField 
      shouldChangeCharactersInRange:(NSRange)range 
      replacementString:(NSString *)string
    

    Each time a character is typed into the UITextField the above function will execute prior to the character being entered. If the function returns YES the character will be entered into the UITextField. For more information on this method see the Apple Developer Documentation.

    Below is the full listing of the completed function:

    
    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
     BOOL result = NO; //default to reject
     
     if([string length] == 0){ //backspace
      result = YES;
     }
     else{
      if([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0){
       result = YES;
      }
     }
     
     //here we deal with the UITextField on our own
     if(result){
      //grab a mutable copy of what's currently in the UITextField
      NSMutableString* mstring = [[textField text] mutableCopy];
      if([mstring length] == 0){
       //special case...nothing in the field yet, so set a currency symbol first
       [mstring appendString:[[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol]];
       
       //now append the replacement string
       [mstring appendString:string];
      }
      else{
       //adding a char or deleting?
       if([string length] > 0){
        [mstring insertString:string atIndex:range.location];
       }
       else {
        //delete case - the length of replacement string is zero for a delete
        [mstring deleteCharactersInRange:range];
       }
      }
      
      //to get the grouping separators properly placed
      //first convert the string into a number. The function
      //will ignore any grouping symbols already present -- NOT in iOS4!
      //fix added below - remove locale specific currency separators first
      NSString* localeSeparator = [[NSLocale currentLocale] 
                                     objectForKey:NSLocaleGroupingSeparator];
      NSNumber* number = [currencyFormatter numberFromString:[mstring
                            stringByReplacingOccurrencesOfString:localeSeparator 
                                                      withString:@""]];
      [mstring release];
      
      //now format the number back to the proper currency string
      //and get the grouping separators added in and put it in the UITextField
      [textField setText:[currencyFormatter stringFromNumber:number]];
     }
     
     //always return no since we are manually changing the text field
     return NO;
    }
    

    The things to note about the finished function is that I am always returning NO from the function. I do this because I am manually managing what characters end up in the text field.

    Next, notice the odd empty string case where I put in the localized currency symbol. The problem is that the currency formatter will not convert a string to a number without a currency symbol. It doesn’t care about grouping symbols, but the lack of a currency symbol will cause it to return nothing. This case makes sure that the currency symbol is always the first character in the text field.

    Finally is the trick that properly places the localized grouping separators. After making the correct string by inserting or removing characters based on the information the callback passes in, we turn that string into its number representation and then turn around and format it right back into a string. This process removes any grouping symbols (localized of course) and then puts them back in in the correct locations.

  • How To Start AND Finish

    I came across this on 43 Folders. Anytime I’m lacking motivation I always pick some random article from the site. I was procrastinating tonight and came across this talk about starting something AND finishing it.

    Like most people I have lots of ideas that I think are great. I’ve started many of them, but never finished any of them (outside of work of course) – basically I’m suffering from brain crack. Starting is generally easy for me, but finishing is hard. I have come up with all kinds of excuses in the past.
    • I’m too busy
    • The idea sucks
    • Technology is too hard
    • I not smart enough
    • I don’t have time to learn it
    What’s interesting is that I write software at work all day and these excuses never get in way. I start and finish project after project. So, I’ve decided to start and finish two personal projects before starting any others. It doesn’t matter if they suck or if I find the ideas have already been done (more excuses). The point here is to take these two projects to completion before moving on.
    Why two projects? Well sometimes I really do need something else to do. I solve a lot of software problems while I’m in the gym, taking a shower, or simply working on something else. I think that having two projects will help me stay focused instead of running into a problem and getting sucked into the internet vortex.
    Project 1 is an iPhone application. It’s a pretty simple utility app, but I think it is genuinely useful. As I get closer to completing it I’ll give a full description of what it is and how I think it can help people. I have already learned a lot about iPhone development and objective-c in general. I have a few posts planned that should be up soon.
    Project 2 is a small website developed using RoR. I’ve played around with RoR in the past, but never took a project to a releasable state. I’ll explain more about the idea later, because it’s currently taking a backseat to project 1.
    Finally, the main reason I put this out here is because telling people I’m going to do something is a motivating thing. Doing something in secret means I can quit and no one will ever know. When I start telling every person I see that I’m working on something it creates an expectation that the next time I see that person I want to have an update for them.
  • jQuery and Scriptmanager in asp.net Custom Controls

    I dove into jQuery today with the intention of using the datepicker control in an asp.net custom control that I had built. I ended up having to jump through a few hoops to get it to work properly so I thought I would share what I discovered.

    First, lets start with a simple user control like the one below:

    What I wanted to do was make the date text box control work as a jQuery date picker and have the custom user control work properly with UpdatePanels. In order to have a text box work as a jQuery date picker you simply have to call the code below (described in detail here):

    The problem when using user controls is that it’s impossible to know the exact control name of the other controls contained in the user control because asp.net renames those controls at will in order to avoid conflicts. To solve this problem we need to use the c# code below in order to get the mangled name that asp.net creates:

    At that point all that is left to do is call register the datepicker() function with the ScriptManager. Since my control was created to only work with an internal website, I could guarantee that the page containing the control would always have ScriptManger tag initialized. If you are working with a generic control that may or may not be in an update panel check out a useful proxy class here.

    Here is the code that should work to register the jQuery script required to put initialize the date picker control with the txtDate text box.

    I said should work above because this code leads to the error described in this knowledge base article.

    Error KB927917 in IE8: Unable to modify the parent container element before the child element is closed.

    What is happening is that the ScriptManager is registering the startup script in a block right before the closing form tag. The problem stems from the fact that jQuery is trying to modify the body tag when it builds the date picker pop up. The body tag is a parent of form tag and the form tag is not yet closed. Bummer.

    After more searching I came across this jQuery tutorial that introduces the (document).ready() function. This turned out to be the key. By including this function in the registered code the datepicker() waits until the page or update panel finishes loading before creating the date picker popup. The final code listing:

    One final note. Most sites I found said to use the control and the control type as the parameters to the RegisterStartupScript function. Using the control parameters works until you add more complexity to the user control. For example, after adding a databound grid, changes to the underlying data would update the grid and thus the update panel the control resided on, but not re-register the date picker script. The fix for this was to pass the page itself to the register script function.

  • News Overload!

    I’m an information junkie. IT, economics, politics, general ‘news’, etc… I’m drawn to it like a drug. Daily I used to visit various web sites like /., The Wallstreet Journal, and Google News in order to get my fix. Then, in order to become more efficient, I started using Google Reader to manage RSS feeds. I thought I had found new nirvana. I could quickly scan, tag, share, and manage hundreds of news stories easily through a single interface. Everything seemed great but…

    It is just too much information. Google reader makes it easy to add new RSS feeds from any source. Before long I was seeing hundreds of new stories through the day. The primary problem is not the raw amount of stories though, but the content. So much of it is duplicated from each source.

    At this point I have gone full circle. I no longer use Google reader, and now just check a handful of sites daily.

  • 32-Bit To 64-Bit Upgrade

    I’ve been busy upgrading and moving a MSSQL server and all of the associated applications from a 32-bit Windows 2000 server to a 64-bit Windows 2003 server. The process has been a lot of trial and error. Below are some tips to use when moving from 32-bit to 64-bit.

    Try to find a 64-bit equivalent of your application. If you wrote the application, recompile it. If you bought the application try to find an upgrade. If you have to use the 32-bit application keep reading.

    If you have to run 32-bit applications using WOW (Windows On Windows) remember that nearly all of the system configurations and libraries are separate between 32/64-bit. The problem is it is not always obvious how to handle each case. The registry for example uses the same regedit.exe for both editing both the 32-bit and 64-bit keys. The difference is that all of the 32-bit keys can be found in the [HKEY_LOCAL_MACHINESOFTWAREWow6432Node]. There are some exceptions for COM, but if you have a 32-bit application that just isn’t working check its registry keys to make sure they are in the right place.

    External drivers are another issue. From my experience many 32-bit ODBC drivers install just fine under WOW. If you come across one that doesn’t, I couldn’t find much else to do other than find a more recent version. While we’re on ODBC it (unlike regedit grr) has two completely separate apps for managing 32-bit and 64-bit ODBC entries. 32-bit applications will only see the entries in the 32-bit ODBC manager and vice versa for 64-bit. This is another gotcha to check if a legacy application isn’t working and it is database driven.

    Since it is a MSSQL server that is being moved there is one final piece to remember. DTS packages only run in the 32-bit container (even when running MSSQL-64). This means that any external ODBC drivers that they may need also have to be installed in the 32-bit ODBC manager. Another small annoyance is that the DTS package editor no longer works under 64-bit windows. This means that all DTS package editing has to happen on a 32-bit machine. All the more reason to finally upgrade those last remaining DTS packages to SSIS.

    Good luck!

  • Agile and Cowboy Coding

    All too often I meet people who claim they are agile developers. After a short discussion I realize they are not using any software development methodologies and are instead cowboy coding. Agile development is not a plan free environment. In fact, being an agile developer requires more developer discipline than even the dreaded waterfall.

    Agile development requires the proper tools. Without tools to help with automated testing, refactoring, source control, etc… agile development would be dead in the water. I believe it also requires programming language support. You could try to be an agile developer writing assembly code, but I don’t think you would get very far. Java really set the ball rolling for languages that supported the agile way of developing. The trend has continued with scripting languages like Python and Ruby (and it’s associated frameworks like Rails).

    The developer must also understand how to properly use all of these tools. Back when K&R released their book on the C programming language you had all you needed to know to write software in a nice consise book. Nowadays you need to know a multitude of languages frameworks, environments, patterns, and so on in order to create useful software.

    Agile development, like other iterative development methodologies, requires proper planning. This is where many developers get tripped up. Agile does not mean jump in and code. Developers must plan short complete blocks (incidentally very similar to short runs of the waterfall) of gathering requirements, designing, developing, testing, and releasing that at some point deliver a complete product with all of the requested features. Determining the features that make the cut each iteration and maintaining the overall project vision can be challenging.

    If you think you are currently an agile developer (and no, just using SCRUM does not make one agile), take a hard look at your process, or lack thereof, and verify that you are not just some cowboy in disguise.

  • 1 TB Loaded in 30 Minutes!

    This is a great new white paper out of Microsoft. In it they explain how to move a lot of data from flat files into MSSQL using SSIS. Some key take aways from the paper and my personal experiences loading data into MSSQL.

    • If at all possible get your source systems to provide flat files to the ETL processes. The popular ways like web services and ODBC are nice, but they tend not to perform as well when you start moving a lot of data.
    • Run SSIS on a separate server from the final destination database server. This is key for balancing the load and being able to easily up later.
    • Test, analyze, change, repeat. While the authors did use the standard off the shelf versions of the MSSQL and SSIS, they did have to tweak them to get the results they were looking for. It is critical to analyze your solution and make adjustments.

    Provide other ETL best practices below.

  • Excel Evils

    I’m a big fan of using the best tool for the job. The old adage that says when you only have a hammer everything looks like a nail explains why so many people use Excel for tasks beyond its capabilities. This article provides some facts for what I’ve been seeing anecdotally for years.

    • “Spreadsheet errors are probably more prevalent than most users realise. A 2005 paper by Jonathan P. Caulkins, Carnegie Mellon University, refers to earlier studies which suggest that the (simple) average proportion of spreadsheets with errors was 46%. A further analysis of this literature by Panko suggested that even those numbers might understate the problem, since not all audits find all errors. Out of 8 studies auditing a total of 421 spreadsheets using better methodologies, only one study had an error rate below 21%. According to Panko, a weighted average of published spreadsheet audits since 1995 suggests that 94% of spreadsheets had errors. Even if these stunning rates overstate the problem in practice, it is hard to avoid the conclusion that errors in spreadsheets are common. “

    The question is, what can replace Excel? I’ve been writing one-off pieces of software to replace Excel for years. The problem is that Excel has become so ingrained in many users workflow that even if I provide all of the options they used in Excel they still want the ability to export the data back to Excel.

    It is time to move past Excel (and thus spreadsheets) and into tools that treat data as data and calculations as calculations and not confusingly mix the two as is often the case with Excel. Enterprise mashups are going in the right direction, but still don’t give users the same flexibility as Excel. So what do you think will eventually replace Excel as the defacto analyst tool in the enterprise?</div>

  • The Lazy Programmer: Introduction

    la⋅zy

    adjective

    1. averse or disinclined to work, activity, or exertion; indolent.
    2. causing idleness or indolence: a hot, lazy afternoon.
    3. slow-moving; sluggish: a lazy stream.
    4. (of a livestock brand) placed on its side instead of upright.

    Nowhere in the definition above does it mention anything about a disinclination to think. In my mind “The Lazy Programmer” is not a derogatory term. In fact the best programmers are lazy. They would rather think before acting in order to prevent more work later.

    Those programmers who are not lazy often code themselves into corners. They are too busy writing code to stop and think about what they are doing. They are the same programmers who get married to one programming language, one tool, or one methodology. They are the same ones who will copy and paste the same piece of code all over a program when a class or library should have been refactored out.

    The Lazy Programmer will be an ongoing section where I will pick one software development topic and explain what it means to be lazy.

  • Hello World

    The typical starter blog post. I went through many names before finding “The Pensive Programmer.” It’s quite annoying the number of abandoned blogs out there that are occupying many good names.

    So what is this blog about?

    First, I plan to write about my ideas on anything and everything that has to do with the creation of software. I hope that my ideas can spur on further discussions. I have only been writing software professionally for a little over 10 years and know enough to know that there is a lot I do not know.

    Second, this blog will be a place where I write about interesting problems that come up at work and how I solved them. Hopefully these answers can be helpful to others and through discussion I can find even better solutions to the problems I come across. I come across various blogs all of the time that provide me with solutions to problems and it is time I give back. Knowledge wants to be shared.

subscribe via RSS