コード例 #1
0
        private static double CalculateListMaleQuota(MeetingElectionCandidates candidates,
                                                     PersonGender nextCandidateGender)
        {
            if (candidates.Count < 1)
            {
                return(0.5); // Division by zero protection, here and in caller
            }

            double malesTotal = 0.0;

            foreach (MeetingElectionCandidate candidate in candidates)
            {
                if (candidate.Person.Gender == PersonGender.Male)
                {
                    malesTotal += 1.0;
                }
            }

            if (nextCandidateGender == PersonGender.Male)
            {
                malesTotal += 1.0;
            }

            return(malesTotal / (candidates.Count + 1.0));
        }
コード例 #2
0
        private static void MailRawElectionResults(MeetingElection poll, SchulzeProcessor processor, bool stillOpen)
        {
            MeetingElectionCandidates candidates = processor.FinalOrder;

            Dictionary <int, bool> dropoutLookup = new Dictionary <int, bool>();

            // TODO SOMETIME: implement and populate dropouts here

            string body = "These are " + (stillOpen ? "intermediate" : "THE FINAL") + " results for the poll \"" +
                          poll.Name +
                          "\". Note that the Dist field is purely informative and not part of the Schulze ranking.\r\n\r\n";

            body += "Rank Dist Candidate\r\n";

            for (int candidateIndex = 0; candidateIndex < candidates.Count; candidateIndex++)
            {
                int distance = processor.GetCandidateDistance(candidateIndex);
                body += String.Format("{0:D3}. {1} {2}{3}\r\n", candidateIndex + 1, (distance > 0 ? distance.ToString("D4") : "----"), candidates[candidateIndex].Person.Canonical, dropoutLookup.ContainsKey(candidates[candidateIndex].PersonId) ? " [hoppat av]" : string.Empty);
            }

            int[] recipients = new int[] { 1, poll.CreatedByPersonId };   // Send to Rick too while stabilizing functionality -- remove as soon as Rick is running in any poll

            string subject = (stillOpen ? "Intermediate" : "FINAL") + " results for poll - " + poll.Name;

            foreach (int personId in recipients)
            {
                Person.FromIdentity(personId).SendNotice(
                    subject, body, Organization.PPSEid);
            }
        }
コード例 #3
0
        // Randomizes the order of candidates on the open polls.
        public static void Run()
        {
            // TODO: Foreach open poll...

            MeetingElectionCandidates candidates = MeetingElectionCandidates.ForPoll(MeetingElection.Primaries2010);

            foreach (MeetingElectionCandidate candidate in candidates)
            {
                candidate.RandomizeSortOrder();
            }
        }
コード例 #4
0
        private static int FindCandidateIndex(int candidateId, MeetingElectionCandidates list)
        {
            for (int index = 0; index < list.Count; index++)
            {
                if (list[index].Identity == candidateId)
                {
                    return(index);
                }
            }

            return(-1);
        }
コード例 #5
0
        private static int GetNextSpecificGenderCandidate(MeetingElectionCandidates candidates,
                                                          Dictionary <int, bool> takenCandidates, PersonGender desiredGender)
        {
            int index = 0;

            while (takenCandidates.ContainsKey(index) || candidates[index].Person.Gender != desiredGender)
            {
                index++; // potential out-of-range exception here, if there aren't enough candidates
            }

            return(index);
        }
コード例 #6
0
    protected void Page_Load(object sender, EventArgs e)
    {
        MeetingElectionCandidates candidates = MeetingElectionCandidates.ForPoll(MeetingElection.Primaries2010);

        string pollIdString = Request.QueryString["PollId"];

        if (!string.IsNullOrEmpty(pollIdString))
        {
            int pollId = Int32.Parse(pollIdString);
            candidates = MeetingElectionCandidates.ForPoll(MeetingElection.FromIdentity(pollId));
        }


        this.RepeaterCandidates.DataSource = candidates;
        this.RepeaterCandidates.DataBind();
    }
