Skip to content

Commit

Permalink
Meet style requirements
Browse files Browse the repository at this point in the history
Update to previous commit to comply with style requirements
  • Loading branch information
octoscorp committed Oct 21, 2023
1 parent 745e5b0 commit 108c91f
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 93 deletions.
2 changes: 1 addition & 1 deletion codewof/programming/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class Meta:


class DraftFilter(django_filters.FilterSet):
"""Filter for drafts extends FilterSet. Allows for filtering identical to questions"""
"""Filter for drafts extends FilterSet. Allows for filtering identical to questions."""

difficulty_level = django_filters.filters.ModelMultipleChoiceFilter(
queryset=DifficultyLevel.objects.order_by('level'),
Expand Down
173 changes: 131 additions & 42 deletions codewof/programming/forms.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
""" Forms for programming pages """
"""Forms for programming pages."""

from django import forms
from django.urls import reverse
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Button, Div, HTML, Field
from crispy_forms.layout import Layout, Submit, Button, Div, HTML
from crispy_forms.bootstrap import Modal
from programming.models import Draft, DifficultyLevel

Expand All @@ -25,22 +25,22 @@
]
CONCEPTS = {
"root": [
('display-text','Display Text'),
('functions','Functions'),
('inputs','Inputs'),
('conditionals','Conditionals'),
('loops','Loops'),
('string-operations','String Operations'),
('lists','Lists'),
('display-text', 'Display Text'),
('functions', 'Functions'),
('inputs', 'Inputs'),
('conditionals', 'Conditionals'),
('loops', 'Loops'),
('string-operations', 'String Operations'),
('lists', 'Lists'),
],
"conditionals": [
('single-condition','Single Condition'),
('multiple-conditions','Multiple Conditions'),
('advanced-conditionals','Advanced Conditionals'),
('single-condition', 'Single Condition'),
('multiple-conditions', 'Multiple Conditions'),
('advanced-conditionals', 'Advanced Conditionals'),
],
"loops": [
('conditional-loops','Conditional Loops'),
('range-loops','Range Loops'),
('conditional-loops', 'Conditional Loops'),
('range-loops', 'Range Loops'),
],
}
CONTEXTS = {
Expand All @@ -58,10 +58,15 @@
],
}


class MacroForm(forms.Form):
"""Form for creating/editing macros for new questions"""
"""Form for creating/editing macros for new questions."""

macro_help_text = 'Separate values with a comma (i.e. 6,7). You can escape commas with a backslash (i.e. 6\\,7)'
name = forms.CharField(required=True, max_length='20')
possible_values = forms.CharField(widget=forms.Textarea, required=True, help_text='Separate values with a comma (i.e. 6,7). You can escape commas with a backslash (i.e. 6\,7)')
possible_values = forms.CharField(widget=forms.Textarea,
required=True,
help_text=macro_help_text)

def __init__(self, *args, **kwargs):
"""Add crispyform helper to form."""
Expand Down Expand Up @@ -92,8 +97,10 @@ def __init__(self, *args, **kwargs):
),
)


class TestCaseForm(forms.Form):
"""Form for creating/editing test cases for new questions"""
"""Form for creating/editing test cases for new questions."""

testcase_type = forms.ChoiceField(required=True, label='Type', choices=TEST_CASE_TYPES)
testcase_code = forms.CharField(widget=forms.Textarea, label='Input Code', required=True)

Expand All @@ -106,7 +113,11 @@ def __init__(self, *args, **kwargs):
Modal(
'testcase_type',
'testcase_code',
HTML('<small class="form-text text-muted font-italic">Expected output is generated from your provided solution code.</small>'),
HTML(
'<small class="form-text text-muted font-italic">' +
'Expected output is generated from your provided solution code.' +
'</small>'
),
Button(
"close_modal",
"Cancel",
Expand All @@ -127,29 +138,108 @@ def __init__(self, *args, **kwargs):
),
)


