Example #1
0
    def perform_tally(self, questions):
        '''
        Actually calls to openstv to perform the tally
        '''
        from openstv.ballots import Ballots
        from openstv.plugins import getMethodPlugins

        # get voting and report methods
        methods = getMethodPlugins("byName", exclude0=False)

        # generate ballots
        dirtyBallots = Ballots()
        dirtyBallots.loadKnown(self.ballots_path, exclude0=False)
        dirtyBallots.numSeats = self.num_winners
        cleanBallots = dirtyBallots.getCleanBallots()

        # create and configure election
        e = methods[self.method_name](cleanBallots)
        question = questions[self.question_num]
        e.maxChosableOptions = question['max']

        # run election and generate the report
        e.runElection()

        # generate report
        from .json_report import JsonReport
        self.report = JsonReport(e)
        self.report.generateReport()
    def perform_tally(self):
        '''
        Actually calls to openstv to perform the tally
        '''
        from openstv.ballots import Ballots
        from openstv.plugins import getMethodPlugins

        # get voting and report methods
        methods = getMethodPlugins("byName", exclude0=False)

        # generate ballots
        dirtyBallots = Ballots()
        dirtyBallots.loadKnown(self.ballots_path, exclude0=False)
        dirtyBallots.numSeats = self.num_seats
        cleanBallots = dirtyBallots.getCleanBallots()

        # create and configure election
        e = methods[self.method_name](cleanBallots)

        if self.strong_tie_break_method is not None:
            e.strongTieBreakMethod = self.strong_tie_break_method

        if self.weak_tie_break_method is not None:
            e.weakTieBreakMethod = self.weak_tie_break_method

        if self.digits_precision is not None:
            e.prec = self.digits_precision

        # run election and generate the report
        e.runElection()

        # generate report
        from .json_report import JsonReport
        self.report = JsonReport(e)
        self.report.generateReport()
Example #3
0
	def load_ballot(self, ballot):
		try:
			dirtyBallots = Ballots()
			dirtyBallots.loadKnown(bltFn, exclude0=False)
			cleanBallots = dirtyBallots.getCleanBallots()
		except RuntimeError, msg:
			print msg
Example #4
0
 def load_ballot(self, ballot):
     try:
         dirtyBallots = Ballots()
         dirtyBallots.loadKnown(bltFn, exclude0=False)
         cleanBallots = dirtyBallots.getCleanBallots()
     except RuntimeError, msg:
         print msg
Example #5
0
    def perform_tally(self):
        '''
        Actually calls to openstv to perform the tally
        '''
        from openstv.ballots import Ballots
        from openstv.plugins import getMethodPlugins

        # get voting and report methods
        methods = getMethodPlugins("byName", exclude0=False)

        # generate ballots
        dirtyBallots = Ballots()
        dirtyBallots.loadKnown(self.ballots_path, exclude0=False)
        dirtyBallots.numSeats = self.num_seats
        cleanBallots = dirtyBallots.getCleanBallots()

        # create and configure election
        e = methods[self.method_name](cleanBallots)

        # run election and generate the report
        # from celery.contrib import rdb; rdb.set_trace()
        e.runElection()

        # generate report
        from .json_report import JsonReport
        self.report = JsonReport(e)
        self.report.generateReport()
Example #6
0
    def perform_tally(self, questions):
        '''
        Actually calls to openstv to perform the tally
        '''
        from openstv.ballots import Ballots
        from openstv.plugins import getMethodPlugins

        # get voting and report methods
        methods = getMethodPlugins("byName", exclude0=False)

        # generate ballots
        dirtyBallots = Ballots()
        dirtyBallots.loadKnown(self.ballots_path, exclude0=False)
        dirtyBallots.numSeats = self.num_winners
        cleanBallots = dirtyBallots.getCleanBallots()

        # create and configure election
        e = methods[self.method_name](cleanBallots)
        question = questions[self.question_num]
        e.maxChosableOptions = question['max']

        # run election and generate the report
        e.runElection()

        # generate report
        from .json_report import JsonReport
        self.report = JsonReport(e)
        self.report.generateReport()
Example #7
0
    def perform_tally(self):
        '''
        Actually calls to openstv to perform the tally
        '''
        from openstv.ballots import Ballots
        from openstv.plugins import getMethodPlugins

        # get voting and report methods
        methods = getMethodPlugins("byName", exclude0=False)

        # generate ballots
        dirtyBallots = Ballots()
        dirtyBallots.loadKnown(self.ballots_path, exclude0=False)
        dirtyBallots.numSeats = self.num_seats
        cleanBallots = dirtyBallots.getCleanBallots()

        # create and configure election
        e = methods[self.method_name](cleanBallots)

        if self.strong_tie_break_method is not None:
            e.strongTieBreakMethod = self.strong_tie_break_method

        if self.weak_tie_break_method is not None:
            e.weakTieBreakMethod = self.weak_tie_break_method

        if self.digits_precision is not None:
            e.prec = self.digits_precision

        # run election and generate the report
        e.runElection()

        # generate report
        from .json_report import JsonReport
        self.report = JsonReport(e)
        self.report.generateReport()
    def perform_tally(self):
        '''
        Actually calls to openstv to perform the tally
        '''
        from openstv.ballots import Ballots
        from openstv.plugins import getMethodPlugins

        # get voting and report methods
        methods = getMethodPlugins("byName", exclude0=False)

        # generate ballots
        dirtyBallots = Ballots()
        dirtyBallots.loadKnown(self.ballots_path, exclude0=False)
        dirtyBallots.numSeats = self.num_winners
        cleanBallots = dirtyBallots.getCleanBallots()

        # create and configure election
        e = methods[self.method_name](cleanBallots)

        # run election and generate the report
        # from celery.contrib import rdb; rdb.set_trace()
        e.runElection()

        # generate report
        from .json_report import JsonReport
        self.report = JsonReport(e)
        self.report.generateReport()
