In Support of “Laziness”

Reminiscent of Lazarus Long’s story of “The Tale of the Man Who Was Too Lazy to Fail” from Time Enough To Love, I recently stumbled into this quote:

Code you don’t write is the easiest and fastest to debut, test, document, read and support.

This quote to me outlines several principles. 

First – while I strongly believe in learning by trying the hard, slow, painful way, by going through the basics, this doesn’t apply to when the priority is to actually produce. Also, the whole point of of doing it hard, slow, and from the basics is to gain an intuitive grasp of how to do it more efficiently, to improve the quality of your work, so that you get better at it, not to be a masochist.

This applies to code as to anything else. Brevity matters. As the quote attests, any line of code you don’t have to write is not only less time spent typing, but the time figuring out how to do it in fewer steps often pays itself back in better performance, and easier maintenance. Lastly, the next time a similar solution is needed, you don’t have to think about it anymore, and you still get the rest of the benefits.

Branding

One thing I have not seen much of in discussions of the ongoing tablet/phone wars if the issue of branding.

In some ways, even with their open platform, Android is like Microsoft. I do not say this lightly, but from the standpoint of the consumer experience in shopping for phones. Most of the clients I run into, when looking for phone are either looking for an iPhone, or they’re looking for an ‘Android’ – and want to know which make and model is the best.

Sure, some want, specifically, a “droid” or “htc” – but for the most part, even those who are aware of them due to the many commercials care less about a specific phone maker than whether or not the phone runs Android, and what features are available on any specific handset.

This is at first blush analogous to the situation with PC’s in the late 90’s where, outside of the Mac camp, everything ran windows, and manufacturers had to really struggle to differentiate themselves from a cheap white-box computer bought at the local computer shop. The manufacturers can’t compete much on features, some models do try to compete on build, but mostly the handset makers try to compete by what “useful” changes they can make to the UI.

The carriers, of course, are still trying to dictate what people can and cannot do on their networks.

I’m not sure if they are succeeding. Because of several key differences in the phone market, the gradual erosion of the handset makers, but more importantly, the phone carriers ability to dictate what features will be available, is a good thing for consumers. And we are already seeing signs that, between the iPhone and the Android, the wireless carriers are losing their ability to dictate terms to the handset makers.

Interesting times, as the phone companies struggle to stay relevant as more than just a commodity connection to the world, and the handset makers struggle to stay relevant in a world where Blackberry is waning, and most of the mindshare belongs to Apple and Google.

OSX 10.7 “Lion” – Not Quite Linux on the Desktop. Yet…..

Courtesy of the guys at Minimal Mac, I took a look at the new information available on OSX 10.7, aka “Lion.”

There are three features that interest me here that I’ll discuss, outside of the “mission control” revamp to finding your open windows. All three features, at first glance, appear to be opaque to non-geeks, yet, like Time Machine, I see them at least two of them becoming nearly indispensable, with the third a huge boost to smaller businesses. 

The first is “Auto Save.” If I understand the verbiage here, Lion will get automated saving of open documents without you ever having to remember to do it yourself. Say goodbye to working on something for 30 minutes or an hour, and losing it all in a software crash, because the computer will take care of it for everything you have open, not just the few programs that explicitly go to the trouble of auto-saving. It’s unclear if this is a feature that software will have to deliberately allow use of, or if any and all programs inherit this ability.

The second is “Versions.” Sortof like Time machine for individual documents, the OS will now keep all previous iterations of a document that you can flip back to.

The last is the fact that there will no longer be a separate “Server” version of the OS. It’s unclear at this time if the license will be unlimited, but from now on, the server administration panels will just be a more advanced set of options for every Mac running OSX 10.7.

The overall impact of this is as follows. Apple is making sure that at a system level, just like Time Machine made backups transparent for the standard home user, that the computer will also act to protect the integrity of your work no matter where you are doing it. 

