Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arreglando el matcher #1100

Merged
merged 1 commit into from Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 37 additions & 0 deletions merepresenta/dicts_and_lists_for_ordering.py
@@ -0,0 +1,37 @@
partidos_mix = {"AVANTE": 0,
"PP": 1,
"PHS": 2,
"PSC": 3,
"PR": 4,
"True": 5,
"PT": 6,
"REDE": 7,
"PTC": 8,
"PMB": 9,
"PDT": 10,
"PPS": 11,
"PROS": 12,
"PSB": 13,
"PV": 14,
"PATRI": 15,
"PODE": 16,
"PSL": 17,
"DC": 18,
"SOLIDARIEDADE": 19,
"PSDB": 20,
"PTB": 21,
"PRB": 22,
"MDB": 23,
"PRTB": 24,
"PRP": 25,
"DEM": 26,
"PMN": 27,
"PC do B": 28,
"PCB": 29,
"PPL": 30,
"PSTU": 31,
"PCO": 32,
"PSD": 33,
"PSOL": 34,
"NOVO": 35}

4 changes: 4 additions & 0 deletions merepresenta/management/commands/set_match_cache.py
Expand Up @@ -5,6 +5,8 @@
from popular_proposal.models import PopularProposal
from popular_proposal.replicator import Replicator
from merepresenta.tse_processor import TSEProcessor
from django.core.cache import cache


class Command(BaseCommand):
help = u'Carga caché del match de merepresenta, esto es para que el match no toque la DB'
Expand All @@ -15,6 +17,8 @@ def add_arguments(self, parser):
def handle(self, *args, **options):
time = options['time'][0]
builder = MatrixBuilder(time=time)
cache.set(builder.cache_key, None)
cache.set(builder.cache_key_candidates_right_positions, None)
r = builder.get_candidates_result()
shape = r.shape
self.stdout.write("Saved matrix of %d candidates with answers, for %d minutes" % (shape[0], time/60))
37 changes: 25 additions & 12 deletions merepresenta/match/matrix_builder.py
Expand Up @@ -6,11 +6,12 @@


class MatrixBuilder(object):

cache_key_candidates_right_positions = 'candidates_right_positions'
cache_key = 'merepresenta_matrix_builder_setup_'
def __init__(self, *args, **kwargs):
cache_key = '____merepresenta_matrix_builder_setup_'

self.cache_time = kwargs.pop('time', 6000)
if cache.get(cache_key) is None:
if cache.get(self.cache_key) is None:
positions = Position.objects.all().order_by('id')
candidates = Candidate.objects.filter(candidatequestioncategory__isnull=False).order_by('id').distinct()
categories = QuestionCategory.objects.all().order_by('id')
Expand All @@ -20,6 +21,7 @@ def __init__(self, *args, **kwargs):
electors_categories = np.ones(categories.count())
coalicagaos_nota = self.get_coaligacao_marks(candidates_id, candidates)
candidates_dict = self.get_candidates_dict(candidates)
desprivilegios = self.get_desprivilegios(candidates)
all_ = (positions,
candidates,
categories,
Expand All @@ -28,19 +30,29 @@ def __init__(self, *args, **kwargs):
candidates_id,
electors_categories,
coalicagaos_nota,
candidates_dict)
cache.set(cache_key, all_, self.cache_time)
candidates_dict,
desprivilegios
)
cache.set(self.cache_key, all_, self.cache_time)
else:
all_ = cache.get(cache_key)
all_ = cache.get(self.cache_key)

self.positions, self.candidates, self.categories, self.positions_id, self.categories_id, self.candidates_id, self.electors_categories, self.coalicagaos_nota, self.candidates_dict = all_
self.positions, self.candidates, self.categories, self.positions_id, self.categories_id, self.candidates_id, self.electors_categories, self.coalicagaos_nota, self.candidates_dict, self.desprivilegios = all_

