<commit_before># -*- coding: utf-8 -*-
#
# This file is part of agora-tools.
# Copyright (C) 2014 <NAME> <edulix AT agoravoting DOT com>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import hashlib
import collections
from base64 import urlsafe_b64encode

from utils import apply_election_changes

def get_hash(message):
    hash = hashlib.sha256()
    hash.update(message.encode('utf-8'))
    return urlsafe_b64encode(hash.digest())

def get_question_hash(election_id, question_num):
    '''
    create the hash for a given question
    '''
    return get_hash("-".join([str(election_id), str(question_num)]))

def get_answer_hash(election_id, question_num, answer_num, answer_text):
    '''
    create the hash for a given answer
    '''
    return get_hash("-".join([str(election_id), str(question_num),
        str(answer_num), answer_text]))

def hash_question(question, election_id, question_num):
    '''
    adds a hash to the question and also all the answers
    '''
    question['hash'] = get_question_hash(election_id, question_num)
    answers = question['answers']
    for answer, j in zip(answers, range(len(answers))):
        answer['hash'] = get_answer_hash(election_id, question_num, j, answer['text'])

def change_question_max(change, election_config, **kwargs):
    '''
    changes the question max and number of winners for a given question.
    Doesn't entail a new election_id
    '''
    apply_election_changes.change_question_max(change, election_config, **kwargs)

    question_num = int(change['question_number'].strip())
    new_question_max = int(change['new_question_max'].strip())
    election_id = change['election_id'].strip()

    # add modified_sizes, which tracks the maximum and minimum allowed for
    # each ancestor, so that for example in election with id #34 we changed
    # max size from 21 to 20, then the allowed max size of a ballot in that
    # specific election will be 21 instead of 20 (so that ballots are not
    # discarded based on that)
    question = election_config['questions'][question_num]
    if 'modified_sizes' not in question:
        question['modified_sizes'] = dict()

    modified_sizes = question['modified_sizes']
    if election_id not in modified_sizes:
        modified_sizes[election_id] = [question['min'], question['max']]

    question = election_config['questions'][question_num]
    question['max'] = question['num_winners'] = new_question_max

    modified_sizes[election_id][1] = max(
        modified_sizes[election_id][1], new_question_max)


def remove_candidate(change, election_config, **kwargs):
    '''
    Removes a candidate, shifting all the other candidates. Entails a new
    election_id
    '''
    election_id = int(change['election_id'].strip())
    question_num = int(change['question_number'].strip())
    candidature_id = int(change['candidature_id'].strip())
    new_candidature_text = change['new_candidature_text'].strip()
    new_candidature_category = change['new_candidature_category'].strip()

    question = election_config['questions'][question_num]
    # create a copy to be able to remove elements in the list while looping
    answer_list_copy = question['answers'][:]
    found = False
    for answer in answer_list_copy:
        if not found and answer['id'] == candidature_id:
            # check for safety
            try:
                assert answer['text'] == new_candidature_text
            except:
                print("remove_candidate: candidate(%d) in question(%s) in election(%d) found with category = '%s' instead of '%s'" % (
                    candidature_id, question['title'], election_id, answer['text'], new_candidature_text))
                return
            try:
                assert answer['category'] == new_candidature_category
            except:
                print("remove_candidate: candidate(%d) in question(%s) in election(%d) found with text = '%s' instead of '%s'" % (
                    candidature_id, question['title'], election_id, answer['text'], new_candidature_text))
                return
            found = True
            question['answers'].remove(answer)
        elif found:
            answer['id'] = answer['id'] - 1
            answer['sort_order'] = answer['sort_order'] - 1

    if not found:
        print("remove_candidate: candidate(%d) in question(%s) in election(%d) not found" % (
            candidature_id, question['title'], election_id))

def add_candidate(change, election_config, **kwargs):
    '''
    Adds a candidate with a certain id, shifting all the existing candidates with
    ids that are equal or bigger.
    '''

    election_id = int(change['election_id'].strip())
    new_election_id = int(change['election_id'].strip())
    question_num = int(change['question_number'].strip())
    new_candidature_id = int(change['new_candidature_id'].strip())
    new_candidature_text = change['new_candidature_text'].strip()
    new_candidature_category = change['new_candidature_category'].strip()

    question = election_config['questions'][question_num]
    # create a copy to be able to remove elements in the list while looping
    answer_list_copy = question['answers'][:]
    if new_candidature_id > len(answer_list_copy):
        print("add_candidate: new_candidature_id > len(answer_list_copy) [%d > %d] in election(%d)" % (
            new_candidature_id, len(answer_list_copy), election_id))
        return

    if 'hash' in kwargs:
        answ_hash = kwargs['hash']
    else:
        answ_hash = get_answer_hash(new_election_id, question_num, new_candidature_id, new_candidature_text)<commit_msg>do not lose hash in change_position<commit_after># -*- coding: utf-8 -*-