They are also expanding on the concept they started with the Mac Mini “servers” pre-loaded with OSX server. Even before that plenty of companies (like Delicious Monster, the makers of the Delicious Library book/media inventory app) had already settled on using several cheap Mac Minis as servers because you could lose one or two and still end up ahead compared to the cost of a full XServe. Now, any mac can be set up with as many, or few, server features that you need without paying a premium for a separate OS.

In some ways, this reminds me of the ongoing quetion on when Linux will be popular on the mainstream desktop. One highlight of the free-to-install Linux OS’s has always been the ability to install any feature from basic user programs to the most complex web and network software without having to obtain a separate version for the more advanced features. You just install and setup the features you want. 

Now, that’s going to be true of the Mac. From iPhoto to office user administration, and everything in between.

I do wish they had some form of rack-mount hardware in place, but that’s not a necessity for the typical home or small office user.

Interesting times.

Learning by Doing, part Three

I’ve discussed before my friend Mike, and his quest to learn new things by mastering them, by taking the time to do them the painful, hard, and slow way so that he could get a nearly intuitive feel of what was involved. 

Again, the goal here wasn’t to knock out as many tomahawks./bows/etc. of a good quality in as short a time as possible – in which case he would have had no problems with modern power tools like dremels, etc., but to learn the skills required at a deeper level.

That depth takes time.

We’ve seen the books. “Learn php in Seven Days!” 

Let’s try the reality: Teach Yourself Programming in Ten Years

In the article, Peter Norvig, researcher at Google, utterly skewers the attitude that you can “learn to program in ‘x’ in seven days.”

Again, it takes time. It takes practice. It takes repetition and challenging yourself to build new constructs and try new things so you don’t just understand the basic theory, but you have a near-intuitive grasp of how they fit together. You have a model in your head of what actually works, and what doesn’t.

The key is persistence. 

 

Industry Trends and In-House Servers

Looking back over the last several years, several things have changed. One definite trend that has shown up over the last couple years has been that of smaller offices and businesses getting away from in-house servers.

I guess you can blame it on the “cloud.” Or at the very least, the fact that for many of the reasons people felt they needed a server, they are still better served by a “cloud” based service, or leasing one offsite.

What are the use cases? What are the pros and cons?

Most of my clients use servers for the following reasons:

  • Email (often exchange)
  • File sharing
  • Shared printers.
  • Custom, served applications (remote desktop or server-client programs like accounting or CRM applications)
  • User and security management

Now, to be utterly honest, when you look at the cost differential over the years, even factoring in typically higher oversight and support costs for in-house servers, you will probably spend more for hosted or cloud based services after three years than you will on an in-house box, but that doesn’t mean it’s a bad value. For one, many of the cloud-based services use standard formats that make it easy to get your data back out and migrate it elsewhere if needed, so lock-in is minimal. For two, though you may pay a few percent more, you usually have the option to quit at any time if flexibility is paramount. Last, unlike a typical small office somewhere relying on their DSL or cable provider, you can often get far more responsive and reliable connectivity to your services while out of the office than you do with an in-house server, without the added headaches of configuring firewalls or VPN’s.

Additionally, with in house servers, your data is absolutely yours, and always (unless stolen, you do keep a copy offsite somewhere, right?) available to you.

So let’s look at some substitutes for in-house servers.

Email:

If people are storing email in house, it’s almost certainly on an Exchange server. There’s a lot of good things I can say about the capabilities of Exchange, but given that 80% of what smaller companies use exchange for (email, shared calendars, delegation of email roles) can be handled by the free version of Google Apps, there’s not much reason to stick with Exchange just to have @whateveryourdomain.com in your email.

If you really, really need exchange, there are also hosted exchange providers like Intermedia who, among other things, provide full Blackberry integration and wireless sync.

All of these are free, or at a reasonable cost compared to licensing and maintaining an exchange store, and they’re accessible from anywhere, on any device.

File Sharing

If you don’t have absolutely huge amounts of data, It’s possible to lease some space online using shared Dropbox or Jungledisk “workgroup” accounts, and then share your files with your office no matter where you are. Both allow you to access your files from the web in an emergency, and Dropbox even has mobile apps for the Android and iPhone. 