def get_candidates_dict(self, candidates):
candidates_dict = {}
for c in candidates:
candidates_dict[c.id] = c.as_dict()
return candidates_dict

def get_desprivilegios(self, candidates):
r = np.zeros(len(candidates))
counter = 0
for c in candidates:
r[counter] = c.desprivilegio
counter += 1
return r

def set_index_of(self, variable):
index = 0
result = {}
Expand Down Expand Up @@ -105,13 +117,14 @@ def set_electors_categories(self, categories):
def get_candidates_result(self):
# Candidates right answers multiplied by 2 if she chooses
# the given TEMA
cache_key = '____candidates_right_positions_'
if cache.get(cache_key) is None:
if cache.get(self.cache_key_candidates_right_positions) is None:
CPR = self.get_candidates_right_positions_matrix()
cache.set(cache_key, CPR, self.cache_time)
cache.set(self.cache_key_candidates_right_positions, CPR, self.cache_time)
else:
CPR = cache.get(cache_key)
return np.dot(CPR, self.electors_categories)
CPR = cache.get(self.cache_key_candidates_right_positions)
result = np.dot(CPR, self.electors_categories)
result = result + self.desprivilegios
return result

def get_result(self):
C = self.get_candidates_result()
Expand Down
22 changes: 14 additions & 8 deletions merepresenta/match/tests/match_tests.py
Expand Up @@ -28,8 +28,8 @@

class MeRepresentaMatchBase(object):
def set_data(self):
self.c1 = Candidate.objects.create(name='c1', cpf='1')
self.c2 = Candidate.objects.create(name='c2', cpf='2')
self.c1 = Candidate.objects.create(name='c1', cpf='1', gender="F")
self.c2 = Candidate.objects.create(name='c2', cpf='2', parda=True)
self.c3 = Candidate.objects.create(name='c3', cpf='3')

self.cat1 = QuestionCategory.objects.create(name="Pautas LGBT")
Expand Down Expand Up @@ -131,6 +131,12 @@ def test_get_position_vector_respect_with_candidate(self):
expected_vector = np.array([2,0,0,2,1,0,1,0,1,0])
assert_equal(vector, expected_vector)

def test_get_desprivilegios_vector(self):
builder = MatrixBuilder()
v = builder.get_desprivilegios(Candidate.objects.all())
self.assertEquals(v.shape, (Candidate.objects.count(), ))
self.assertTrue(v[0])

def test_get_matrix_of_candidates_with_positions(self):
builder = MatrixBuilder()
matrix = builder.get_matrix_positions_and_candidates()
Expand Down Expand Up @@ -181,9 +187,9 @@ def test_get_candidates_full_answer_including_partido(self):
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)
self.assertEquals(r[0], 56)
self.assertEquals(r[1], 4)
self.assertEquals(r[2], 10)

def test_get_result_as_dict(self):
coaligacao = Coaligacao.objects.create(name=u"Coaligacao a", initials='CA', number='1234')
Expand All @@ -204,8 +210,8 @@ def test_get_result_as_dict(self):
builder.set_electors_categories([self.cat1, self.cat2])
r = builder.get_result_as_array()
self.assertEquals(r[0]['id'], self.c1.id)
self.assertEquals(r[0]['nota'], 48)
self.assertEquals(r[0]['nota'], 56)
self.assertEquals(r[1]['id'], self.c2.id)
self.assertEquals(r[1]['nota'], 3)
self.assertEquals(r[1]['nota'], 4)
self.assertEquals(r[2]['id'], self.c3.id)
self.assertEquals(r[2]['nota'], 9)
self.assertEquals(r[2]['nota'], 10)
21 changes: 19 additions & 2 deletions merepresenta/match/tests/views_and_forms_tests.py
Expand Up @@ -31,6 +31,23 @@ def test_get_post(self):
data = {'categories': [self.cat1.id, self.cat2.id]}
response = self.client.post(url, data=data)
self.assertEquals(response.status_code, 200)
candidatos = response.context['candidatos']
c_as_dict = json.dumps(candidatos)
self.assertTemplateUsed(response, 'match/paso2_explicacion_pautas.html')
self.assertIn(self.cat1, response.context['categories'])
self.assertIn(self.cat2, response.context['categories'])
self.assertIsInstance(response.context['form'], QuestionsCategoryForm)

