USENet vote taking script examples, Part01/02

Kent Paul Dolan xanthian at zorch.SF-Bay.ORG
Thu Dec 20 09:43:36 AEST 1990


Submitted-by: xanthian at zorch.SF-Bay.ORG (Kent Paul Dolan)
Posting-number: <fill in the blank>
Archive-name: vote_tools/Part01

This is the first part of a two part distribution.

Enclosed are the set of scripts I used to run the comp.sys.amiga
reorganization vote acceptance. They have been cleaned up and modestly
documented (and tested - they still work) so that they can be shared
with the net.

There are more explanations in the README, just below the MANIFEST here.

There is no trailing signature, and this shar is complete in this
posting. A second posting and shar contains the remainder of the files
for this distribution. Thanks to Rich Salz for his cshar that packaged this
distribution so nicely. Enjoy!

Kent, the man from xanth.
<xanthian at Zorch.SF-Bay.ORG> <xanthian at well.sf.ca.us>

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  MANIFEST README awksrc awksrc/abstain.awk
#   awksrc/classify.awk awksrc/mail_filt.awk awksrc/parse.awk
#   awksrc/score.awk awksrc/total.awk bin bin/classifyvotes
#   bin/dothevotes bin/filtervotes bin/mailfilter bin/parsevotes
#   bin/scorevotes bin/totalvotes bin/writeletter docs
#   docs/FILE_PURPOSES examples examples/classedvotes
#   examples/classifiedvotes examples/parsedvotes examples/scoredvotes
#   examples/scoreletter examples/sl_header examples/sl_middle
#   examples/totaledvotes
# Wrapped by csa-vote at zorch on Wed Dec 19 14:05:22 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(2348 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
XMANIFEST                 -- this file
XREADME                   -- introduction to this distribution
X
Xawksrc/abstain.awk       -- program to count votes with >= one abstention
Xawksrc/classify.awk      -- program to reformat classedvotes
Xawksrc/mail_filt.awk     -- program to filter header trash from an email file
Xawksrc/parse.awk         -- program to pull author and votes from 1 email file
Xawksrc/score.awk         -- program to score votes from parsedvotes file
Xawksrc/total.awk         -- program to total all votes for ballot together
X
Xbin/classifyvotes        -- csh script to build classedvotes, use classify.awk
X                            and abstain.awk to build classifiedvotes
Xbin/dothevotes           -- csh script to run the other scripts
Xbin/filtervotes          -- csh script to run mailfilter in a loop
Xbin/parsevotes           -- csh script to run parse.awk in a loop
Xbin/mailfilter           -- csh script to run mail_filt.awk on one email file
Xbin/scorevotes           -- csh script to run score.awk
Xbin/totalvotes           -- csh script to run total.awk
Xbin/writeletter          -- csh script to create scoreletter from reports and
X                            canned text
Xdocs/FILE_PURPOSES       -- text to further describe the vote counting files
X                            and ballot counting account setup
Xdocs/POLLING_PLACE       -- "how to run a USENet vote (and use these scripts
X                            to help)"
Xexamples/classedvotes    -- intermediate data file for next item
Xexamples/classifiedvotes -- counts of all ballots, all yes, all no, all
X                            abstain, mixed, and at least one abstain, with
X                            percents.
Xexamples/parsedvotes     -- individual votes and email paths for voters
X                            (a small subset of the real 940 entry file)
Xexamples/scoreletter     -- final balloting results report example
Xexamples/scoredvotes     -- report output of scorevotes, score.awk, contains
X                            yes/no/abstain/invalid counts and percent yes
X                            votes for each ballot item
Xexamples/sl_header       -- top text of scoreletter
Xexamples/sl_middle       -- middle text of scoreletter
Xexamples/totaledvotes    -- sums of the yes, no, abstain, and invalid votes
X                            for the whole ballot
END_OF_FILE
if test 2348 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1815 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XUSENet multi-vote ballot counting scripts.
X
XKent Paul Dolan, LCDR, USNOAA Corps, Retired.
X15 December 1990.
X
XEnclosed are the set of scripts I used to run the comp.sys.amiga
Xreorganization vote acceptance. They have been cleaned up and modestly
Xdocumented (and tested - they still work) so that they can be shared
Xwith the net.
X
XThese scripts are meant to be used as examples and modified by the vote
Xtaker to suit the system and file layout and number of votes in the
Xballot concerned. They are simple but effective, and are placed in the
Xpublic domain for any use whatever. Credit to the author is not required
Xor requested.
X
XThere are two kinds of scripts enclosed: csh scripts and (old) awk
Xscripts. The csh scripts depend on several facilities not available in
Xsh, and any sh expert is invited to rewrite them in sh to have the same
Xfunctionality and repost them; I'm not that good at sh.  Life will be
Xsimpler if you put the csh scripts in your path (they unpack into ./bin)
Xand use chmod to make them executable
X
XThe awk scripts are deliberately restricted to old awk functionality so
Xthat they may be run on a wider variety of systems. They should run
Xunmodified under new awk. I don't know bawk well enough to know if they
Xwould also run unchanged under it.
X
XEnclosed files FILE_PURPOSES and POLLING_PLACE should be read to
Xunderstand the files and directory structures used with these scripts,
Xand to understand the methodology of running a vote.
X
X                                                           /// It's Amiga
X                                                          /// for me:  why
XKent, the man from xanth.                             \\\///   settle for
X<xanthian at Zorch.SF-Bay.ORG> <xanthian at well.sf.ca.us>   \XX/  anything less?
X--
XConvener, ongoing comp.sys.amiga grand reorganization.
END_OF_FILE
if test 1815 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test ! -d 'awksrc' ; then
    echo shar: Creating directory \"'awksrc'\"
    mkdir 'awksrc'
