Example #1
0
    def preCount(self):
        "QPQ pre-count"
        Iterative.preCount(self)

        QX.set_precision(self, self.prec)
        QX.set_guard(self, self.prec)

        self.R = 0  # current round
        self.numRounds = 0  # total number of rounds
        self.msg = []  # msg[r] contains text describing round r
        self.count = []  # count[r][c] is candidate c's quotient qc at round r

        for c in range(self.b.numCandidates):
            self.votes.append([])
Example #2
0
  def preCount(self):
    "QPQ pre-count"
    Iterative.preCount(self)

    QX.set_precision(self, self.prec)
    QX.set_guard(self, self.prec)

    self.R = 0           # current round
    self.numRounds = 0     # total number of rounds
    self.msg = []        # msg[r] contains text describing round r
    self.count = []      # count[r][c] is candidate c's quotient qc at round r

    for c in range(self.b.numCandidates):
      self.votes.append([])
Example #3
0
  def updateCount(self):
    "Update quotients."

    # Count contribution of all ballots (will eventually subtract active contributions)
    for i in range(self.b.numWeightedBallots):
      self.tx[self.R] += self.b.contrib[i]

    # Count number (vc) and contribution (tc) of active ballots (ranking hopeful candidates);
    # Calculate quotient for each hopeful candidate (qc=count)
    # Count total number of active ballots (va)
    # Adjust tx.
    for c in range(self.b.numCandidates):
      for i in self.votes[c]:
        self.vc[self.R][c] += QX.fix(self.b.getWeight(i))
        self.tc[self.R][c] += self.b.contrib[i]
      self.count[self.R][c] = QX.div(self.vc[self.R][c], QX.One + self.tc[self.R][c])
      self.va[self.R] += self.vc[self.R][c]
      self.tx[self.R] -= self.tc[self.R][c]

    # Calculate quota for current round
    self.thresh[self.R] = QX.div(self.va[self.R], QX.fix(1 + self.numSeats) - self.tx[self.R])
Example #4
0
    def updateWinners(self):
        "Find best winning candidate."

        desc = ""
        best = 0
        winners = set()
        self.restart = False
        for c in self.continuing:
            if QX.gt(self.count[self.R][c], best):
                winners = set([c])
                best = self.count[self.R][c]
            elif self.count[self.R][c] == best:
                winners.add(c)

        if (len(winners) != 0 and QX.gt(best, self.thresh[self.R])):
            # determine single winner
            (cWin, desc) = self.breakWeakTie(self.R, winners, "most", "winner")
            desc = self.newWinners([cWin])
            self.roundInfo[self.R]["action"] = ("surplus", [cWin])
            # distribute ballots to next choice
            for i in self.votes[cWin][:]:
                self.b.contrib[i] = self.b.getWeight(i) * QX.div(
                    QX.One, self.count[self.R][cWin])
                c = self.b.getTopChoiceFromWeightedBallot(i, self.continuing)
                if c is not None:
                    self.votes[c].append(i)
            self.votes[cWin] = []
        else:
            # if no winner, exclude one candidate
            (elimList, desc) = self.selectCandidatesToEliminate()
            self.roundInfo[self.R]["action"] = ("eliminate", elimList)
            cLose = elimList[0]
            # distribute ballots to next choice
            for i in self.votes[cLose][:]:
                c = self.b.getTopChoiceFromWeightedBallot(i, self.continuing)
                if c is not None:
                    self.votes[c].append(i)
            self.votes[cLose] = []
            self.restart = self.optRestart
        return desc