class NewQuestionForm(forms.ModelForm):
"""Form for creating or editing new questions."""
macros = forms.CharField(widget=forms.Textarea, required=False)
initial_code = forms.CharField(widget=forms.Textarea, required=False)
read_only_lines_top = forms.IntegerField(required=False, help_text="The number of lines at the top of the initial code to make read-only")
read_only_lines_bottom = forms.IntegerField(required=False, help_text="The number of lines at the bottom of the initial code to make read-only")
lines = forms.CharField(widget=forms.Textarea, required=False, label="Extra lines", help_text="Lines to mix in with solution lines")
test_cases = forms.CharField(widget=forms.Textarea, required=False, help_text="Drag test cases up and down to reorder them (may not work with touch devices)")

concepts = forms.MultipleChoiceField(required=False, choices=CONCEPTS["root"], widget=forms.CheckboxSelectMultiple(), label=False)
concept_conditionals = forms.ChoiceField(required=False, choices=CONCEPTS["conditionals"], widget=forms.RadioSelect, label=False)
concept_loops = forms.ChoiceField(required=False, choices=CONCEPTS["loops"], widget=forms.RadioSelect, label=False)
# Fields specific to a type of question
initial_code = forms.CharField(
widget=forms.Textarea,
required=False
)
read_only_lines_top = forms.IntegerField(
required=False,
help_text="The number of lines at the top of the initial code to make read-only"
)
read_only_lines_bottom = forms.IntegerField(
required=False,
help_text="The number of lines at the bottom of the initial code to make read-only"
)
lines = forms.CharField(
widget=forms.Textarea,
required=False,
label="Extra lines",
help_text="Lines to mix in with solution lines"
)

contexts = forms.MultipleChoiceField(required=False, choices=CONTEXTS["root"], widget=forms.CheckboxSelectMultiple(), label=False)
context_has_geometry = forms.BooleanField(required=False, initial=False, label="Geometry")
context_mathematics = forms.ChoiceField(required=False, choices=CONTEXTS["mathematics"], widget=forms.RadioSelect, label=False)
context_geometry = forms.ChoiceField(required=False, choices=CONTEXTS["geometry"], widget=forms.RadioSelect, label=False)
# Many-to-many fields
macros = forms.CharField(
widget=forms.Textarea,
required=False
)
test_cases = forms.CharField(
widget=forms.Textarea,
required=False,
help_text="Drag test cases up and down to reorder them (may not work with touch devices)"
)
concepts = forms.MultipleChoiceField(
required=False,
choices=CONCEPTS["root"],
widget=forms.CheckboxSelectMultiple(),
label=False
)
contexts = forms.MultipleChoiceField(
required=False,
choices=CONTEXTS["root"],
widget=forms.CheckboxSelectMultiple(),
label=False
)

difficulty_level = forms.ChoiceField(required=False, choices=QUESTION_DIFFICULTY_CHOICES, initial=QUESTION_DIFFICULTY_CHOICES[0], label='Difficulty')
# Helpers for concepts/contexts
concept_conditionals = forms.ChoiceField(
required=False,
choices=CONCEPTS["conditionals"],
widget=forms.RadioSelect,
label=False
)
concept_loops = forms.ChoiceField(
required=False,
choices=CONCEPTS["loops"],
widget=forms.RadioSelect,
label=False
)

context_has_geometry = forms.BooleanField(
required=False,
initial=False,
label="Geometry"
)
context_mathematics = forms.ChoiceField(
required=False,
choices=CONTEXTS["mathematics"],
widget=forms.RadioSelect,
label=False
)
context_geometry = forms.ChoiceField(
required=False,
choices=CONTEXTS["geometry"],
widget=forms.RadioSelect,
label=False
)

# Defining a custom widget for difficulty to enable correct display names for the options
difficulty_level = forms.ChoiceField(
required=False,
choices=QUESTION_DIFFICULTY_CHOICES,
initial=QUESTION_DIFFICULTY_CHOICES[0],
label='Difficulty'
)

class Meta:
"""Defines attributes for crispy form generation."""