fi
if test -f 'awksrc/abstain.awk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'awksrc/abstain.awk'\"
else
echo shar: Extracting \"'awksrc/abstain.awk'\" \(584 characters\)
sed "s/^X//" >'awksrc/abstain.awk' <<'END_OF_FILE'
X{thisabstain = 0}
X$1 ~  /A/ { thisabstain = 1 }
X$2 ~  /A/ { thisabstain = 1 }
X$3 ~  /A/ { thisabstain = 1 }
X$4 ~  /A/ { thisabstain = 1 }
X$5 ~  /A/ { thisabstain = 1 }
X$6 ~  /A/ { thisabstain = 1 }
X$7 ~  /A/ { thisabstain = 1 }
X$8 ~  /A/ { thisabstain = 1 }
X$9 ~  /A/ { thisabstain = 1 }
X$10 ~ /A/ { thisabstain = 1 }
X$11 ~ /A/ { thisabstain = 1 }
X$12 ~ /A/ { thisabstain = 1 }
X$13 ~ /A/ { thisabstain = 1 }
X$14 ~ /A/ { thisabstain = 1 }
X{abstain += thisabstain}
X{total += 1}
XEND {
X  printf("Ballots with at least 1 abstain %4d, or %5.2f%%\n",\
X         abstain,100*abstain/total)
X}
X
END_OF_FILE
if test 584 -ne `wc -c <'awksrc/abstain.awk'`; then
    echo shar: \"'awksrc/abstain.awk'\" unpacked with wrong size!
fi
# end of 'awksrc/abstain.awk'
fi
if test -f 'awksrc/classify.awk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'awksrc/classify.awk'\"
else
echo shar: Extracting \"'awksrc/classify.awk'\" \(563 characters\)
sed "s/^X//" >'awksrc/classify.awk' <<'END_OF_FILE'
X/total/      {total = $2}
X/allyes/     {allyes = $2}
X/allno/      {allno = $2}
X/allabstain/ {allabstain = $2}
X
XEND {
X  mixed = total - allyes - allno - allabstain
X  printf("Mixed       ballots: %5d, or %6.2f%%\n",mixed,(100*mixed)/total)
X  printf("All yes     ballots: %5d, or %6.2f%%\n",allyes,(100*allyes)/total)
X  printf("All no      ballots: %5d, or %6.2f%%\n",allno,(100*allno)/total)
X  printf("All abstain ballots: %5d, or %6.2f%%\n",allabstain,\
X         (100*allabstain)/total)
X  printf("Total       ballots: %5d, or %6.2f%%\n",total,(100*total)/total)
X}
END_OF_FILE
if test 563 -ne `wc -c <'awksrc/classify.awk'`; then
    echo shar: \"'awksrc/classify.awk'\" unpacked with wrong size!
fi
# end of 'awksrc/classify.awk'
fi
if test -f 'awksrc/mail_filt.awk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'awksrc/mail_filt.awk'\"
else
echo shar: Extracting \"'awksrc/mail_filt.awk'\" \(252 characters\)
sed "s/^X//" >'awksrc/mail_filt.awk' <<'END_OF_FILE'
XBEGIN {receiving = 0}
Xreceiving == 1 && (/^ / || /^	/) {next}
X{receiving = 0}
X/^Received: /  {receiving = 1 ; next}
X/^Date: / {next}
X/^Message-Id: / {next}
X/^Sender: / {next}
X/^X-Mailer: / {next}
X/^In-Reply-To: / {next}
X/^References: / {next}
X{print}
X
END_OF_FILE
if test 252 -ne `wc -c <'awksrc/mail_filt.awk'`; then
    echo shar: \"'awksrc/mail_filt.awk'\" unpacked with wrong size!
fi
# end of 'awksrc/mail_filt.awk'
fi
if test -f 'awksrc/parse.awk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'awksrc/parse.awk'\"
else
echo shar: Extracting \"'awksrc/parse.awk'\" \(734 characters\)
sed "s/^X//" >'awksrc/parse.awk' <<'END_OF_FILE'
XBEGIN { numgroups = 14; votecue = "Create";
X tag[1]  = "misc";          tag[2]  = "programmer";    tag[3]  = "announce";
X tag[4]  = "reviews";       tag[5]  = "introduction";  tag[6]  = "audio";
X tag[7]  = "graphics";      tag[8]  = "marketplace";   tag[9]  = "multimedia";
X tag[10] = "applications";  tag[11] = "emulations";    tag[12] = "advocacy";
X tag[13] = "datacomm";      tag[14] = "unix";
X for (i=1; i<=numgroups; i++) {vote[i] = "I";}
X voter = " I ";
X}
X
X/^From: / {$1 = ""; voter = "" $0;}
X
X{ if ($2 == votecue )
X   for (i=1; i<=numgroups; i++)
X    if (($1 ~ /^(Y|N|A)$/) && (index($3,tag[i]) > 0)) { vote[i] = $1 }
X}
X
XEND {
X for (i=1; i<=numgroups; i++) printf("%s ",vote[i]);
X printf("%s %s\n",FILENAME,substr(voter,2));
X}
END_OF_FILE
if test 734 -ne `wc -c <'awksrc/parse.awk'`; then
    echo shar: \"'awksrc/parse.awk'\" unpacked with wrong size!