def test_post_get_result(self):
url = reverse('match_result')
data = {'categories': [self.cat1.id, self.cat2.id]}
response = self.client.post(url, data=data)
self.assertEquals(response.status_code, 200)
self.assertTemplateUsed(response, 'match/resultado_ajax.html')
self.assertIn(self.cat1, response.context['categories'])
self.assertIn(self.cat2, response.context['categories'])

def test_post_ajax_result(self):
url = reverse('match_result_ajax')
data = {'categories[]': [self.cat1.id, self.cat2.id]}
response = self.client.post(url, data=data)
c_as_dict = json.dumps(response.content)
self.assertTrue(c_as_dict)
35 changes: 28 additions & 7 deletions merepresenta/match/views.py
@@ -1,19 +1,40 @@
from django.views.generic.edit import FormView
from django.http import JsonResponse
from django.views import View
from merepresenta.match.forms import QuestionsCategoryForm
from merepresenta.models import QuestionCategory
from django.shortcuts import render
from merepresenta.match.matrix_builder import MatrixBuilder
import json


class MatchView(FormView):
template_name = 'match/pergunta.html'
class MatchQuestionCategoryBase(FormView):
form_class = QuestionsCategoryForm

def form_valid(self, form):
builder = MatrixBuilder()
# builder = MatrixBuilder()
categories = form.cleaned_data['categories']
# builder.set_electors_categories(categories)
# r = builder.get_result_as_array()
context = self.get_context_data()
context['categories'] = categories
return render(self.request, self.success_template, context)

class MatchView(MatchQuestionCategoryBase):
template_name = 'match/pergunta.html'
success_template = 'match/paso2_explicacion_pautas.html'


class MatchResultView(MatchQuestionCategoryBase):
template_name = 'match/pergunta.html'
success_template = 'match/resultado_ajax.html'


class MatchResultAjaxView(View):
def post(self, request, *args, **kwargs):
categories = dict(request.POST)['categories[]']
categories = QuestionCategory.objects.filter(id__in=categories)
builder = MatrixBuilder()
builder.set_electors_categories(categories)
r = builder.get_result_as_array()
context = self.get_context_data()
context['candidatos'] = json.dumps(r)
return render(self.request, 'match/resultado.html', context)
return JsonResponse(json.dumps(r), safe=False)

26 changes: 26 additions & 0 deletions merepresenta/models.py
Expand Up @@ -16,6 +16,7 @@
from django.dispatch import receiver
from django.db.models.signals import post_save
from candidator.models import Position
from merepresenta.dicts_and_lists_for_ordering import partidos_mix


class MeRepresentaPopularProposal(PopularProposal):
Expand Down Expand Up @@ -174,6 +175,31 @@ def as_dict(self):
'partido': partido_initials,
'coaligacao': coaligacao,
}
try:
d['image'] = self.candidacy_set.first.user.profile.image.url
except:
d['image'] = None
area_id = ""
try:
area_id = self.election.area.id
except:
pass
if self.partido:
partido_id = partidos_mix.get(self.partido.initials, self.partido.initials)
else:
partido_id = None
_filter = {
'mulher': self.gender == NON_MALE_KEY,
'is_lgbt': self.lgbt,
'partido': partido_id,
'estado': area_id
}
for desc in LGBTQDescription.objects.all():
if desc in self.lgbt_desc.all():
_filter['lgbt_' + str(desc.id)] = True
else:
_filter['lgbt_' + str(desc.id)] = False
d['filter'] = _filter
return d

