I’m Wasting Time / Truncating Numbers with Regex

I’m Wasting Time

I waste too much time relearning how to do simple things that only come up once or twice per year. Some recent examples:

  • Figuring out how to build an AppleScript to show/hide hidden files. Every time I reinstall OS X I’m starting from scratch, with only a faint recollection that I once knew how to do this.
  • Every time I modify my /etc/hosts file I completely forget how to flush my local DNS. Sure the answer is a quick Google search away, but it’s frustrating that I can’t just remember this.
  • Once every 12 months or so I find myself needing to write a regex to truncate decimal numbers. This is trivial, but every time it comes up I have to spend thirty seconds thinking it through for like the tenth time in my life.

From this day forward, every time I learn (or re-learn) a simple task like this I’m going to document it on my blog. This is partially so that I can query my blog as a proxy for my past knowledge, but by making these little things public perhaps I can help somebody else also trying to relearn that little piece of syntax they once knew but forgot years ago.

Truncating Numbers with Regex

Today I was working with a JSON object containing SVG paths. The paths contain decimals with a ridiculous amount of precision and I needed a way to quickly truncate all of them at once. A portion of that file looked like this:

"frame" : {
"framePath" : "M 338.00358637178726,76.44431778009219C 337.3533534525326,76.44431778009219 328.2739344566734,75.22811129070296 319.67,74.15 C 317.50,73.88 295.21,70.88417372385919 293.094015386729,70.33711592961231 C 219.8144624861983,51.43448609977959 150.69444444444446,59.13249044730145 98.71787208607293,79.69548237636549 C 98.71787208607293,80.34571529562014 98.71787208607293,105.05456622729717 98.71787208607293,105.70479914655182 C 104.19818564217239,138.56241136723992 103.1188808312146,165.83046925594903 130.05909879414747,185.423355047173 C 171.04623388375416,215.2321805668871 230.55555555555557,210.52137933619036 259.1511450329329,197.25759417760776 C 274.12500192608155,190.31211676462385 284.23559266287486,174.83312522486972 297.3344728765868,163.7922732666347 ",
"nosePath" : "M 297.3344728765868,163.7922732666347C 300.61877960915047,157.71737810848663 299.45871165265066,156.9281764260582 303.90308634171424,151.64248295033855 C 312.8221414955163,141.03505334903969 324.94089906256886,132.40677608534708 338.00358637178726,131.06388299748352 ",
"templeProfilePath" : "M 103.39210998206816,86.42137601547572C 104.39210998206816,86.42137601547572 112.39210998206816,86.42137601547572 113.39210998206816,86.42137601547572 C 113.39210998206816,87.42137601547572 113.39210998206816,95.42137601547572 113.39210998206816,96.42137601547572 C 112.39210998206816,96.42137601547572 104.39210998206816,96.42137601547572 103.39210998206816,96.42137601547572 C 103.39210998206816,95.42137601547572 103.39210998206816,87.42137601547572 103.39210998206816,86.42137601547572 ",
"lensPath" : "M 304.6828883843359,94.28066353971869C 315.15242080095635,110.11085599156657 281.8913723752886,154.36727094138655 249.95695467226062,174.5634496818991 C 229.19157202630007,187.6960323215128 179.15619563044785,190.04204825863354 143.7124545468221,168.68589073225627 C 115.0311971938544,151.40437835918695 116.3066956065222,98.9434122137887 120.8796942175233,89.74067422456241 C 125.76091487574503,79.91766778910245 168.00571744139953,73.51652014971526 205.07771935487446,74.05426220951449 C 229.19157202630007,74.40404188517087 295.166110391501,79.8910593861534 304.6828883843359,94.28066353971869 "
}

So, I fired open my favorite text editor and built a regex to search for three groups in a row:

  • (\d+\.): A group of one or more digits ending with a period, followed by…
  • (\d{2}): a group of exactly two digits, followed by…
  • (\d*): a group of 0 or more digits

Altogether, the full regex search is:
(\d+\.)(\d{2})(\d*)

I wanted to keep the results of the first two groups, and ignore the last group, so my regex
replacement looked like this: $1$2

I know. It’s hardly rocket science. But now that it’s documented I’ll save myself 30 seconds every six months.

After running the regex find/replace my JSON shrunk to just this:

"frame" : {
"framePath" : "M 338.00,76.44C 337.35,76.44 328.27,75.22 319.67,74.15 C 317.50,73.88 295.21,70.88 293.09,70.33 C 219.81,51.43 150.69,59.13 98.71,79.69 C 98.71,80.34 98.71,105.05 98.71,105.70 C 104.19,138.56 103.11,165.83 130.05,185.42 C 171.04,215.23 230.55,210.52 259.15,197.25 C 274.12,190.31 284.23,174.83 297.33,163.79 ",
"nosePath" : "M 297.33,163.79C 300.61,157.71 299.45,156.92 303.90,151.64 C 312.82,141.03 324.94,132.40 338.00,131.06 ",
"templeProfilePath" : "M 103.39,86.42C 104.39,86.42 112.39,86.42 113.39,86.42 C 113.39,87.42 113.39,95.42 113.39,96.42 C 112.39,96.42 104.39,96.42 103.39,96.42 C 103.39,95.42 103.39,87.42 103.39,86.42 ",
"lensPath" : "M 304.68,94.28C 315.15,110.11 281.89,154.36 249.95,174.56 C 229.19,187.69 179.15,190.04 143.71,168.68 C 115.03,151.40 116.30,98.94 120.87,89.74 C 125.76,79.91 168.00,73.51 205.07,74.05 C 229.19,74.40 295.16,79.89 304.68,94.28 "
}

TextMate - Before Regex

TextMate - After Regex

Git-R-Done!