fi
# end of 'awksrc/parse.awk'
fi
if test -f 'awksrc/score.awk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'awksrc/score.awk'\"
else
echo shar: Extracting \"'awksrc/score.awk'\" \(839 characters\)
sed "s/^X//" >'awksrc/score.awk' <<'END_OF_FILE'
XBEGIN { numgroups = 14; h = "comp.sys.amiga."
X name[1] =  h "misc";          name[2] =  h "programmer";
X name[3] =  h "announce";      name[4] =  h "reviews";
X name[5] =  h "introduction";  name[6] =  h "audio";
X name[7] =  h "graphics";      name[8] =  h "marketplace";
X name[9] =  h "multimedia";    name[10] = h "applications";
X name[11] = h "emulations";    name[12] = h "advocacy";
X name[13] = h "datacomm";      name[14] = "comp.unix.amiga";
X}
X{
X  for (i = 1; i <= numgroups; i++) {
X    if ($i ~ /Y/) { yes[i]     += 1 };
X    if ($i ~ /N/) { no[i]      += 1 };
X    if ($i ~ /A/) { abstain[i] += 1 };
X    if ($i ~ /I/) { invalid[i] += 1 };
X  }
X}
XEND {
X for (i = 1; i <= numgroups; i++)
X  printf("y %4d   n %4d   y%% %6.2f%%   a %4d   i%2d %s\n",yes[i],no[i],\
X         (100*yes[i]/(yes[i] + no[i])),abstain[i],invalid[i],name[i]) 
X}
X
END_OF_FILE
if test 839 -ne `wc -c <'awksrc/score.awk'`; then
    echo shar: \"'awksrc/score.awk'\" unpacked with wrong size!
fi
# end of 'awksrc/score.awk'
fi
if test -f 'awksrc/total.awk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'awksrc/total.awk'\"
else
echo shar: Extracting \"'awksrc/total.awk'\" \(474 characters\)
sed "s/^X//" >'awksrc/total.awk' <<'END_OF_FILE'
X{yes += $2; no += $4; abstain += $8; invalid += $10;}
XEND {
X  votes = yes + no + abstain + invalid
X  printf("Total yes     votes: %5d, or %6.2f%%\n",yes,(100*yes)/votes)
X  printf("Total no      votes: %5d, or %6.2f%%\n",no,(100*no)/votes)
X  printf("Total abstain votes: %5d, or %6.2f%%\n",abstain,(100*abstain)/votes)
X  printf("Total invalid votes: %5d, or %6.2f%%\n",invalid,(100*invalid)/votes)
X  printf("Total         votes: %5d, or %6.2f%%\n",votes,(100*votes)/votes)
X}
END_OF_FILE
if test 474 -ne `wc -c <'awksrc/total.awk'`; then
    echo shar: \"'awksrc/total.awk'\" unpacked with wrong size!
fi
# end of 'awksrc/total.awk'
fi
if test ! -d 'bin' ; then
    echo shar: Creating directory \"'bin'\"
    mkdir 'bin'
fi
if test -f 'bin/classifyvotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/classifyvotes'\"
else
echo shar: Extracting \"'bin/classifyvotes'\" \(1003 characters\)
sed "s/^X//" >'bin/classifyvotes' <<'END_OF_FILE'
X#!/bin/csh
X#
X# "classifyvotes" gathers "nice to have" statistics about the ballots
X#
X# This script controls counting of the "all 'yes'", "all 'no'",
X# "all 'abstain'", and  "at least one 'abstain'" votes from the
X# "parsedvotes" file.
X#
X# This will need to be tailored for the number of votes in your ballot
X# by changing the fgrep search strings here and by modifying abstain.awk.
X#
Xpushd ~/tally
Xecho -n "total " > classedvotes
Xcat parsedvotes | wc -l >> classedvotes
Xecho -n "allyes " >> classedvotes
Xfgrep "Y Y Y Y Y Y Y Y Y Y Y Y Y Y " parsedvotes | wc -l >> classedvotes
Xecho -n "allno " >> classedvotes
Xfgrep "N N N N N N N N N N N N N N " parsedvotes | wc -l >> classedvotes
Xecho -n "allabstain " >> classedvotes
Xfgrep "A A A A A A A A A A A A A A " parsedvotes | wc -l >> classedvotes
Xawk -f ~/awksrc/classify.awk classedvotes > classifiedvotes
Xecho "" >> classifiedvotes
Xawk -f ~/awksrc/abstain.awk parsedvotes >> classifiedvotes
Xecho "************** classifyvotes done ****************"
Xpopd
END_OF_FILE
if test 1003 -ne `wc -c <'bin/classifyvotes'`; then
    echo shar: \"'bin/classifyvotes'\" unpacked with wrong size!
fi
chmod +x 'bin/classifyvotes'
# end of 'bin/classifyvotes'
fi
if test -f 'bin/dothevotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/dothevotes'\"
else
echo shar: Extracting \"'bin/dothevotes'\" \(478 characters\)
sed "s/^X//" >'bin/dothevotes' <<'END_OF_FILE'
X#!/bin/csh
X#
X# "dothevotes" is the overall control script; start this off in background
X# and go about your work.
X#
X# You _really_ want to run this stuff "niced" and this script in the
X# background.  It can take 2 minutes per hundred votes, and run without
X# the nice, it slows the whole system down while running.
X#
Xnice -15 ~/bin/filtervotes
Xnice -15 ~/bin/parsevotes
Xnice -15 ~/bin/scorevotes
Xnice -15 ~/bin/totalvotes
Xnice -15 ~/bin/classifyvotes
Xnice -15 ~/bin/writeletter
END_OF_FILE
if test 478 -ne `wc -c <'bin/dothevotes'`; then
    echo shar: \"'bin/dothevotes'\" unpacked with wrong size!