コード例 #7
0
    protected void Page_Load(object sender, EventArgs e)
    {
        Dictionary <int, bool> personLookup = new Dictionary <int, bool>();

        for (int pollId = 9; pollId <= 36; pollId++)
        {
            MeetingElectionCandidates candidates = MeetingElectionCandidates.ForPoll(MeetingElection.FromIdentity(pollId));

            foreach (MeetingElectionCandidate candidate in candidates)
            {
                personLookup[candidate.PersonId] = true;
            }
        }

        foreach (int personId in personLookup.Keys)
        {
            this.LiteralMailAddresses.Text += Person.FromIdentity(personId).Email + "<br/>";
        }
    }
コード例 #8
0
    public void PopulateLists(MeetingElection poll, string verificationCode)
    {
        MeetingElectionCandidates candidates = poll.Candidates;
        Dictionary <int, bool>    lookup     = new Dictionary <int, bool>();

        if (!string.IsNullOrEmpty(verificationCode))
        {
            MeetingElectionVote vote = MeetingElectionVote.FromVerificationCode(verificationCode);

            if (poll.Identity != vote.InternalPollId)
            {
                throw new ArgumentException("Verification Code does not exist or does not match Poll Identity");
            }

            int[] candidateIds = vote.SelectedCandidateIdsInOrder;

            foreach (int candidateId in candidateIds)
            {
                lookup[candidateId] = true;

                MeetingElectionCandidate candidate = MeetingElectionCandidate.FromIdentity(candidateId);

                this.ListVote.Items.Add(new RadListBoxItem(candidate.Person.Canonical,
                                                           candidate.Identity.ToString()));
            }
        }


        foreach (MeetingElectionCandidate candidate in candidates)
        {
            if (!lookup.ContainsKey(candidate.Identity))
            {
                this.ListCandidates.Items.Add(new RadListBoxItem(candidate.Person.Canonical,
                                                                 candidate.Identity.ToString()));
            }
        }

        this.ListCandidates.DataBind();
    }
コード例 #9
0
    protected void PersonCandidate_SelectedPersonChanged(object sender, EventArgs e)
    {
        Person          candidate = this.PersonCandidate.SelectedPerson;
        int             pollId    = Int32.Parse(Request.QueryString["PollId"]);
        MeetingElection poll      = MeetingElection.FromIdentity(pollId);


        this.ImageCandidatePhoto.ImageUrl = "http://data.piratpartiet.se/Handlers/DisplayPortrait.aspx?YSize=300&PersonId=" + candidate.Identity.ToString();

        this.LabelCandidateName1.Text         =
            this.LabelCandidateName2.Text     =
                this.LabelCandidateName3.Text = candidate.Canonical;

        // Already running?

        MeetingElectionCandidates candidates = poll.Candidates;
        bool alreadyCandidate = false;

        foreach (MeetingElectionCandidate testCandidate in candidates)
        {
            if (candidate.PersonId == testCandidate.PersonId)
            {
                alreadyCandidate = true;
                break;
            }
        }

        this.PanelCandidacy.Visible        = !alreadyCandidate;
        this.PanelAlreadyCandidate.Visible = alreadyCandidate;

        if (!alreadyCandidate)
        {
            this.TextBlogUrl.Text        = candidate.BlogUrl;
            this.TextBlogName.Text       = candidate.BlogName;
            this.TextPhotographer.Text   = candidate.PortraitPhotographer;
            this.TextPersonalNumber.Text = candidate.PersonalNumber;
        }
    }
コード例 #10
0
        private void AssembleFinalOrder()
        {
            Console.WriteLine("Assembling final list.");

            MeetingElectionCandidates result = new MeetingElectionCandidates();

            Dictionary<int, bool> candidateAdded = new Dictionary<int, bool>();
            int candidatesRemaining = candidateIds.Count;

            int count = 1;

            while (candidatesRemaining > 0)
            {
                Console.Write("\r - remaining: {0:D4}", candidatesRemaining);

                // Find the first nontaken candidate

                int winningCandidateIndex = 0;

                while (candidateAdded.ContainsKey(winningCandidateIndex))
                {
                    winningCandidateIndex++;
                }

                // Iterate over all linkStrength[X,*] and [*,X]; this candidate is only a winner if
                // all [X,*] are >= all [*,X].

                bool allSuperior = false;


                while (!allSuperior)
                {
                    allSuperior = true;

                    for (int compareCandidateIndex = 0; compareCandidateIndex < candidateIds.Count; compareCandidateIndex++)
                    {
                        if (candidateAdded.ContainsKey(compareCandidateIndex))
                        {
                            continue;
                        }

                        if (linkStrengthXtoY[winningCandidateIndex, compareCandidateIndex] <
                            linkStrengthXtoY[compareCandidateIndex,winningCandidateIndex])
                        {
                            // the compareCandidateIndex had a greater link strength, so jump there and take it as
                            // a new potential winner, restarting the comparison

                            winningCandidateIndex = compareCandidateIndex;
                            allSuperior = false;
                            break;
                        }
                    }
                }

                // We have the winning candidate among the not-yet-ranked candidates:

                MeetingElectionCandidate candidate = MeetingElectionCandidate.FromIdentity(candidateIds[winningCandidateIndex]);

                candidateAdded[winningCandidateIndex] = true;
                result.Add(candidate);
                candidatesRemaining--;
                count++;
            }

            FinalOrder = result;

            Console.WriteLine(", done.");
        }
