Skip to content

Commit 42da489

Browse files
committed
Update Experiment
1 parent ef4f811 commit 42da489

18 files changed

+343
-38
lines changed

experiments/forms.py

+48-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from django import forms
44

55
from experiments.models import Execution, Experiment, HeatMapFeedback,\
6-
LatinSquare, Participant
6+
LatinSquare, Participant, SocialRepresentation, DifficultLinesFeedback
77
from experiments.services.search_available_latin_square_row import \
88
SearchAvailableLatinSquareRow
99

@@ -28,7 +28,7 @@ def save_participant(self):
2828
experiment_id = self.cleaned_data['experiment_id']
2929
experiment = self.__experiment(experiment_id)
3030

31-
participant = Participant.objects.create(name=name, email=email)
31+
participant = Participant.objects.create(name=name, email=email, experiment=experiment)
3232

3333
latin_square_row = SearchAvailableLatinSquareRow(experiment).call()
3434

@@ -77,3 +77,49 @@ def save_heat_map_feedback(self):
7777

7878
def __execution(self, execution_id):
7979
return Execution.objects.get(pk=execution_id)
80+
81+
82+
class DifficultLinesFeedbackForm(forms.ModelForm):
83+
def __init__(self, *args, **kwargs):
84+
super(DifficultLinesFeedbackForm, self).__init__(*args, **kwargs)
85+
self.fields['hard_lines'].widget.attrs['class'] = 'form-control'
86+
87+
def save_difficult_lines_feedback(self):
88+
hard_lines = self.cleaned_data['hard_lines']
89+
execution_id = self.data['execution_id']
90+
return DifficultLinesFeedback.objects.create(
91+
hard_lines=hard_lines,
92+
execution_id=execution_id
93+
)
94+
95+
class Meta:
96+
model = DifficultLinesFeedback
97+
fields = ['hard_lines']
98+
99+
100+
101+
class SocialRepresentationForm(forms.ModelForm):
102+
def __init__(self, *args, **kwargs):
103+
super(SocialRepresentationForm, self).__init__(*args, **kwargs)
104+
self.fields['words'].widget.attrs['class'] = 'form-control'
105+
self.fields['most_relevant'].widget.attrs['class'] = 'form-control'
106+
107+
108+
class Meta:
109+
model = SocialRepresentation
110+
fields = ['words', 'most_relevant']
111+
112+
def save_social_representation(self):
113+
words = self.cleaned_data['words']
114+
most_relevant = self.cleaned_data['most_relevant']
115+
participant_id = self.data['participant_id']
116+
participant = self.__participant(participant_id)
117+
118+
return SocialRepresentation.objects.create(
119+
words = words,
120+
most_relevant = most_relevant,
121+
participant = participant
122+
)
123+
124+
def __participant(self, participant_id):
125+
return Participant.objects.get(pk=participant_id)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.26 on 2020-01-22 05:36
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('experiments', '0030_auto_20191202_0411'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='experiment',
17+
name='hidden',
18+
field=models.BooleanField(default=False),
19+
),
20+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.26 on 2020-01-22 06:12
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
import django.db.models.deletion
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
dependencies = [
12+
('experiments', '0031_experiment_hidden'),
13+
]
14+
15+
operations = [
16+
migrations.CreateModel(
17+
name='SocialRepresentation',
18+
fields=[
19+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20+
('created_at', models.DateTimeField(auto_now_add=True, null=True)),
21+
('updated_at', models.DateTimeField(auto_now=True, null=True)),
22+
('words', models.TextField(blank=True, null=True)),
23+
('most_relevant', models.TextField(blank=True, null=True)),
24+
],
25+
options={
26+
'abstract': False,
27+
},
28+
),
29+
migrations.AddField(
30+
model_name='participant',
31+
name='experiment',
32+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='experiments.Experiment'),
33+
),
34+
migrations.AddField(
35+
model_name='socialrepresentation',
36+
name='participant',
37+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='experiments.Participant'),
38+
),
39+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.26 on 2020-01-22 05:12
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
import django.db.models.deletion
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
dependencies = [
12+
('experiments', '0032_auto_20200122_0312'),
13+
]
14+
15+
operations = [
16+
migrations.CreateModel(
17+
name='DifficultLinesFeedback',
18+
fields=[
19+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20+
('created_at', models.DateTimeField(auto_now_add=True, null=True)),
21+
('updated_at', models.DateTimeField(auto_now=True, null=True)),
22+
('hard_lines', models.CharField(blank=True, max_length=500, null=True)),
23+
('execution', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='experiments.Execution')),
24+
],
25+
options={
26+
'abstract': False,
27+
},
28+
),
29+
]

experiments/models.py