fi
chmod +x 'bin/dothevotes'
# end of 'bin/dothevotes'
fi
if test -f 'bin/filtervotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/filtervotes'\"
else
echo shar: Extracting \"'bin/filtervotes'\" \(597 characters\)
sed "s/^X//" >'bin/filtervotes' <<'END_OF_FILE'
X#!/bin/csh
X#
X#  "filtervotes" removes the useless header lines from vote email;
X#  this can easily cut the space needed to store votes by 2/3rds.
X#
X#  By changing "votes" to your standard mailfolder file, this and
X#  the "mailfilter" and "mail_filt.awk" scripts are useful for 
X#  trimming useless cruft from your normal mail archives, as well.
X#
Xpushd ~/votes
X#
X# Since grep runs _much_ faster than the awk script, picking out
X# just the newly received votes with grep before filtering them
X# saves a lot of time and is a big win.
X#
Xforeach i (`grep -l Received: *`)
X~/bin/mailfilter $i
Xend
Xpopd
END_OF_FILE
if test 597 -ne `wc -c <'bin/filtervotes'`; then
    echo shar: \"'bin/filtervotes'\" unpacked with wrong size!
fi
chmod +x 'bin/filtervotes'
# end of 'bin/filtervotes'
fi
if test -f 'bin/mailfilter' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/mailfilter'\"
else
echo shar: Extracting \"'bin/mailfilter'\" \(666 characters\)
sed "s/^X//" >'bin/mailfilter' <<'END_OF_FILE'
X#!/bin/csh
X#
X# "mailfilter" takes an email file name on the command line,
X# and uses mail_filt.awk to filter lots of garbage out of the
X# headers of received email.  You don't want to do this until
X# you are sure you don't need the garbage to figure out a working
X# mail path back to the sender.  Once communication is established,
X# the header cruft is just eating space on your mass storage to no
X# purpose, and this script can easily cut out one or two Kbytes of
X# trace information per letter.
X#
Xecho "mail filter running on	$1 "
Xmv $1 mf_temp
Xawk -f ~/awksrc/mail_filt.awk mf_temp > $1
X# defeat normal alias that forces interactive confirmation
X/bin/rm mf_temp
END_OF_FILE
if test 666 -ne `wc -c <'bin/mailfilter'`; then
    echo shar: \"'bin/mailfilter'\" unpacked with wrong size!
fi
chmod +x 'bin/mailfilter'
# end of 'bin/mailfilter'
fi
if test -f 'bin/parsevotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/parsevotes'\"
else
echo shar: Extracting \"'bin/parsevotes'\" \(632 characters\)
sed "s/^X//" >'bin/parsevotes' <<'END_OF_FILE'
X#!/bin/csh
X#
X# "parsevotes" takes the most time, reading each email ballot as a separate
X# file and using "parse.awk" to extract the contents of the "From:" line,
X# and the "Y", "N", or "A" from each vote line, then building a line of
X# space delimited votes, the filename, and the author information onto the
X# end of the "parsedvotes" file.  This file then becomes the final mass
X# acknowledgement record, as well as the input to other vote counting
X# scripts.
X#
Xcp /dev/null ~/tally/parsedvotes
Xpushd ~/votes
Xforeach i (*)
Xawk -f ~/awksrc/parse.awk $i >> ~/tally/parsedvotes
Xend
Xecho "********** PARSEVOTES DONE **********"
Xpopd
END_OF_FILE
if test 632 -ne `wc -c <'bin/parsevotes'`; then
    echo shar: \"'bin/parsevotes'\" unpacked with wrong size!
fi
chmod +x 'bin/parsevotes'
# end of 'bin/parsevotes'
fi
if test -f 'bin/scorevotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/scorevotes'\"
else
echo shar: Extracting \"'bin/scorevotes'\" \(278 characters\)
sed "s/^X//" >'bin/scorevotes' <<'END_OF_FILE'
X#!/bin/csh
X#
X# "scorevotes" uses "score.awk" to read and count votes from the
X# "parsedvotes" file; it can take a minute or two per thousand
X# votes.
X#
Xpushd ~/tally
Xawk -f ~/awksrc/score.awk parsedvotes > scoredvotes
Xecho "************** scorevotes done ****************"
Xpopd
END_OF_FILE
if test 278 -ne `wc -c <'bin/scorevotes'`; then
    echo shar: \"'bin/scorevotes'\" unpacked with wrong size!
fi
chmod +x 'bin/scorevotes'
# end of 'bin/scorevotes'
fi
if test -f 'bin/totalvotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/totalvotes'\"
else
echo shar: Extracting \"'bin/totalvotes'\" \(332 characters\)
sed "s/^X//" >'bin/totalvotes' <<'END_OF_FILE'
X#!/bin/csh
X#
X# "totalvotes" counts the overall votes, independent of the issue, just to
X# show how the overall reorganization is being accepted; it saves time by
X# working from the output of scorevotes.
X#
Xpushd ~/tally
Xawk -f ~/awksrc/total.awk scoredvotes > totaledvotes
Xecho "************** totalvotes done ****************"
Xpopd
END_OF_FILE
if test 332 -ne `wc -c <'bin/totalvotes'`; then
    echo shar: \"'bin/totalvotes'\" unpacked with wrong size!