#
# This file is part of agora-tools.
# Copyright (C) 2014 <NAME> <edulix AT agoravoting DOT com>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import hashlib
import collections
from base64 import urlsafe_b64encode

from utils import apply_election_changes

def get_hash(message):
    hash = hashlib.sha256()
    hash.update(message.encode('utf-8'))
    return urlsafe_b64encode(hash.digest())

def get_question_hash(election_id, question_num):
    '''
    create the hash for a given question
    '''
    return get_hash("-".join([str(election_id), str(question_num)]))

def get_answer_hash(election_id, question_num, answer_num, answer_text):
    '''
    create the hash for a given answer
    '''
    return get_hash("-".join([str(election_id), str(question_num),
        str(answer_num), answer_text]))

def hash_question(question, election_id, question_num):
    '''
    adds a hash to the question and also all the answers
    '''
    question['hash'] = get_question_hash(election_id, question_num)
    answers = question['answers']
    for answer, j in zip(answers, range(len(answers))):
        answer['hash'] = get_answer_hash(election_id, question_num, j, answer['text'])

def change_question_max(change, election_config, **kwargs):
    '''
    changes the question max and number of winners for a given question.
    Doesn't entail a new election_id
    '''
    apply_election_changes.change_question_max(change, election_config, **kwargs)

    question_num = int(change['question_number'].strip())
    new_question_max = int(change['new_question_max'].strip())
    election_id = change['election_id'].strip()

    # add modified_sizes, which tracks the maximum and minimum allowed for
    # each ancestor, so that for example in election with id #34 we changed
    # max size from 21 to 20, then the allowed max size of a ballot in that
    # specific election will be 21 instead of 20 (so that ballots are not
    # discarded based on that)
    question = election_config['questions'][question_num]
    if 'modified_sizes' not in question:
        question['modified_sizes'] = dict()

    modified_sizes = question['modified_sizes']
    if election_id not in modified_sizes:
        modified_sizes[election_id] = [question['min'], question['max']]

    question = election_config['questions'][question_num]
    question['max'] = question['num_winners'] = new_question_max

    modified_sizes[election_id][1] = max(
        modified_sizes[election_id][1], new_question_max)


def remove_candidate(change, election_config, **kwargs):
    '''
    Removes a candidate, shifting all the other candidates. Entails a new
    election_id
    '''
    election_id = int(change['election_id'].strip())
    question_num = int(change['question_number'].strip())
    candidature_id = int(change['candidature_id'].strip())
    new_candidature_text = change['new_candidature_text'].strip()
    new_candidature_category = change['new_candidature_category'].strip()

    question = election_config['questions'][question_num]
    # create a copy to be able to remove elements in the list while looping
    answer_list_copy = question['answers'][:]
    found = False
    for answer in answer_list_copy:
        if not found and answer['id'] == candidature_id:
            # check for safety
            try:
                assert answer['text'] == new_candidature_text
            except:
                print("remove_candidate: candidate(%d) in question(%s) in election(%d) found with category = '%s' instead of '%s'" % (
                    candidature_id, question['title'], election_id, answer['text'], new_candidature_text))
                return
            try:
                assert answer['category'] == new_candidature_category
            except:
                print("remove_candidate: candidate(%d) in question(%s) in election(%d) found with text = '%s' instead of '%s'" % (
                    candidature_id, question['title'], election_id, answer['text'], new_candidature_text))
                return
            found = True
            question['answers'].remove(answer)
        elif found:
            answer['id'] = answer['id'] - 1
            answer['sort_order'] = answer['sort_order'] - 1

    if not found:
        print("remove_candidate: candidate(%d) in question(%s) in election(%d) not found" % (
            candidature_id, question['title'], election_id))

def add_candidate(change, election_config, **kwargs):
    '''
    Adds a candidate with a certain id, shifting all the existing candidates with
    ids that are equal or bigger.
    '''

    election_id = int(change['election_id'].strip())
    new_election_id = int(change['election_id'].strip())
    question_num = int(change['question_number'].strip())
    new_candidature_id = int(change['new_candidature_id'].strip())
    new_candidature_text = change['new_candidature_text'].strip()
    new_candidature_category = change['new_candidature_category'].strip()

    question = election_config['questions'][question_num]
    # create a copy to be able to remove elements in the list while looping
    answer_list_copy = question['answers'][:]
    if new_candidature_id > len(answer_list_copy):
        print("add_candidate: new_candidature_id > len(answer_list_copy) [%d > %d] in election(%d)" % (
            new_candidature_id, len(answer_list_copy), election_id))
        return

    if 'hash' in change:
        answ_hash = change['hash']
    else:
        answ_hash = get_answer_hash(new_election_id, question_num, new_candidature_id, new_candidature_text)
{'fraction_non_alphanumeric': 0.1070567432888603, 'fraction_numerical': 0.0048223758238225365, 'mean_word_length': 3.691930618401207, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7624695', 'n_tokens_mistral': 3624, 'n_tokens_neox': 3540, 'n_words': 1054}