Example #9
0
    def loadBallots(self):
        self.dirtyBallots = Ballots()
        self.dirtyBallots.exceptionQueue = Queue(1)
        loadThread = Thread(target=self.dirtyBallots.loadUnknown,
                            args=(self.filename, ))
        loadThread.start()

        # Display a progress dialog
        dlg = wx.ProgressDialog(\
          "Loading ballots",
          "Loading ballots from %s\nNumber of ballots: %d" %
          (os.path.basename(self.filename), self.dirtyBallots.numBallots),
          parent=self.frame, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
        )
        while loadThread.isAlive():
            sleep(0.1)
            dlg.Pulse("Loading ballots from %s\nNumber of ballots: %d" %
                      (os.path.basename(
                          self.filename), self.dirtyBallots.numBallots))
        dlg.Destroy()

        if not self.dirtyBallots.exceptionQueue.empty():
            raise RuntimeError(self.dirtyBallots.exceptionQueue.get())
Example #10
0
def iterate_rankings(names, votes, withdrawn_names):
        "Determine at least one winner"

        # If there's only one candidate left, return it
        if len(names) - len(withdrawn_names) == 1:
                return set(names) - set(withdrawn_names)

        ballots = Ballots()
        ballots.setAllNames(names)
        withdrawn_indices = [names.index(name) for name in withdrawn_names]
        ballots.setWithdrawn(withdrawn_indices)
        for ranking in votes:
                ballots.appendBallot(ranking)
        election = Condorcet(ballots)
        election.run()
        winning_names = [ballots.names[winner] for winner in election.winners]
        return winning_names
Example #11
0
 def loadBallots(self):
   self.dirtyBallots = Ballots()
   self.dirtyBallots.exceptionQueue = Queue(1)
   loadThread = Thread(target=self.dirtyBallots.loadUnknown, args=(self.filename,))
   loadThread.start()
   
   # Display a progress dialog
   dlg = wx.ProgressDialog(\
     "Loading ballots",
     "Loading ballots from %s\nNumber of ballots: %d" % 
     (os.path.basename(self.filename), self.dirtyBallots.numBallots),
     parent=self.frame, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
   )
   while loadThread.isAlive():
     sleep(0.1)
     dlg.Pulse("Loading ballots from %s\nNumber of ballots: %d" %
               (os.path.basename(self.filename), self.dirtyBallots.numBallots))
   dlg.Destroy()
   
   if not self.dirtyBallots.exceptionQueue.empty():
     raise RuntimeError(self.dirtyBallots.exceptionQueue.get())
Example #12
0
    def count(cls, vote, **kwargs):
        from Meeting.models import BallotEntry, Vote
        seats = kwargs.get("num_seats", 1)
        assert vote.method == Vote.STV
        ballots = Ballots()

        options = vote.option_set.all().order_by('pk')
        option_translation = {}
        names = []
        for index, option in enumerate(options):
            option_translation[option.id] = index
            names.append(option.name)
        ballots.setNames(names)
        ballots.numSeats = seats

        voter = -1
        ballot = []
        for be in BallotEntry.objects.filter(option__vote=vote).order_by('token_id', 'value').all():
            if voter != be.token_id and ballot != []:
                ballots.appendBallot(ballot)
                ballot = []
            voter = be.token_id
            ballot.append(option_translation[be.option_id])
        if ballots != []:
            ballots.appendBallot(ballot)

        electionCounter = ScottishSTV(ballots)
        electionCounter.strongTieBreakMethod = "manual"
        electionCounter.breakTieRequestQueue = Queue(1)
        electionCounter.breakTieResponseQueue = Queue(1)
        countThread = Thread(target=electionCounter.runElection)
        countThread.start()
        while countThread.isAlive():
            sleep(0.1)
            if not electionCounter.breakTieRequestQueue.empty():
                [tiedCandidates, names, what] = electionCounter.breakTieRequestQueue.get()
                c = cls.ask_user_to_break_tie(tiedCandidates, names, what, vote)
                electionCounter.breakTieResponseQueue.put(c)
            if "R" in vars(electionCounter):
                status = "Counting votes using {}\nRound: {}".format(electionCounter.longMethodName,
                                                                     electionCounter.R + 1)
            else:
                status = "Counting votes using %s\nInitializing..." % \
                         electionCounter.longMethodName
            logger.debug(status)
        logger.info(electionCounter.winners)
        vote.refresh_from_db()
        winners = []
        losers = []
        for w in electionCounter.winners:
            winners.append(ballots.names[w])
        for l in electionCounter.losers:
            losers.append(ballots.names[l])
        vote.results = "Winners: {} \nLosers:{}".format(winners, losers)
        r = YamlReport(electionCounter, outputToString=True)
        r.generateReport()
        report = "\n"
        for index, name in enumerate(ballots.names):
            report += "[{}] -> {}\n".format(index, name)
        report += r.outputFile
        vote.results += report
        vote.save()