fi
chmod +x 'bin/totalvotes'
# end of 'bin/totalvotes'
fi
if test -f 'bin/writeletter' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bin/writeletter'\"
else
echo shar: Extracting \"'bin/writeletter'\" \(663 characters\)
sed "s/^X//" >'bin/writeletter' <<'END_OF_FILE'
X#!/bin/csh
X#
X# "writeletter" saved the time needed to cut and paste new information
X# into an ongoing or final status letter; it assumes a format of a
X# header, the vote scores, a middle bit of text, the vote totals and
X# ballot classifications, and a signature file.  You may want to modify
X# the "sl_header", "sl_middle", and ".amigasig" file names here.
X#
Xpushd ~
Xcp sl_header scoreletter
Xcat tally/scoredvotes >> scoreletter
Xcat sl_middle >> scoreletter
Xcat tally/totaledvotes >> scoreletter
Xecho "" >> scoreletter
Xcat tally/classifiedvotes >> scoreletter
Xecho "" >> scoreletter
Xcat .amigasig >> scoreletter
Xecho "********** WRITELETTER DONE **********"
Xpopd
END_OF_FILE
if test 663 -ne `wc -c <'bin/writeletter'`; then
    echo shar: \"'bin/writeletter'\" unpacked with wrong size!
fi
chmod +x 'bin/writeletter'
# end of 'bin/writeletter'
fi
if test ! -d 'docs' ; then
    echo shar: Creating directory \"'docs'\"
    mkdir 'docs'
fi
if test -f 'docs/FILE_PURPOSES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'docs/FILE_PURPOSES'\"
else
echo shar: Extracting \"'docs/FILE_PURPOSES'\" \(9330 characters\)
sed "s/^X//" >'docs/FILE_PURPOSES' <<'END_OF_FILE'
XFILE_PURPOSES
X
XKent Paul Dolan, LCDR, USNOAA Corps, Retired.
X
XThis document may be excerpted or copied freely for any purposes.
X
XHere is the file structure assumed by the enclosed software; it is built
Xfrom the output of an ls -F, so the file names are tagged:
X
X~:          The home directory, contains:
X
Xacks/       A directory into which to store copies of the mail sent
X            from the vote account.  This is supported by a line in
X            the .mailrc file like:
X
X               set record=/usr/users/csa-vote/acks/ack-record
X
X            also useful in the .mailrc is
X
X               set asksub
X               set hold
X
X            since an amazing number of ballots arrive without a
X            subject line to be used in the acknowledgement, and you
X            don't want votes being pulled off into mbox if you have
X            to stop in mid-list for other work.
X
Xawksrc/     The awk scripts that do the brunt of the work go here.
X            See below.
X
Xballot      You'll get lots of votes that just say "I vote yes on
X            everything", and ignore your carefully crafted ballot;
X            I kept this "all 'yes'" ballot around to make it easy
X            to include a countable ballot in these votes before I
X            saved them away in ~/votes.
X
Xbin/        The shell scripts that run each other and the awk scripts
X            go here.  See below.
X
Xbounces/    You'll get lots of your acknowledgements thrown back in
X            your teeth by USENet's incredible excuse for an email
X            system; this is a place to put the ones you can't deal
X            with right away or ever.
X
Xgossip/     Despite your pleas for mail other than votes to go to
X            your personal account, you'll get lots of non-votes;
X            this is a place to save that mail away for later handling
X            or archiving.
X
Xproblems/   You'll get stuff from folks who tried to vote, but couldn't
X            quite cope with the ballot: empty letters, ballots chopped
X            off, ballots sent back unmarked, etc.  Store them here while
X            you try to get back to the authors, and as a record later of
X            why they don't show up in the final vote list.
X
Xrawballot   Lots of sites expire ballots a lot faster than voters think
X            to look for them, so you'll get a lot of "please send me a
X            ballot" requests; keep one around to stick in your reply.
X
Xscoreletter The output of "writeletter", this is what you send to your
X            proposed moderators and other friends who ask how the vote
X            is going, and at the end post to show the results; it is
X            built automatically from some canned text and the output of
X            the various vote counting scripts.
X
Xsl_header   The canned text top for scoreletter.
X
Xsl_middle   The canned text middle for scoreletter.
X
Xtally/      Here is where the various counted vote files built by the
X            scripts go.
X
Xthanks      You need some canned text to pull into your acknowledgements;
X            that's what this is.
X
X
Xvotes/      This is where the received vote email is stored, one,
X            uniquely named file per ballot.  You'll see less than
X            10% collisions if you store by userid, and I just saved
X            all the david's and mike's by extending the userid with
X            the last name and got along fine.  You can hold saving
X            and counting the votes down to about 20 keystrokes per
X            correctly formatted ballot cast if you're clever,
X            but you _must_ eyeball filter and possible edit received
X            ballots.  You'll find ballots with ">Y", "> Y", "y", and
X            lots of other stuff these scripts won't handle and you'd
X            be wasting your time to try to anticipate.  You're much
X            better off to edit what the voter said into what s/he
X            wanted.  Again, about 10% of the ballots need this step.
X            It's an unavoidable pain.
X
X~/acks:     Where your ballot acknowledgements go.
X
Xack-record  The ballot acknowledgements; don't toss them out, you'll
X            need them to make sense out of the bounce messages!  It
X            saves lots of space to keep them as one big file; mine
X            ran about 900K.  In passing, you probably want to have
X            about 5 megs of storage available for storing stuff
X            between filter runs; near the end of this reorganization
X            vote, and after filtering the ballots and the ack-record,
X            here's the damage as listed by du -s:
X
X                2805  /usr/users/csa-vote
X
X~/awksrc:      This is where the scripts go that do all the work; these
X               are all "old awk" scripts, so they should run under any
X               tattered old awk you might happen to have around.
X
Xabstain.awk    A simple script that counts the lines from "parsedvotes"
X               that contain at least one "abstain" vote, to make the
X               last part of "classifiedvotes".
X
Xclassify.awk   A simple script to reformat the intermediate
X               "classedvotes" output of classifyvotes to make the
X               first part of "classifiedvotes".
X
Xmail_filt.awk  A simple script to strip redundant or path tracing
X               lines out of email headers to save space.
X
Xparse.awk      A simple script to pull the author and vote information
X               out of a file containing a single ballot and write it as
X               a single line (onto "parsedvotes" with the help of
X               parsevotes) ready for counting.
X
Xscore.awk      A simple script to count up the votes from "parsedvotes"
X               and format them into a report "scoredvotes" of the voting
X               results.
X
Xtotal.awk      A simple script to do a summary report of the
X               "scoredvotes" data that shows how the overall
X               reorganization is faring.
X
X~/bin:         This is where the executable scripts used to count and
X               classify the votes, and to filter mail, go.  These are
X               all csh scripts; that's what I know how to do.  For
X               several of the scripts, all they do is package a change
X               to the correct directory, the call of the awk script,
X               and printing of a "done" line.
X
Xclassifyvotes* Uses fgrep several times to look for ballots cast with
X               the same vote for each proposal in "parsedvotes", counts
X               them with wc -l,  builds an intermediate file,
X               "classedvotes", using echo and this output, then uses
X               classify.awk to reformat this into a report, and
X               abstain.awk to add a line to the report counting ballots
X               with at least one "abstain" vote, to document how many
X               voters took advantage of the chance _not_ to vote on
X               items in a combined ballot.
X
Xdothevotes*    The master script for filtering and counting and
X               classifying the votes and writing the final report;
X               calls filtervotes, parsevotes, scorevotes, totalvotes,
X               classifyvotes, and writeletter, in order, all with a
X               "nice -15" to keep from dragging down system response.
X
Xfiltervotes*   Runs a mailfilter on each newly received vote to clean
X               out the header trash added by intermediate mail sites.
X
Xmailfilter*    Called by filtervotes, mailfilter filters one mail file
X               using mail_filt.awk and replaces the original file with
X               the filtered copy.  Used to save disk space (lots, ~40%).
X
Xparsevotes*    Creates an empty "parsedvotes" file, then uses parse.awk
X               to process each ballot file in turn from votes, adding
X               a line per ballot to "parsedvotes".  Long and slow.  On
X               my 900-odd ballot vote it was running 20 or 30 minutes
X               depending on other system loads (niced at -15, though).
X               That's not too startling for an interpreter processing
X               more than a megabyte of data.
X
Xscorevotes*    Given "parsedvotes", uses score.awk to count the votes
X               and write a report, "scoredvotes".
X
Xtotalvotes*    Given "scoredvotes", uses total.awk to write a report,
X               "totaledvotes", about the overall reorganization vote.
X
Xwriteletter*   I got too lazy to keep editing the report letter from
X               all the various parts, so I saved off the text as a
X               couple of files, "sl_header" and "sl_middle", and this
X               script uses cp, cat, and echo to build the letter from
X               these text file, the automatically produced reports
X               "scoredvotes", "totaledvotes", and "classifiedvotes",
X               and the special .signature built for this reorganization
X               project.
X
X~/tally:         Here is where the reports (except scoreletter) go, and
X                 the intermediate data files used to create them.
X
Xclassedvotes     An intermediate file built by classifyvotes.
X
Xclassifiedvotes  A report built by classifyvotes
X
Xparsedvotes      An intermediate file built by parsevotes, also used as
X                 the acknowledgement list, but primarily as input by the
X                 vote counting scripts.
X
Xscoredvotes      A report built by scorevotes.
X
Xtotaledvotes     A report built by totalvotes.
X
X
END_OF_FILE
if test 9330 -ne `wc -c <'docs/FILE_PURPOSES'`; then
    echo shar: \"'docs/FILE_PURPOSES'\" unpacked with wrong size!
