## Mathematical Pumpkins

Over the past few years, Pumpkin carving in my family has somehow ended up focusing on two themes: Math, and Knitting.

A Sierpinski Triangle -- which surprisingly only took a toothpick or two to repair isolated triangles:

Sierpinski Carpet (along with a wee bit of evil, of course:)

Not being one to cut 64 of the level-three squares by hand, a cordless drill came in extremely handy.

Mandelbrot, and Koch snowflake:

Knitting randoms:

And just a cool cat in a window:

Unfortunately, when I'm out trick-or-treating, there's nobody around to give candy to the little monsters.  I leave a note above a bowl on a chair – and now I finally know why my calligraphy pens include red in the set!

## Removing Deleted Items Left by the iPhone

One thing you might notice if you have an iPhone connecting to an Inbox via the IMAP protocol is that messages you delete tend to stick around when viewed from other devices (such as Outlook, Outlook Web Access, etc.)

This is caused by an out-of-date view of mail management, where your Inbox handles everything. When you delete an item, some IMAP clients (such as the iPhone) mark them as deleted, but don’t actually remove the item from the server. Some clients hide these deleted items. Some show them with a line through them. Some ignore the deleted flag altogether.

Most email clients (including iPhone) move deleted items to their own sub-folder, so marking items as deleted just ends up being an annoyance:

The solution is the IMAP ‘EXPUNGE’ command. It permanently deletes items that have been marked for deletion (while of course leaving everything in Deleted Items untouched.) The iPhone has an option to do this once a day, but it doesn’t seem to work very well (and a day lag feels like an eternity, anyways.)

The folks at freshlogic have a fine application to run the command against your mail server. We can improve on it in a few ways by writing it in PowerShell. Our version:

• Enables support for securely cached credentials
• Doesn’t require an always-running application
• Runs in the background

To do this, our script imports our saved password, and then uses Send-TcpRequest to simply connect to the server and send the EXPUNGE command. Finally, we use schtasks.exe to automate it.

 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 # 1) Get your password into a securestring: # $ss = Read-Host -AsSecureString # 2) Export it to disk #$ss | ConvertFrom-SecureString | # Out-File (Join-Path (Split-Path $profile) Sync-MailboxDeletedState.ps1.credential) # 3) Create the scheduled task # schtasks /Create /TN MailboxUpdater /SC MINUTE /MO 5 /TR # "powershell -NoProfile -WindowStyle Hidden -File 'c:\path\to\Sync-MailboxDeletedState.ps1'"$username =  $server = "imap.example.com"$port = 993 $passwordPath = Join-Path (Split-Path$profile) Sync-MailboxDeletedState.ps1.credential $password = Get-Content$passwordPath | ConvertTo-SecureString $cred = New-Object System.Management.Automation.PsCredential$username,$password$nc = $cred.GetNetworkCredential()$commands = "A1 LOGIN $($nc.UserName + '@' + $nc.Domain)$($nc.Password)", 'A2 SELECT INBOX', 'A3 EXPUNGE', 'A4 LOGOUT'$commands | Send-TcpRequest $server$port -UseSSL

## Scripting Network / TCP Connections in PowerShell

[Edit: This function has been improved and added to the PowerShell Cookbook module. Get it from the PowerShell Gallery.]

Awhile back, I introduced a script that allows you interact with remote TCP ports (such as Telnet.) While useful, it worked only interactively. It would be even more useful if you were able to script a network or TCP connection.

Let me introduce Send-TcpRequest.ps1 v2, which allows exactly that:

First, a simple scripted HTTP session:

$http = @" GET / HTTP/1.1 Host:search.msn.com nn "@$http | Send-TcpRequest search.msn.com 80

