Skip to content

Commit

Permalink
Refactor EXPERIMENT_RULES to BLOCK_RULES
Browse files Browse the repository at this point in the history
  • Loading branch information
drikusroor committed Jul 3, 2024
1 parent 6b76399 commit 0630f3a
Show file tree
Hide file tree
Showing 20 changed files with 60 additions and 63 deletions.
8 changes: 4 additions & 4 deletions backend/experiment/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.forms import CheckboxSelectMultiple, ModelForm, ChoiceField, Form, MultipleChoiceField, ModelMultipleChoiceField, Select, TypedMultipleChoiceField, CheckboxSelectMultiple, TextInput
from experiment.models import ExperimentCollection, Block, SocialMediaConfig
from experiment.rules import EXPERIMENT_RULES
from experiment.rules import BLOCK_RULES


# session_keys for Export CSV
Expand Down Expand Up @@ -155,8 +155,8 @@ def __init__(self, *args, **kwargs):
super(ModelForm, self).__init__(*args, **kwargs)

choices = tuple()
for i in EXPERIMENT_RULES:
choices += ((i, EXPERIMENT_RULES[i].__name__),)
for i in BLOCK_RULES:
choices += ((i, BLOCK_RULES[i].__name__),)
choices += (("", "---------"),)

self.fields['rules'] = ChoiceField(
Expand All @@ -171,7 +171,7 @@ def clean_playlists(self):

# Validat the rules' playlist
rule_id = self.cleaned_data['rules']
cl = EXPERIMENT_RULES[rule_id]
cl = BLOCK_RULES[rule_id]
rules = cl()

playlists = self.cleaned_data['playlists']
Expand Down
4 changes: 2 additions & 2 deletions backend/experiment/management/commands/compileplaylist.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings

from experiment.rules import EXPERIMENT_RULES
from experiment.rules import BLOCK_RULES


class Command(BaseCommand):
Expand Down Expand Up @@ -63,7 +63,7 @@ def handle(self, *args, **options):
artist_name = song_names[audio_file_clean]
song_name = basename(audio_file)[:-4]
elif experiment_option:
rules = EXPERIMENT_RULES.get(experiment_option)
rules = BLOCK_RULES.get(experiment_option)
info = rules.get_info_playlist(rules, audio_file_clean)
artist_name = info.get('artist')
song_name = info.get('song')
Expand Down
12 changes: 6 additions & 6 deletions backend/experiment/management/commands/createruleset.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ def create_experiment_rule_class(self, ruleset_name):
with open('./experiment/management/commands/templates/experiment.py', 'r') as template:
f.write(template.read()
.replace('NewExperimentRuleset', ruleset_name_pascal_case)
.replace('new_experiment_ruleset', ruleset_name_snake_case)
.replace('NEW_EXPERIMENT_RULESET', ruleset_name_snake_case_upper)
.replace('new_block_ruleset', ruleset_name_snake_case)
.replace('NEW_BLOCK_RULESET', ruleset_name_snake_case_upper)
.replace('New Experiment Ruleset', ruleset_name.title())
)

Expand All @@ -64,8 +64,8 @@ def register_experiment_rule(self, ruleset_name, file_path):
import_index = next(i for i, line in enumerate(lines) if line.startswith('from .') and line > new_import)
lines.insert(import_index, new_import)

# Find the line to insert the new dictionary entry, maintaining alphabetical order within the EXPERIMENT_RULES
dict_start_index = lines.index("EXPERIMENT_RULES = {\n") + 1 # Start after the opening brace
# Find the line to insert the new dictionary entry, maintaining alphabetical order within the BLOCK_RULES
dict_start_index = lines.index("BLOCK_RULES = {\n") + 1 # Start after the opening brace
dict_end_index = lines.index("}\n", dict_start_index) # Find the closing brace
dict_entry_index = next((i for i, line in enumerate(lines[dict_start_index:dict_end_index], dict_start_index) if line > new_dict_entry), dict_end_index)
lines.insert(dict_entry_index, new_dict_entry)
Expand Down Expand Up @@ -93,8 +93,8 @@ def create_test_file(self, ruleset_name):
with open('./experiment/management/commands/templates/test_experiment.py', 'r') as template:
f.write(template.read()
.replace('NewExperimentRuleset', ruleset_name_pascal_case)
.replace('new_experiment_ruleset', ruleset_name_snake_case)
.replace('NEW_EXPERIMENT_RULESET', ruleset_name_snake_case_upper)
.replace('new_block_ruleset', ruleset_name_snake_case)
.replace('NEW_BLOCK_RULESET', ruleset_name_snake_case_upper)
.replace('New Experiment Ruleset', ruleset_name.title())
)

Expand Down
13 changes: 6 additions & 7 deletions backend/experiment/management/commands/templates/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class NewExperimentRuleset(Base):
''' An experiment type that could be used to test musical preferences '''
ID = 'NEW_EXPERIMENT_RULESET'
ID = 'NEW_BLOCK_RULESET'
contact_email = 'info@example.com'

def __init__(self):
Expand All @@ -33,17 +33,17 @@ def __init__(self):
]