+25
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ class Experiment(BaseModel):
2323
tasks_quantity_by_cell = models.IntegerField(
2424
default=1, blank=True, null=True
2525
)
26+
hidden = models.BooleanField(default=False)
2627

2728
def __unicode__(self):
2829
return self.description
2930

3031

3132
class Participant(BaseModel):
33+
experiment = models.ForeignKey('Experiment', on_delete=models.CASCADE, blank=True, null=True)
3234
name = models.CharField(max_length=200)
3335
email = models.CharField(max_length=200)
3436

@@ -226,6 +228,29 @@ class SurveyAnswer(BaseModel):
226228
answer = models.CharField(max_length=500)
227229

228230

231+
class SocialRepresentation(BaseModel):
232+
participant = models.ForeignKey('Participant', on_delete=models.CASCADE)
233+
words = models.TextField(blank=True, null=True)
234+
most_relevant = models.TextField(blank=True, null=True)
235+
236+
237+
# class ParticipantCharacterization(BaseModel):
238+
# HIGHER_DEGREE_CHOICES = (
239+
# ('graduation', 'Graduação'),
240+
# ('master', 'Mestrado'),
241+
# ('doctor', 'Doutorado')
242+
# )
243+
# participant = models.ForeignKey('Participant', on_delete=models.CASCADE)
244+
# higher_degree = models.CharField(max_length=20, choices=HIGHER_DEGREE_CHOICES, null=True, blank=True)
245+
# work_for_industry = models.TextField(blank=True, null=True)
246+
# development_background_summary = models.TextField(blank=True, null=True)
247+
248+
249+
class DifficultLinesFeedback(BaseModel):
250+
execution = models.ForeignKey('Execution', on_delete=models.CASCADE)
251+
hard_lines = models.CharField(max_length=500, blank=True, null=True)
252+
253+
229254
# from django.db.models.signals import post_save
230255
#
231256
# post_save.connect(handlers.my_handler, sender=LatinSquare)