fi
# end of 'docs/FILE_PURPOSES'
fi
if test ! -d 'examples' ; then
    echo shar: Creating directory \"'examples'\"
    mkdir 'examples'
fi
if test -f 'examples/classedvotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/classedvotes'\"
else
echo shar: Extracting \"'examples/classedvotes'\" \(66 characters\)
sed "s/^X//" >'examples/classedvotes' <<'END_OF_FILE'
Xtotal      940
Xallyes      540
Xallno        9
Xallabstain        1
END_OF_FILE
if test 66 -ne `wc -c <'examples/classedvotes'`; then
    echo shar: \"'examples/classedvotes'\" unpacked with wrong size!
fi
# end of 'examples/classedvotes'
fi
if test -f 'examples/classifiedvotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/classifiedvotes'\"
else
echo shar: Extracting \"'examples/classifiedvotes'\" \(244 characters\)
sed "s/^X//" >'examples/classifiedvotes' <<'END_OF_FILE'
XMixed       ballots:   390, or  41.49%
XAll yes     ballots:   540, or  57.45%
XAll no      ballots:     9, or   0.96%
XAll abstain ballots:     1, or   0.11%
XTotal       ballots:   940, or 100.00%
X
XBallots with at least 1 abstain  227, or 24.15%
END_OF_FILE
if test 244 -ne `wc -c <'examples/classifiedvotes'`; then
    echo shar: \"'examples/classifiedvotes'\" unpacked with wrong size!
