Tuesday, August 9, 2011

How to revive Mac App Store when its stuck forever waiting...

I recently went to the App Store application on my Mac to download the Lion version of Apple's Xcode development tools.  I was prompted for my Apple ID and password (which I provided) and then I left the App Store app on its own to complete the download and install.  After about 30 minutes I went to check in on its progress and saw that it had downloaded exactly 0 bytes.  The status on the Purchased page was Waiting...

Waiting for Godot

...and waiting and waiting.  I quit and restarted App Store and still my downloads were stuck waiting.  I dug around a little and it turns out this is not an uncommon problem but the remedies suggested were all over the place.  Everything from installing updates and deleting caches (both good ideas) to deleting your Library folder (not a good idea).  I like to attack problems like this by starting with the easiest and least invasive measures.

I should state right off the bat that these solutions are meant to incur as little disruption as possible but do require the use of some programs that might not be in your usual repertoire: Activity Monitor and Terminal.  If you are at all uncomfortable using these tools you can always use that old Windows chestnut... reboot.  Yes, rebooting your Mac should have the same affect as solution 1 at least.  But if you don't want the hassle of rebooting then read on.



Solution 1: Kill the Zombie

The App Store uses a process called "storeagent" that runs continuously in the background.  It seems that sometimes this process can go a little wonky and fail to respond to requests to download app purchases.  What we want to do is kill this zombie process (it will start up again automatically).