When it comes to backing up your data, Dropbox stores the last 30 days of changes to your files, while Jungledisk allows you to not only back up your shared files, but as many computers as you’re willing to cover by simply setting aside the space needed to cover your backup needs.

Speaking of backups, you also have Mozy, which allows you to create both local and remote backups of any computer or even server in your office, thus reducing the need for a server just for backups.

Shared Printers

Networkable printers are relatively cheap, and most network capable printers can easily be detected and setup using some variant of zeroconfig (Bonjour for macs, and downloadable for Windows). Most smaller offices don’t change printer setups that often, don’t need to manage user access or permissions for said printers, and don’t change the network often enough to justify buying a server to set up printer sharing. They also don’t have enough of them to need a central directory to find them all.

Custom Applications

In a lot of cases, server-client configurations are so network intensive that putting them on their own server is often a necessity anyway, and with VPN performance being totally unworkable, the best solution is often to bite the bullet and just run the program under terminal services for everyone. Again, this almost always requires a separate machine. 

At that point, checking out a hosted application provider like Trapp Online for a small handful of users suddenly gets much more attractive. Where reliability and availability are absolutely paramount (accountants across a number of states, etc., and needing to maintain operations even with local disasters and hurricanes), the availability and high grade internet connections of the better hosted providers justifies the higher long-term price tag for even larger numbers of users.

User Management

This is where hosted service still fail. While most of them are very good about letting you control security and user access, spreading out your services across a number of providers complicates administration, application, and tracking of passwords.

But then, if you’ve got 50 or more users, you probably still have very good reasons to need your own in-house server, including the employee base to justify it and a better ability to handle the IT overhead. You also will likely need the fine-grained control that buying your own servers gives you – even if only making it far, far easier to maintain security and antivirus software.

 Summing it All Up

For many smaller businesses, the advances of modern internet-based services, and the need for mobility and access to information even when not at the office make hosted or cloud solutions a great value when you consider the lower startup costs, and the gains in flexibility and power. It’s far from a universal fit, but keep it in mind.

My Experiment with Chrome

Chrome, is the rather nifty browser from Google that is also being used as the foundation of the “ChromeOS” based netbooks that will be coming out. 

In the past, I had used Chrome as an alternative to Safari when I needed to cross-check web rendering for building web sites, and more frequently, when logging into google-based accounts other than my main one, since Chrome does a better job of handling multiple windows for multiple google-based accounts. Otherwise, it was all safari, all the time.

Because of this behavior, and it’s faster rendering, I decided to give Chrome a shot as my primary browser. A serious shot.

So I moved all of my bookmarks over, and had at it. At first, all was well. In addition to the above mentioned advantages, I really liked how Command-clicking on nested links in my toolbar didn’t replace my window instead of adding new tabs. I also really liked not having to tab over to a separate search bar. 

I was enjoying it so much that I even went to the trouble of rearranging and slimming down my bookmarks.

You can almost hear the “but” coming.

First of all, there’s no way I can find or figure out to manually add a link to the default new-page “tab” view. It’s clumsy enough in Safari, requiring two windows, but it’s doable.

Secondly, the bookmark manager, while nice enough, just isn’t up to par with that in Safari, especially when you keep a running folder of “to look at” links that you regularly flush out. This is a matter of personal taste.

Thirdly – using Logmein (for several clients) effectively requires me to open up Firefox or Safari anyway.

Fourth – some pages like the app store management pages simply didn’t load quite right in Chrome.

Fifth – printouts did not get the web address posted into the header or the footer of the page like they do with Safari.

Sixth, while the plugin for 1Password generally worked flawlessly in Chrome, there were several sites that worked without hiccups in Safari that required me to disable features like auto-logon.

I could live without these features, but it was already a near-run thing, as the downsides began really encroaching on the reasons I really, really wanted to switch over in the first place.

So of course, Google decides that in the near future, for reasons of “openness”, Chrome will no longer support the video codec named H.264. They’re keeping Flash.