コード例 #11
0
    protected void Page_Load(object sender, EventArgs e)
    {
        this.TextCandidacy.Style[HtmlTextWriterStyle.Width]     = "400px";
        this.TextEditCandidacy.Style[HtmlTextWriterStyle.Width] = "400px";

        if (!Page.IsPostBack)
        {
            MeetingElection poll = MeetingElection.Primaries2010;

            MeetingElectionCandidates candidates   = MeetingElection.Primaries2010.Candidates;
            bool thisUserIsCandidate               = false;
            MeetingElectionCandidate thisCandidate = null;

            foreach (MeetingElectionCandidate candidate in candidates)
            {
                if (candidate.PersonId == _currentUser.Identity)
                {
                    thisUserIsCandidate = true;
                    thisCandidate       = candidate;
                    break;
                }
            }

            if (!poll.RunningOpen)
            {
                this.PanelCallForCandidatesIntro.Visible  = false;
                this.PanelCallForCandidatesClosed.Visible = true;
            }
            if (!_currentUser.MemberOf(Organization.PPSE))
            {
                this.PanelNotEligible.Visible = true;
                this.PanelCandidacy.Visible   = false;
                this.PanelCandidate.Visible   = false;
            }
            else if (thisUserIsCandidate)
            {
                this.PanelCandidate.Visible     = true;
                this.PanelCandidacy.Visible     = false;
                this.PanelEditCandidacy.Visible = true;
                this.TextEditCandidacy.Text     = thisCandidate.CandidacyStatement;
            }

            this.TextPersonalNumber.Text = _currentUser.PersonalNumber;
            this.TextPhotographer.Text   = _currentUser.PortraitPhotographer;
            this.TextBlogName.Text       = _currentUser.BlogName;

            if (String.IsNullOrEmpty(_currentUser.BlogUrl))
            {
                this.TextBlogUrl.Text = "http://";
            }
            else
            {
                this.TextBlogUrl.Text = _currentUser.BlogUrl;
            }

            string tShirtSize = _currentUser.TShirtSize;

            if (!String.IsNullOrEmpty(tShirtSize))
            {
                this.DropTShirtSizes.SelectedValue = tShirtSize;
            }
        }
    }