fi
# end of 'examples/classifiedvotes'
fi
if test -f 'examples/parsedvotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/parsedvotes'\"
else
echo shar: Extracting \"'examples/parsedvotes'\" \(725 characters\)
sed "s/^X//" >'examples/parsedvotes' <<'END_OF_FILE'
XY Y Y Y Y Y Y Y Y Y Y Y Y Y 007hayp.witsvma 007HAYP.WITSVMA at f4.n494.z5.fidonet.org (007HAYP WITSVMA)
XY Y Y Y Y Y Y Y Y Y Y Y Y Y 34masrb JOHN OBERMESIK <34MASRB%CMUVM at pucc.PRINCETON.EDU>
XY Y Y Y Y Y Y Y Y Y Y Y Y Y 71571.277 "Kevin J. Northover" <71571.277 at CompuServe.COM>
XY Y Y Y Y Y Y A Y Y A A N Y 871579l 871579l at AcadiaU.CA
XY Y Y Y Y N N N Y N N N N Y 880274d 880274d at AcadiaU.CA
XY Y Y Y Y Y Y Y Y Y Y Y Y Y 880584b 880584b at AcadiaU.CA
XY Y Y Y Y Y Y Y Y Y Y Y Y A IP06106 IP06106 at PORTLAND.maine.edu
XY Y Y Y Y Y Y Y Y Y Y Y Y Y _pftaylor PFTAYLOR%cs.tcd.ie at pucc.PRINCETON.EDU
XY Y Y Y Y Y Y Y Y Y Y Y Y Y a.duncan a.duncan at trl.oz.au (Allan Duncan)
XY Y Y Y Y Y Y Y Y Y Y Y Y Y a3s67478 a3s67478%CCNYVME.BITNET at CUNYVM.CUNY.EDU
END_OF_FILE
if test 725 -ne `wc -c <'examples/parsedvotes'`; then
    echo shar: \"'examples/parsedvotes'\" unpacked with wrong size!
fi
# end of 'examples/parsedvotes'
fi
if test -f 'examples/scoredvotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/scoredvotes'\"
else
echo shar: Extracting \"'examples/scoredvotes'\" \(953 characters\)
sed "s/^X//" >'examples/scoredvotes' <<'END_OF_FILE'
Xy  870   n   57   y%  93.85%   a   13   i 0 comp.sys.amiga.misc
Xy  885   n   40   y%  95.68%   a   15   i 0 comp.sys.amiga.programmer
Xy  884   n   41   y%  95.57%   a   15   i 0 comp.sys.amiga.announce
Xy  868   n   48   y%  94.76%   a   24   i 0 comp.sys.amiga.reviews
Xy  801   n   90   y%  89.90%   a   49   i 0 comp.sys.amiga.introduction
Xy  789   n   98   y%  88.95%   a   53   i 0 comp.sys.amiga.audio
Xy  852   n   53   y%  94.14%   a   35   i 0 comp.sys.amiga.graphics
Xy  726   n  145   y%  83.35%   a   69   i 0 comp.sys.amiga.marketplace
Xy  803   n   78   y%  91.15%   a   59   i 0 comp.sys.amiga.multimedia
Xy  801   n   91   y%  89.80%   a   48   i 0 comp.sys.amiga.applications
Xy  698   n  171   y%  80.32%   a   71   i 0 comp.sys.amiga.emulations
Xy  624   n  207   y%  75.09%   a  109   i 0 comp.sys.amiga.advocacy
Xy  728   n  144   y%  83.49%   a   68   i 0 comp.sys.amiga.datacomm
Xy  845   n   48   y%  94.62%   a   47   i 0 comp.unix.amiga
END_OF_FILE
if test 953 -ne `wc -c <'examples/scoredvotes'`; then
    echo shar: \"'examples/scoredvotes'\" unpacked with wrong size!