class VolunteerInCandidate(models.Model):
Expand Down
63 changes: 63 additions & 0 deletions merepresenta/static/js/dicts_for_result.js
@@ -0,0 +1,63 @@
var partidos_ids = [{'id': 0, 'label': "AVANTE"},
{'id': 1, 'label': "PP"},
{'id': 2, 'label': "PHS"},
{'id': 3, 'label': "PSC"},
{'id': 4, 'label': "PR"},
{'id': 5, 'label': "True"},
{'id': 6, 'label': "PT"},
{'id': 7, 'label': "REDE"},
{'id': 8, 'label': "PTC"},
{'id': 9, 'label': "PMB"},
{'id': 10, 'label': "PDT"},
{'id': 11, 'label': "PPS"},
{'id': 12, 'label': "PROS"},
{'id': 13, 'label': "PSB"},
{'id': 14, 'label': "PV"},
{'id': 15, 'label': "PATRI"},
{'id': 16, 'label': "PODE"},
{'id': 17, 'label': "PSL"},
{'id': 18, 'label': "DC"},
{'id': 19, 'label': "SOLIDARIEDADE"},
{'id': 20, 'label': "PSDB"},
{'id': 21, 'label': "PTB"},
{'id': 22, 'label': "PRB"},
{'id': 23, 'label': "MDB"},
{'id': 24, 'label': "PRTB"},
{'id': 25, 'label': "PRP"},
{'id': 26, 'label': "DEM"},
{'id': 27, 'label': "PMN"},
{'id': 28, 'label': "PC do B"},
{'id': 29, 'label': "PCB"},
{'id': 30, 'label': "PPL"},
{'id': 31, 'label': "PSTU"},
{'id': 32, 'label': "PCO"},
{'id': 33, 'label': "PSD"},
{'id': 34, 'label': "PSOL"},
{'id': 35, 'label': "NOVO"}]
var estados_ids = [{'id': "sao-paulo-state-sp", 'label': "SÃO PAULO"},
{'id': "rio-de-janeiro-state-rj", 'label': "RIO DE JANEIRO"},
{'id': "acre-state-ac", 'label': "ACRE"},
{'id': "alagoas-state-al", 'label': "ALAGOAS"},
{'id': "amazonas-state-am", 'label': "AMAZONAS"},
{'id': "bahia-state-ba", 'label': "BAHIA"},
{'id': "distrito-federal-state-df", 'label': "DISTRITO FEDERAL"},
{'id': "mato-grosso-state-mt", 'label': "MATO GROSSO"},
{'id': "mato-grosso-do-sul-state-ms", 'label': "MATO GROSSO DO SUL"},
{'id': "minas-gerais-state-mg", 'label': "MINAS GERAIS"},
{'id': "pernambuco-state-pe", 'label': "PERNAMBUCO"},
{'id': "rio-grande-do-norte-state-rn", 'label': "RIO GRANDE DO NORTE"},
{'id': "rio-grande-do-sul-state-rs", 'label': "RIO GRANDE DO SUL"},
{'id': "roraima-state-rr", 'label': "RORAIMA"},
{'id': "santa-catarina-state-sc", 'label': "SANTA CATARINA"},
{'id': "sergipe-state-se", 'label': "SERGIPE"},
{'id': "tocantins-state-to", 'label': "TOCANTINS"},
{'id': "amapa-state-ap-2", 'label': "AMAPÁ"},
{'id': "ceara-state-ce-2", 'label': "CEARÁ"},
{'id': "espirito-santo-state-es", 'label': "ESPÍRITO SANTO"},
{'id': "goias-state-go-2", 'label': "GOIÁS"},
{'id': "maranhao-state-ma-2", 'label': "MARANHÃO"},
{'id': "para-state-pa-2", 'label': "PARÁ"},
{'id': "paraiba-state-pb", 'label': "PARAÍBA"},
{'id': "parana-state-pr-2", 'label': "PARANÁ"},
{'id': "piaui-state-pi", 'label': "PIAUÍ"},
{'id': "rondonia-state-ro", 'label': "RONDÔNIA"}]