Yes, many in the geek crowd are aware that H.264, since it is not open-source, is subject to licensing terms and eventually, a possible royalty. But, as a result of the popularity of the iPhone and the iPad, almost anyone on the web serving video streams has their video encoded for H.264, while also wrapping it up in a flash player for computers with Flash installed.

Almost nobody, especially mobile devices like Android and the iPhone, support WebM or Ogg  that Google claims it wants to use (yet other video codecs that are theoreticallymore “open”).

So, in favor of “open-ness”, Google’s scrapping support for a video format that may have some encumbrances in favor of one who’s legal liability – while reasonably clean – is utterly unknown, and keeping support for a video and interactive programming system (Flash) that is utterly, totally proprietary and closed. This aside from how much of a utter resource hog Flash has historically been (in all fairness, it is getting better).

The practical upshot is, everyone hosting video likely will not be doubling their storage space just to support two video codecs when they can just keep their single codec and use flash for browsers like Chrome that do not support H.264.

And in the meantime, the very “open” standards that Chrome strove so hard to support (along with Safari and Firefox) will be undermined.

All by itself, despite how much of a bully Adobe has been with it’s single-handed control of the Flash format, I would not have cared enough to change. I don’t care about the politics of the company, I care about the best tool for the job, and in the computer biz, that changes monthly. Chrome is a great browser. There are plenty of people without my use case for whom it will continue to be a great, and preferred browser.

But as for me, I’m writing this out of Safari.

Busy

Worked up a multi-level core data schema last night for storing and handling data, and wrote a loader to allow importing files into the data store, allowing me to provide default data without hard-coding it into the app itself.

Core Data is an interesting technology. It has some weaknesses compared to SQL databases – there are no “uniqueness” tests built in, and everything is in memory for large data sets which is a bigger issue on memory-limited devices like the iPhone – but it also provides an excellent wrapper for managing data without having to write a lot of code yourself.

There are actually a number of decent tutorials, including Apple’s own documentation, but it’s not a “beginner” topic, and I’ve found that the only way I could get my own head wrapped around it was to actually work with it, so there won’t be tutorials coming soon.

Drobo – Stuff That Works

While not quite under “stuff I have at home” – but definitely under stuff I have my clients use – the “drobo” series of drive cases from Data Robotics, Inc. is a fantastic series of drive cases that do far more than allow you to hook up external storage or set up RAID arrays.

Most external drives are limited to the maximum size of one disk, and when your computer drives are near that maximum, backing them up with any sort of history you can dial back becomes a problem. Well, RAID is a solution to this kind of issue, but RAID is finicky to setup, and even more finicky to change or expand.

Hook up a Drobo, and slot in two drives. Now, if one of those drives fails, the other one keeps chugging with all of your data intact. All you have to do is yank the failed drive and slot in a new one, and it automagically rebuilds itself.

Need more space? Add a drive.

That’s it. No fuss, no muss, no reformatting or commands. Just. Add. A. Drive. The Drobo does all the work.

Need more space? Add another drive. Used up all your drive bays? Yank out your smallest drive and replace it with a bigger one. No need to shut it down, etc.

At every stage, the Drobo takes care of everything else.

We even had a client who’s Drobo had gone bad (the top bay failed) pull all the drives out under power, slot them into a new drive bay, and power it up. The drive rebuilt itself and is working just great.

Needless to say, I can’t recommend it highly enough. It’s expandable drive space for backups or storage, for people who don’t want to think about technical details.

Update: Over time this has become a recommendation I’ve reversed. At first, many of these worked, but over time flakiness with dealing with drives (even if you carefully shopped off the compatibility list) and network connectivity and access speeds drove us to finding other solutions.

Python Variables

As much as I love Python, there are two things about it I’ve seen drive programmers experienced in other languages absolutely nuts. The first is the syntax. Instead of using curly braces to delimit blocks of code, Python uses indentation. The second is how variables are handled.

But wait! Aren’t variables like boxes with names, that we can put data into using the names?

Well, yes, and barring pointer operations in C and its derivative languages, that mental model often works perfectly well. For most languages.