コード例 #12
0
        private MeetingElectionCandidates GenerateBallot(MeetingElectionCandidates rawList, int candidateCount,
                                                         BallotCompositionMethod method)
        {
            MeetingElectionCandidates result          = new MeetingElectionCandidates();
            Dictionary <int, bool>    takenCandidates = new Dictionary <int, bool>();

            if (candidateCount == -1)
            {
                candidateCount = rawList.Count;
            }

            // First, cancel out the defected candidates. Expensive op, but don't care.

            for (int rawIndex = 0; rawIndex < rawList.Count; rawIndex++)
            {
                if (CandidatePersonIdDefected(rawList[rawIndex].PersonId))
                {
                    takenCandidates[rawIndex] = true;
                }
            }

            if (candidateCount == rawList.Count)
            {
                candidateCount -= takenCandidates.Count;
            }

            // Assemble list.

            while (result.Count < candidateCount)
            {
                // Add a candidate.
                //
                // Should we add a candidate from the raw list or from the quoted master list?

                int masterPosition = GetMasterListPosition(result.Count + 1, method);

                if (masterPosition > 0)
                {
                    // We should add a candidate from the master list, no quota calculations, BUT ONLY if this candidate
                    // hasn't already been added from the district list.

                    int rawListIndex = FindCandidateIndex(QuotedMasterList[masterPosition - 1].InternalPollCandidateId,
                                                          rawList);

                    if (rawListIndex >= 0 && !takenCandidates.ContainsKey(rawListIndex))
                    {
                        // The master list candidate is also on the district list, but has not been added. Add
                        // the candidate in the master list position.

                        result.Add(QuotedMasterList[masterPosition - 1]);
                        takenCandidates[rawListIndex] = true;
                        continue;
                    }

                    if (rawListIndex == -1)
                    {
                        // The master list candidate is not on the district list. Add the candidate.

                        result.Add(QuotedMasterList[masterPosition - 1]);
                        continue;
                    }

                    // Getting here, the candidate on the master position had already been placed on the list through his
                    // or her district, so fallthrough to local candidates for this master position
                }

                // Add a candidate from the local list. First, try adding the next available candidate.
                // If this puts us outside of the allowed gender quota, pick the next candidate of the
                // underrepresented gender instead.

                int nextCandidateIndex = 0;

                while (takenCandidates.ContainsKey(nextCandidateIndex))
                {
                    nextCandidateIndex++;
                }

                PersonGender candidateGender = rawList[nextCandidateIndex].Person.Gender;

                double currentMaleQuota = CalculateListMaleQuota(result, candidateGender);

                // Here, we account an extremely rare situation where the correct quota is not even obtainable, e.g.
                // for position #3 where #1 is male and #2 is female and with a quota of 40%. Either way, it will
                // fall outside of bounds (33% or 66%). If so, ignore the quota if it is not obtainable.

                PersonGender oppositeGender = (candidateGender == PersonGender.Male
                    ? PersonGender.Female
                    : PersonGender.Male);

                double alternateMaleQuota = CalculateListMaleQuota(result, oppositeGender);

                // If currentMaleQuota is outside of bounds AND the alternate quota IS inside of bounds...

                if (currentMaleQuota < GenderQuota || currentMaleQuota > (1.0 - GenderQuota))
                {
                    if (alternateMaleQuota >= GenderQuota && alternateMaleQuota <= (1.0 - GenderQuota))
                    {
                        // ...pick the alternate (underrepresented) candidate

                        try
                        {
                            nextCandidateIndex = GetNextSpecificGenderCandidate(rawList, takenCandidates,
                                                                                oppositeGender);
                        }
                        catch (ArgumentOutOfRangeException)
                        {
                            // there isn't any more candidate of the requested gender, so go with what we have
                        }
                    }
                }

                result.Add(rawList[nextCandidateIndex]);
                takenCandidates[nextCandidateIndex] = true;
            }

            return(result);
        }