Example #13
0
class Election():
  
  def __init__(self, frame, filename, methodClass):
    self.frame = frame
    self.filename = filename
    self.methodClass = methodClass
    self.dispWidth = 100
    self.dirtyBallots = None
    self.cleanBallots = None
    self.e = None

  def loadBallots(self):
    self.dirtyBallots = Ballots()
    self.dirtyBallots.exceptionQueue = Queue(1)
    loadThread = Thread(target=self.dirtyBallots.loadUnknown, args=(self.filename,))
    loadThread.start()
    
    # Display a progress dialog
    dlg = wx.ProgressDialog(\
      "Loading ballots",
      "Loading ballots from %s\nNumber of ballots: %d" % 
      (os.path.basename(self.filename), self.dirtyBallots.numBallots),
      parent=self.frame, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
    )
    while loadThread.isAlive():
      sleep(0.1)
      dlg.Pulse("Loading ballots from %s\nNumber of ballots: %d" %
                (os.path.basename(self.filename), self.dirtyBallots.numBallots))
    dlg.Destroy()
    
    if not self.dirtyBallots.exceptionQueue.empty():
      raise RuntimeError(self.dirtyBallots.exceptionQueue.get())

  def initializeElection(self, cleanType):

    self.cleanBallots = self.dirtyBallots.getCleanBallots(removeOvervotes=cleanType)
    self.e = self.methodClass(self.cleanBallots)
            
  def runElection(self):

    if not self.frame.breakTiesRandomly:
      self.e.strongTieBreakMethod = "manual"
    self.e.breakTieRequestQueue = Queue(1)
    self.e.breakTieResponseQueue = Queue(1)

    countThread = Thread(target=self.e.runElection)
    countThread.start()
    # Display a progress dialog
    dlg = wx.ProgressDialog(\
      "Counting votes",
      "Counting votes using %s\nInitializing..." % self.e.longMethodName,
      parent=self.frame, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
    )
    while countThread.isAlive():
      sleep(0.1)
      if not self.e.breakTieRequestQueue.empty():
        [tiedCandidates, names, what] = self.e.breakTieRequestQueue.get()
        c = self.askUserToBreakTie(tiedCandidates, names, what)
        self.e.breakTieResponseQueue.put(c)
      if "R" in vars(self.e):
        status = "Counting votes using %s\nRound: %d" % \
               (self.e.longMethodName, self.e.R+1)
      else:
        status = "Counting votes using %s\nInitializing..." % \
               self.e.longMethodName          
      dlg.Pulse(status)
    dlg.Destroy()

  def askUserToBreakTie(self, candidates, names, what):
    "Provide a window to ask the user to break a tie."
    
    instructions = """\
Tie when selecting %s.  
Break the tie by selecting a candidate or choose Cancel 
to break the tie randomly.""" % what
    dlg = wx.SingleChoiceDialog(self.frame, instructions, "Break Tie Manually",
                                names, wx.CHOICEDLG_STYLE)
    if dlg.ShowModal() == wx.ID_OK:
      selection = dlg.GetStringSelection()
      i = names.index(selection)
      return candidates[i]
    else:
      return None

  def generateReport(self, reportObj):
    reportObj.generateReport()
    
  def generateTextOutput(self, output):
    self.generateReport(TextReport(self.e, self.dispWidth, outputFile=output))

  def generateCsvOutput(self, output):
    self.generateReport(CsvReport(self.e, outputFile=output))

  def generateHtmlOutput(self, output):
    self.generateReport(HtmlReport(self.e, outputFile=output))
Example #14
0
        print "Specify method and ballot file"
    else:
        print "Too many arguments"
    print usage
    sys.exit(1)

name = args[0]
bltFn = args[1]

if name not in methodNames:
    print "Unrecognized method '%s'" % name
    print usage
    sys.exit(1)

try:
    dirtyBallots = Ballots()
    dirtyBallots.loadKnown(bltFn, exclude0=False)
    if numSeats:
        dirtyBallots.numSeats = numSeats
    cleanBallots = dirtyBallots.getCleanBallots()
except RuntimeError, msg:
    print msg
    sys.exit(1)


def doElection(reps=1):
    "run election with repeat count for profiling"
    for i in xrange(reps):
        e = methods[name](cleanBallots)
        if strongTieBreakMethod is not None:
            e.strongTieBreakMethod = strongTieBreakMethod
