PowerShell the Oracle — Instant Answers from your Prompt

One of the scripts I like the most in my toolbox is the one that gives me answers to questions from the command line.

For the past 2 years or so, Encarta has offered an extremely useful “Instant Answers” feature.  It’s since been integrated into MSN Search, as well as a wildly popular Chat Bot.  MoW showed how to use that feature through a Monad IM interface (via the Conversagent bot,) but we can do a great job with good ol’ screen scraping.

PS:51 > Get-Answer "What is the population of China?"

China Population, total: 1,313,973,700
2006 estimate
United States Census International Programs Center

PS:52 > Get-Answer "5^(e^(x^2))=50"

5^(e ^( x^2))=50 : x=-0.942428

PS:53 > Get-Answer "define:Canadian Bacon"

Definition for Canadian bacon
lean bacon

PS:54 > Get-Answer "How many calories in an apple?"

Apples calories
1.0 cup, quartered or chopped has 65 calories
1.0 NLEA serving has 80 calories
1.0 small (2-1/2" dia) (approx 4 per lb) has 55 calories
1.0 medium (2-3/4" dia) (approx 3 per lb) has 72 calories
1.0 large (3-1/4" dia) (approx 2 per lb) has 110 calories
1.0 cup slices has 57 calories

PS:55 > Get-Answer "How many inches in a light year?"

1 lightyear = 372,461,748,226,857,000 inches

Here is the script, should you require your own command-line oracle:

## Get-Answer.ps1
## Use Encarta's Instant Answers to answer your question
## Example:
##    Get-Answer "What is the population of China?"

param([string] $question = $( throw "Please ask a question."))

function Main
    ## Load the System.Web.HttpUtility DLL, to let us URLEncode
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Web")

    ## Get the web page into a single string with newlines between
    ## the lines.
    $encoded = [System.Web.HttpUtility]::UrlEncode($question)
    $text = (new-object System.Net.WebClient).DownloadString("http://search.msn.com/encarta/results.aspx?q=$encoded")

    ## Get the answer with annotations
    $startIndex = $text.IndexOf('<span class="answer_header">')
    $endIndex = $text.IndexOf('</div><div id="results">')

    ## If we found a result, then filter the result
    if(($startIndex -ge 0) -and ($endIndex -ge 0))
       $partialText = $text.Substring($startIndex, $endIndex - $startIndex)

       ## Very fragile, voodoo screen scraping here
       $partialText = $partialText -replace '<span class="answer_feedback">.*Is this useful\?',"`n"
       $partialText = $partialText -replace '<span class="attr...">',"`n"
       $partialText = $partialText -replace '<BR />',"`n"

       $partialText = clean-html $partialText
       $partialText = $partialText -replace "`n`n""`n"

       "No answer found."

## Clean HTML from a text chunk
function clean-html ($htmlInput)
    $tempString = [Regex]::Replace($htmlInput, "<[^>]*>""")

. Main


[Edit: Updated to work with Windows Live Serach, and with recent PowerShell builds.]

4 Responses to “PowerShell the Oracle — Instant Answers from your Prompt”

  1. zzz writes:

    It’d be more interesting if you could hook up to the Vista box: Press Win-key, it popups start menu search box, then type in something like "tr-en-fr word" and the start menu could, instead of showing programs that being with tr-en-fr, show translation(s) of "word" in french…

  2. Lee writes:

    You could technically do this with Monad (with Win+Something opening a Monad prompt, then using cmdlets to do what you’re talking about,) but that might be stretching it a bit. However, that is also the focus of YubNub, a project done for a Ruby on Rails competition. I wrote a script to let you interact with YubNub from the command line: https://www.leeholmes.com/blog/MSHAndYubNubACommunityCommandline.aspx

    As for the GUI option — I’m not sure if it ships as part of Vista, but the deskbar that comes with the MSN Search toolbar can do exactly that. There are also a whole host of GUI tools that do the job well, too.

  3. /\/\o\/\/ writes:

    wow. our Queen is back 😉

  4. Scott Hanselman writes:

    zzz – you can do that by integrating Monad with Slickrun…

Leave a Reply