Wednesday, April 10, 2013

Forget Algebra, this is Powershell

Think back to basic algebra.  Some people struggle through it.  Some people are intrigued by it. A lot of people claim they have never used algebra in their entire adult life.  I have always worked an office job that included working in spreadsheets, so I know every time I'm constructing a formula in Excel I use algebra.  Programmers, and even people who use basic scripting, use techniques from algebra as well.

I remember learning some basic logical properties of equality waaaaay back in the beginning of algebra that seemed so obvious and logical that I didn't understand why we had to even write down that they were rules.

For example, the reflexic property of equality states that for any quantity a, a=a. Duh.  Why are we wasting time writing this down?  Ok, fine, for a test I guess I have to know that's the "reflexive" property.

How about the symmetric property of equality?  For any quantities a and b, if a=b then b=a. Again, duh. That's so obvious I can't believe someone wasted time writing it down.

Another example, the transitive property states that for any quantities a, b, and c, if a=b and b=c then a=c.  Even at the beginning stages of algebra, that seemed to me like it would be more useful.

For more refreshers on equality, there's a whole Wikipedia page on it.  http://en.wikipedia.org/wiki/Equality_(mathematics)


So what does this have to do with Powershell, anyways?   Today, I followed a Twitter link to a Powershell Mini-game on equality.  (http://beefycode.com/post/PowerShell-Mini-game-Equality.aspx). He presented the following:

Query: In PowerShell, when is the following statement true? Explain why.
      ( $a -eq $b ) -ne ( $b -eq $a )

Um, wait.  That can't ever be true, can it?  I mean, read the symmetric property of equality again.  For any quantities a and b, if a=b then b=a.  So, I learned way back in basic algebra that statement could *never* be true.  Or...could it?

Oh, dear.  There's an entire Powershell help file about all the comparison operators like -eq, -ne, -lt, etc.   In your shell, check out help about_comparison_operators or read the online version at http://technet.microsoft.com/en-us/library/hh847759.aspx

Guess what?  ($a -eq $b) can return MORE than just $true or $false.  It can return $true, $false, a value, or nothing at all. It means more than just 'equal to', it also means 'includes an identical value'.  So when comparing one value (a scalar) and a collection of values (an array), it's entirely possible that ($a -eq $b) is not the same as ($b -eq $a).   The help gives an example with strings. I'll provide another example with integers.

Let's say $array is an array containing the integers from 1 to 5 inclusive:
$array = 1..5
Now let's say $scalar is a scalar value equal to 4
$scalar = 4

Now watch this:
($array -eq $scalar) will return the identical value 4
($scalar -eq $array) will return $False

So guess what?  ($array -eq $scalar) -ne ($scalar -eq $array)

Monday, March 25, 2013


How about some code to get the new URLs that I've added to my favorites over the past 24 hours?


$NewFavorites = get-childitem $env:userprofile\favorites -recurse`
  -include *.url |
 where-object {($_.lastwritetime -ge (Get-date).adddays(-1))}
$urls = @()
Foreach ($NewFavorite in $NewFavorites) {
 $content = get-content $NewFavorite
 $url = ($content[1]).split("=")[1]
 $urls += $url
}
$urls


I need to test more - what if I've added 0 or 1 item to my favorites, does this still work?

UPDATE:
And then again, this guy's a genius :)
Courtesy of http://madprops.org/blog/list-your-favorites-in-powershell/
And modified to get just the 'new' URLS


gci $env:userprofile\favorites -rec -inc *.url |
  where-object {($_.lastwritetime -ge (Get-date).adddays(-1))}
    | ? {select-string -inp $_ -quiet "^URL=http"}
       | select @{Name="Name";`
          Expression={[IO.Path]::GetFileNameWithoutExtension($_.FullName)}},`
           @{Name="URL"; Expression={get-content $_ |`
               ? {$_ -match "^URL=http"} | % {$_.Substring(4)}}}


Hopefully my added line breaks still produce some code that runs.