Start Activity Monitor
First, quit the App Store application (e.g. by selecting "App Store->Quit App Store" or pressing Cmd-Q or click the red dot in the top left corner of the window).  Start up Activity Monitor (you'll find it on Lion's launchpad in the Utilities collection or using Finder in Applications/Utilities/Activity Monitor.  Activity monitor is used to display the processes running on your Mac.  You could go hunt around for the process called "storeagent" but an easier method is to enter "storeagent" in the Activity Monitor filter box as illustrated below (some of the numbers will be different).  Highlight the "storeagent" process by clicking on it.  The "Quit Process" stop sign should become available.  Go ahead and click on Quit Process to kill "storeagent". You'll be asked if you really want to quit the process.  Confirm by clicking "Quit".  Normally this should do the trick and the process will disappear immediately and be replaced a little while later by a new process (with a different number in the PID column).  However, if the process is a deep zombie, you will need to click "Force Quit" in the confirmation dialog.  Do this only as a last resort as it is possible to damage system files by using Force Quit too often. 

Activity Monitor Filtered for "storeagent".  Note the "Quit Process" stop sign is now clickable.

Now go ahead and restart the App Store application.  Click on Purchased, find your purchase and select Resume. After you enter your Apple ID and password your purchase should start downloading.   However, if the App Store is still stuck in Waiting move on to Solution 2.

Solution 2 - Purge the Caches

Solution 1 has always worked for me but I've heard of cases where more intervention is required.  If this fits your situation then go ahead and quit the App Store application again.  Now we do some typing into Terminal. You can find Terminal in the same Utilities folder that you found Activity Monitor.  When you start it, it should look something like below.

At the Terminal prompt
What we're going to do is use some commands to delete App Store caches.  You do not need to worry about deleting these files since, by definition, they are a copy of what is already stored on the Apple servers and will automatically be restored.  Type of the following commands exactly as you see below (in fact, go ahead and copy and paste them into Terminal).

rm -r ~/Library/Caches/com.apple.appstore
rm -r ~/Library/Caches/com.apple.storeagent
rm ~/Library/Preferences/com.apple.appstore.plist
rm ~/Library/Preferences/com.apple.storeagent.plist
rm ~/Library/Cookies/com.apple.appstore.plist

Now go and do the steps in Solution 1 again.  Once you're done that, start up App Store, go to Purchases, and select Resume on your download.  Enter your Apple ID and password and you're off to the races.

Sunday, August 7, 2011

Ruby Koan for Dice Scoring (Greed) - Solution #2

It's interesting what some sleep and exercise can do.  The next day while approaching the "big hill" part of my run I came up with a new solution to the Greed Ruby Koan.  This solution is shorter and is more Rubyesque (I think). It also includes a reasonable amount of error checking (nil parameter and valid dice values).  Again, I'd love to hear from Ruby enthusiasts to comment on style and other approaches.

def score(dice)

  return 0 if dice == nil

  score  = 0
  counts = [0, 0, 0, 0, 0, 0]
  dice.each { |roll| counts[roll-1] += 1 if (1..6) === roll } # Count valid rolls

  (1..6).each { |i| score += (i == 1) ? 1000 : i * 100 if counts[i-1] >= 3 } # Score triples

  # Score the rest
  score += counts[0] % 3 * 100
  score += counts[4] % 3 * 50

  return score
end

Friday, August 5, 2011

Ruby Koan for Dice Scoring (Greed) - Solution #1

Recently I've started teaching myself Ruby and as part of my quest I discovered the amazing Ruby Koan site by EdgeCase.  The concept of a koan dates back to the foundations of Zen Buddhism.  You might recognize the question "what is the sound of one hand clapping".  This is actually part of a Zen koan.  A koan is a question or story that serves as a fundamental teaching tool.  A traditional Zen koan cannot be understood via rational thought but rather through intuition leading to an "Aha!" moment.

Ruby Koans, as developed by EdgeCase, consist of 274 test cases and incomplete Ruby code.  Your task is to implement the code in order to make all the tests pass in classic TDD style.  For those unfamiliar with the term, TDD means Test Driven Development.  TDD follows the pattern of red, green, refactor.  When implementing a new section of code you start with its tests which will all fail (be 'red') initially.  Then you implement the code turning all of the tests green.  Finally, and over time, you go forth with confidence and refactor the code to higher and higher levels of quality (keeping it green).

Many of the Ruby Koan tests are fairly simple to make pass.  Some of the more esoteric Ruby features were more difficult to master (I thought Array.inject and blocks/yield would drive me to murder).  However, one of the most interesting koan related to scoring dice throws in a fictional game called Greed.  This koan is quite different than the others and is more like a Kata (a martial arts term referring to a repetitive exercise meant to hone skill -- I'll save Kata for another post).  Briefly, the koan asks you to implement a class that conforms to the following requirements:

# A greed roll is scored as follows [for a roll of up to 5 dice]:
#
# * A set of three ones is 1000 points
#
# * A set of three numbers (other than ones) is worth 100 times the
#   number. (e.g. three fives is 500 points).
#
# * A one (that is not part of a set of three) is worth 100 points.
#
# * A five (that is not part of a set of three) is worth 50 points.
#
# * Everything else is worth 0 points.
#
# Examples:
#
# score([1,1,1,5,1]) => 1150 points
# score([2,3,4,6,2]) => 0 points
# score([3,4,5,3,3]) => 350 points
# score([1,5,1,2,4]) => 250 points

This particular koan consists of 13 (initially failing) tests.  Your implementation of the scoring method must make them all pass.  Ruby, by its nature, provides a multitude of ways (more than any other language I think) to solve this problem.  What follows is my first attempt.  It should be noted that error checking was excluded from the requirements nor did any of the tests include input error tests (like dice rolls outside 1..6, strings, etc.).

As a student of Ruby I am keen for feedback (particularly from the Ruby masters) as this solution seems a little... wordy.

def score(dice)
  score = 0
  sorted_dice = dice.sort # Sort the rolls

  while sorted_dice.length > 0
    val = sorted_dice.shift
    if sorted_dice.length >= 2 && val == sorted_dice[0] && val == sorted_dice[1]  # a triple!
      score += val == 1 ? 1000 : val * 100
      sorted_dice.shift(2)
    else
      score += 100 if val == 1
      score += 50  if val == 5
    end
  end

  return score
end