Category Archives: Code

What do you care, Excel?

While doing some automation work, I unintentionally tried to open two files with the same name but from different directories in Excel. Then, this happened:

excel_two_files

I don’t think this is something I’ve ever done in the past, but I also don’t understand why this would be a problem. If the complete paths were the same, I would understand because Mac OS treats all network volumes as /Volumes/path/to/file.ext. Statistically, small but not to the point of being pragmatically impossible, two files on two external volumes could have the same path. But going by just the name seems…short-sighted…or something. Weird.

U.S. Digital Services Playbook

Today, too many of our digital services projects do not work well, are delivered late, or are over budget. To increase the success rate of these projects, the U.S. Government needs a new approach. We created a playbook of 13 key “plays” drawn from successful best practices from the private sector and government that, if followed together, will help government build effective digital services.
U.S. Digital Services Playbook

Three of the plays—1, 6, and 7—focus on people alone. Solid advice for any project.

“You don’t choose what will work. You simply do the best you can each time.”

From a blog post by Neil Gaiman in 2009:

Yes, it’s unrealistic of you to think George is “letting you down”.

Look, this may not be palatable, Gareth, and I keep trying to come up with a better way to put it, but the simplicity of things, at least from my perspective is this:

George R.R. Martin is not your bitch.

But beyond that initial blast is this really great gem that I think applies to any creative endeavor including programming:

Sometimes it happens like that. You don’t choose what will work. You simply do the best you can each time. And you try to do what you can to increase the likelihood that good art will be created.

And sometimes, and it’s as true of authors as it is of readers, you have a life.

I have started more projects than I have finished, each for their own reasons. “Finished” is entirely subjective, but in my case it would likely mean “used by someone else” and/or “used in day-to-day production by me.” Some unfinished projects get revisited, but most don’t, again each for their own reasons. Outside of important deadlines, not getting hung up on whether something is finished is important, at least for me. What is just as important, however, is learning something new from that project, including how not to do something. Each project I started has been a learning experience of some kind, so even the unfinished ones have value.

Having a deadline is another matter entirely.

Apple hijacks Unix headers into Xcode in Mavericks

I am currently taking a class on Unix systems programming. While following along with lecture, the professor stated that almost always the header files needed for our type of work are located at /usr/include. However, that directory does not exist on my brand new Mavericks MacBook Pro. I have learned (after much searching the web) that the header files are now here:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr

After doing some more research, I found that to get those Unix header files back into /usr/include, one has to install Xcode’s command line tools. But, in order to get those, one has to be a registered member on Apple’s developer website. Not necessarily a paying member, but registered.

I was once a paying member for Apple’s developer tools but I gave it up because I was not actually using everything that was made available. My focus changed and the annual $99 was going to waste. In fact, because of that and that Apple has so much of their Cocoa documentation available externally for free, my need to log into their website has decreased over time to my not touching it in over a year. Now I am jumping through the hoops to figure out which account I was using and what was the password, but that is turning out to be harder than expected for a variety of reasons on Apple’s side, the servers not propagating my Apple ID resets to the developer site being one of them. Yes, I should have done a better job of recording my information, but a simple password reset shouldn’t be this hard either. At this point, I will likely just create a new account solely for getting me what I need.

I have no idea when Apple hijacked the header files, and i can understand the logic and convenience of doing so for tool updates, but knowing what little I do about Unix, hijacking seems to be anathema to the Unix culture. Apple has made my morning nothing but hassle trying to get this fixed and I will have an assignment due soon. So, cheers for that, Apple.

UPDATE: I wound up creating an account solely for the developer account, and it was, as expected, faster and easier than mucking about with a bunch of password resets. Once I did that, getting the command line tools was not straightforward though not hard (Xcode > Open Developer Tool > More Developer Tools… which then kicks you over to a downloads page on the developer website, with registration required for access).

As for my comment about the new default header location being anathema to Unix, I realize now that’s not necessarily true. If anything, Apple can do whatever they want with their distro. But the fact remains based on everything I have read so far that there are some clear expectations about there things ought to be and the header file location is one of them. But at least now I can establish a workflow where I can use the muscle of Xcode to develop and then confidently test outside before submission.

Applescript: Getting unique items in a list update

I love getting questions about the contents of, or topics related to, my site. Most recently, I was emailed a question about one of the older functions I have in the Applescript section. In particular, it was one for getting unique items in a list. Here’s the function…

on GetUniqueItems(sourceList)
	set itemCount to (get count of items in sourceList)
	set compiledList to {}
	--get the first item to kick off the list
	repeat with x from 1 to itemCount
		set itemFound to false
		set itemX to item x of sourceList
		if x < itemCount then
			repeat with y from (x + 1) to itemCount
				set itemY to item y of sourceList
				if itemY is itemX then set itemFound to true
			end repeat
		else
			repeat with y from 0 to (itemCount - 1)
				set itemY to item y of sourceList
				if itemY is itemX then set itemFound to true
			end repeat
		end if
		if itemFound is false then
			set end of compiledList to itemX
			exit repeat
		end if
	end repeat
	--if no items are found
	if (get count of items in compiledList) is 0 then
		return compiledList
	end if
	--find the rest of the unique items
	repeat with x from 1 to itemCount
		set itemFound to false
		set itemX to item x of sourceList
		set resultCount to (get count of items in compiledList)
		repeat with y from 1 to resultCount
			set itemY to item y of compiledList
			if itemY is itemX then set itemFound to true
		end repeat
		if itemFound is false then set end of compiledList to itemX
	end repeat
	return compiledList