Second, a scripted POP3 session (Parse-TextObject comes from here: http://www.leeholmes.com/blog/parsetextObjectAWKWithAVengeance.aspx):

if(-not (test-path Variable:\mailCredential))
{
$mailCredential = Get-Credential }$address = $mailCredential.UserName$password = $mailCredential.GetNetworkCredential().Password$pop3Commands = "USER $address","PASS$password","STAT","QUIT"
$output =$pop3Commands | Send-TcpRequest mail.leeholmes.com 110
$inbox =$output.Split("n")[3]
$status =$inbox | Parse-TextObject -PropertyName "Response","Waiting","BytesTotal","Extra"
"{0} messages waiting, totaling {1} bytes." -f $status.Waiting,$status.BytesTotal

Now, here is Send-TcpRequest.ps1

## PowerShell RPN Calculator

Adam Barr blogged bits and pieces of a PowerShell RPN calculator a few years ago: first the basics, and then some tweaks to clean it up. An RPN calculator, if you haven’t played with one before, flips the way you enter data. Rather than type “2 + 2”, you type “2 2 +”. RPN-style calculation supposedly has lots of great benefits. While I understand it and can do it, I wouldn’t say I “get it.”

Anyways.

One of the things he runs into with the last version is the PowerShell’s (version one) inability to dynamically invoke static methods:

… you should be able to write:

$add = [Decimal]::Add$add.Invoke(2,3)`

but it doesn't work. That's not exactly the same as getting the value of a static property, but maybe there's a related issue, or maybe I just can't figure out how to do it right.

Well, in version two it does work, and that makes the RPN calculator a whole lot cleaner.

Another interesting aspect about the latest implementation is that it has a lot of very similar code segments. It has tables for operations on the Double class that take one argument, operations on the Double class that take two arguments, operations on the Math class that take one argument, and operations on the Math class that take two arguments. Afterward, there are four nearly identical blocks of code that perform the operation and store the result.

Note: This of course isn’t a slag on the implementation, this is just continuing the tinkering on an interesting concept.

We can simplify this in two ways:

1. Don’t create hard-coded lists of operators. Instead, we’ll look at all methods in the Math and Double class to see if one matches. This approach gives us 30-something operators for free, and perhaps more in future versions of the .NET Framework.
2. Don’t create hard-coded lists of arity: the number of arguments consumed by an operator. Instead, we’ll look at the method overloads that match the operator name, and see how many arguments they consume.

Now, there are some subtleties to both points:

1. The method names in the Decimal and Math classes get kind of long. You don’t want to have to write “2 3 Multiply” in an RPN calculator. To work around that, we’ll define a hashtable of shortcuts that simply map operators to their names.
2. Some operators have multiple overloads. For example, the one-argument Round method rounds a number to zero decimal points. The two-argument Round method rounds it to the specified number of decimal points.

By leveraging PowerShell’s built-in support for introspection and dynamic method invocation, we now have a script that is both much shorter, and much more powerful.

 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 ############################################################################## ## ## rpn.ps1 ## ############################################################################## <# .SYNOPSIS Evaluates a statement as an RPN calculator. Supports all operations from System.Math and System.Decimal. .EXAMPLE rpn 2 2 + .EXAMPLE rpn 2 3 + 1.3 / 2 Round2 Negate #> $s = new-object System.Collections.Stack$n = 0d $shortcuts = @{ "+" = "Add"; "-" = "Subtract"; "/" = "Divide"; "*" = "Multiply"; "%" = "Remainder"; "^" = "Pow"; "||" = "Abs" } :ARGLOOP foreach ($a in $args) { if($shortcuts[$a]) {$a = $shortcuts[$a] }     ## First, see if it's a number. If so, push it.     try { $s.Push( [Decimal]$a ); continue } catch {}     ## It's an operation. Extract the operation name     ## (such as Floor, Round, etc.) It may also represent a     ## specific operation (such as Round2 - Round to specified precision).     $argCountList =$a -replace "(\D+)(\d*)",'$2'$op = $a.Substring(0,$a.Length - $argCountList.Length) ## We support any static operations from the Decimal or Math classes foreach($type in [Decimal],[Math])     {         if($definition =$type::$op) { ## If they haven't specifically given the number of arguments, ## see how many this method supports. We go through each overload ## definition, and see how many commas it has. if(-not$argCountList)             {                 $argCountList =$definition.OverloadDefinitions |                     Foreach-Object { ($_ -split ", ").Count } | Sort-Object -Unique } ## Now, for each overload, see if we can call it. foreach($argCount in $argCountList) { try {$methodArguments = $s.ToArray()[($argCount-1)..0]                     $result =$type::$op.Invoke($methodArguments)                     ## If we were able to call the method, pop all of its                     ## arguments off of the stack.                     $null = 1..$argCount | % { $s.Pop() } ## Then push the result$s.Push($result) continue ARGLOOP } catch { ## If we catch an error, try with the next number of ## arguments } } } } }$s