
About the Author Don Jones is a nationally-recognized author, instructor, speaker, and consultant, with more than a decade of experience in the Information Technology industry, and with a strong focus on Microsoft-centric solutions. Don is the author of nearly two dozen published works on IT subjects, is a regular speaker at national conferences like Windows Connections, Microsoft TechEd, and TechMentor, is a past Contributing Editor and columnist for REDMOND Magazine, and is a regular columnist for Microsoft TechNet Magazine. Don is a multiple-year recipient of Microsoft's Most Valuable Professional award in recognition of his advocacy of scripting and automation, specifically for Windows PowerShell. Don currently serves as the Director of Projects and Services for SAPIEN Technologies, where he manages the company's Publishing, Training, and Community divisions. |
Here is a heavily-commented solution to Event 3 written by Don Jones, one of the founding members of the Web site PowerShellCommunity.org. PowerShell aficionados might be especially interested in Don’s use of the Write-Progress cmdlet; here he shows a very valid – and very cool – use for that oft-neglected and misunderstood cmdlet.
Here’s the code that Don came up with:
# 2008 Scripting Games - Event 3 - Don Jones
# don@sapien.com
function Tally($round,$numvotes,$votes,$eliminated="") {
# Set up vote counts
[hashtable]$counts = @{"_"=0}
$voted = 0
# Run through votes one line at a time
foreach ($vote in $votes) {
# tally this vote
$voted++
# show progress
Write-Progress -Activity "Counting Votes" -Status "Vote $voted of $numvotes" `
-PercentComplete ((($voted / $numvotes) * 100) -as [int]) `
-CurrentOperation "Round $round"
# split out vote choices into an array
$choices = $vote.split(",")
# tally next non-eliminated candidate
$choice = 0
while ($choice -lt 4) {
# was this candidate eliminated?
if ($eliminated -notcontains $choices[$choice] ) {
# candidate not eliminated
# counted this candidate already?
if ($counts.contains($choices[$choice])) {
# this candidate has votes already
# increment vote for candidate
$counts.item($choices[$choice])++
} else {
# this candidate doesn't yet have votes
# add candidate with vote of 1
$counts.add($choices[$choice],1)
} # if counted
# on to the next vote...
break
} else {
# candidate eliminated
# try next one
$choice++
} #if eliminated
} #while
} #foreach
# close progress
Write-Progress -Activity "Counting votes" -Completed -Status "Please wait"
# remove placeholder
$counts.remove("_")
# replace counts with percentages and output objects
foreach ($candidate in $counts.keys) {
$candidatevotes = $counts.item($candidate)
$out = New-Object psobject
$out | Add-Member noteproperty Name $candidate
$out | Add-Member noteproperty Vote ((($candidatevotes / $numvotes) * 100) )
Write-Output $out
}
# remove progress bar
Write-Progress -Activity "Counting Votes" -Status "Wait" -completed $true
} #function
# get votes
$votes = gc c:\scripts\votes.txt
# how many votes is that?
$numvotes = ($votes | Measure-Object).count
# set up eliminated candidates array
[array]$eliminated = ""
# initialize round
$round = 0