fi
# end of 'examples/scoredvotes'
fi
if test -f 'examples/scoreletter' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/scoreletter'\"
else
echo shar: Extracting \"'examples/scoreletter'\" \(3210 characters\)
sed "s/^X//" >'examples/scoreletter' <<'END_OF_FILE'
X
XInterested folks,
X
XThe comp.sys.amiga reorganization vote is over, and all the groups
Xpassed! Many thanks to all who participated in designing the
Xreorganization, and many thanks to all who voted. We didn't make top
Xvote getter ever, but we put up a substantial showing indeed, especially
Xconsidering the (relative) lack of controversy over the reorganization.
X
XFollowing the group by group vote breakdown is a small analysis of use
Xto those trying to design a standard reorganization mechanism. I intend
Xto post the rather modest software used to analyze the vote to
Xalt.sources, for those interested in running a similar reorganization to
Xuse as a guide.
X
XThe individual votes are posted in a separate MASS ACKNOWLEDGEMENT
Xarticle, for the usual five day protest period. I will leave the task of
Xissuing the appropriate "newgroup" and "rmgroup" and alias directing
Xcontrol messages to the moderator of news.announce.newgroups, whose
Xassistance and advice in conducting this reorganization I would also
Xlike to credit here.
X
XThe task of posting to the right groups is up to the comp.sys.amiga.*
Xsubscribers, and the moderators and monitor are ready to go.  Enjoy!
XTime for the vote taker to get out of the loop.
X
Xy = yes, n = no, y% = 100*y/(y+n), a = abstain, i = invalid (data check)
X
Xy  870   n   57   y%  93.85%   a   13   i 0 comp.sys.amiga.misc
Xy  885   n   40   y%  95.68%   a   15   i 0 comp.sys.amiga.programmer
Xy  884   n   41   y%  95.57%   a   15   i 0 comp.sys.amiga.announce
Xy  868   n   48   y%  94.76%   a   24   i 0 comp.sys.amiga.reviews
Xy  801   n   90   y%  89.90%   a   49   i 0 comp.sys.amiga.introduction
Xy  789   n   98   y%  88.95%   a   53   i 0 comp.sys.amiga.audio
Xy  852   n   53   y%  94.14%   a   35   i 0 comp.sys.amiga.graphics
Xy  726   n  145   y%  83.35%   a   69   i 0 comp.sys.amiga.marketplace
Xy  803   n   78   y%  91.15%   a   59   i 0 comp.sys.amiga.multimedia
Xy  801   n   91   y%  89.80%   a   48   i 0 comp.sys.amiga.applications
Xy  698   n  171   y%  80.32%   a   71   i 0 comp.sys.amiga.emulations
Xy  624   n  207   y%  75.09%   a  109   i 0 comp.sys.amiga.advocacy
Xy  728   n  144   y%  83.49%   a   68   i 0 comp.sys.amiga.datacomm
Xy  845   n   48   y%  94.62%   a   47   i 0 comp.unix.amiga
X
XMeaningless but comforting statistics on the overall acceptance of doing
Xthis kind of a reorganization at all, and fuel for the news.groups
Xreorganization discussions:
X
XTotal yes     votes: 11174, or  84.91%
XTotal no      votes:  1311, or   9.96%
XTotal abstain votes:   675, or   5.13%
XTotal invalid votes:     0, or   0.00%
XTotal         votes: 13160, or 100.00%
X
XMixed       ballots:   390, or  41.49%
XAll yes     ballots:   540, or  57.45%
XAll no      ballots:     9, or   0.96%
XAll abstain ballots:     1, or   0.11%
XTotal       ballots:   940, or 100.00%
X
XBallots with at least 1 abstain  227, or 24.15%
X
X                                                           /// It's Amiga
X                                                          /// for me:  why
XKent, the man from xanth.                             \\\///   settle for
X<xanthian at Zorch.SF-Bay.ORG> <xanthian at well.sf.ca.us>   \XX/  anything less?
X--
XConvener, ongoing comp.sys.amiga grand reorganization.
END_OF_FILE
if test 3210 -ne `wc -c <'examples/scoreletter'`; then
    echo shar: \"'examples/scoreletter'\" unpacked with wrong size!
fi
# end of 'examples/scoreletter'
fi
if test -f 'examples/sl_header' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/sl_header'\"
else
echo shar: Extracting \"'examples/sl_header'\" \(1289 characters\)
sed "s/^X//" >'examples/sl_header' <<'END_OF_FILE'
X
XInterested folks,
X
XThe comp.sys.amiga reorganization vote is over, and all the groups
Xpassed! Many thanks to all who participated in designing the
Xreorganization, and many thanks to all who voted. We didn't make top
Xvote getter ever, but we put up a substantial showing indeed, especially
Xconsidering the (relative) lack of controversy over the reorganization.
X
XFollowing the group by group vote breakdown is a small analysis of use
Xto those trying to design a standard reorganization mechanism. I intend
Xto post the rather modest software used to analyze the vote to
Xalt.sources, for those interested in running a similar reorganization to
Xuse as a guide.
X
XThe individual votes are posted in a separate MASS ACKNOWLEDGEMENT
Xarticle, for the usual five day protest period. I will leave the task of
Xissuing the appropriate "newgroup" and "rmgroup" and alias directing
Xcontrol messages to the moderator of news.announce.newgroups, whose
Xassistance and advice in conducting this reorganization I would also
Xlike to credit here.
X
XThe task of posting to the right groups is up to the comp.sys.amiga.*
Xsubscribers, and the moderators and monitor are ready to go.  Enjoy!
XTime for the vote taker to get out of the loop.
X
Xy = yes, n = no, y% = 100*y/(y+n), a = abstain, i = invalid (data check)
X
END_OF_FILE
if test 1289 -ne `wc -c <'examples/sl_header'`; then
    echo shar: \"'examples/sl_header'\" unpacked with wrong size!
fi
# end of 'examples/sl_header'
fi
if test -f 'examples/sl_middle' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/sl_middle'\"
else
echo shar: Extracting \"'examples/sl_middle'\" \(170 characters\)
sed "s/^X//" >'examples/sl_middle' <<'END_OF_FILE'
X
XMeaningless but comforting statistics on the overall acceptance of doing
Xthis kind of a reorganization at all, and fuel for the news.groups
Xreorganization discussions:
X
END_OF_FILE
if test 170 -ne `wc -c <'examples/sl_middle'`; then
    echo shar: \"'examples/sl_middle'\" unpacked with wrong size!
fi
# end of 'examples/sl_middle'
fi
if test -f 'examples/totaledvotes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'examples/totaledvotes'\"
else
echo shar: Extracting \"'examples/totaledvotes'\" \(195 characters\)
sed "s/^X//" >'examples/totaledvotes' <<'END_OF_FILE'
XTotal yes     votes: 11174, or  84.91%
XTotal no      votes:  1311, or   9.96%
XTotal abstain votes:   675, or   5.13%
XTotal invalid votes:     0, or   0.00%
XTotal         votes: 13160, or 100.00%
END_OF_FILE
if test 195 -ne `wc -c <'examples/totaledvotes'`; then
    echo shar: \"'examples/totaledvotes'\" unpacked with wrong size!
fi
# end of 'examples/totaledvotes'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Alt.sources mailing list