Example #5
0
  def updateWinners(self):
    "Find best winning candidate."

    desc = ""
    best = 0
    winners = set()
    self.restart = False
    for c in self.continuing:
      if QX.gt(self.count[self.R][c], best):
        winners = set([c])
        best = self.count[self.R][c]
      elif self.count[self.R][c] == best:
        winners.add(c)

    if (len(winners) != 0 and QX.gt(best, self.thresh[self.R])):
      # determine single winner
      (cWin, desc) = self.breakWeakTie(self.R, winners, "most", "winner")
      desc = self.newWinners([cWin])
      self.roundInfo[self.R]["action"] = ("surplus", [cWin])
      # distribute ballots to next choice
      for i in self.votes[cWin][:]:
        self.b.contrib[i] = self.b.getWeight(i) * QX.div(QX.One, self.count[self.R][cWin])
        c = self.b.getTopChoiceFromWeightedBallot(i, self.continuing)
        if c is not None:
          self.votes[c].append(i)
      self.votes[cWin] = []
    else:
      # if no winner, exclude one candidate
      (elimList, desc) = self.selectCandidatesToEliminate()
      self.roundInfo[self.R]["action"] = ("eliminate", elimList)
      cLose = elimList[0]
      # distribute ballots to next choice
      for i in self.votes[cLose][:]:
        c = self.b.getTopChoiceFromWeightedBallot(i, self.continuing)
        if c is not None:
          self.votes[c].append(i)
      self.votes[cLose] = []
      self.restart = self.optRestart
    return desc
Example #6
0
    def updateCount(self):
        "Update quotients."

        # Count contribution of all ballots (will eventually subtract active contributions)
        for i in xrange(self.b.numWeightedBallots):
            self.tx[self.R] += self.b.contrib[i]

        # Count number (vc) and contribution (tc) of active ballots (ranking hopeful candidates);
        # Calculate quotient for each hopeful candidate (qc=count)
        # Count total number of active ballots (va)
        # Adjust tx.
        for c in range(self.b.numCandidates):
            for i in self.votes[c]:
                self.vc[self.R][c] += QX.fix(self.b.getWeight(i))
                self.tc[self.R][c] += self.b.contrib[i]
            self.count[self.R][c] = QX.div(self.vc[self.R][c],
                                           QX.One + self.tc[self.R][c])
            self.va[self.R] += self.vc[self.R][c]
            self.tx[self.R] -= self.tc[self.R][c]

        # Calculate quota for current round
        self.thresh[self.R] = QX.div(
            self.va[self.R],
            QX.fix(1 + self.numSeats) - self.tx[self.R])
Example #7
0
  def findTiedCand(self, cList, mostfewest, function):
    "Return a list of candidates tied for first or last."

    assert(mostfewest in ["most", "fewest"])
    assert(len(cList) > 0)
    cList = list(cList)
    tiedCand = []

    # Find a candidate who is winning/losing.  He may be tied with others.
    if mostfewest == "most":
      cList.sort(key=lambda a, f=function: -f[a])
    elif mostfewest == "fewest":
      cList.sort(key=lambda a, f=function: f[a])
    top = cList[0] # first/last place candidate

    # Find the number of candidates who are tied with him.
    for c in cList:
      if QX.eq(function[c], function[top]):
        tiedCand.append(c)

    return tiedCand
Example #8
0
    def findTiedCand(self, cList, mostfewest, function):
        "Return a list of candidates tied for first or last."

        assert (mostfewest in ["most", "fewest"])
        assert (len(cList) > 0)
        cList = list(cList)
        tiedCand = []

        # Find a candidate who is winning/losing.  He may be tied with others.
        if mostfewest == "most":
            cList.sort(key=lambda a, f=function: -f[a])
        elif mostfewest == "fewest":
            cList.sort(key=lambda a, f=function: f[a])
        top = cList[0]  # first/last place candidate

        # Find the number of candidates who are tied with him.
        for c in cList:
            if QX.eq(function[c], function[top]):
                tiedCand.append(c)

        return tiedCand
Example #9
0
  def displayValue(self, value):
    "Format a value with specified precision."

    return QX.str(value)
Example #10
0
 def postCount(self):
   "Report QX stats if enabled"
   self.numRounds = self.R
   if False:
     QX.postCount(self, self.R)
Example #11
0
 def postCount(self):
     "Report QX stats if enabled"
     self.numRounds = self.R
     if False:
         QX.postCount(self, self.R)
Example #12
0
    def displayValue(self, value):
        "Format a value with specified precision."

        return QX.str(value)