Example #15
0
class Election():
    def __init__(self, frame, filename, methodClass):
        self.frame = frame
        self.filename = filename
        self.methodClass = methodClass
        self.dispWidth = 100
        self.dirtyBallots = None
        self.cleanBallots = None
        self.e = None

    def loadBallots(self):
        self.dirtyBallots = Ballots()
        self.dirtyBallots.exceptionQueue = Queue(1)
        loadThread = Thread(target=self.dirtyBallots.loadUnknown,
                            args=(self.filename, ))
        loadThread.start()

        # Display a progress dialog
        dlg = wx.ProgressDialog(\
          "Loading ballots",
          "Loading ballots from %s\nNumber of ballots: %d" %
          (os.path.basename(self.filename), self.dirtyBallots.numBallots),
          parent=self.frame, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
        )
        while loadThread.isAlive():
            sleep(0.1)
            dlg.Pulse("Loading ballots from %s\nNumber of ballots: %d" %
                      (os.path.basename(
                          self.filename), self.dirtyBallots.numBallots))
        dlg.Destroy()

        if not self.dirtyBallots.exceptionQueue.empty():
            raise RuntimeError(self.dirtyBallots.exceptionQueue.get())

    def initializeElection(self, cleanType):

        self.cleanBallots = self.dirtyBallots.getCleanBallots(
            removeOvervotes=cleanType)
        self.e = self.methodClass(self.cleanBallots)

    def runElection(self):

        if not self.frame.breakTiesRandomly:
            self.e.strongTieBreakMethod = "manual"
        self.e.breakTieRequestQueue = Queue(1)
        self.e.breakTieResponseQueue = Queue(1)

        countThread = Thread(target=self.e.runElection)
        countThread.start()
        # Display a progress dialog
        dlg = wx.ProgressDialog(\
          "Counting votes",
          "Counting votes using %s\nInitializing..." % self.e.longMethodName,
          parent=self.frame, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
        )
        while countThread.isAlive():
            sleep(0.1)
            if not self.e.breakTieRequestQueue.empty():
                [tiedCandidates, names,
                 what] = self.e.breakTieRequestQueue.get()
                c = self.askUserToBreakTie(tiedCandidates, names, what)
                self.e.breakTieResponseQueue.put(c)
            if "R" in vars(self.e):
                status = "Counting votes using %s\nRound: %d" % \
                       (self.e.longMethodName, self.e.R+1)
            else:
                status = "Counting votes using %s\nInitializing..." % \
                       self.e.longMethodName
            dlg.Pulse(status)
        dlg.Destroy()

    def askUserToBreakTie(self, candidates, names, what):
        "Provide a window to ask the user to break a tie."

        instructions = """\
Tie when selecting %s.  
Break the tie by selecting a candidate or choose Cancel 
to break the tie randomly.""" % what
        dlg = wx.SingleChoiceDialog(self.frame, instructions,
                                    "Break Tie Manually", names,
                                    wx.CHOICEDLG_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            selection = dlg.GetStringSelection()
            i = names.index(selection)
            return candidates[i]
        else:
            return None

    def generateReport(self, reportObj):
        reportObj.generateReport()

    def generateTextOutput(self, output):
        self.generateReport(
            TextReport(self.e, self.dispWidth, outputFile=output))

    def generateCsvOutput(self, output):
        self.generateReport(CsvReport(self.e, outputFile=output))

    def generateHtmlOutput(self, output):
        self.generateReport(HtmlReport(self.e, outputFile=output))
Example #16
0
    print "Specify method and ballot file"
  else:
    print "Too many arguments"
  print usage
  sys.exit(1)

name = args[0]
bltFn = args[1]

if name not in methodNames:
  print "Unrecognized method '%s'" % name
  print usage
  sys.exit(1)

try:
  dirtyBallots = Ballots()
  dirtyBallots.loadKnown(bltFn, exclude0=False)
  if numSeats:
    dirtyBallots.numSeats = numSeats
  cleanBallots = dirtyBallots.getCleanBallots()
except RuntimeError, msg:
  print msg
  sys.exit(1)

def doElection(reps=1):
  "run election with repeat count for profiling"
  for i in xrange(reps):
    e = methods[name](cleanBallots)
    if strongTieBreakMethod is not None:
      e.strongTieBreakMethod = strongTieBreakMethod
    if weakTieBreakMethod is not None:
Example #17
0
  def __init__(self, parent, mode):
    wx.Frame.__init__(self, parent, -1, "Ballot File Editor")

    warnings.showwarning = self.catchWarnings

    self.MakeMenu()
    self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
    self.logfName = ""

    fn = os.path.join(getHome(), "Icons", "blt.ico")
    icon = wx.Icon(fn, wx.BITMAP_TYPE_ICO)
    self.SetIcon(icon)

    # Edit a new ballot file
    if mode == "new":

      # Create an empty ballots class instance
      self.b = Ballots()

      # Get the candidate names from the user
      dlg = CandidatesDialog(parent, self.b)
      dlg.Center()
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      dlg.Destroy()
        
    # Edit an existing ballot file
    elif mode == "old":
      dlg = wx.FileDialog(self, "Edit Ballot File",
                          style=wx.FD_OPEN|wx.FD_CHANGE_DIR)
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      fName = dlg.GetPath()
      dlg.Destroy()

      # Open the file
      try:
        self.b = Ballots()
        self.b.loadUnknown(fName)
      except RuntimeError as msg:
        wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
        self.Destroy()
        return

    else:
      assert(0)

    # Set the window title to include the filename
    fn = self.b.getFileName()
    if fn is not None:
      title = "%s - Ballot File Editor" % os.path.basename(fn)
    else:
      title = "%s - Ballot File Editor" % "New File"
    self.SetTitle(title)

    # Create a notebook with an editing page and a log page
    nb = wx.Notebook(self, -1)

    self.panel = BallotsPanel(nb, self.b)
    nb.AddPage(self.panel, "Ballots")

    self.logN = 1 # counter for display purposes
    self.log = wx.TextCtrl(nb, -1,
                           style=wx.TE_MULTILINE|wx.TE_READONLY|\
                           wx.TE_WORDWRAP|wx.FIXED)
    nb.AddPage(self.log, "Log")

    # Initialize
    if mode == "new":
      self.panel.NeedToSaveBallots = True
      self.Log("Created a new ballot file.")
    elif mode == "old":
      self.panel.NeedToSaveBallots = False
      self.Log("Loaded %d ballots from file %s." %\
               (self.b.numBallots, os.path.basename(self.b.getFileName())))
    else:
      assert(0)

    # Set up the sizer
    sizer = wx.BoxSizer()
    sizer.Add(nb, 1, wx.EXPAND, 0)
    self.SetSizer(sizer)
    sizer.Fit(self)
    sizer.SetSizeHints(self)
Example #18
0
  def __init__(self, parent, mode):
    wx.Frame.__init__(self, parent, -1, "Ballot File Editor")

    warnings.showwarning = self.catchWarnings

    self.MakeMenu()
    self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
    self.logfName = ""

    fn = os.path.join(getHome(), "Icons", "blt.ico")
    icon = wx.Icon(fn, wx.BITMAP_TYPE_ICO)
    self.SetIcon(icon)

    # Edit a new ballot file
    if mode == "new":

      # Create an empty ballots class instance
      self.b = Ballots()

      # Get the candidate names from the user
      dlg = CandidatesDialog(parent, self.b)
      dlg.Center()
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      dlg.Destroy()
        
    # Edit an existing ballot file
    elif mode == "old":
      dlg = wx.FileDialog(self, "Edit Ballot File",
                          style=wx.OPEN|wx.CHANGE_DIR)
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      fName = dlg.GetPath()
      dlg.Destroy()

      # Open the file
      try:
        self.b = Ballots()
        self.b.loadUnknown(fName)
      except RuntimeError as msg:
        wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
        self.Destroy()
        return

    else:
      assert(0)

    # Set the window title to include the filename
    fn = self.b.getFileName()
    if fn is not None:
      title = "%s - Ballot File Editor" % os.path.basename(fn)
    else:
      title = "%s - Ballot File Editor" % "New File"
    self.SetTitle(title)

    # Create a notebook with an editing page and a log page
    nb = wx.Notebook(self, -1)

    self.panel = BallotsPanel(nb, self.b)
    nb.AddPage(self.panel, "Ballots")

    self.logN = 1 # counter for display purposes
    self.log = wx.TextCtrl(nb, -1,
                           style=wx.TE_MULTILINE|wx.TE_READONLY|\
                           wx.TE_WORDWRAP|wx.FIXED)
    self.log.SetMaxLength(0)
    nb.AddPage(self.log, "Log")

    # Initialize
    if mode == "new":
      self.panel.NeedToSaveBallots = True
      self.Log("Created a new ballot file.")
    elif mode == "old":
      self.panel.NeedToSaveBallots = False
      self.Log("Loaded %d ballots from file %s." %\
               (self.b.numBallots, os.path.basename(self.b.getFileName())))
    else:
      assert(0)

    # Set up the sizer
    sizer = wx.BoxSizer()
    sizer.Add(nb, 1, wx.EXPAND, 0)
    self.SetSizer(sizer)
    sizer.Fit(self)
    sizer.SetSizeHints(self)
Example #19
0
class BFEFrame(wx.Frame):

  def __init__(self, parent, mode):
    wx.Frame.__init__(self, parent, -1, "Ballot File Editor")

    warnings.showwarning = self.catchWarnings

    self.MakeMenu()
    self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
    self.logfName = ""

    fn = os.path.join(getHome(), "Icons", "blt.ico")
    icon = wx.Icon(fn, wx.BITMAP_TYPE_ICO)
    self.SetIcon(icon)

    # Edit a new ballot file
    if mode == "new":

      # Create an empty ballots class instance
      self.b = Ballots()

      # Get the candidate names from the user
      dlg = CandidatesDialog(parent, self.b)
      dlg.Center()
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      dlg.Destroy()
        
    # Edit an existing ballot file
    elif mode == "old":
      dlg = wx.FileDialog(self, "Edit Ballot File",
                          style=wx.FD_OPEN|wx.FD_CHANGE_DIR)
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      fName = dlg.GetPath()
      dlg.Destroy()

      # Open the file
      try:
        self.b = Ballots()
        self.b.loadUnknown(fName)
      except RuntimeError as msg:
        wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
        self.Destroy()
        return

    else:
      assert(0)

    # Set the window title to include the filename
    fn = self.b.getFileName()
    if fn is not None:
      title = "%s - Ballot File Editor" % os.path.basename(fn)
    else:
      title = "%s - Ballot File Editor" % "New File"
    self.SetTitle(title)

    # Create a notebook with an editing page and a log page
    nb = wx.Notebook(self, -1)

    self.panel = BallotsPanel(nb, self.b)
    nb.AddPage(self.panel, "Ballots")

    self.logN = 1 # counter for display purposes
    self.log = wx.TextCtrl(nb, -1,
                           style=wx.TE_MULTILINE|wx.TE_READONLY|\
                           wx.TE_WORDWRAP|wx.FIXED)
    nb.AddPage(self.log, "Log")

    # Initialize
    if mode == "new":
      self.panel.NeedToSaveBallots = True
      self.Log("Created a new ballot file.")
    elif mode == "old":
      self.panel.NeedToSaveBallots = False
      self.Log("Loaded %d ballots from file %s." %\
               (self.b.numBallots, os.path.basename(self.b.getFileName())))
    else:
      assert(0)

    # Set up the sizer
    sizer = wx.BoxSizer()
    sizer.Add(nb, 1, wx.EXPAND, 0)
    self.SetSizer(sizer)
    sizer.Fit(self)
    sizer.SetSizeHints(self)
    
  def catchWarnings(self, message, category, filename, lineno):
    "Catch any warnings and display them in a dialog box."
    
    wx.MessageBox(str(message), "Warning", wx.OK|wx.ICON_INFORMATION)

  def Log(self, txt):

    # create a prompt for each new line
    prompt = "%3d: " % self.logN
    self.log.AppendText(prompt + txt + "\n")
    self.logN += 1
    
  def MakeMenu(self):

    fileMenu = wx.Menu()

    append = fileMenu.Append(-1, "A&ppend ballots from file...")
    saveBallots = fileMenu.Append(-1, "&Save ballots")
    saveBallotsAs = fileMenu.Append(-1, "Save ballots &as...")
    saveLog = fileMenu.Append(-1, "Save &log")
    saveLogAs = fileMenu.Append(-1, "Save log as...")
    exitBFE = fileMenu.Append(wx.ID_EXIT, "E&xit")

    self.Bind(wx.EVT_MENU, self.OnAppendBF, append)
    self.Bind(wx.EVT_MENU, self.OnSaveBallots, saveBallots)
    self.Bind(wx.EVT_MENU, self.OnSaveBallotsAs, saveBallotsAs)
    self.Bind(wx.EVT_MENU, self.OnSaveLog, saveLog)
    self.Bind(wx.EVT_MENU, self.OnSaveLogAs, saveLogAs)
    self.Bind(wx.EVT_MENU, self.OnExit, exitBFE)

    if wx.Platform == "__WXMAC__":
      wx.App.SetMacExitMenuItemId(wx.ID_EXIT)

    menuBar = wx.MenuBar()
    menuBar.Append(fileMenu, "&File")
    self.SetMenuBar(menuBar)

  def OnAppendBF(self, event):

    # Get the filename of the ballots to be appended
    dlg = wx.FileDialog(self, "Select Ballot File",
                        style=wx.FD_OPEN|wx.FD_CHANGE_DIR)
    if dlg.ShowModal() != wx.ID_OK:
      dlg.Destroy()
      return
    fName = dlg.GetPath()
    dlg.Destroy()

    # Attempt to append the ballots
    try:
      oldNumBallots = self.b.numBallots
      self.b.appendFile(fName)
      self.b = self.b.getCleanBallots(removeEmpty=False, removeWithdrawn=False)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
    else:
      self.Log("Appended %d ballots from file %s." %\
               (self.b.numBallots - oldNumBallots, os.path.basename(fName)))

    self.panel.NeedToSaveBallots = True
    self.panel.NeedToSaveLog = True
    self.panel.UpdatePanel()
    
  def OnSaveBallots(self, event):

    if self.b.getFileName() is None:
      self.OnSaveBallotsAs(event)
      return

    try:
      self.b.save()
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return
    self.panel.NeedToSaveBallots = False

  def OnSaveBallotsAs(self, event):

    # Ask the user to choose the filename.
    dlg = wx.FileDialog(self, "Save Ballot File",
                        style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.FD_CHANGE_DIR)
    if dlg.ShowModal() != wx.ID_OK:
      dlg.Destroy()
      return
    fName = dlg.GetPath()
    dlg.Destroy()

    # Save
    try:
      self.b.saveAs(fName)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return
    self.panel.NeedToSaveBallots = False

    # Set the window title to include the filename
    title = "%s - Ballot File Editor" % os.path.basename(fName)
    self.SetTitle(title)
    self.panel.fNameC.SetLabel(os.path.basename(fName))

  def OnSaveLog(self, event):

    if self.logfName == "":
      self.OnSaveLogAs(event)
      return

    try:
      self.log.SaveFile(self.logfName)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return

    self.panel.NeedToSaveLog = False

  def OnSaveLogAs(self, event):
    dlg = wx.FileDialog(self, "Save Log to a File",
                        style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.FD_CHANGE_DIR)
    if dlg.ShowModal() != wx.ID_OK:
      dlg.Destroy()
      return
    self.logfName = dlg.GetPath()
    dlg.Destroy()

    try:
      self.log.SaveFile(self.logfName)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return

    self.panel.NeedToSaveLog = False

  def OnExit(self, event):
    self.Close()

  def OnCloseWindow(self, event):

    # Check to see if the current ballot is empty and warn user
    if self.panel.currentBallot == []:
      txt = "The current ballot is empty.  Ok to close editor?"
      code = wx.MessageBox(txt, "Warning", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
      if code == wx.CANCEL:
        # Don't exit
        event.Veto()
        return

    # Ask user if we should save ballots.
    if self.panel.NeedToSaveBallots == True:
      if self.b.getFileName() is None:
        msg = "Do you want to save the ballots?"
      else:
        msg = "Do you want to save the ballots to %s?" % self.b.getFileName()
      saveBallots = wx.MessageBox(msg, "Warning",
                                  wx.YES_NO|wx.CANCEL|wx.ICON_INFORMATION)
      if saveBallots == wx.CANCEL:
        event.Veto() # Don't exit
        return
      elif saveBallots == wx.YES:
        self.OnSaveBallots(None) # Save ballots
      elif saveBallots == wx.NO:
        # If user is discarding ballot changes then don't ask to save the log
        self.panel.NeedToSaveLog = False

    # Ask user if we should also save the log.
    if self.panel.NeedToSaveLog == True:
      msg = "Do you want to save the log for ballot file %s?"\
            % os.path.basename(self.b.getFileName())
      saveLog = wx.MessageBox(msg, "Warning",
                                  wx.YES_NO|wx.CANCEL|wx.ICON_INFORMATION)
      if saveLog == wx.CANCEL:
        event.Veto() # Don't exit
        return
      elif saveLog == wx.YES:
        self.OnSaveLog(None) # Save log

    self.Destroy()
Example #20
0
class BFEFrame(wx.Frame):

  def __init__(self, parent, mode):
    wx.Frame.__init__(self, parent, -1, "Ballot File Editor")

    warnings.showwarning = self.catchWarnings

    self.MakeMenu()
    self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
    self.logfName = ""

    fn = os.path.join(getHome(), "Icons", "blt.ico")
    icon = wx.Icon(fn, wx.BITMAP_TYPE_ICO)
    self.SetIcon(icon)

    # Edit a new ballot file
    if mode == "new":

      # Create an empty ballots class instance
      self.b = Ballots()

      # Get the candidate names from the user
      dlg = CandidatesDialog(parent, self.b)
      dlg.Center()
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      dlg.Destroy()
        
    # Edit an existing ballot file
    elif mode == "old":
      dlg = wx.FileDialog(self, "Edit Ballot File",
                          style=wx.OPEN|wx.CHANGE_DIR)
      if dlg.ShowModal() != wx.ID_OK:
        dlg.Destroy()
        self.Destroy()
        return
      fName = dlg.GetPath()
      dlg.Destroy()

      # Open the file
      try:
        self.b = Ballots()
        self.b.loadUnknown(fName)
      except RuntimeError as msg:
        wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
        self.Destroy()
        return

    else:
      assert(0)

    # Set the window title to include the filename
    fn = self.b.getFileName()
    if fn is not None:
      title = "%s - Ballot File Editor" % os.path.basename(fn)
    else:
      title = "%s - Ballot File Editor" % "New File"
    self.SetTitle(title)

    # Create a notebook with an editing page and a log page
    nb = wx.Notebook(self, -1)

    self.panel = BallotsPanel(nb, self.b)
    nb.AddPage(self.panel, "Ballots")

    self.logN = 1 # counter for display purposes
    self.log = wx.TextCtrl(nb, -1,
                           style=wx.TE_MULTILINE|wx.TE_READONLY|\
                           wx.TE_WORDWRAP|wx.FIXED)
    self.log.SetMaxLength(0)
    nb.AddPage(self.log, "Log")

    # Initialize
    if mode == "new":
      self.panel.NeedToSaveBallots = True
      self.Log("Created a new ballot file.")
    elif mode == "old":
      self.panel.NeedToSaveBallots = False
      self.Log("Loaded %d ballots from file %s." %\
               (self.b.numBallots, os.path.basename(self.b.getFileName())))
    else:
      assert(0)

    # Set up the sizer
    sizer = wx.BoxSizer()
    sizer.Add(nb, 1, wx.EXPAND, 0)
    self.SetSizer(sizer)
    sizer.Fit(self)
    sizer.SetSizeHints(self)
    
  def catchWarnings(self, message, category, filename, lineno):
    "Catch any warnings and display them in a dialog box."
    
    wx.MessageBox(str(message), "Warning", wx.OK|wx.ICON_INFORMATION)

  def Log(self, txt):

    # create a prompt for each new line
    prompt = "%3d: " % self.logN
    self.log.AppendText(prompt + txt + "\n")
    self.logN += 1
    
  def MakeMenu(self):

    fileMenu = wx.Menu()

    append = fileMenu.Append(-1, "A&ppend ballots from file...")
    saveBallots = fileMenu.Append(-1, "&Save ballots")
    saveBallotsAs = fileMenu.Append(-1, "Save ballots &as...")
    saveLog = fileMenu.Append(-1, "Save &log")
    saveLogAs = fileMenu.Append(-1, "Save log as...")
    exitBFE = fileMenu.Append(wx.ID_EXIT, "E&xit")

    self.Bind(wx.EVT_MENU, self.OnAppendBF, append)
    self.Bind(wx.EVT_MENU, self.OnSaveBallots, saveBallots)
    self.Bind(wx.EVT_MENU, self.OnSaveBallotsAs, saveBallotsAs)
    self.Bind(wx.EVT_MENU, self.OnSaveLog, saveLog)
    self.Bind(wx.EVT_MENU, self.OnSaveLogAs, saveLogAs)
    self.Bind(wx.EVT_MENU, self.OnExit, exitBFE)

    if wx.Platform == "__WXMAC__":
      wx.App.SetMacExitMenuItemId(wx.ID_EXIT)

    menuBar = wx.MenuBar()
    menuBar.Append(fileMenu, "&File")
    self.SetMenuBar(menuBar)

  def OnAppendBF(self, event):

    # Get the filename of the ballots to be appended
    dlg = wx.FileDialog(self, "Select Ballot File",
                        style=wx.OPEN|wx.CHANGE_DIR)
    if dlg.ShowModal() != wx.ID_OK:
      dlg.Destroy()
      return
    fName = dlg.GetPath()
    dlg.Destroy()

    # Attempt to append the ballots
    try:
      oldNumBallots = self.b.numBallots
      self.b.appendFile(fName)
      self.b = self.b.getCleanBallots(removeEmpty=False, removeWithdrawn=False)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
    else:
      self.Log("Appended %d ballots from file %s." %\
               (self.b.numBallots - oldNumBallots, os.path.basename(fName)))

    self.panel.NeedToSaveBallots = True
    self.panel.NeedToSaveLog = True
    self.panel.UpdatePanel()
    
  def OnSaveBallots(self, event):

    if self.b.getFileName() is None:
      self.OnSaveBallotsAs(event)
      return

    try:
      self.b.save()
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return
    self.panel.NeedToSaveBallots = False

  def OnSaveBallotsAs(self, event):

    # Ask the user to choose the filename.
    dlg = wx.FileDialog(self, "Save Ballot File",
                        style=wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR)
    if dlg.ShowModal() != wx.ID_OK:
      dlg.Destroy()
      return
    fName = dlg.GetPath()
    dlg.Destroy()

    # Save
    try:
      self.b.saveAs(fName)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return
    self.panel.NeedToSaveBallots = False

    # Set the window title to include the filename
    title = "%s - Ballot File Editor" % os.path.basename(fName)
    self.SetTitle(title)
    self.panel.fNameC.SetLabel(os.path.basename(fName))

  def OnSaveLog(self, event):

    if self.logfName == "":
      self.OnSaveLogAs(event)
      return

    try:
      self.log.SaveFile(self.logfName)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return

    self.panel.NeedToSaveLog = False

  def OnSaveLogAs(self, event):
    dlg = wx.FileDialog(self, "Save Log to a File",
                        style=wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR)
    if dlg.ShowModal() != wx.ID_OK:
      dlg.Destroy()
      return
    self.logfName = dlg.GetPath()
    dlg.Destroy()

    try:
      self.log.SaveFile(self.logfName)
    except RuntimeError as msg:
      wx.MessageBox(str(msg), "Error", wx.OK|wx.ICON_ERROR)
      return

    self.panel.NeedToSaveLog = False

  def OnExit(self, event):
    self.Close()

  def OnCloseWindow(self, event):

    # Check to see if the current ballot is empty and warn user
    if self.panel.currentBallot == []:
      txt = "The current ballot is empty.  Ok to close editor?"
      code = wx.MessageBox(txt, "Warning", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
      if code == wx.CANCEL:
        # Don't exit
        event.Veto()
        return

    # Ask user if we should save ballots.
    if self.panel.NeedToSaveBallots == True:
      if self.b.getFileName() is None:
        msg = "Do you want to save the ballots?"
      else:
        msg = "Do you want to save the ballots to %s?" % self.b.getFileName()
      saveBallots = wx.MessageBox(msg, "Warning",
                                  wx.YES_NO|wx.CANCEL|wx.ICON_INFORMATION)
      if saveBallots == wx.CANCEL:
        event.Veto() # Don't exit
        return
      elif saveBallots == wx.YES:
        self.OnSaveBallots(None) # Save ballots
      elif saveBallots == wx.NO:
        # If user is discarding ballot changes then don't ask to save the log
        self.panel.NeedToSaveLog = False

    # Ask user if we should also save the log.
    if self.panel.NeedToSaveLog == True:
      msg = "Do you want to save the log for ballot file %s?"\
            % os.path.basename(self.b.getFileName())
      saveLog = wx.MessageBox(msg, "Warning",
                                  wx.YES_NO|wx.CANCEL|wx.ICON_INFORMATION)
      if saveLog == wx.CANCEL:
        event.Veto() # Don't exit
        return
      elif saveLog == wx.YES:
        self.OnSaveLog(None) # Save log

    self.Destroy()