def first_round(self, experiment):
''' Provide the first rounds of the experiment,
''' Provide the first rounds of the experiment,
before session creation
The first_round must return at least one Info or Explainer action
Consent and Playlist are often desired, but optional
'''
# 1. Informed consent (optional)
consent = Consent(experiment.consent,
title=_('Informed consent'),
confirm=_('I agree'),
confirm=_('I agree'),
deny=_('Stop'))

# 2. Choose playlist (optional, only relevant if there are multiple playlists the participant can choose from)
playlist = Playlist(experiment.playlists.all())

Expand All @@ -57,13 +57,13 @@ def first_round(self, experiment):
],
step_numbers=True
)

return [
consent,
playlist,
explainer
]

def next_round(self, session):
# ask any questions defined in the admin interface
actions = self.get_questionnaire(session)
Expand Down Expand Up @@ -109,4 +109,3 @@ def get_trial(self, session):
}
)
return view

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from django.db import migrations
from experiment.rules import EXPERIMENT_RULES
from experiment.rules import BLOCK_RULES as EXPERIMENT_RULES


def set_default_question_data(apps, schema_editor):

Experiment = apps.get_model("experiment", "Experiment")

for experiment in Experiment.objects.all():
experiment.questions = [q.key for q in EXPERIMENT_RULES[experiment.rules]().questions]
experiment.save()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

from django.db import migrations
from experiment.models import Block as Experiment
from experiment.rules import EXPERIMENT_RULES
from experiment.rules import BLOCK_RULES as EXPERIMENT_RULES


def add_default_question_series(apps, schema_editor):
Expand Down
10 changes: 5 additions & 5 deletions backend/experiment/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,12 @@ def export_table(self, session_keys: List[str], result_keys: List[str], export_o

def get_rules(self):
"""Get instance of rules class to be used for this session"""
from experiment.rules import EXPERIMENT_RULES
from experiment.rules import BLOCK_RULES

if self.rules not in EXPERIMENT_RULES:
if self.rules not in BLOCK_RULES:
raise ValueError(f"Rules do not exist (anymore): {self.rules} for block {self.name} ({self.slug})")

cl = EXPERIMENT_RULES[self.rules]
cl = BLOCK_RULES[self.rules]
return cl()

def max_score(self):
Expand All @@ -305,9 +305,9 @@ def max_score(self):

def add_default_question_series(self):
""" Add default question_series to block"""
from experiment.rules import EXPERIMENT_RULES
from experiment.rules import BLOCK_RULES
from question.models import Question, QuestionSeries, QuestionInSeries
question_series = getattr(EXPERIMENT_RULES[self.rules](), "question_series", None)
question_series = getattr(BLOCK_RULES[self.rules](), "question_series", None)
if question_series:
for i, question_series in enumerate(question_series):
qs = QuestionSeries.objects.create(
Expand Down
2 changes: 1 addition & 1 deletion backend/experiment/rules/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
# If you create new Rules, add them to the list
# so they can be referred to by the admin

EXPERIMENT_RULES = {
BLOCK_RULES = {
Anisochrony.ID: Anisochrony,
BeatAlignment.ID: BeatAlignment,
BST.ID: BST,
Expand Down
8 changes: 4 additions & 4 deletions backend/experiment/rules/tafc.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class TwoAlternativeForced(Base):

# Add to __init.py__ file in the same directory as the current file:
# from .tafc import TwoAlternativeForced
# To EXPERIMENT_RULES dictionary in __init.py__
# To BLOCK_RULES dictionary in __init.py__
# TwoAlternativeForced.ID: TwoAlternativeForced
ID = 'TWO_ALTERNATIVE_FORCED'

Expand Down Expand Up @@ -90,7 +90,7 @@ def next_round(self, session):
if actions:
return actions

if session.rounds_passed() == 0:
if session.rounds_passed() == 0:
# Beginning of experiment, return an explainer and the next trial action, no feedback on previous trial

explainer2 = Explainer(
Expand All @@ -104,13 +104,13 @@ def next_round(self, session):
# Combine two actions, feedback on previous action and next trial action
return [self.get_feedback(session), self.next_trial_action(session)]

else:
else:
# All sections have been played, finalize the experiment and return feedback
session.finish()
session.save()

return [self.get_feedback(session), self.get_final_view(session)]

def next_trial_action(self, session):
"""
Returns the next trial action for the experiment. Not necessary as a separate method, but often used for convenience.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def setUpTestData(cls):
participant=cls.participant,
playlist=cls.playlist
)
cls.rules = cls.session.experiment_rules()
cls.rules = cls.session.block_rules()

def test_trial_action(self):
difference = 200000
Expand Down Expand Up @@ -53,8 +53,8 @@ def setUpTestData(cls):
participant=cls.participant,
playlist=cls.playlist
)
cls.rules = cls.session.experiment_rules()
cls.rules = cls.session.block_rules()

def test_trial_action(self):
difficulty = 1001
catch_section = Section.objects.get(playlist=self.playlist.id, song__name=0)
Expand Down
10 changes: 5 additions & 5 deletions backend/experiment/rules/tests/test_hbat.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def setUpTestData(cls):
participant=cls.participant,
playlist=cls.playlist
)
cls.rules = cls.session.experiment_rules()
cls.rules = cls.session.block_rules()

def test_trial_action(self):
level = 4
slower_trial = self.rules.next_trial_action(self.session, 1, level)
Expand Down Expand Up @@ -54,8 +54,8 @@ def setUpTestData(cls):
participant=cls.participant,
playlist=cls.playlist
)
cls.rules = cls.session.experiment_rules()
cls.rules = cls.session.block_rules()

def test_trial_action(self):
in2 = self.rules.next_trial_action(self.session, 1, 3)
assert in2
Expand All @@ -68,4 +68,4 @@ def test_trial_action(self):
result_id = in3.feedback_form.form[0].result_id
result = Result.objects.get(pk=result_id)
assert result
assert result.expected_response == 'in3'
assert result.expected_response == 'in3'
10 changes: 4 additions & 6 deletions backend/experiment/rules/tests/test_hooked.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def test_hooked(self):
participant=self.participant,
playlist=playlist
)
rules = session.experiment_rules()
rules = session.block_rules()
rules.plan_sections(session)
plan = session.load_json_data().get('plan')
assert plan is not None
Expand All @@ -45,7 +45,7 @@ def test_eurovision(self):
participant=self.participant,
playlist=playlist
)
rules = session.experiment_rules()
rules = session.block_rules()
for i in range(0, experiment.rounds):
actions = rules.next_round(session)
assert actions
Expand All @@ -60,7 +60,7 @@ def test_thats_my_song(self):
participant=self.participant,
playlist=playlist
)
rules = session.experiment_rules()
rules = session.block_rules()
assert rules.feedback_info() is None

for i in range(0, experiment.rounds):
Expand Down Expand Up @@ -125,12 +125,10 @@ def test_hooked_china(self):
participant=self.participant,
playlist=playlist
)
rules = session.experiment_rules()
rules = session.block_rules()
assert rules.feedback_info() is not None
question_trials = rules.get_questionnaire(session)
# assert len(question_trials) == len(rules.questions)
keys = [q.feedback_form.form[0].key for q in question_trials]
questions = rules.question_series[0]['keys'][0:3]
assert set(keys).difference(set(questions)) == set()


6 changes: 3 additions & 3 deletions backend/experiment/rules/tests/test_matching_pairs.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ def setUpTestData(cls):
participant=cls.participant,
playlist=cls.playlist
)
cls.rules = cls.session.experiment_rules()
cls.rules = cls.session.block_rules()

def test_matching_pairs_trial(self):
self.rules.num_pairs = 2
for i in range(6):
for i in range(6):
trial = self.rules.get_matching_pairs_trial(self.session)
assert trial
data = self.session.load_json_data()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ def test_lite_version(self):
participant=self.participant,
playlist=self.playlist
)
first_trial = session.experiment_rules().get_matching_pairs_trial(session)
first_trial = session.block_rules().get_matching_pairs_trial(session)
another_session = Session.objects.create(
experiment=experiment,
participant=self.participant,
playlist=self.playlist
)
second_trial = another_session.experiment_rules(
second_trial = another_session.block_rules(
).get_matching_pairs_trial(another_session)
assert isinstance(first_trial, Trial)
assert isinstance(second_trial, Trial)
Expand All @@ -56,13 +56,13 @@ def test_fixed_order_sections(self):
participant=self.participant,
playlist=self.playlist
)
first_trial = session.experiment_rules().get_matching_pairs_trial(session)
first_trial = session.block_rules().get_matching_pairs_trial(session)
another_session = Session.objects.create(
experiment=experiment,
participant=self.participant,
playlist=self.playlist
)
second_trial = another_session.experiment_rules(
second_trial = another_session.block_rules(
).get_matching_pairs_trial(another_session)
assert isinstance(first_trial, Trial)
assert isinstance(second_trial, Trial)
Expand Down
4 changes: 2 additions & 2 deletions backend/experiment/tests/test_forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.test import TestCase

from experiment.forms import ExperimentForm, ExportForm, TemplateForm, EXPERIMENT_RULES, SESSION_CHOICES, RESULT_CHOICES, EXPORT_OPTIONS, TEMPLATE_CHOICES
from experiment.forms import ExperimentForm, ExportForm, TemplateForm, BLOCK_RULES, SESSION_CHOICES, RESULT_CHOICES, EXPORT_OPTIONS, TEMPLATE_CHOICES


class ExperimentFormTest(TestCase):
Expand All @@ -16,7 +16,7 @@ def test_form_fields(self):

def test_rules_field_choices(self):
form = ExperimentForm()
expected_choices = [(i, EXPERIMENT_RULES[i].__name__) for i in EXPERIMENT_RULES]
expected_choices = [(i, BLOCK_RULES[i].__name__) for i in BLOCK_RULES]
expected_choices.append(("", "---------"))
self.assertEqual(form.fields['rules'].choices, sorted(expected_choices))

Expand Down
4 changes: 2 additions & 2 deletions backend/experiment/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .models import Block, ExperimentCollection, Phase, Feedback
from section.models import Playlist
from experiment.serializers import serialize_actions, serialize_experiment_collection, serialize_phase
from experiment.rules import EXPERIMENT_RULES
from experiment.rules import BLOCK_RULES
from experiment.actions.utils import COLLECTION_KEY
from image.serializers import serialize_image
from participant.utils import get_participant
Expand Down Expand Up @@ -176,7 +176,7 @@ def validate_experiment_playlist(
if not playlists:
return JsonResponse({'status': 'error', 'message': 'The experiment must have a playlist.'})

rules = EXPERIMENT_RULES[rules_id]()
rules = BLOCK_RULES[rules_id]()

if not rules.validate_playlist:
return JsonResponse({'status': 'warn', 'message': 'This rulesset does not have a playlist validation.'})
Expand Down
Loading

0 comments on commit 0630f3a

Please sign in to comment.