end GetUniqueItems

The question was focused on why I go through the source list more than once. As soon as I saw the function after the question, I knew they were right that something was wrong. My answer essentially explained that this was one of the first useful home-brewed functions I wrote, and since it worked, it stuck, as working code is wont to do. But, honestly, I’ve reviewed this code a dozen times and it has me completely baffled as to how it works. I think there is even a whole block on there that can come out and nothing would change.

I started writing my first Applescripts in 2005, which was also my first serious foray into programming. The last time I thought about if...then statements was in high school writing BASIC for the Commodore 64 in high school. This function, according to my notes, was written in 2007 when my needs and skills were becoming more robust. This function is currently in use in several scripts today with nary an error. But, nine years of experience later and immediately that function is absolutely cringe-worthy (though only to a point considering when I wrote it), so I rewrote it. Et voilà…

on getUniqueItems(src)

	set srcCount to (count src)

	set unq to {}

	repeat with x from 1 to srcCount

		set srcItem to item x of src

		set unqCount to (count unq)
		set match to false

		repeat with y from 1 to unqCount
			set unqItem to item y of unq
			if srcItem = unqItem then
				set match to true
			end if
		end repeat

		if match is false then
			set end of unq to srcItem
		end if

	end repeat

	return unq

end getUniqueItems

Hindsight being 20/20 and all that, this a “duh!” moment. There are a couple important things to note about this.

First, my test data for these types of functions is reliable but small. This is O(n2) on the low-end of things, but almost invariably Applescripts very rarely ever deal with data sets large enough where O(nk) has enough of an impact to get a coffee and sandwich while waiting. My personal experience and preference is that if that were the case, then I need to go find a more appropriate tool for data prep.

Second (and last), this block…

set unqCount to (count unq)
set match to false

repeat with y from 1 to unqCount
	set unqItem to item y of unq
	if srcItem = unqItem then
		set match to true
	end if
end repeat

if match is false then
	set end of unq to srcItem
end if

…could be replaced with this common Applescript hook…

if unq does not contain srcItem then
	set end of unq to srcItem
end if

The only problem with this, as I see it, is when trying to compare custom data types as opposed to core data types. This is great if I only ever worked with Applescript’s core data types, like string, number, date, and the like. But almost all of my Applescript code has been targeted to Adobe’s Creative Cloud, which brings a wealth of custom objects with loads of properties with which to work. I think leaving in the extra code (and any possible hits on speed since this not baked into the language like contains) is reasonable for the sake of easy customization later. By way of example, this…

-- compare memory addresses
if srcItem = unqItem then

…becomes this in a pinch…

-- compare object properties
if foo of srcItem = foo of unqItem then

…or even…

-- deep comparison
if my customCompare(foo of srcItem, foo of unqItem) then

So, a bit of extra code for the win. I suppose I could set up a hash table implementation to improve upon the O(n2)O(nk) range of complexity, but with Applescript work, again, it’s really not worth it.

That was a really great question on a number of levels. Not just that this shows that people actually read the site on occasion and finds something useful, which is the core goal of the site (this blog is really more of just a place to vent that offers me more flexibility than other blogging sites or social media) but also to be compelled to review and improve old code and find just how far I have advanced over the years. Win-win.

“And in truth, I’ve never known a man worth his salt who, in the long run, deep down in his heart, didn’t appreciate the grind, the discipline. The difference between a successful person and others is not a lack of strength, not a lack of knowledge, but rather… a lack of will.”
Vince Lombardi

Studies in Semicolons: The Parable of the Carpenter

The carpenter understands the value of something he works with every day, and that’s why he spends so much money on the hammer. But he also understands that value is a double-edged sword: he’s committing to the product he knows, that is reliable.
Studies in Semicolons: The Parable of the Carpenter

Replacing the subject of the punchline with other tools in which I have invested makes this parable applicable to more areas than I care to think about. Interestingly enough, Microsoft Office is not one of them.

Xcode, Mavericks, and OSA

It would appear that Xcode in Mavericks now shows certain Scripting Bridge warnings in the console by default. I upgraded to Mavericks Friday, started a debug run of a SB-using project and this appeared out of nowhere:

2013-10-28 09:14:42.849 Ratchet[2387:303] warning: failed to get scripting definition from /Applications/Adobe Photoshop CC/Adobe Photoshop CC.app; it may not be scriptable.
2013-10-28 09:15:08.048 Ratchet[2387:303] warning: failed to get scripting definition from /Applications/Adobe InDesign CC/Adobe InDesign CC.app; it may not be scriptable.

This appears to be neither actionable or able to be disabled, so not much use during runtime. Not that it matters to me anymore anyway.