コード例 #13
0
ファイル: BallotComposer.cs プロジェクト: SwarmCorp/Swarmops
        private MeetingElectionCandidates GenerateBallot (MeetingElectionCandidates rawList, int candidateCount, BallotCompositionMethod method)
        {
            MeetingElectionCandidates result = new MeetingElectionCandidates();
            Dictionary<int, bool> takenCandidates = new Dictionary<int, bool>();

            if (candidateCount == -1)
            {
                candidateCount = rawList.Count;
            }

            // First, cancel out the defected candidates. Expensive op, but don't care.

            for (int rawIndex = 0; rawIndex < rawList.Count; rawIndex++)
            {
                if (this.CandidatePersonIdDefected(rawList [rawIndex].PersonId))
                {
                    takenCandidates[rawIndex] = true;
                }
            }

            if (candidateCount == rawList.Count)
            {
                candidateCount -= takenCandidates.Count;
            }

            // Assemble list.

            while (result.Count < candidateCount)
            {
                // Add a candidate.
                //
                // Should we add a candidate from the raw list or from the quoted master list?

                int masterPosition = GetMasterListPosition (result.Count + 1, method);

                if (masterPosition > 0)
                {
                    // We should add a candidate from the master list, no quota calculations, BUT ONLY if this candidate
                    // hasn't already been added from the district list.

                    int rawListIndex = FindCandidateIndex (QuotedMasterList[masterPosition - 1].InternalPollCandidateId,
                                                     rawList);

                    if (rawListIndex >= 0 && !takenCandidates.ContainsKey(rawListIndex))
                    {
                        // The master list candidate is also on the district list, but has not been added. Add
                        // the candidate in the master list position.

                        result.Add(QuotedMasterList[masterPosition - 1]);
                        takenCandidates[rawListIndex] = true;
                        continue;
                    }

                    if (rawListIndex == -1)
                    {
                        // The master list candidate is not on the district list. Add the candidate.

                        result.Add(QuotedMasterList[masterPosition - 1]);
                        continue;
                    }

                    // Getting here, the candidate on the master position had already been placed on the list through his
                    // or her district, so fallthrough to local candidates for this master position
                }

                // Add a candidate from the local list. First, try adding the next available candidate.
                // If this puts us outside of the allowed gender quota, pick the next candidate of the 
                // underrepresented gender instead.

                int nextCandidateIndex = 0;

                while (takenCandidates.ContainsKey(nextCandidateIndex))
                {
                    nextCandidateIndex++;
                }

                PersonGender candidateGender = rawList[nextCandidateIndex].Person.Gender;

                double currentMaleQuota = CalculateListMaleQuota(result, candidateGender);

                // Here, we account an extremely rare situation where the correct quota is not even obtainable, e.g. 
                // for position #3 where #1 is male and #2 is female and with a quota of 40%. Either way, it will
                // fall outside of bounds (33% or 66%). If so, ignore the quota if it is not obtainable.

                PersonGender oppositeGender = (candidateGender == PersonGender.Male
                                                   ? PersonGender.Female
                                                   : PersonGender.Male);

                double alternateMaleQuota = CalculateListMaleQuota(result, oppositeGender);

                // If currentMaleQuota is outside of bounds AND the alternate quota IS inside of bounds...

                if (currentMaleQuota < GenderQuota || currentMaleQuota > (1.0 - GenderQuota))
                {
                    if (alternateMaleQuota >= GenderQuota && alternateMaleQuota <= (1.0 - GenderQuota))
                    {
                        // ...pick the alternate (underrepresented) candidate

                        try
                        {
                            nextCandidateIndex = GetNextSpecificGenderCandidate(rawList, takenCandidates, oppositeGender);
                        }
                        catch (ArgumentOutOfRangeException)
                        {
                            // there isn't any more candidate of the requested gender, so go with what we have
                        }
                    }
                }

                result.Add(rawList[nextCandidateIndex]);
                takenCandidates[nextCandidateIndex] = true;
                
            }

            return result;
        }
コード例 #14
0
ファイル: BallotComposer.cs プロジェクト: SwarmCorp/Swarmops
        private static int FindCandidateIndex (int candidateId, MeetingElectionCandidates list)
        {
            for (int index = 0; index < list.Count; index++)
            {
                if (list [index].Identity == candidateId)
                {
                    return index;
                }
            }

            return -1;
        }
コード例 #15
0
ファイル: SchulzeProcessor.cs プロジェクト: mikran/Swarmops
        private void AssembleFinalOrder()
        {
            Console.WriteLine("Assembling final list.");

            MeetingElectionCandidates result = new MeetingElectionCandidates();

            Dictionary <int, bool> candidateAdded = new Dictionary <int, bool>();
            int candidatesRemaining = this.candidateIds.Count;

            int count = 1;

            while (candidatesRemaining > 0)
            {
                Console.Write("\r - remaining: {0:D4}", candidatesRemaining);

                // Find the first nontaken candidate

                int winningCandidateIndex = 0;

                while (candidateAdded.ContainsKey(winningCandidateIndex))
                {
                    winningCandidateIndex++;
                }

                // Iterate over all linkStrength[X,*] and [*,X]; this candidate is only a winner if
                // all [X,*] are >= all [*,X].

                bool allSuperior = false;


                while (!allSuperior)
                {
                    allSuperior = true;

                    for (int compareCandidateIndex = 0;
                         compareCandidateIndex < this.candidateIds.Count;
                         compareCandidateIndex++)
                    {
                        if (candidateAdded.ContainsKey(compareCandidateIndex))
                        {
                            continue;
                        }

                        if (this.linkStrengthXtoY[winningCandidateIndex, compareCandidateIndex] <
                            this.linkStrengthXtoY[compareCandidateIndex, winningCandidateIndex])
                        {
                            // the compareCandidateIndex had a greater link strength, so jump there and take it as
                            // a new potential winner, restarting the comparison

                            winningCandidateIndex = compareCandidateIndex;
                            allSuperior           = false;
                            break;
                        }
                    }
                }

                // We have the winning candidate among the not-yet-ranked candidates:

                MeetingElectionCandidate candidate =
                    MeetingElectionCandidate.FromIdentity(this.candidateIds[winningCandidateIndex]);

                candidateAdded[winningCandidateIndex] = true;
                result.Add(candidate);
                candidatesRemaining--;
                count++;
            }

            FinalOrder = result;

            Console.WriteLine(", done.");
        }