Note: This article originally appeared in the June, 2010 edition of TEQ Magazine.

From: Michael Righi
To: Joe Gallo
Subject: Git

Dear friend and business partner,

I’m writing to thank you for convincing me to replace Subversion with Git as our source control management (SCM) tool. At first I resisted the change, but after making it past the learning curve I realized that Git is the best tool for managing changes to our source code. It makes it much easier for developers to collaborate than any other tool I’ve tried. This thing rocks!

My previous experiences with SCM tools were with Visual Source Safe, CVS, and Subversion, which all rely on a central repository. Git’s distributed approach was initially very alien to me, but things made more sense once I realized that Git is to source control what Napster was to music: a peer-to-peer tool for sharing files. With Git, each developer’s computer has a complete copy of a software project’s history, and teammates can send each other new code by transferring it directly from machine to machine.

The best thing about Git is its blazing fast speed! Subversion would sometimes take ten minutes to merge two branches of code, but Git’s merges only take seconds. Instead of getting a cup of coffee while my code merges, now I barely have time to check my email before it’s done. At first I assumed that only black magic could explain a speed increase of that magnitude, but now I realize that Git is so fast because of how it stores changes to files: instead of copying the entire codebase when a branch is made, Git only stores the incremental changes. And unlike Subversion which compares the differences between files over the network, Git can do the comparison on the local hard drive. Very clever.

Do you remember that time my computer crashed after I opened an attachment from the Nigerian prince who needed help wiring $10M into the country? I couldn’t decide if I should be more upset that I lost all my data, or that I lost out on making a quick million! What unfortunate timing for my hard drive to crash just as I opened his email. Anyway, at least I didn’t lose any of my work in the Java project I was developing, because I was able to restore my code from GitHub.com, the online Git hosting service you recommended.

Another benefit of Git is that it lets me code while flying, because it doesn’t require a live network connection the way Subversion does. Since Git can operate as a standalone tool, I’m now able to branch and merge my code at 30,000 feet! This was a lifesaver on my last flight when a bad-breathed accountant wanted to chat my ear off about tax law. I told him to go bother the Subversion developer in aisle twelve because I had work to do!

I’ve been encouraging my friends and customers to learn more about Git at its official web site, http://git-scm.com/ . When they ask how much it costs I explain that Git is free and open-source, so the only cost is the time it takes to learn it.

Thanks again for the great recommendation!

Take care,
Michael

P.S. I was finally able to track down that Nigerian prince, and would you believe he still needs my help wiring the $10M? Can I borrow $5,000 to cover the transaction fee? Everything is explained in the attached file, EasyMoney.pdf.exe.

Holding a Finger to the Wind

Note: This article originally appeared in the May, 2010 edition of TEQ Magazine.

A fashion trend has been growing over the last few years, and I saw it widely displayed on a recent stay in New York: the decorative man-scarf. On a warm day in Central Park, my girlfriend and I calculated the percentage of men wearing a decorative scarf, and it would only be a slight exaggeration to say that it was 150%.

Personally, if I wanted a stylish way to keep my neck warm I’d rather grow a mullet than wrap a plaid tablecloth around my neck. That said, it’s difficult to tell which clothing trends will stick, and I wonder if the future will make me look like a fashion fool. In twenty years will our skies be filled with flying cars, decorative man-scarves fluttering from the windows? Are man-scarves more like MC Hammer pants in the 1980s, or denim jeans in the 1880s?

Exiting Central Park, we caught a brief glimpse of the trendiest man to ever walk the earth. Except he wasn’t walking the earth, because he was riding a Segway…while wearing a decorative scarf. Never before had I witnessed such a powerful intersection of fashion and technology trends.

This chance encounter got me thinking about two things: First, technology is much like fashion in the sense that it’s hard to predict what the future holds. Second, how awesome would it be to use a Segway as a segue in my next TEQ article?

I love working with new technology, and I’m fortunate that my job as a software developer allows me to do this often. However, working with the latest tools comes at the expense of sometimes learning a technology that quickly becomes abandoned and obsolete. (WML, VRML, and J# come to mind.) Employing the newest technologies also prevents me from being able to apply all of the experience gained from my last project to the next one, because by the time one project wraps up there are new tools to learn.

My team and I recently started developing condominium management software. Our previous project lasted fourteen months, and many tools were released in the interim for us to consider adding to our tool chest. It was a challenge deciding which new technologies to adopt, which old ones to upgrade, and which to abandon altogether. We took into consideration our knowledge invested in the old tools, the benefits of alternatives, and how likely it would be for the technologies to still be around in a few years.

Nothing was sacred, and we even considered replacing Java (our staple language) with Python. Although we’re sticking with Java, some things we’ll be using are very new to us, such as EC2 (Amazon’s Cloud Computing service), Git for version control (in place of Subversion), and Spring 3.0 as our application framework on top of Java.

Mispredicting the future of technology is costlier than getting it wrong with fashion. A silly looking scarf might set you back $40, but investing in a dead-end technology can cost you years that you’ll never get back. Worse still, it can leave your company entrenched in obsolete solutions that are hard to maintain or replace. Performing due diligence can help prevent this situation, but I don’t trust my prognostication skills to rely on them alone. That’s why we architected our software in a decoupled and layered manner that will allow parts to be more easily replaced. (Like swapping a scarf for a necktie while keeping the pants and shirt.)

In future articles I’ll describe the decisions we made for this project, and since we’re still in the early stages I’ll get to share realtime updates along the way. The choices we made are leading us down an unfamiliar road, but hopefully you’ll enjoy reading about the adventure. By the end I’ll probably be pleased with some decisions and come to regret others. Who knows, maybe in a year you’ll even spot me zipping away from Barnes & Noble on a Segway, with a scarf rippling from my neck, and a Python book in tow.