Packing a list and checking dupicates is slooow

I’ve written a script to choose Albums at random and throw them onto a playlist called “Pack the 'Pod” and have a few problems. The first problem is speed. Because I don’t want any duplicate albums in the playlist, I’m having the script maintain a list of all the albums it has encountered and checking any new albums against that list to make sure no duplicates show up. Naturally, this becomes a very slow proccess as the list builds. I’m wondering if there is a better way to approach this problem as it currently takes about 6 minutes to fill the playlist to 15 gigs.

My second problem is the matter of checking to see if the playlist exists on the offchance that it’s a first run. This is a relatively smaller problem as it introduces new problems. In other words, if I set the script to delete the playlist and create a new one each time, the iPod looses the preference indicating it needs to be updated, and it’s passed by, so fixing the problem seems to raise more headaches than is worth to me, but if you know the answer, I’d love to hear.

Last, but not least, is the dashed out couple of lines. Those are there because I don’t want tracks that are deselected in the main window to be copied, but if you can figure out how to make those lines work, too, that’d be groovy!

Finally, here’s the code!

tell application "iTunes"
	set album_list to {}
	delete every track of playlist "Pack the 'Pod"
	repeat with i from 1 to the count of sources
		if the kind of source i is iPod then
			set thePod to the name of source i as text
		end if
	end repeat
	set theCapacity to the text returned of (display dialog "How full shall I pack'r, Sir? (Please give your answer in Gigs)" default answer 15 giving up after 300)
	set theCapacity to theCapacity * 1.0E+9 as real
	set theSize to (size of playlist "Pack the 'Pod") as real
	
	set randomLibrary to playlist "Library" of source "Library"
	set shuffle of randomLibrary to true
	set shuffle of randomLibrary to false
	set shuffle of randomLibrary to true
	set trackCounter to 1
	repeat while theSize < theCapacity
		--    if enabled of trackCounter of randomLibrary is true then 
		set albumName to album of track trackCounter of randomLibrary
		if albumName is "" or album_list contains albumName then
			set trackCounter to trackCounter + 1
		else if album_list does not contain albumName then
			try
				copy (get a reference to (every track in randomLibrary whose album is albumName)) to albumLister
				duplicate albumLister to playlist "Pack the 'Pod"
			on error
				-- keep going? 
			end try
			set trackCounter to trackCounter + 1
			set theSize to size of playlist "Pack the 'Pod" as real
			set album_list to (album_list & albumName) as list
		end if
		--    end if 
	end repeat
	update thePod
end tell

fs

p.s. Jonn, did I do something wrong in the post? The link to ‘Open this script in a new window’ doesn’t seem to work.

No, as it states in the documentation, there is a bug in the AppleScript URL protocol that prevents the links from working when there are high-ASCII characters. Your script includes the continuation character (“¬”) and this prevents the link from opening correctly.

Jon

In typical male fashion (‘Documentation?! Bah! I can figure it out!’), I read only what I needed… Thanks for the quick response, though.

Back to the script, though. Any takers?

fs

This won’t make much difference in terms of time but the code is slightly more optimized:
property default_capacity : 15
property default_playlist : “Pack the 'Pod”

tell application "iTunes"
	set album_list to {""}
	delete every track of playlist default_playlist
	set default_capacity to text returned of (display dialog "How full shall I pack'r, Sir? (Please give your answer in Gigs)" default answer default_capacity giving up after 300) as integer
	set theCapacity to (default_capacity * 1.0E+9) as real
	
	set randomLibrary to playlist "Library" of source "Library"
	set shuffle of randomLibrary to true
	set shuffle of randomLibrary to false
	set shuffle of randomLibrary to true
	set trackCounter to 1
	repeat while (size of playlist default_playlist as real) < theCapacity
		set albumName to album of track trackCounter of randomLibrary
		if albumName is not in album_list then
			try
				duplicate (get a reference to (every track in randomLibrary whose album = albumName)) to playlist default_playlist
				set end of album_list to albumName
			end try
		end if
		set trackCounter to trackCounter + 1
	end repeat
	repeat with i from 1 to (count of sources)
		if kind of source i = iPod then
			set thePod to name of source i as text
			exit repeat
		end if
	end repeat
	try
		update thePod
	end try
end tell

Jon

Dang. I should’ve seen those optimizations… Thanks for the pointers, Jon!

I had an idea last night. Back in the day, a friend of mine and I wrote a series of card games on our TI-92’s and each one needed a shuffle sub-directory. Well, obviously it’s silly to write something different (or the same thing over again) for each one, so we wrote one sub-program to handle it all.

The first attempt at a ‘Shuffle’ program generated the same problem I have now: as it got deeper into the deck, the odds of it choosing the last unchosen card became more and more unlikely and the program would slow to unbearable pace. Well, our solution became quite simple! Hard-code the ‘deck list’ from the beginning to contain all the known cards and then subtract from the list as new cards were chosen! I’d love to incorporate that idea here, but the situation is somewhat different as the full album list is unknown and constantly changing.

Is there anyone out there who can think of a way to somehow incorporate this approach into my script? Is there some way to harvest the information from the XML file iTunes creates? Or do my dreams begin to push beyond what AppleScript is capable of?

fs