xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) (12/20/90)
Submitted-by: xanthian@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@Zorch.SF-Bay.ORG> <xanthian@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@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@Zorch.SF-Bay.ORG> <xanthian@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@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@pucc.PRINCETON.EDU> XY Y Y Y Y Y Y Y Y Y Y Y Y Y 71571.277 "Kevin J. Northover" <71571.277@CompuServe.COM> XY Y Y Y Y Y Y A Y Y A A N Y 871579l 871579l@AcadiaU.CA XY Y Y Y Y N N N Y N N N N Y 880274d 880274d@AcadiaU.CA XY Y Y Y Y Y Y Y Y Y Y Y Y Y 880584b 880584b@AcadiaU.CA XY Y Y Y Y Y Y Y Y Y Y Y Y A IP06106 IP06106@PORTLAND.maine.edu XY Y Y Y Y Y Y Y Y Y Y Y Y Y _pftaylor PFTAYLOR%cs.tcd.ie@pucc.PRINCETON.EDU XY Y Y Y Y Y Y Y Y Y Y Y Y Y a.duncan a.duncan@trl.oz.au (Allan Duncan) XY Y Y Y Y Y Y Y Y Y Y Y Y Y a3s67478 a3s67478%CCNYVME.BITNET@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@Zorch.SF-Bay.ORG> <xanthian@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