Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
443 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.11.9 on 2018-09-05 19:22 | ||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('agenda', '0004_auto_20180525_1552'), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterModelOptions( | ||
name='activity', | ||
options={'ordering': ['date']}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.11.9 on 2018-09-03 16:14 | ||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('elections', '0033_auto_20180717_2345'), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name='election', | ||
name='extra_info_content', | ||
field=models.TextField(blank=True, help_text='Voc\xea pode usar Markdown. <br/> <a href="http://daringfireball.net/projects/markdown/syntax" target="_blank">Markdown syntax</a> allowed, but no raw HTML. Examples: **bold**, *italic*, indent 4 spaces for a code block.', max_length=3000, null=True), | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import numpy as np | ||
from candidator.models import Position | ||
from elections.models import QuestionCategory | ||
from merepresenta.models import Candidate | ||
|
||
|
||
class MatrixBuilder(object): | ||
def __init__(self, *args, **kwargs): | ||
self.positions = Position.objects.all().order_by('id') | ||
self.candidates = Candidate.objects.filter(candidatequestioncategory__isnull=False).order_by('id') | ||
self.categories = QuestionCategory.objects.all().order_by('id') | ||
self.positions_id = self.set_index_of(self.positions) | ||
self.categories_id = self.set_index_of(self.categories) | ||
self.candidates_id = self.set_index_of(self.candidates) | ||
self.electors_categories = np.ones(self.categories.count()) | ||
self.coalicagaos_nota = self.get_coaligacao_marks() | ||
|
||
def set_index_of(self, variable): | ||
index = 0 | ||
result = {} | ||
for v in variable: | ||
result[v.id] = index | ||
index +=1 | ||
return result | ||
|
||
def get_coaligacao_marks(self): | ||
coalicagaos_nota = np.ones(len(self.candidates_id)) | ||
for c in self.candidates: | ||
index = self.candidates_id[c.id] | ||
try: | ||
mark = c.partido.coaligacao.mark | ||
coalicagaos_nota[index] = mark | ||
except: | ||
pass | ||
return coalicagaos_nota | ||
|
||
def get_positions_vector_for_category(self, cat): | ||
result = np.zeros(self.positions.count()) | ||
for topic in cat.topics.all(): | ||
i = self.positions_id[topic.right_answer.position.id] | ||
result[i] = 1 | ||
return result | ||
|
||
def get_matrix_positions_and_categories(self): | ||
r = [] | ||
for c in self.categories: | ||
r.append(self.get_positions_vector_for_category(c)) | ||
return np.vstack(r).T | ||
|
||
def get_positions_vector_for_candidate(self, cand): | ||
r = np.zeros(self.positions.count()) | ||
for p in self.positions: | ||
if cand.candidatequestioncategory_set.filter(category=p.topic.category).exists(): | ||
multiplier = 2 | ||
else: | ||
multiplier = 1 | ||
if cand.taken_positions.filter(position=p).exists(): | ||
index = self.positions_id[p.id] | ||
r[index] = 1 * multiplier | ||
return r.T | ||
|
||
def get_matrix_positions_and_candidates(self): | ||
r = [] | ||
for c in self.candidates: | ||
r.append(self.get_positions_vector_for_candidate(c)) | ||
return np.vstack(r) | ||
|
||
def get_candidates_right_positions_matrix(self): | ||
C = self.get_matrix_positions_and_candidates() | ||
P = self.get_matrix_positions_and_categories() | ||
return np.dot(C ,P) | ||
|
||
def set_electors_categories(self, categories): | ||
for c in categories: | ||
index = self.categories_id[c.id] | ||
self.electors_categories[index] = 3 | ||
|
||
def get_candidates_result(self): | ||
# Candidates right answers multiplied by 2 if she chooses | ||
# the given TEMA | ||
CPR = self.get_candidates_right_positions_matrix() | ||
return np.dot(CPR, self.electors_categories) | ||
|
||
def get_result(self): | ||
C = self.get_candidates_result() | ||
notas = self.coalicagaos_nota.T | ||
return C * notas | ||
|
||
def get_result_as_array(self): | ||
r = self.get_result() | ||
as_array = [] | ||
index = 0 | ||
for c in self.candidates: | ||
i = self.candidates_id[c.id] | ||
mark = r[i] | ||
as_array.append({'candidato': c, 'nota': mark}) | ||
return as_array |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
# coding=utf-8 | ||
from django.test import TestCase | ||
from elections.tests import VotaInteligenteTestCase | ||
from popular_proposal.models import PopularProposal, Commitment | ||
from merepresenta.models import (MeRepresentaPopularProposal, | ||
MeRepresentaCommitment, | ||
Candidate, | ||
Coaligacao, | ||
Partido, | ||
VolunteerInCandidate, | ||
CandidateQuestionCategory, | ||
LGBTQDescription, | ||
RightAnswer, | ||
QuestionCategory) | ||
from django.contrib.auth.models import User | ||
from elections.models import Election, Topic | ||
from candidator.models import Position, TakenPosition | ||
from django.utils import timezone | ||
import datetime | ||
from django.core.urlresolvers import reverse | ||
from merepresenta.voluntarios.models import VolunteerProfile | ||
from backend_candidate.models import Candidacy | ||
from django.test import override_settings | ||
import numpy as np | ||
from merepresenta.match.matrix_builder import MatrixBuilder | ||
from numpy.testing import assert_equal | ||
|
||
|
||
class QuestionCategoryVectors(TestCase): | ||
def setUp(self): | ||
super(QuestionCategoryVectors, self).setUp() | ||
self.c1 = Candidate.objects.create(name='c1', cpf='1') | ||
self.c2 = Candidate.objects.create(name='c2', cpf='2') | ||
self.c3 = Candidate.objects.create(name='c3', cpf='3') | ||
|
||
self.cat1 = QuestionCategory.objects.create(name="Pautas LGBT") | ||
topic = Topic.objects.create(label=u"Adoção de crianças por famílias LGBTs", category=self.cat1) | ||
yes = Position.objects.create(topic=topic, label=u"Sou a FAVOR da adoção de crianças por famílias LGBTs") | ||
no = Position.objects.create(topic=topic, label=u"Sou CONTRA a adoção de crianças por famílias LGBTs") | ||
RightAnswer.objects.create(topic=topic,position=yes) | ||
TakenPosition.objects.create(topic=topic, person=self.c1, position=yes) | ||
TakenPosition.objects.create(topic=topic, person=self.c2, position=no) | ||
TakenPosition.objects.create(topic=topic, person=self.c3, position=yes) | ||
CandidateQuestionCategory.objects.create(category=self.cat1, candidate=self.c1) | ||
|
||
topic2 = Topic.objects.create(label=u"é A favor?", category=self.cat1) | ||
yes2 = Position.objects.create(topic=topic2, label=u"Sou a FAVOR") | ||
no2 = Position.objects.create(topic=topic2, label=u"Sou CONTRA") | ||
RightAnswer.objects.create(topic=topic2, position=yes2) | ||
|
||
TakenPosition.objects.create(topic=topic2, person=self.c1, position=no2) | ||
TakenPosition.objects.create(topic=topic2, person=self.c2, position=yes2) | ||
TakenPosition.objects.create(topic=topic2, person=self.c3, position=yes2) | ||
|
||
self.cat2 = QuestionCategory.objects.create(name="Genero") | ||
CandidateQuestionCategory.objects.create(category=self.cat2, candidate=self.c2) | ||
topic3 = Topic.objects.create(label=u"Aborto é A favor?", category=self.cat2) | ||
yes3 = Position.objects.create(topic=topic3, label=u"Sou a FAVOR") | ||
no3 = Position.objects.create(topic=topic3, label=u"Sou CONTRA") | ||
RightAnswer.objects.create(topic=topic3, position=yes3) | ||
TakenPosition.objects.create(topic=topic3, person=self.c1, position=yes3) | ||
TakenPosition.objects.create(topic=topic3, person=self.c2, position=no3) | ||
TakenPosition.objects.create(topic=topic3, person=self.c3, position=no3) | ||
|
||
topic4 = Topic.objects.create(label=u"Monitoramento da Lei do feminicídio", category=self.cat2) | ||
yes4 = Position.objects.create(topic=topic4, label=u"Sou a FAVOR") | ||
no4 = Position.objects.create(topic=topic4, label=u"Sou CONTRA") | ||
RightAnswer.objects.create(topic=topic4, position=yes4) | ||
TakenPosition.objects.create(topic=topic4, person=self.c1, position=yes4) | ||
TakenPosition.objects.create(topic=topic4, person=self.c2, position=no4) | ||
TakenPosition.objects.create(topic=topic4, person=self.c3, position=yes4) | ||
|
||
self.cat3 = QuestionCategory.objects.create(name=u"Corrupção") | ||
CandidateQuestionCategory.objects.create(category=self.cat3, candidate=self.c3) | ||
topic5 = Topic.objects.create(label=u"Políticos serem donos de emissoras de rádio e TV", category=self.cat3) | ||
yes5 = Position.objects.create(topic=topic5, label=u"Sou a FAVOR") | ||
no5 = Position.objects.create(topic=topic5, label=u"Sou CONTRA") | ||
RightAnswer.objects.create(topic=topic5, position=no5) | ||
TakenPosition.objects.create(topic=topic5, person=self.c1, position=yes5) | ||
TakenPosition.objects.create(topic=topic5, person=self.c2, position=yes5) | ||
TakenPosition.objects.create(topic=topic5, person=self.c3, position=yes5) | ||
|
||
|
||
def test_get_positions_vector_of_categories(self): | ||
''' | ||
Aqui o que eu quero lograr é um vector de dimensiones (Nao sei falar portugues) | ||
Dx1 onde D é a quantidade de possivels respostas, asim: | ||
yes1 | 1 | | ||
no1 | 0 | | ||
yes2 | 1 | | ||
no2 | 0 | | ||
yes3 | 0 | | ||
no3 | 0 | | ||
yes4 | 0 | | ||
no4 | 0 | | ||
yes5 | 0 | | ||
no5 | 0 | | ||
Más que só tem os dados do Tema | ||
''' | ||
builder = MatrixBuilder() | ||
vector = builder.get_positions_vector_for_category(self.cat1) | ||
self.assertEquals(vector.shape, (Position.objects.count(),)) | ||
expected_vector = np.array([1,0,1,0,0,0,0,0,0,0]) | ||
|
||
assert_equal(vector, expected_vector) | ||
|
||
def test_get_matrix_of_positions_and_categories(self): | ||
builder = MatrixBuilder() | ||
matrix = builder.get_matrix_positions_and_categories() | ||
expected_mat = np.array([[1,0,1,0,0,0,0,0,0,0], | ||
[0,0,0,0,1,0,1,0,0,0], | ||
[0,0,0,0,0,0,0,0,0,1] | ||
]).T | ||
assert_equal(matrix, expected_mat) | ||
|
||
def test_get_zeros_if_not_right_answers_selected(self): | ||
builder = MatrixBuilder() | ||
vector = builder.get_positions_vector_for_category(self.cat1) | ||
RightAnswer.objects.all().delete() | ||
expected_vector = np.array([0,0,0,0,0,0,0,0,0,0]) | ||
|
||
def test_get_position_vector_respect_with_candidate(self): | ||
builder = MatrixBuilder() | ||
vector = builder.get_positions_vector_for_candidate(self.c1) | ||
expected_vector = np.array([2,0,0,2,1,0,1,0,1,0]) | ||
assert_equal(vector, expected_vector) | ||
|
||
def test_get_matrix_of_candidates_with_positions(self): | ||
builder = MatrixBuilder() | ||
matrix = builder.get_matrix_positions_and_candidates() | ||
expected_mat = np.array([[2,0,0,2,1,0,1,0,1,0], | ||
[0,1,1,0,0,2,0,2,1,0], | ||
[1,0,1,0,0,1,1,0,2,0] | ||
]) | ||
assert_equal(matrix, expected_mat) | ||
|
||
def test_get_matrix_of_candidates_and_positions_and_right_positions(self): | ||
builder = MatrixBuilder() | ||
matrix = builder.get_candidates_right_positions_matrix() | ||
self.assertEquals(matrix.shape, (3 ,3)) | ||
self.assertEquals(matrix[0][0], 2) | ||
self.assertEquals(matrix[0][1], 2) | ||
self.assertEquals(matrix[0][2], 0) | ||
|
||
def test_set_electors_categories(self): | ||
builder = MatrixBuilder() | ||
builder.set_electors_categories([self.cat1, self.cat2]) | ||
electors_choices = builder.electors_categories | ||
self.assertEquals(electors_choices.shape, (3,)) | ||
self.assertEquals(electors_choices[0], 3) | ||
self.assertEquals(electors_choices[1], 3) | ||
self.assertEquals(electors_choices[2], 1) | ||
|
||
def test_get_candidates_right_answers_vs_electors(self): | ||
builder = MatrixBuilder() | ||
builder.set_electors_categories([self.cat1, self.cat2]) | ||
r = builder.get_candidates_result() | ||
self.assertEquals(r.shape, (Candidate.objects.count(), )) | ||
|
||
def test_get_candidates_full_answer_including_partido(self): | ||
coaligacao = Coaligacao.objects.create(name=u"Coaligacao a", initials='CA', number='1234') | ||
Partido.objects.create(name=u"Partido de los trabalhadores", | ||
initials='PT', | ||
number='12345', | ||
mark=3.5, | ||
coaligacao=coaligacao) | ||
peta = Partido.objects.create(name=u"Petronila", | ||
initials='PeTa', | ||
number='1232', | ||
mark=4.5, | ||
coaligacao=coaligacao) | ||
self.c1.partido = peta | ||
self.c1.save() | ||
builder = MatrixBuilder() | ||
builder.set_electors_categories([self.cat1, self.cat2]) | ||
r = builder.get_result() | ||
self.assertEquals(r.shape, (Candidate.objects.count(), )) | ||
self.assertEquals(r[0], 48) | ||
self.assertEquals(r[1], 3) | ||
self.assertEquals(r[2], 9) | ||
|
||
def test_get_result_as_dict(self): | ||
coaligacao = Coaligacao.objects.create(name=u"Coaligacao a", initials='CA', number='1234') | ||
Partido.objects.create(name=u"Partido de los trabalhadores", | ||
initials='PT', | ||
number='12345', | ||
mark=3.5, | ||
coaligacao=coaligacao) | ||
peta = Partido.objects.create(name=u"Petronila", | ||
initials='PeTa', | ||
number='1232', | ||
mark=4.5, | ||
coaligacao=coaligacao) | ||
|
||
self.c1.partido = peta | ||
self.c1.save() | ||
builder = MatrixBuilder() | ||
builder.set_electors_categories([self.cat1, self.cat2]) | ||
r = builder.get_result_as_array() | ||
self.assertEquals(r[0]['candidato'], self.c1) | ||
self.assertEquals(r[0]['nota'], 48) | ||
self.assertEquals(r[1]['candidato'], self.c2) | ||
self.assertEquals(r[1]['nota'], 3) | ||
self.assertEquals(r[2]['candidato'], self.c3) | ||
self.assertEquals(r[2]['nota'], 9) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.11.9 on 2018-09-03 16:14 | ||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('elections', '0034_auto_20180903_1614'), | ||
('merepresenta', '0018_auto_20180830_1923'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='RightAnswer', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('position', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='candidator.Position')), | ||
('topic', models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='right_answer', to='elections.Topic')), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.11.9 on 2018-09-05 19:22 | ||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('merepresenta', '0019_rightanswer'), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name='partido', | ||
name='mark', | ||
field=models.FloatField(null=True), | ||
), | ||
] |
Oops, something went wrong.