So what makes Python different? First, the fact that everything is an object. Even basic datatypes like integers.

Second, variables in Python, like PHP, are dynamic. The type of data is not predetermined when you first create the variable name, or “identifier”. Because of this, you will never see a variable declaration specifying a type as in Java or C like this:

int car = 3;

As a result, the following commands are perfectly valid:

car = 3

car = “Ferrari”

Third, and most importantly, the variable identifier is just a reference to the data. Any data. Even integers. For example, if I create the variables “car” and “pet”, and set them both to 3, they both point to an integer object with the value of 3. If I set the variable “joe” equal to “car”, it doesn’t make a copy of “joe” – it just points “joe” to the same object as “car”:

8753197-9976584-thumbnail

For immutable data types like numbers and strings, the behavior is effectively the same as you’re used to in any other language, because if you change the value that a variable points to, it just gets redirected to the new value. For example:

8753197-9976599-thumbnail

 

Where things get interesting though, is when dealing with mutable data, like lists.

Try this out:

L1 = [2,3,4]

L2 = L1

L1[0] = 24

In the first two lines, you create a list, and set the second variable, L2, equal to the first. Since we are just passing pointers, then L2 actually ends up pointing to the very same list as L1.

8753197-9976608-thumbnail

So when, in the third line, we set the first item in the list L1 to 24.

8753197-9976617-thumbnail

Since both L1 and L2 point to the same list, the first value in BOTH lists is now 24.

Why was it chosen to make Python behave like this? I haven’t found the specific answer in either the python.org sites, or at Guido Rossum’s blog detailing the history and philosophy behind it, but It’s almost certainly a part of trying to make everything an object, while allowing dynamic variable types, and reducing the memory overhead as much as possible while also keeping you from having to deal with memory management.

One of the most useful consequences of these design choices is the ridiculous amount of flexibility in how you pass around and manipulate data. Since everything is an “object” – you are not restricted to “integers” and ‘floats.” Specifically, I’m talking about “duck typing” – named for the expression “If it walks like a duck, and talks like a duck.”. In the case of Python, (or id-type objects in Objective-C), what this means is that not only can you assign any type of data to a variable as we already discussed, but you can try to run any method on it you wish as long as the object supports the method.

This is fundamental. Unlike, for example, Java – where polymorphism is limited to methods of a class or superclass from which the class inherits – Python doesn’t care what type the class is – it just cares if the method exists. It doesn’t matter whether it’s a duck, a rectangle, or a car, it just matters if it responds to the method “quack()”.

So how do we deal with this?

Well, if you’re just passing the variable into a function to be read, it doesn’t matter. If, on the other hand, you want to actually make a copy, or create a new, modified data set without changing the original, you need to make a copy.

Even with copies we run into issues. Lists are objects just like anything else. What happens if the list you are copying contains lists? A simple copy of the top-level list makes a separate set of references for anything in the list, so now both lists seem to be entirely separate. Yet, if the list we are copying has sublists, our copy still contains shared pointers to those sublists, with all of the problems we saw above.

So first, unless you, the programmer explicitly ask it to, Python only passes references. This is never going to cause trouble when dealing with immutable data types.

Secondly, if you want to make a separate copy of a list or mutable datatype, you have to explicitly copy it by using the “copy” method, or a slice  like this:

aList = [0,1,2,3]

bList = a[:] # shallow copy of a using a slice

or

import copy #import the copy module

aList = [0,1,2,3]

bList = copy.copy(aList) # shallow copy using copy module

Third – if you have sublists or other mutable data types within a mutable data type, you need to make “deep” copies. Deep copies allow you to make separate copies of any sublists, dictionaries, or other mutable data that would cause issues in a shallow copy. They require you to either code your own method, or again, you can import the copy module, and use the deepcopy method.

import copy #import the copy module

aList = [0,1,2,3, [“a”, “b”, “c”]  ] # list with sublist

bList = copy.deepcopy(aList) # deep copy using copy module

Hopefully this helps someone out there trying to get their heads wrapped around Python variable handling.