The Blog of Maxim Porges

Archive for January, 2010

  • iPad, You Pad, We All Pad For iPad

    The name’s pretty awful. But besides that, I kind of like this new device.

    Kicking about the house, I like to go on the Internet to read RSS feeds, watch YouTube, play a game, etc. while cooking or half-watching a TV show. A laptop is too clumsy and fragile for these tasks (I’m always scared to spill liquids on the keyboard when reading recipes off the web). So, I’ve been doing these things a lot recently on my iPhone. But the iPhone’s a bit small and the battery dies pretty fast under intense use. So the iPad’s a perfect replacement for around-the-house computing.

    When we travel, there’s a few things for which I like to bring a laptop along: music, movies, occasional Internet use (to find a hotel, restaurant, attraction, or map to somewhere), and to offload photos and video from the digital camera/camcorder. But taking a laptop on a trip along with its case and charger is a pain in the ass, and then you have to either have an air card for Internet access, find a wireless hotspot, or pay for in-hotel service. Sure, the iPhone can get the job done for most of these needs – but it’s not ideal. So if you gave me a big iPhone and threw in a nice e-reader, a mobile bookstore, and a reasonable data plan, then I’d say the travel computer problem is solved. And compared to my 7-lb laptop, it’s a lot less to carry if I want to take it with me.

    I spend a fair amount of time presenting stuff at work to execs/peers/users, running to meetings to take notes, and checking email/surfing the web between these activities. Unplugging my laptop from my workstation and running around with it is painful; especially between office suites since I don’t want to shut the lid and put it to sleep, but I can’t sling it under my arm if the lid’s open. So once again, the iPhone has been doing double-duty as a note taker and email browser. But again, it’s a bit small – especially for taking notes and presenting diagrams and Keynote presentations. So there’s another fit for the iPad: a secondary device on my work desktop, acting as a digital picture frame and music player until I’m ready to whip it up of its dock to take around the office for some brief mobile chore.

    There’s a few things I don’t like about the iPad. It doesn’t appear to have the ability to annotate documents (at least not yet). Like the iPhone, it seems to be similarly crippled in to having no arbitrary local storage. A camera on the front would have been nice for video conferencing or sending video postcards. A smart media card slot would make a lot of sense. Charging $130 extra for 3G seems like a bit much.

    But then I have to put things in perspective. Most of the things I’d store on the iPad have apps that do the storage for me. I almost never video-conference on the other three computers that I own, all of which have video cameras. And is it really that pricey in the big scheme of things? The entry-level iPad with 3G service is $629, which is about $30 more than an out-of-contract iPhone 3GS – and you get a lot more computer for $30 than you do with an iPhone.

    So pretty much the only thing it’s lacking is document annotation, which is a software thing. I’d really like to see Apple add this, and if not, there’s an app that does it for me. And if Apple fulfills some rumors out there to store my iTunes library in the cloud for me, then the small amount of flash storage in the entry-level model becomes no problem at all.

    So while I won’t be rushing out to buy an iPad, I can definitely see one somewhere in my future.

    2010.01.27 / no responses / Category: Uncategorized

  • Using AppleScript to Position iChat Windows

    We use instant messaging quite a bit at Highwinds. I bounce back and forth between using my laptop by itself, and using it with a secondary 22″ display. Regardless of how I’m using my laptop, I like my iChat windows to fill the laptop screen with about a 3-pixel gap between each of them. This means that when I’m on my laptop alone, its screen gets filled when I Apple-Tab to iChat, and when I’m on a two-monitor setup, the larger attached monitor display is free of chat windows and they are all present on my laptop screen so I can work while watching for chats.

    My AIM and GMail buddy lists are about the same length, so I like to stack them on top of each other with half of the screen height given to each. My Highwinds buddy list is the longest, so that gets a full column to itself to the right of my AIM/GMail lists. Finally, I have my chat window occupying the rest of the right-hand side of the display. You can see this in the image below (some screen names have been obscured to protect the innocent).

    My iChat Layout

    Unfortunately, Apple hasn’t programmed OS X to remember the position of windows between laptop-only and display-attached configurations, which means I always have to manually move my chat windows back to the second display after I reconnect it to my laptop. This is a pain in the ass. I finally got a few minutes to write an AppleScript to do this for me automatically, presented below.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    
    -- Get display area
    tell application "Finder"
    	set displayAreaDimensions to bounds of window of desktop
    	set widthOfDisplayArea to item 3 of displayAreaDimensions
    	set heightOfDisplayArea to item 4 of displayAreaDimensions
    end tell
     
    tell application "System Events" to tell process "Dock"
    	set dockDimensions to size in list 1
    	set heightOfDock to item 2 of dockDimensions
    end tell
     
    -- Set up desired coordinates when running iChat on the laptop monitor at 1440x900
    set maximumChatWindowHeight to (heightOfDisplayArea - heightOfDock)
    set chatWindowWidth to 275
    set padding to 3
    set heightOfMenuBar to 22
    set laptopPhysicalDisplayWidth to 1440
     
    set aimCoordinates to [0, 0, chatWindowWidth, (maximumChatWindowHeight / 2) - heightOfMenuBar]
    set gmailCoordinates to [0, (item 4 of aimCoordinates) + (heightOfMenuBar + padding), chatWindowWidth, maximumChatWindowHeight]
    set highwindsCoordinates to [chatWindowWidth + padding, 0, (chatWindowWidth * 2) + padding, maximumChatWindowHeight]
    set chatWindowCoordinates to [(chatWindowWidth * 2) + (padding * 2), 0, laptopPhysicalDisplayWidth, maximumChatWindowHeight]
     
    -- Shift everything over by laptop display width if using a second monitor
    if widthOfDisplayArea is greater than laptopPhysicalDisplayWidth then
    	set widthOfSecondaryDisplay to (widthOfDisplayArea - laptopPhysicalDisplayWidth)
    	repeat with currentDimensions in [aimCoordinates, gmailCoordinates, highwindsCoordinates, chatWindowCoordinates]
    		repeat with itemPosition in [1, 3]
    			set item itemPosition of currentDimensions to ((item itemPosition of currentDimensions) + widthOfSecondaryDisplay)
    		end repeat
    	end repeat
    end if
     
    -- Position chat windows
    tell application "iChat"
    	set bounds of window "AIM Buddy List" to aimCoordinates
    	set bounds of window "myGoogleTalkAddress@gmail.com" to gmailCoordinates
    	set bounds of window "myWorkEmailAddress@highwinds.com" to highwindsCoordinates
    	set bounds of windows whose name contains "Chats" to chatWindowCoordinates
    end tell

    The script is pretty simple. It grabs the screen and dock dimensions, and sets up some global variables. Then, for each of my buddy lists (AIM, GMail, and Highwinds) it sets up 4-coordinate position arrays describing the [top left x, top left y, bottom right x, bottom right y] coordinates that I want each window to end up in. Next, it checks the total display area: if the area is greater than the width of my physical laptop display, it bumps all the X coordinates over by the width of the secondary display so that the windows end up on my laptop display (since I position my laptop to the right of my secondary display). Finally, it tells iChat to position the windows, referencing each by their title bar. I group all my chats in to a single window, so the title of this window is something like “18 Chats”; as a result, I use a query-like expression to reference this window’s title.

    Rather than dynamically setting the position of your chat windows, if you would prefer to move your chat windows to the positions that you want them in and have your Mac tell you what the coordinates are, you can use the script below. You can then hard-code these coordinates in to the coordinate arrays in the script above.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    tell application "iChat"
    	activate
    	set allChatWindows to every window
    	repeat with currentWindow in allChatWindows
    		set windowBounds to the bounds of currentWindow
    		set allBounds to ""
    		repeat with bound in windowBounds
    			set allBounds to (allBounds & bound & ",")
    		end repeat
    		display dialog (name of currentWindow & ": " & allBounds)
    	end repeat
    end tell

    2010.01.25 / 2 responses / Category: Uncategorized

  • An Objective-C Tutorial for Enterprise Java Programmers

    As a programmer, the lingua franca for computers and I is mainly Java. And although I have no real work-related purpose for it, I’ve always had a hankering to learn Objective-C and OS X development.

    And so, over the years, I’ve acquired a handful of really nice books on Objective-C and OS X programming that generous relatives have bought for me as gifts from my Amazon wish list, including Aaron Hillegass’s Cocoa Programming for Mac OS X and Beginning Mac OS X Programming from Wiley. But after a handful of evening coding sessions, I’ve never been able to stick with it long enough to learn it, and every time I return to an old project I find that I’ve forgotten most of what I learned and have to start over at the early chapters again.

    Last night, I finally figured out why this is the case when I decided to give OS X development another try. All the books I have dive in and say: “Let’s build a program with a GUI!” And then I’m bouncing around between Xcode and Interface Builder, and I’m doing drag-and-drop UI building, and I’m hooking up selectors to class methods, and it’s totally alien from anything I’ve ever done before.

    The reason this is so alien to me is that I’m an enterprise Java programmer with years of experience writing web and desktop apps through code, with the IDE as a participant rather than the full-blown means. The last time I used a drag-and-drop editor to build a GUI was when I was forced to take a VB6 class in college; even in my programming salad days, I thought that a “program that builds a program” was way too far from the metal. I’ve got a solid foundation in ground-up MVC principles, and I never, ever start building an application GUI-first nor use drag-and-drop GUI builders.

    When building something in Java, what I do is code the core business logic of the app, write unit tests, and then hook the GUI in to it last once I know everything at the core is working perfectly. If I could just apply this pattern to development of an Objective-C project, I knew I would have a chance of actually retaining what I had learned. I know that the way things are done with OS X is to use Interface Builder and hook up the GUI to the classes visually (and that this is one of the things that makes it a rapid development environment), but for me it was just the wrong place to start.

    So, I decided to try building a test-only GUI-less app last night, and I had some success. I’d like to share what I did with other Java developers in case it can help them too. This won’t be a tutorial as much as a post with a bunch of links to other tutorials that helped me accomplish my goal along with notes about using Objective-C and Xcode that were helpful to somebody familiar with Eclipse. If you like, you can download the project that I put together for reference.

    Getting Started

    I’ll assume that if you are reading this, you (a) have a Mac and (b) have installed Xcode. If not, go and do these things now. Go ahead, I’ll wait.

    As I usually advise programmers learning JUnit to build the world’s simplest calculator application, I decided to apply this same principle to what I was doing. So that’s what I’ll be telling you about; riveting, I know…

    Making Xcode Livable

    Having worked in Eclipse so long, I’m used to having code completion on by default, all my editing happening in a single window, strong support for custom code formatting, and many other things that just seem like good plain common sense.

    Xcode in its default state appears to have none of this, and is really frustrating to use when you first dive in if you are familiar with Eclipse. Have no fear, though – these features are mostly there and just need to be turned on. before you do anything with Xcode, I suggest that you open the preference pane and set up the following options. Note that I am using Xcode 3.0 on Leopard so you may see the options under different headings depending on the version you are using.

    General Tab

    • “Layout”: set this to “All-In-One” to prevent tons of new windows from opening whenever you do anything at all.
    • Check “Open counterparts in same editor” to prevent Apple-Option-Up (used to switch between header and implementation files) from causing the files to open in a new window.
    • Check “Automatically open/close attached editor” to cause the in-window editor to be used when you select code files.
    • Check “Automatically clear log” to clear out the log between runs, a la Eclipse.

    Code Sense Tab
    For some reason, code sense is not on by default from what I could see, which just seems plain silly to me. The options for turning it on in this tab are self-explanatory .

    Debugging Tab
    Launching an app in debug mode doesn’t show the debug “perspective” in Xcode by default. I changed the “On Start” option to “Show Console & Debugger” to make this happen, since I am used to switching to debug mode in Eclipse when I launch an app to see what it’s doing. Press Apple-0 in Xcode to switch back to the project “perspective” after running your app.

    SCM
    Setting up a source control repo is totally painless, and Xcode has a built-in SCM browser that’s as nice as anything I’ve used elsewhere. I got it hooked up to my SVN repo running on my old G4 tower in about ten seconds using svn+ssh.

    Unit Testing in Objective-C

    In Java, I always use JUnit and its associated set of libraries (such as JMock). There’s a framework for Objective-C called OCUnit which is basically identical to JUnit in purpose and operation, and an associated mocking framework called OCMock. Apparently OCUnit is such a standard that Apple decided to include it in Xcode 3.x, so unless you are developing in Xcode 2.x or lower you don’t need to download and compile OCUnit yourself.

    To get a basic Xcode project set up with unit testing, I found this tutorial on the ADC site to be the easiest to follow. There are a few gotchas.

    1. If you are using an older version of Xcode 3.x like I am and the ADC site is being retarded and not letting you download a newer non-Snow Leopard version of Xcode, then the panels are not as nicely broken down as the screenshots in the tutorial. It’s very easy to accidentally pick the C++ Unit Test Bundle instead of the Cocoa Unit Test Bundle. If your project compiles fine but you get linking errors during your build, you picked the wrong framework. You’ll also be able to tell this by looking in the Info window for the Unit Tests target (select the target, right click, and select Get Info). Under the Build tab, if the Linking => Other Linker Flags section shows “-framework Carbon -framework SenTestingKit” instead of “-framework Cocoa -framework SenTestingKit”, you selected the wrong thing – you need the Cocoa version for a Cocoa app.
    2. The way that OCUnit works, it links in to your main application as a dependency during building. So, you’ll create a regular GUI app, create a unit testing target with a dependency on this app, and then when you build the unit testing target it fires up a unit test wrapper during the build and exercises your code; the build will simply fail if any tests fail. The nice thing about this is that your test errors appear as build errors in Xcode, which lets you see build error bubbles adjacent to the broken assertions (in other words, no custom OCUnit runner plugin is needed in Xcode like the JUnit plugin is needed in Eclipse). The key takeaway here is that you want to make sure that your Cocoa GUI app fires up in main.m (i.e. the default “return NSApplicationMain(argc, (const char **) argv);” code is present); if not, then the OCUnit hooks can’t work their magic.
    3. Each class implementation file (i.e. .m file) in an Xcode project can be built for one or more targets. You choose the target for your classes as you create them using the “New File…” wizard, but you can verify and/or change your build targets by right-clicking the .m file and selecting “Get Info” and looking in the “targets” tab. Like with JUnit, you don’t want your tests ending up in your main application, so make sure your app code is aimed at the main application target in your project, and your test code is pointed to your unit testing target.

    Besides this, OCUnit is very similar to JUnit with the convention for test method names to begin with “test…”, setUp() and tearDown() methods, and automatic introspection of the unit test class to determine the tests to run. Assertions are implemented as macros (which are kind of like Java’s static imports from what I can see).

    Writing Some Objective-C

    I’m told Objective-C is like SmallTalk, but having never learned SmallTalk I can’t tell you if this is true or not. In any event, it’s a piece of cake to learn for anybody who has a basic understanding of object-oriented development and C/C++. I’ve forgotten a lot of the C/C++ I learned in college, and haven’t refreshed on method overloading or language specifics yet since my primary goal last night was to get a unit testable project up and running, so forgive the basic-ness of the code presented below, but I wanted to share what I wrote so that people familiar with Java and JUnit can get the idea.

    I found a few useful tutorials on the language to get me going, in addition to referring to my books for sample code. Tristan O’Tierney has a nice language overview on his blog.

    Here’s the awful Objective-C code for my calculator app.

    Calculator.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #import <Cocoa/Cocoa.h>
     
    @interface Calculator : NSObject
    {
     
    }
     
    - (int) addTwoNumbers: (int) first secondNumber:(int) second;
    - (float) addTwoDecimals: (float) first plus:(float) second;
     
    @end

    Calculator.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    #import "Calculator.h"
     
    @implementation Calculator
     
    - (int) addTwoNumbers: (int) first secondNumber:(int) second
    {
      return (first + second);
    }
     
    - (float) addTwoDecimals: (float) first plus:(float) second
    {
      return (first + second);
    }
     
    @end

    CalculatorTest.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    #import <SenTestingKit/SenTestingKit.h>
    #import "Calculator.h"
     
    @interface CalculatorTest : SenTestCase
    {
      // it's standard in Objective-C to declare class
      // members in the header file; this will be our fixture
      Calculator *calculator;
    }
     
    - (void) testAddTwoNumbers;
    - (void) testAddTwoDecimals;
     
    @end

    CalculatorTest.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    #import "CalculatorTest.h"
     
    @implementation CalculatorTest
     
    - (void) setUp
    {
      // I'm using Objective-C 2.0 which has built-in garbage collection
      // so I didn't use [[Calculator alloc] init] or use autorelease pools;
      // not sure if this is the right way to do this yet but I saw it in a
      // tutorial
      calculator = [Calculator new];
    }
     
    - (void) tearDown
    {
      // This resets the fixture reference for each test. Again, this
      // was recommended so I'm just towing the line
      calculator = nil;
    }
     
    - (void) testAddTwoNumbers
    {
      // I wanted to see where log output for tests goes; more on this later
      NSLog(@"Something in my test...");
      int result = [calculator addTwoNumbers:3 secondNumber:6];
     
      // This is how SenTest rolls for assertions... ugh. See my update
      // at the end of this blog post for a way to get JUnit-style
      // assertions with Hamcrest if you prefer them
      STAssertEquals(9, result, @"Expected 9, got %d", result);
    }
     
    - (void) testAddTwoDecimals
    {
      float result = [calculator addTwoDecimals:10.1 plus:1.2];
      STAssertEquals(11.3f, result, @"Expected 11.3, got %f", result);
    }
     
    @end

    Getting Output

    Any output from print statements in your main app code will show up in the console in Xcode, but output in the test classes themselves does not. However, everything you NSLog shows up in the OS X Console, so if you really need to print something in your unit test and see it come out as output, open up the Console application. There is a little lag since Console polls its logs. There might be a way to get the output of the unit test inside Xcode but I couldn’t find it.

    Next Steps

    Now that I have all that working, for my next trick I want to do something else that is familiar to me: talk to a web service. Apple has a few tutorials on their web service APIs as well as their tree-based XML parsing. I haven’t gone through these yet, but they look pretty thorough and have tutorials. They also provide a sample Java web service app (linked to in the web service document) which will echo back whatever is sent to it, so you can use this to test out your Cocoa calls to SOAP.

    I hope you find this useful. I’m looking forward to corrections/tips from anybody who really knows what they are doing with this stuff, so please add them in the comments.

    UPDATE 2010.02.06:The “STAssertEquals”-style syntax for assertions in SenTest is really annoying if you are used to JUnit-style assertXXX()-style assertions. I just found a blog post by the guys at CarbonFive where they describe how to set up Hamcrest matches for Obj-C. Check it out! The source for the Obj-C implementation of the Hamcrest project has an Xcode build that works flawlessly.

    2010.01.23 / 12 responses / Category: Uncategorized

  • Performing SQL Validation (a.k.a. “Data Dips”) with RIATest

    We started using RIATest at Highwinds to automate our Flex functional testing. For those of you who are unfamiliar, RIATest is a great Flex-only alternative to products like HP’s QuickTest Pro, allowing you to fully automate your Flex functional testing either from the RIATest IDE itself, or via the command line. While QuickTest Pro can be used to automate a wide variety of GUI-based apps, it costs about five times as much as RIATest, so if you are only testing Flex apps RIATest is a great low-cost alternative.

    Something else that QuickTest Pro lets you do that RIATest does not is perform “data dips” or, to put it in layman’s terms, query a database during functional testing. This can be useful for validating non-visual system state.

    For example, let’s say that you have an application that allows you to change user information, and that the requirements dictate that whenever the user information is changed, a last modified date on the user’s record should be updated. If the last modified date is not visible as a label within the Flex app, RIATest can’t validate that the last modified date has changed, since it can only validate the state of Flex components. In this scenario, you’d typically want to

    (a) execute a functional test to change a user’s info,
    (b) validate the changes to the UI after the user’s information is saved and loaded again for viewing, and
    (c) check the state of the database to validate that the last modified date has indeed been updated.

    However, since RIATest doesn’t offer data dip functionality, step (c) would be impossible without manual intervention from a QA tester. This is where riatest-integrator comes in.

    Thankfully, the RIATest developers put a special object in RIATest called Process. Process allows you to execute an external process, and interact with its input, output, and error streams. Once I discovered this, I decided to write a little Java library that would make it easy for me to fire up a Java process from the command line, hook RIATest to its input and output streams, and write input from RIATest to it. The process would then pass the input to some kind of integration inside of the Java process, and return output from the integration for inspection by RIATest. This turned out to be pretty easy as expected, and I published the library to Google Code under the name riatest-integrator.

    Currently, there is a download available on the Google Code site that lets you query MySQL databases right out of the box. There is a sample RIATest script on the home page of the project showing how you can call it from RIATest and validate output coming back from the database. It’s a really simple implementation, but if people are interested in it, I’ll add more features and functions. The API is also really straightforward, so any Java developer with even the most modest skills should be able to customize it to their needs.

    The API in the library is not limited to SQL; anything that Java can talk to can be hooked in to. We have some proprietary back-end servers at Highwinds that speak NNTP, so we could easily write an NNTP integration that allows us to have RIATest query the state of our NNTP message groups after actions are taken in our Flex apps.

    If you are a RIATest user, please take a look at the project, and share your feedback either here on my blog, or as feature/bug requests in the project’s issue tracker.

    2010.01.19 / 4 responses / Category: Uncategorized

  • Debt To America

    I just finished watching the documentary Maxed Out on NetFlix Streaming this evening. Considering that I spent most of the morning reconciling a year’s worth of monthly statements for my 401k and brokerage accounts, I’ve had money matters on the brain all day, and this blog post is the result.

    Maxed Out
    Maxed Out looks at the credit industry from a number of different angles, interviewing debt collectors, consumers from various walks of life, and a few Harvard professors. They also throw in a smattering of clips from congressional hearings, and sound bites of president G.W. Bush making an ass out of himself and signing in laws that only help big businesses. The whole point of the film is to expose our debt culture, and how the poor stay poorer by being saddled with debt they can never pay off while the government gives legislative hand-outs to big lenders.

    In my opinion, the movie tried a little too hard to present a damning perspective of the creditors and our government officials. Far be it from me to defend the credit vampires or the influential lapdogs in public office, but credit takes two to tango. When things go south with an irresponsible consumer that drank too much from the credit firehose, they are as much to blame as the credit card company who gave them the credit they should never have had.

    Well, that’s not very satisfying; this is America, so somebody must be to blame for all this debt… but who?

    Is it the government’s fault?
    It’s hard to discuss our government without sounding jaded, but please know that I’m not. I’ve come to understand that our capitalist society, like most things in life, is a two-sided coin with a number of cons that I must be willing to accept in order to enjoy the pros.

    Because of the way this country operates, I can live a lifestyle that would be considered fabulous in some parts of the world, but in order to do so I have to accept that our government is largely controlled by the flow of money. Along with this, I have to accept that (regardless of any utopian ideals) the people in our government have a primary purpose to protect the interests of the businesses who will keep their campaigns well-funded; my personal interests and protection are mostly secondary concerns. So long as our government acts favorably to business, businesses can be successful, and I’ll be able to earn a decent wage as an employee and continue to enjoy the life I left England for.

    This is simply the way of the USA. There’s not much any of us can, ever will, or necessarily should do to change that.

    So, is it the credit card company’s fault?
    If government protects the interest of businesses first, we can’t expect the government to protect us as consumers. We also shouldn’t be surprised that lending companies, like all companies, want to make as much money as they can. We should be equally unsurprised at the choice of people creditors want to lend to, i.e. those who are most likely to make minimum payments from the day they make their first credit card purchase until the day they die (leaving the creditors with massive profits).

    Personally, I think it’s somewhat hypocritical for us as a nation to criticize these companies for doing what they do. I may not find it ethical, but I understand the motivation for a business to make as much money as it can from the best possible consumer of their product.

    It’s our fault.
    We’re the ones that sign the credit card agreements. We’re the ones who charge all the crap that we can’t afford. We’re the ones who don’t educate our children about how to save money and live within their means. We have nobody to blame but ourselves. There isn’t a credit card company on the planet that can force any of us in to debt without us playing our part.

    If there is anything to be angry about, it’s our collective apathy.

    I took a life skills class in high school. They taught me about baking and condoms, but they never touched on how to balance a checkbook or what compound interest looks like. Nobody showed me a sample of monthly expenses for running a household, paying a mortgage, or owning a car. My guidance counselors showed me a big binder full of careers and the starting salaries for each, but I had no idea what kind of lifestyle I could lead with a $20,000 starting salary versus a $40,000 one. There was no mention of how to save money, let alone of how I should invest it for the future.

    And so, the only good financial habit I picked up as a teenager was a stoic motivation to pay my credit card off every month – the result of being given a credit card at age 16 by my parents along with a white lie that my account couldn’t carry a balance beyond the grace period. If you’re wondering, I intend to play the same trick on my kids.

    While I left high school with a solid education in all things academic, I lacked the life skills to be effective as a financially responsible human being. I spent six post-graduation months working a single job and constantly owing money. Finally, my step-mom sat me down for about an hour and worked me through my budget. Looking back, that one hour has had more impact on my life than almost anything I learned in all my years of school.

    The result was that I couldn’t afford to support myself on a single job; I either needed to make more money or work two jobs. I ended up doing the latter. I took the foundation that my step-mom gave me and put together a two-year plan to save up enough money to pay off my car loan and go to college. The plan involved the abandonment of every luxury (no matter how small), and left me with about $20 a month in discretionary spending money. It was a hard two years of brown-bag lunches and lackluster Friday nights, but in turn, I learned both the crushing financial constraints that a loan could put on me and the discipline to save money to meet a future goal. Barring interest-free promos and necessities like auto and housing loans, I’ve been debt-free ever since – all because somebody who knew the potential perils cared enough to take responsibility for me.

    Let’s Take Ownership.
    And thus, we arrive at the point of my rant: as a country, we need to take ownership of our finances. We need to make sure that our kids understand the money minefields awaiting them in life. No kid should leave high school without knowing what kind of lifestyle the salary associated with their chosen career will let them lead, or just how important it is for them to pay themselves in savings before they pay their bills. Every school should cover this stuff in home economics; it’s maybe two class’s worth of material along with some basic reading as homework. And since that’s unlikely to happen, I urge you to talk to your kids (or nieces and nephews) and set them straight.

    If you yourself are confused, don’t be embarrassed; seek some help. There’s loads of it in the library and on the web. I recommend The Millionaire Next Door as a starting point, along with a saying whose origin I have long since forgotten: “The secret to happiness is to live beneath your means.”

    In closing
    I think it’s likely that the reason our government is racking up trillions in debt is because many of the people running our country grew up in a debt culture. I also think our collective apathy toward our government’s financial irresponsibility stems from how many of our citizens owe money and can’t imagine a debt-free existence.

    Perhaps if we can raise a generation of fiscally responsible kids, they’ll form the next generation of fiscally responsible adults, and we’ll see an end to irresponsible borrowing in both our government offices and our personal lives. It’s worth a try.

    2010.01.03 / 4 responses / Category: Uncategorized