This is an automated email from the ASF dual-hosted git repository.

gstein pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/steve.git

commit 174aca193bad4ae6cf09c8b1b81294f8fbc8fefa
Author: Greg Stein <[email protected]>
AuthorDate: Tue Mar 3 22:33:14 2026 -0600

    Read/process v3 result files in the stv_tool.py.
---
 monitoring/stv_tool.py | 59 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 21 deletions(-)

diff --git a/monitoring/stv_tool.py b/monitoring/stv_tool.py
index e25b130..5340cf9 100755
--- a/monitoring/stv_tool.py
+++ b/monitoring/stv_tool.py
@@ -123,14 +123,14 @@ def read_votefile(fname, newformat):
   return list(votes.values())
 
 
-def read_jsonvotes(fname):
-  "Return a list of votestrings."
+def process_jsonvotes(votestrings):
+  "Return a list (each voter) of ordered lists of vote-labels."
 
   votes = [ ]
-  for v in json.load(open(fname))['votes'].values():
+  for v in votestrings:
     # Ignore the "null" votes, for STV purposes.
     if (vote := v['vote']) != '-':
-      votes.append(vote)
+      votes.append(vote.lower().split())
   return votes
 
 
@@ -486,26 +486,43 @@ def main(argv):
     parser.print_help()
     sys.exit(1)
 
-  # Get mapping from vote label (typically "a" to "z") to human name.
-  labelmap = read_nominees(args.raw_file)
+  if args.raw_file.endswith('.json'):
+    jvalue = json.load(open(args.raw_file))
+  else:
+    jvalue = None
 
-  # Construct a label-sorted list of names from the labelmap.
-  names = [name for _, name in sorted(labelmap.items())]
+  if jvalue and 'candidates' in jvalue:
+    # This is a modern (v3 starting in 2026) vote-results.json file.
+    # It contains everything we need.
+    labelmap = jvalue['labelmap']
+
+    votes_by_label = jvalue['votestrings']
+    votes = [[labelmap[l] for l in vote.split(',')] for vote in votes_by_label]
 
-  # Turn votes using labels into by-name.
-  if args.raw_file.endswith('.json'):
-    ### noted on 2025-03-06:
-    ### this appears totally broken. The prior-year raw JSON files have
-    ### labels such as "AK" and "AB", yet the labels extracted from
-    ### board_nominations.ini uses labels like "k" and "b".
-    ### QUESTION: do new .json files have a mapping in them? eg. who is "AK"?
-    votes_by_label = read_jsonvotes(args.raw_file)
-    votes = [[labelmap[l.lower()] for l in vote.split()] for vote in 
votes_by_label]
   else:
-    newformat = (len(next(iter(labelmap))) > 1)  # keys like "a" or "aa"?
-    # votes_by_label: [ [L1, L2, ...], [ L1, L2, ... ], ... ]
-    votes_by_label = read_votefile(args.raw_file, newformat)
-    votes = [[labelmap[label] for label in votelist] for votelist in 
votes_by_label]
+    # Older styles of vote records.
+
+    # Get mapping from vote label (typically "a" to "z") to human name.
+    labelmap = read_nominees(args.raw_file)
+    print('LABELMAP:', labelmap)
+
+    # Turn votes using labels into by-name.
+    if jvalue:
+      ### noted on 2025-03-06:
+      ### this appears totally broken. The prior-year raw JSON files have
+      ### labels such as "AK" and "AB", yet the labels extracted from
+      ### board_nominations.ini uses labels like "k" and "b".
+      ### QUESTION: do new .json files have a mapping in them? eg. who is "AK"?
+      votes_by_label = process_jsonvotes(jvalue['votes'].values())
+      votes = [[labelmap[l] for l in votelist] for votelist in votes_by_label]
+    else:
+      newformat = (len(next(iter(labelmap))) > 1)  # keys like "a" or "aa"?
+      # votes_by_label: [ [L1, L2, ...], [ L1, L2, ... ], ... ]
+      votes_by_label = read_votefile(args.raw_file, newformat)
+      votes = [[labelmap[label] for label in votelist] for votelist in 
votes_by_label]
+
+  # Construct a label-sorted list of names from the labelmap.
+  names = [name for _, name in sorted(labelmap.items())]
 
   candidates = run_stv(names, votes, args.seats)
   candidates.print_results()

Reply via email to