experiments/services/next_task_service.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class NextTaskService(object):
3838
LIMIT 1;
3939
"""
4040

41-
def __init__(self, experiment, participant):
41+
def __init__(self, participant):
4242
"""Contructor"""
43-
self.experiment = experiment
4443
self.participant = participant
44+
self.experiment = participant.experiment
4545

4646
def call(self):
4747
return self.__task()

experiments/templates/base.html

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
77
</head>
88
<body>
9-
<div class="container">
9+
<div class="container-fluid">
1010
{% block content %}{% endblock %}
1111
</div>
1212

13+
{% block body_content %}{% endblock %}
14+
1315
<script
1416
src="https://code.jquery.com/jquery-3.3.1.min.js"
1517
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{% extends "base.html" %}
2+
3+
{% block title %}Trechos Difíceis{% endblock %}
4+
5+
{% block content %}
6+
<h2 class="display-3">Trechos de difícil compreensão</h2>
7+
<hr>
8+
<form method="post">{% csrf_token %}
9+
<input type="hidden" id="execution_id" name="execution_id" value="{{ execution.id }}" />
10+
11+
<div class="form-group row">
12+
<div class="col-sm-10">
13+
<img src="{{ execution.task.image.url }}" style="height: 90%; object-fit: contain; top: 0;" />
14+
</div>
15+
<div class="col-sm-2">
16+
<label for="{{ form.hard_lines.id_for_label }}">Por favor, informe abaixo que linha(s) de código você acha mais complexa(s).</label>
17+
18+
{{ form.hard_lines }}
19+
20+
<hr>
21+
22+
<input type="submit" class="btn btn-primary" value="Enviar">
23+
</div>
24+
</div>
25+
</form>
26+
{% endblock %}
27+
28+
{% block javascript %}
29+
30+
{% endblock %}

experiments/templates/next_task.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<body>
2222
<img class="center-fit" src="{{ execution.task.image.url }}" alt="Image not found" />
2323

24-
<form action="/experiments/next-task/{{participant_id}}/{{experiment_id}}/" method="get">
24+
<form action="/experiments/next-task/{{participant_id}}/" method="get">
2525
<input type="hidden" value="{{execution.id}}" name="previous_execution_id" />
2626
<button class="hide" id="next_task_button">
2727
</form>

experiments/templates/pause_execution.html

+8-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ <h5 class="modal-title" id="exampleModalLabel">Qual a sua resposta?</h5>
9090
if (result.correct) {
9191
alert('Resposta correta!');
9292
showLoader();
93-
gotoHeatMap();
93+
hideResponseButton();
94+
gotoNextTask();
9495
} else {
9596
alert('Resposta incorreta!')
9697
$("#responseButton").html("Digite outra Resposta");
@@ -114,10 +115,15 @@ <h5 class="modal-title" id="exampleModalLabel">Qual a sua resposta?</h5>
114115
window.location.replace("{% url 'experiments:heat_map' pause.execution.id %}");
115116
}
116117

118+
function gotoNextTask() {
119+
window.location.replace("{% url 'experiments:next_task' pause.execution.participant.id %}?previous_execution_id={{ pause.execution.id }}");
120+
121+
}
122+
117123
function changeNavigationButtonToNextTask() {
118124
var navigationButton = $("#navigationButton");
119125
$(navigationButton).html('Ir para a próxima tarefa');
120-
$(navigationButton).attr('href', "{% url 'experiments:next_task' pause.execution.participant.id pause.execution.task.experiment.id %}?previous_execution_id={{ pause.execution.id }}");
126+
$(navigationButton).attr('href', "{% url 'experiments:next_task' pause.execution.participant.id %}?previous_execution_id={{ pause.execution.id }}");
121127
}
122128

123129
function hideResponseButton() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% extends "base.html" %}
2+
3+
{% block title %}Compreensão de Código{% endblock %}
4+
5+
{% block content %}
6+
<div class="jumbotron">
7+
<h2 class="display-3">Compreensão de Código</h2>
8+
<hr>
9+
<form method="post">{% csrf_token %}
10+
<input type="hidden" id="participant_id" name="participant_id" value="{{ participant_id }}" />
11+
12+
<div class="form-group">
13+
<label for="{{ form.words.id_for_label }}">O que vem &lt;&lt;imediatamente&gt;&gt; à sua mente quando você pensa &lt;&lt;código fonte confuso&gt;&gt;? Por favor, informar até cinco palavras na ordem que elas vierem à sua mente.</label>
14+
{{ form.words }}
15+
</div>
16+
17+
<div class="form-group">
18+
<label for="{{ form.most_relevant.id_for_label }}">Considerando as palavras que você informou, qual delas você considera a mais relevante para expressar sua percepção sobre o código-fonte confuso? Por quê?</label>
19+
{{ form.most_relevant }}
20+
</div>
21+
<input type="submit" class="btn btn-primary" value="Iniciar">
22+
</form>
23+
</div>
24+
{% endblock %}
25+
26+
{% block javascript %}
27+
28+
{% endblock %}

experiments/urls.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,21 @@
1313
from experiments.views.next_task import NextTask
1414
from experiments.views.start_flow import StartFlow
1515
from experiments.views.submit_answer import SubmitAnswer
16+
from experiments.views.social_representation import SocialRepresentationView
17+
from experiments.views.difficult_lines import DifficultLinesView
1618

1719

1820
urlpatterns = [
1921
url(r'^$', ExperimentList.as_view(), name='choose_experiment'),
2022
url(r'^start-flow/(?P<experiment_id>[0-9]+)/$', StartFlow.as_view(), name='start_flow'),
21-
url(r'^next-task/(?P<participant_id>[0-9]+)/(?P<experiment_id>[0-9]+)/$', NextTask.as_view(), name='next_task'),
23+
url(r'^next-task/(?P<participant_id>[0-9]+)/$', NextTask.as_view(), name='next_task'),
2224
url(r'^previous-task/(?P<participant_id>[0-9]+)/(?P<experiment_id>[0-9]+)/$', PreviousTask.as_view(), name='previous_task'),
2325
url(r'^finish-execution/$', FinishExecution.as_view(), name='finish_execution'),
2426
url(r'^pause-execution/(?P<execution_id>[0-9]+)/$', PauseExecution.as_view(), name='pause_execution'),
2527
url(r'^resume-execution/(?P<execution_id>[0-9]+)/$', ResumeExecution.as_view(), name='resume_execution'),
2628
url(r'^increment-number-of-errors/(?P<execution_id>[0-9]+)/$', IncrementNumberOfErrors.as_view(), name='increment_number_of_errors'),
2729
url(r'^submit-answer/(?P<execution_id>[0-9]+)/$', SubmitAnswer.as_view(), name='submit_answer'),
2830
url(r'^heat-map/(?P<execution_id>[0-9]+)/$', HeatMap.as_view(), name='heat_map'),
31+
url(r'^social-representation/(?P<participant_id>[0-9]+)/$', SocialRepresentationView.as_view(), name='social_representation'),
32+
url(r'^difficult-lines/(?P<execution_id>[0-9]+)/?', DifficultLinesView.as_view(), name='difficult_lines'),
2933
]

experiments/views/choose_experiment.py

+3
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55
class ExperimentList(ListView):
66
model = Experiment
77
paginate_by = 100
8+
9+
def get_queryset(self):
10+
return Experiment.objects.filter(hidden=False)

0 commit comments

Comments
 (0)