model = Draft
fields = ["title", "question_type", "difficulty_level", "question_text", "macros", "solution", "concepts", "contexts", "lines"]
fields = [
"title",
"question_type",
"difficulty_level",
"question_text",
"macros",
"solution",
"concepts",
"contexts",
"lines"
]
labels = {
"title": "Question Title",
"question_type": "Type",
Expand All @@ -158,8 +248,6 @@ class Meta:
"question_type": forms.Select(choices=QUESTION_TYPE_CHOICES),
}



def __init__(self, *args, **kwargs):
"""Add crispyform helper to form."""
super().__init__(*args, **kwargs)
Expand All @@ -175,7 +263,7 @@ def __init__(self, *args, **kwargs):
Div(
Div(
HTML('{% include "programming/question_creation/macros_display_table.html" %}'),
css_class = "table-responsive",
css_class="table-responsive",
),
Button(
"new_macro",
Expand All @@ -184,7 +272,7 @@ def __init__(self, *args, **kwargs):
css_class="btn-outline-secondary",
type="button",
),
css_class = "text-center",
css_class="text-center",
),
'solution',
HTML('{% include "programming/question_components/indentation-warning.html" %}'),
Expand Down Expand Up @@ -232,8 +320,8 @@ def __init__(self, *args, **kwargs):
Div(
Div(
HTML('{% include "programming/question_creation/creation_test_case_table.html" %}'),
css_class = "table-responsive",
css_id = "test_case_table_container",
css_class="table-responsive",
css_id="test_case_table_container",
),
Button(
"new_test_case",
Expand All @@ -242,7 +330,7 @@ def __init__(self, *args, **kwargs):
css_class="btn-outline-secondary",
type="button",
),
css_class = "text-center",
css_class="text-center",
),
Div(
HTML(f'<a href = "{reverse("programming:draft_list")}" class="btn btn-outline-secondary">Cancel</a>'),
Expand All @@ -253,8 +341,9 @@ def __init__(self, *args, **kwargs):

def clean(self, *args, **kwargs):
"""
Overrides the validation, as difficulty level is a foreign key and would otherwise
raise an error.
Override the values returned from cleaning the form.
Difficulty level is a foreign key and would otherwise raise an error.
"""
cleaned_data = self.cleaned_data
cleaned_data['difficulty_level'] = DifficultyLevel.objects.get(
Expand Down
11 changes: 8 additions & 3 deletions codewof/programming/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ class Meta:

# ----- Base draft classes -------------------------------------------------
class Draft(TranslatableModel):
"""Class for a draft question"""
"""Class for a draft question."""

slug = models.SlugField(unique=True)
title = models.CharField(max_length=SMALL)
Expand Down Expand Up @@ -301,6 +301,7 @@ class Meta:
verbose_name = 'Draft'
verbose_name_plural = 'Drafts'


class DraftTestCase(TranslatableModel):
"""Base class for a draft for TestCase."""

Expand All @@ -323,6 +324,7 @@ def __str__(self):
return self.type
pass


class DraftMacro(models.Model):
"""A macro for a draft question."""

Expand All @@ -333,8 +335,9 @@ class DraftMacro(models.Model):
on_delete=models.CASCADE,
)


class DraftMacroValue(TranslatableModel):
"""A potential value for a draft macro to take"""
"""A potential value for a draft macro to take."""

macro = models.ForeignKey(
DraftMacro,
Expand All @@ -343,7 +346,9 @@ class DraftMacroValue(TranslatableModel):
)
value = models.TextField()


# ----- Base question classes -------------------------------------------------

class Question(TranslatableModel):
"""Base class for a question for CodeWOF.
Expand Down Expand Up @@ -431,7 +436,7 @@ class Macro(models.Model):


class MacroValue(TranslatableModel):
"""A potential value for a macro to take"""
"""A potential value for a macro to take."""

macro = models.ForeignKey(
Macro,
Expand Down
Loading

0 comments on commit 108c91f

Please sign in to comment.