コード例 #16
0
ファイル: BallotComposer.cs プロジェクト: SwarmCorp/Swarmops
        private static double CalculateListMaleQuota (MeetingElectionCandidates candidates, PersonGender nextCandidateGender)
        {
            if (candidates.Count < 1)
            {
                return 0.5; // Division by zero protection, here and in caller
            }

            double malesTotal = 0.0;

            foreach (MeetingElectionCandidate candidate in candidates)
            {
                if (candidate.Person.Gender == PersonGender.Male)
                {
                    malesTotal += 1.0;
                }
            }

            if (nextCandidateGender == PersonGender.Male)
            {
                malesTotal += 1.0;
            }

            return malesTotal/(candidates.Count + 1.0);
        }
コード例 #17
0
ファイル: AddBallot.aspx.cs プロジェクト: osoftware/Swarmops
    protected void ButtonAdd_Click(object sender, EventArgs e)
    {
        Organization org        = Organization.PPSE;
        Geography    geo        = this.DropGeographies.SelectedGeography;
        Election     election   = Election.September2010;
        string       ballotName = this.TextName.Text;
        MeetingElectionCandidates candidates =
            MeetingElection.FromIdentity(Int32.Parse(this.DropPolls.SelectedValue)).Candidates;

        Ballot ballot = Ballot.Create(election, org, geo, ballotName, 0, string.Empty);

        Dictionary <string, int> nameLookup = new Dictionary <string, int>();

        foreach (MeetingElectionCandidate candidate in candidates)
        {
            nameLookup[candidate.Person.Name.ToLowerInvariant()] = candidate.PersonId;
        }

        string[] candidateNames = this.TextCandidates.Text.Split('\r', '\n');

        foreach (string candidateNameSource in candidateNames)
        {
            int personId = 0;

            int idStartIndex = candidateNameSource.LastIndexOf("(#");

            if (idStartIndex > 0)
            {
                string identityString = candidateNameSource.Substring(idStartIndex + 2);
                int    idEndIndex     = identityString.IndexOf(")");

                identityString = identityString.Substring(0, idEndIndex);

                personId = Int32.Parse(identityString);
            }

            if (personId == 0)
            {
                // Derive from name

                string candidateName = candidateNameSource;
                int    parenIndex    = candidateName.IndexOfAny(new char[] { '(', ',' });
                if (parenIndex >= 0)
                {
                    candidateName = candidateName.Substring(0, parenIndex);
                }
                candidateName = candidateName.ToLowerInvariant().Trim();

                if (candidateName.Length < 1)
                {
                    continue;
                }

                personId = nameLookup[candidateName];
            }

            ballot.AddCandidate(Person.FromIdentity(personId));
        }

        Page.ClientScript.RegisterStartupScript(typeof(Page), "OkMessage", @"alert ('Valsedel #" + ballot.Identity + " registrerades.');", true);
    }
コード例 #18
0
ファイル: BallotComposer.cs プロジェクト: SwarmCorp/Swarmops
        private static int GetNextSpecificGenderCandidate (MeetingElectionCandidates candidates, 
            Dictionary<int,bool> takenCandidates, PersonGender desiredGender)
        {
            int index = 0;

            while (takenCandidates.ContainsKey(index) || candidates [index].Person.Gender != desiredGender)
            {
                index++;  // potential out-of-range exception here, if there aren't enough candidates
            }

            return index;
        }