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 652dcb7a02fea4dbd56d16e8b03c6104afb460b5
Author: Greg Stein <[email protected]>
AuthorDate: Mon Feb 2 23:54:02 2026 -0600

    feat: update STV tally for comma-separated votestrings and kv versioning
    
    Co-authored-by: aider (openrouter/x-ai/grok-code-fast-1) <[email protected]>
---
 v3/steve/vtypes/stv.py | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/v3/steve/vtypes/stv.py b/v3/steve/vtypes/stv.py
index f82f891..72755bb 100644
--- a/v3/steve/vtypes/stv.py
+++ b/v3/steve/vtypes/stv.py
@@ -37,30 +37,32 @@ def load_stv():
 stv_tool = load_stv()
 
 
-def tally(votestrings, kv, names=None):
-    "Run the STV tally process."
-
-    # NOTE: the NAMES parameter is usually not passed, but is available
-    # to compare operation against custom ordering of NAMES in the
-    # LABELMAP. This function takes a specific approach, which differs
-    # from historical orderings.
-
+def tally(votestrings, kv):
+    """
+    Run the STV tally process.
+    
+    votestrings: List of strings, each representing a voter's preferences as 
comma-separated labels
+                 (e.g., 'a,b,c' for votes in order of preference). Labels must 
match keys in kv['labelmap'].
+    kv: Dict containing STV configuration.
+        - 'version': Integer version of the kv format (currently 1).
+        - 'labelmap': Dict mapping single-character labels to candidate names 
(e.g., {'a': 'Alice'}).
+        - 'seats': Integer number of seats to elect.
+    """
+    
     # kv['labelmap'] should be: LABEL: NAME
     # for example: { 'a': 'John Doe', }
     labelmap = kv['labelmap']
-
+    
     seats = kv['seats']
-
-    # Remap all votestrings from a string sequence of label characters,
-    # into a sequence of NAMEs.
-    votes = [[labelmap[c] for c in v] for v in votestrings]
-
-    # NOTE: it is important that the names are sorted, to create a
-    # reproducible list of names. Callers may specify a custom ordering.
-    if names is None:
-        names = sorted(labelmap.values())
+    
+    # Remap all votestrings from comma-separated label strings into sequences 
of NAMEs.
+    # Split on commas, strip whitespace, and filter out empty parts.
+    votes = [[labelmap[label.strip()] for label in v.split(',') if 
label.strip()] for v in votestrings]
+    
+    # Use sorted names for reproducible ordering.
+    names = sorted(labelmap.values())
     results = stv_tool.run_stv(names, votes, seats)
-
+    
     human = '\n'.join(
         f'{c.name:40}{" " if c.status == stv_tool.ELECTED else " not "}elected'
         for c in results.l

Reply via email to