Merge pull request #207 from edx/dhm/pep8
pep8 changes made during long refactoring
This commit is contained in:
@@ -39,8 +39,6 @@ def get_users_in_course_group_by_role(location, role):
|
||||
'''
|
||||
Create all permission groups for a new course and subscribe the caller into those roles
|
||||
'''
|
||||
|
||||
|
||||
def create_all_course_groups(creator, location):
|
||||
create_new_course_group(creator, location, INSTRUCTOR_ROLE_NAME)
|
||||
create_new_course_group(creator, location, STAFF_ROLE_NAME)
|
||||
@@ -57,13 +55,11 @@ def create_new_course_group(creator, location, role):
|
||||
|
||||
return
|
||||
|
||||
'''
|
||||
This is to be called only by either a command line code path or through a app which has already
|
||||
asserted permissions
|
||||
'''
|
||||
|
||||
|
||||
def _delete_course_group(location):
|
||||
'''
|
||||
This is to be called only by either a command line code path or through a app which has already
|
||||
asserted permissions
|
||||
'''
|
||||
# remove all memberships
|
||||
instructors = Group.objects.get(name=get_course_groupname_for_role(location, INSTRUCTOR_ROLE_NAME))
|
||||
for user in instructors.user_set.all():
|
||||
@@ -75,13 +71,11 @@ def _delete_course_group(location):
|
||||
user.groups.remove(staff)
|
||||
user.save()
|
||||
|
||||
'''
|
||||
This is to be called only by either a command line code path or through an app which has already
|
||||
asserted permissions to do this action
|
||||
'''
|
||||
|
||||
|
||||
def _copy_course_group(source, dest):
|
||||
'''
|
||||
This is to be called only by either a command line code path or through an app which has already
|
||||
asserted permissions to do this action
|
||||
'''
|
||||
instructors = Group.objects.get(name=get_course_groupname_for_role(source, INSTRUCTOR_ROLE_NAME))
|
||||
new_instructors_group = Group.objects.get(name=get_course_groupname_for_role(dest, INSTRUCTOR_ROLE_NAME))
|
||||
for user in instructors.user_set.all():
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pylint: disable=C0111
|
||||
#pylint: disable=W0621
|
||||
# pylint: disable=C0111
|
||||
# pylint: disable=W0621
|
||||
|
||||
from lettuce import world, step
|
||||
from nose.tools import assert_true
|
||||
@@ -16,7 +16,7 @@ logger = getLogger(__name__)
|
||||
########### STEP HELPERS ##############
|
||||
|
||||
@step('I (?:visit|access|open) the Studio homepage$')
|
||||
def i_visit_the_studio_homepage(step):
|
||||
def i_visit_the_studio_homepage(_step):
|
||||
# To make this go to port 8001, put
|
||||
# LETTUCE_SERVER_PORT = 8001
|
||||
# in your settings.py file.
|
||||
@@ -26,17 +26,17 @@ def i_visit_the_studio_homepage(step):
|
||||
|
||||
|
||||
@step('I am logged into Studio$')
|
||||
def i_am_logged_into_studio(step):
|
||||
def i_am_logged_into_studio(_step):
|
||||
log_into_studio()
|
||||
|
||||
|
||||
@step('I confirm the alert$')
|
||||
def i_confirm_with_ok(step):
|
||||
def i_confirm_with_ok(_step):
|
||||
world.browser.get_alert().accept()
|
||||
|
||||
|
||||
@step(u'I press the "([^"]*)" delete icon$')
|
||||
def i_press_the_category_delete_icon(step, category):
|
||||
def i_press_the_category_delete_icon(_step, category):
|
||||
if category == 'section':
|
||||
css = 'a.delete-button.delete-section-button span.delete-icon'
|
||||
elif category == 'subsection':
|
||||
@@ -47,7 +47,7 @@ def i_press_the_category_delete_icon(step, category):
|
||||
|
||||
|
||||
@step('I have opened a new course in Studio$')
|
||||
def i_have_opened_a_new_course(step):
|
||||
def i_have_opened_a_new_course(_step):
|
||||
open_new_course()
|
||||
|
||||
|
||||
@@ -73,7 +73,6 @@ def create_studio_user(
|
||||
registration.register(studio_user)
|
||||
registration.activate()
|
||||
|
||||
|
||||
def fill_in_course_info(
|
||||
name='Robot Super Course',
|
||||
org='MITx',
|
||||
@@ -107,7 +106,7 @@ def log_into_studio(
|
||||
|
||||
|
||||
def create_a_course():
|
||||
c = world.CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
|
||||
world.CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
|
||||
|
||||
# Add the user to the instructor group of the course
|
||||
# so they will have the permissions to see it in studio
|
||||
@@ -147,6 +146,7 @@ def set_date_and_time(date_css, desired_date, time_css, desired_time):
|
||||
world.css_fill(date_css, desired_date)
|
||||
# hit TAB to get to the time field
|
||||
e = world.css_find(date_css).first
|
||||
# pylint: disable=W0212
|
||||
e._element.send_keys(Keys.TAB)
|
||||
world.css_fill(time_css, desired_time)
|
||||
e = world.css_find(time_css).first
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pylint: disable=C0111
|
||||
#pylint: disable=W0621
|
||||
# pylint: disable=C0111
|
||||
# pylint: disable=W0621
|
||||
|
||||
from lettuce import world, step
|
||||
from common import *
|
||||
@@ -8,7 +8,7 @@ from nose.tools import assert_equal
|
||||
############### ACTIONS ####################
|
||||
|
||||
|
||||
@step('I click the new section link$')
|
||||
@step('I click the New Section link$')
|
||||
def i_click_new_section_link(_step):
|
||||
link_css = 'a.new-courseware-section-button'
|
||||
world.css_click(link_css)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pylint: disable=C0111
|
||||
#pylint: disable=W0621
|
||||
# pylint: disable=C0111
|
||||
# pylint: disable=W0621
|
||||
|
||||
from lettuce import world, step
|
||||
from common import *
|
||||
|
||||
@@ -6,13 +6,13 @@ from lettuce import world, step
|
||||
|
||||
|
||||
@step('when I view the video it does not have autoplay enabled')
|
||||
def does_not_autoplay(step):
|
||||
def does_not_autoplay(_step):
|
||||
assert world.css_find('.video')[0]['data-autoplay'] == 'False'
|
||||
assert world.css_find('.video_control')[0].has_class('play')
|
||||
|
||||
|
||||
@step('creating a video takes a single click')
|
||||
def video_takes_a_single_click(step):
|
||||
def video_takes_a_single_click(_step):
|
||||
assert(not world.is_css_present('.xmodule_VideoModule'))
|
||||
world.css_click("a[data-location='i4x://edx/templates/video/default']")
|
||||
assert(world.is_css_present('.xmodule_VideoModule'))
|
||||
|
||||
@@ -39,10 +39,7 @@ def get_module_info(store, location, parent_location=None, rewrite_static_links=
|
||||
def set_module_info(store, location, post_data):
|
||||
module = None
|
||||
try:
|
||||
if location.revision is None:
|
||||
module = store.get_item(location)
|
||||
else:
|
||||
module = store.get_item(location)
|
||||
module = store.get_item(location)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ class ChecklistTestCase(CourseTestCase):
|
||||
'name': self.course.location.name,
|
||||
'checklist_index': 2})
|
||||
|
||||
|
||||
def get_first_item(checklist):
|
||||
return checklist['items'][0]
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
|
||||
# just pick one vertical
|
||||
descriptor = store.get_items(Location('i4x', 'edX', 'simple', 'vertical', None, None))[0]
|
||||
location = descriptor.location._replace(name='.' + descriptor.location.name)
|
||||
location = descriptor.location.replace(name='.' + descriptor.location.name)
|
||||
|
||||
resp = self.client.get(reverse('edit_unit', kwargs={'location': location.url()}))
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
@@ -224,7 +224,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
draft_store.clone_item(html_module.location, html_module.location)
|
||||
html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None])
|
||||
|
||||
new_graceperiod = timedelta(**{'hours': 1})
|
||||
new_graceperiod = timedelta(hours=1)
|
||||
|
||||
self.assertNotIn('graceperiod', own_metadata(html_module))
|
||||
html_module.lms.graceperiod = new_graceperiod
|
||||
@@ -369,7 +369,6 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
'''
|
||||
module_store = modulestore('direct')
|
||||
import_from_xml(module_store, 'common/test/data/', ['full'])
|
||||
|
||||
effort = module_store.get_item(Location(['i4x', 'edX', 'full', 'about', 'effort', None]))
|
||||
self.assertEqual(effort.data, '6 hours')
|
||||
|
||||
@@ -617,12 +616,12 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
items = module_store.get_items(Location(['i4x', 'edX', 'full', 'vertical', None]))
|
||||
self.assertEqual(len(items), 0)
|
||||
|
||||
def verify_content_existence(self, modulestore, root_dir, location, dirname, category_name, filename_suffix=''):
|
||||
def verify_content_existence(self, store, root_dir, location, dirname, category_name, filename_suffix=''):
|
||||
filesystem = OSFS(root_dir / 'test_export')
|
||||
self.assertTrue(filesystem.exists(dirname))
|
||||
|
||||
query_loc = Location('i4x', location.org, location.course, category_name, None)
|
||||
items = modulestore.get_items(query_loc)
|
||||
items = store.get_items(query_loc)
|
||||
|
||||
for item in items:
|
||||
filesystem = OSFS(root_dir / ('test_export/' + dirname))
|
||||
@@ -768,7 +767,6 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
def test_prefetch_children(self):
|
||||
module_store = modulestore('direct')
|
||||
import_from_xml(module_store, 'common/test/data/', ['full'])
|
||||
|
||||
location = CourseDescriptor.id_to_location('edX/full/6.002_Spring_2012')
|
||||
|
||||
wrapper = MongoCollectionFindWrapper(module_store.collection.find)
|
||||
@@ -864,7 +862,7 @@ class ContentStoreTest(ModuleStoreTestCase):
|
||||
|
||||
def test_create_course_duplicate_course(self):
|
||||
"""Test new course creation - error path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
self.client.post(reverse('create_new_course'), self.course_data)
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
data = parse_json(resp)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
@@ -872,7 +870,7 @@ class ContentStoreTest(ModuleStoreTestCase):
|
||||
|
||||
def test_create_course_duplicate_number(self):
|
||||
"""Test new course creation - error path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
self.client.post(reverse('create_new_course'), self.course_data)
|
||||
self.course_data['display_name'] = 'Robot Super Course Two'
|
||||
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
@@ -1090,11 +1088,9 @@ class ContentStoreTest(ModuleStoreTestCase):
|
||||
json.dumps({'id': del_loc.url()}), "application/json")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
|
||||
def test_import_metadata_with_attempts_empty_string(self):
|
||||
module_store = modulestore('direct')
|
||||
import_from_xml(module_store, 'common/test/data/', ['simple'])
|
||||
|
||||
did_load_item = False
|
||||
try:
|
||||
module_store.get_item(Location(['i4x', 'edX', 'simple', 'problem', 'ps01-simple', None]))
|
||||
|
||||
@@ -224,14 +224,14 @@ def add_extra_panel_tab(tab_type, course):
|
||||
@param course: A course object from the modulestore.
|
||||
@return: Boolean indicating whether or not a tab was added and a list of tabs for the course.
|
||||
"""
|
||||
#Copy course tabs
|
||||
# Copy course tabs
|
||||
course_tabs = copy.copy(course.tabs)
|
||||
changed = False
|
||||
#Check to see if open ended panel is defined in the course
|
||||
# Check to see if open ended panel is defined in the course
|
||||
|
||||
tab_panel = EXTRA_TAB_PANELS.get(tab_type)
|
||||
if tab_panel not in course_tabs:
|
||||
#Add panel to the tabs if it is not defined
|
||||
# Add panel to the tabs if it is not defined
|
||||
course_tabs.append(tab_panel)
|
||||
changed = True
|
||||
return changed, course_tabs
|
||||
@@ -244,14 +244,14 @@ def remove_extra_panel_tab(tab_type, course):
|
||||
@param course: A course object from the modulestore.
|
||||
@return: Boolean indicating whether or not a tab was added and a list of tabs for the course.
|
||||
"""
|
||||
#Copy course tabs
|
||||
# Copy course tabs
|
||||
course_tabs = copy.copy(course.tabs)
|
||||
changed = False
|
||||
#Check to see if open ended panel is defined in the course
|
||||
# Check to see if open ended panel is defined in the course
|
||||
|
||||
tab_panel = EXTRA_TAB_PANELS.get(tab_type)
|
||||
if tab_panel in course_tabs:
|
||||
#Add panel to the tabs if it is not defined
|
||||
# Add panel to the tabs if it is not defined
|
||||
course_tabs = [ct for ct in course_tabs if ct != tab_panel]
|
||||
changed = True
|
||||
return changed, course_tabs
|
||||
|
||||
@@ -12,8 +12,8 @@ from django.core.urlresolvers import reverse
|
||||
from mitxmako.shortcuts import render_to_response
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, \
|
||||
InvalidLocationError
|
||||
from xmodule.modulestore import Location
|
||||
|
||||
from contentstore.course_info_model import get_course_updates, update_course_updates, delete_course_update
|
||||
@@ -33,9 +33,6 @@ from .component import OPEN_ENDED_COMPONENT_TYPES, \
|
||||
from django_comment_common.utils import seed_permissions_roles
|
||||
import datetime
|
||||
from django.utils.timezone import UTC
|
||||
|
||||
# TODO: should explicitly enumerate exports with __all__
|
||||
|
||||
__all__ = ['course_index', 'create_new_course', 'course_info',
|
||||
'course_info_updates', 'get_course_settings',
|
||||
'course_config_graders_page',
|
||||
|
||||
@@ -103,7 +103,7 @@ def clone_item(request):
|
||||
@expect_json
|
||||
def delete_item(request):
|
||||
item_location = request.POST['id']
|
||||
item_loc = Location(item_location)
|
||||
item_location = Location(item_location)
|
||||
|
||||
# check permissions for this user within this course
|
||||
if not has_access(request.user, item_location):
|
||||
@@ -124,11 +124,11 @@ def delete_item(request):
|
||||
|
||||
# cdodge: we need to remove our parent's pointer to us so that it is no longer dangling
|
||||
if delete_all_versions:
|
||||
parent_locs = modulestore('direct').get_parent_locations(item_loc, None)
|
||||
parent_locs = modulestore('direct').get_parent_locations(item_location, None)
|
||||
|
||||
for parent_loc in parent_locs:
|
||||
parent = modulestore('direct').get_item(parent_loc)
|
||||
item_url = item_loc.url()
|
||||
item_url = item_location.url()
|
||||
if item_url in parent.children:
|
||||
children = parent.children
|
||||
children.remove(item_url)
|
||||
|
||||
@@ -41,25 +41,25 @@ class CourseDetails(object):
|
||||
course.enrollment_start = descriptor.enrollment_start
|
||||
course.enrollment_end = descriptor.enrollment_end
|
||||
|
||||
temploc = course_location._replace(category='about', name='syllabus')
|
||||
temploc = course_location.replace(category='about', name='syllabus')
|
||||
try:
|
||||
course.syllabus = get_modulestore(temploc).get_item(temploc).data
|
||||
except ItemNotFoundError:
|
||||
pass
|
||||
|
||||
temploc = temploc._replace(name='overview')
|
||||
temploc = temploc.replace(name='overview')
|
||||
try:
|
||||
course.overview = get_modulestore(temploc).get_item(temploc).data
|
||||
except ItemNotFoundError:
|
||||
pass
|
||||
|
||||
temploc = temploc._replace(name='effort')
|
||||
temploc = temploc.replace(name='effort')
|
||||
try:
|
||||
course.effort = get_modulestore(temploc).get_item(temploc).data
|
||||
except ItemNotFoundError:
|
||||
pass
|
||||
|
||||
temploc = temploc._replace(name='video')
|
||||
temploc = temploc.replace(name='video')
|
||||
try:
|
||||
raw_video = get_modulestore(temploc).get_item(temploc).data
|
||||
course.intro_video = CourseDetails.parse_video_tag(raw_video)
|
||||
@@ -126,16 +126,16 @@ class CourseDetails(object):
|
||||
|
||||
# NOTE: below auto writes to the db w/o verifying that any of the fields actually changed
|
||||
# to make faster, could compare against db or could have client send over a list of which fields changed.
|
||||
temploc = Location(course_location)._replace(category='about', name='syllabus')
|
||||
temploc = Location(course_location).replace(category='about', name='syllabus')
|
||||
update_item(temploc, jsondict['syllabus'])
|
||||
|
||||
temploc = temploc._replace(name='overview')
|
||||
temploc = temploc.replace(name='overview')
|
||||
update_item(temploc, jsondict['overview'])
|
||||
|
||||
temploc = temploc._replace(name='effort')
|
||||
temploc = temploc.replace(name='effort')
|
||||
update_item(temploc, jsondict['effort'])
|
||||
|
||||
temploc = temploc._replace(name='video')
|
||||
temploc = temploc.replace(name='video')
|
||||
recomposed_video_tag = CourseDetails.recompose_video_tag(jsondict['intro_video'])
|
||||
update_item(temploc, recomposed_video_tag)
|
||||
|
||||
@@ -174,10 +174,10 @@ class CourseDetails(object):
|
||||
return result
|
||||
|
||||
|
||||
# TODO move to a more general util? Is there a better way to do the isinstance model check?
|
||||
# TODO move to a more general util?
|
||||
class CourseSettingsEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if isinstance(obj, CourseDetails) or isinstance(obj, course_grading.CourseGradingModel):
|
||||
if isinstance(obj, (CourseDetails, course_grading.CourseGradingModel)):
|
||||
return obj.__dict__
|
||||
elif isinstance(obj, Location):
|
||||
return obj.dict()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pylint: disable=C0111
|
||||
#pylint: disable=W0621
|
||||
# pylint: disable=C0111
|
||||
# pylint: disable=W0621
|
||||
|
||||
from lettuce import world, step
|
||||
from .factories import *
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import re
|
||||
import json
|
||||
import logging
|
||||
import static_replace
|
||||
|
||||
@@ -58,7 +58,7 @@ class CombinedOpenEndedFields(object):
|
||||
state = String(help="Which step within the current task that the student is on.", default="initial",
|
||||
scope=Scope.user_state)
|
||||
student_attempts = Integer(help="Number of attempts taken by the student on this problem", default=0,
|
||||
scope=Scope.user_state)
|
||||
scope=Scope.user_state)
|
||||
ready_to_reset = Boolean(
|
||||
help="If the problem is ready to be reset or not.", default=False,
|
||||
scope=Scope.user_state
|
||||
@@ -66,7 +66,7 @@ class CombinedOpenEndedFields(object):
|
||||
attempts = Integer(
|
||||
display_name="Maximum Attempts",
|
||||
help="The number of times the student can try to answer this problem.", default=1,
|
||||
scope=Scope.settings, values = {"min" : 1 }
|
||||
scope=Scope.settings, values={"min" : 1 }
|
||||
)
|
||||
is_graded = Boolean(display_name="Graded", help="Whether or not the problem is graded.", default=False, scope=Scope.settings)
|
||||
accept_file_upload = Boolean(
|
||||
@@ -89,7 +89,7 @@ class CombinedOpenEndedFields(object):
|
||||
weight = Float(
|
||||
display_name="Problem Weight",
|
||||
help="Defines the number of points each problem is worth. If the value is not set, each problem is worth one point.",
|
||||
scope=Scope.settings, values = {"min" : 0 , "step": ".1"}
|
||||
scope=Scope.settings, values={"min" : 0 , "step": ".1"}
|
||||
)
|
||||
markdown = String(help="Markdown source of this module", scope=Scope.settings)
|
||||
|
||||
|
||||
@@ -77,10 +77,8 @@ class Date(ModelType):
|
||||
else:
|
||||
return value.isoformat()
|
||||
|
||||
|
||||
TIMEDELTA_REGEX = re.compile(r'^((?P<days>\d+?) day(?:s?))?(\s)?((?P<hours>\d+?) hour(?:s?))?(\s)?((?P<minutes>\d+?) minute(?:s)?)?(\s)?((?P<seconds>\d+?) second(?:s)?)?$')
|
||||
|
||||
|
||||
class Timedelta(ModelType):
|
||||
def from_json(self, time_str):
|
||||
"""
|
||||
|
||||
@@ -84,7 +84,7 @@ class GraphicalSliderToolModule(GraphicalSliderToolFields, XModule):
|
||||
|
||||
xml = html.fromstring(html_string)
|
||||
|
||||
#substitute plot, if presented
|
||||
# substitute plot, if presented
|
||||
plot_div = '<div class="{element_class}_plot" id="{element_id}_plot" \
|
||||
style="{style}"></div>'
|
||||
plot_el = xml.xpath('//plot')
|
||||
@@ -95,7 +95,7 @@ class GraphicalSliderToolModule(GraphicalSliderToolFields, XModule):
|
||||
element_id=self.html_id,
|
||||
style=plot_el.get('style', ""))))
|
||||
|
||||
#substitute sliders
|
||||
# substitute sliders
|
||||
slider_div = '<div class="{element_class}_slider" \
|
||||
id="{element_id}_slider_{var}" \
|
||||
data-var="{var}" \
|
||||
|
||||
@@ -57,7 +57,7 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor):
|
||||
if path.endswith('.html.xml'):
|
||||
path = path[:-9] + '.html' # backcompat--look for html instead of xml
|
||||
if path.endswith('.html.html'):
|
||||
path = path[:-5] # some people like to include .html in filenames..
|
||||
path = path[:-5] # some people like to include .html in filenames..
|
||||
candidates = []
|
||||
while os.sep in path:
|
||||
candidates.append(path)
|
||||
@@ -100,9 +100,9 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor):
|
||||
pointer_path = "{category}/{url_path}".format(category='html',
|
||||
url_path=name_to_pathname(location.name))
|
||||
base = path(pointer_path).dirname()
|
||||
#log.debug("base = {0}, base.dirname={1}, filename={2}".format(base, base.dirname(), filename))
|
||||
# log.debug("base = {0}, base.dirname={1}, filename={2}".format(base, base.dirname(), filename))
|
||||
filepath = "{base}/{name}.html".format(base=base, name=filename)
|
||||
#log.debug("looking for html file for {0} at {1}".format(location, filepath))
|
||||
# log.debug("looking for html file for {0} at {1}".format(location, filepath))
|
||||
|
||||
# VS[compat]
|
||||
# TODO (cpennington): If the file doesn't exist at the right path,
|
||||
@@ -111,7 +111,7 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor):
|
||||
# online and has imported all current (fall 2012) courses from xml
|
||||
if not system.resources_fs.exists(filepath):
|
||||
candidates = cls.backcompat_paths(filepath)
|
||||
#log.debug("candidates = {0}".format(candidates))
|
||||
# log.debug("candidates = {0}".format(candidates))
|
||||
for candidate in candidates:
|
||||
if system.resources_fs.exists(candidate):
|
||||
filepath = candidate
|
||||
|
||||
@@ -196,7 +196,7 @@ class Location(_LocationBase):
|
||||
raise InvalidLocationError(location)
|
||||
|
||||
if len(location) == 5:
|
||||
args = tuple(location) + (None, )
|
||||
args = tuple(location) + (None,)
|
||||
else:
|
||||
args = tuple(location)
|
||||
|
||||
@@ -415,7 +415,7 @@ class ModuleStoreBase(ModuleStore):
|
||||
'''
|
||||
Set up the error-tracking logic.
|
||||
'''
|
||||
self._location_errors = {} # location -> ErrorLog
|
||||
self._location_errors = {} # location -> ErrorLog
|
||||
self.metadata_inheritance_cache = None
|
||||
self.modulestore_update_signal = None # can be set by runtime to route notifications of datastore changes
|
||||
|
||||
@@ -440,7 +440,7 @@ class ModuleStoreBase(ModuleStore):
|
||||
"""
|
||||
# check that item is present and raise the promised exceptions if needed
|
||||
# TODO (vshnayder): post-launch, make errors properties of items
|
||||
#self.get_item(location)
|
||||
# self.get_item(location)
|
||||
|
||||
errorlog = self._get_errorlog(location)
|
||||
return errorlog.errors
|
||||
|
||||
@@ -15,14 +15,14 @@ def as_draft(location):
|
||||
"""
|
||||
Returns the Location that is the draft for `location`
|
||||
"""
|
||||
return Location(location)._replace(revision=DRAFT)
|
||||
return Location(location).replace(revision=DRAFT)
|
||||
|
||||
|
||||
def as_published(location):
|
||||
"""
|
||||
Returns the Location that is the published version for `location`
|
||||
"""
|
||||
return Location(location)._replace(revision=None)
|
||||
return Location(location).replace(revision=None)
|
||||
|
||||
|
||||
def wrap_draft(item):
|
||||
@@ -32,7 +32,7 @@ def wrap_draft(item):
|
||||
non-draft location in either case
|
||||
"""
|
||||
setattr(item, 'is_draft', item.location.revision == DRAFT)
|
||||
item.location = item.location._replace(revision=None)
|
||||
item.location = item.location.replace(revision=None)
|
||||
return item
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ class DraftModuleStore(ModuleStoreBase):
|
||||
# always return the draft - if available
|
||||
for draft in to_process_drafts:
|
||||
draft_loc = Location(draft["_id"])
|
||||
draft_as_non_draft_loc = draft_loc._replace(revision=None)
|
||||
draft_as_non_draft_loc = draft_loc.replace(revision=None)
|
||||
|
||||
# does non-draft exist in the collection
|
||||
# if so, replace it
|
||||
|
||||
@@ -307,7 +307,7 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
location = Location(result['_id'])
|
||||
# We need to collate between draft and non-draft
|
||||
# i.e. draft verticals can have children which are not in non-draft versions
|
||||
location = location._replace(revision=None)
|
||||
location = location.replace(revision=None)
|
||||
location_url = location.url()
|
||||
if location_url in results_by_url:
|
||||
existing_children = results_by_url[location_url].get('definition', {}).get('children', [])
|
||||
|
||||
@@ -19,18 +19,18 @@ log = logging.getLogger("mitx.courseware")
|
||||
# attempts specified in xml definition overrides this.
|
||||
MAX_ATTEMPTS = 1
|
||||
|
||||
#The highest score allowed for the overall xmodule and for each rubric point
|
||||
# The highest score allowed for the overall xmodule and for each rubric point
|
||||
MAX_SCORE_ALLOWED = 50
|
||||
|
||||
#If true, default behavior is to score module as a practice problem. Otherwise, no grade at all is shown in progress
|
||||
#Metadata overrides this.
|
||||
# If true, default behavior is to score module as a practice problem. Otherwise, no grade at all is shown in progress
|
||||
# Metadata overrides this.
|
||||
IS_SCORED = False
|
||||
|
||||
#If true, then default behavior is to require a file upload or pasted link from a student for this problem.
|
||||
#Metadata overrides this.
|
||||
# If true, then default behavior is to require a file upload or pasted link from a student for this problem.
|
||||
# Metadata overrides this.
|
||||
ACCEPT_FILE_UPLOAD = False
|
||||
|
||||
#Contains all reasonable bool and case combinations of True
|
||||
# Contains all reasonable bool and case combinations of True
|
||||
TRUE_DICT = ["True", True, "TRUE", "true"]
|
||||
|
||||
HUMAN_TASK_TYPE = {
|
||||
@@ -38,8 +38,8 @@ HUMAN_TASK_TYPE = {
|
||||
'openended': "edX Assessment",
|
||||
}
|
||||
|
||||
#Default value that controls whether or not to skip basic spelling checks in the controller
|
||||
#Metadata overrides this
|
||||
# Default value that controls whether or not to skip basic spelling checks in the controller
|
||||
# Metadata overrides this
|
||||
SKIP_BASIC_CHECKS = False
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class CombinedOpenEndedV1Module():
|
||||
INTERMEDIATE_DONE = 'intermediate_done'
|
||||
DONE = 'done'
|
||||
|
||||
#Where the templates live for this problem
|
||||
# Where the templates live for this problem
|
||||
TEMPLATE_DIR = "combinedopenended"
|
||||
|
||||
def __init__(self, system, location, definition, descriptor,
|
||||
@@ -118,21 +118,21 @@ class CombinedOpenEndedV1Module():
|
||||
self.instance_state = instance_state
|
||||
self.display_name = instance_state.get('display_name', "Open Ended")
|
||||
|
||||
#We need to set the location here so the child modules can use it
|
||||
# We need to set the location here so the child modules can use it
|
||||
system.set('location', location)
|
||||
self.system = system
|
||||
|
||||
#Tells the system which xml definition to load
|
||||
# Tells the system which xml definition to load
|
||||
self.current_task_number = instance_state.get('current_task_number', 0)
|
||||
#This loads the states of the individual children
|
||||
# This loads the states of the individual children
|
||||
self.task_states = instance_state.get('task_states', [])
|
||||
#Overall state of the combined open ended module
|
||||
# Overall state of the combined open ended module
|
||||
self.state = instance_state.get('state', self.INITIAL)
|
||||
|
||||
self.student_attempts = instance_state.get('student_attempts', 0)
|
||||
self.weight = instance_state.get('weight', 1)
|
||||
|
||||
#Allow reset is true if student has failed the criteria to move to the next child task
|
||||
# Allow reset is true if student has failed the criteria to move to the next child task
|
||||
self.ready_to_reset = instance_state.get('ready_to_reset', False)
|
||||
self.attempts = self.instance_state.get('attempts', MAX_ATTEMPTS)
|
||||
self.is_scored = self.instance_state.get('is_graded', IS_SCORED) in TRUE_DICT
|
||||
@@ -153,7 +153,7 @@ class CombinedOpenEndedV1Module():
|
||||
rubric_string = stringify_children(definition['rubric'])
|
||||
self._max_score = self.rubric_renderer.check_if_rubric_is_parseable(rubric_string, location, MAX_SCORE_ALLOWED)
|
||||
|
||||
#Static data is passed to the child modules to render
|
||||
# Static data is passed to the child modules to render
|
||||
self.static_data = {
|
||||
'max_score': self._max_score,
|
||||
'max_attempts': self.attempts,
|
||||
@@ -243,11 +243,11 @@ class CombinedOpenEndedV1Module():
|
||||
|
||||
self.current_task_descriptor = children['descriptors'][current_task_type](self.system)
|
||||
|
||||
#This is the xml object created from the xml definition of the current task
|
||||
# This is the xml object created from the xml definition of the current task
|
||||
etree_xml = etree.fromstring(self.current_task_xml)
|
||||
|
||||
#This sends the etree_xml object through the descriptor module of the current task, and
|
||||
#returns the xml parsed by the descriptor
|
||||
# This sends the etree_xml object through the descriptor module of the current task, and
|
||||
# returns the xml parsed by the descriptor
|
||||
self.current_task_parsed_xml = self.current_task_descriptor.definition_from_xml(etree_xml, self.system)
|
||||
if current_task_state is None and self.current_task_number == 0:
|
||||
self.current_task = child_task_module(self.system, self.location,
|
||||
@@ -293,8 +293,9 @@ class CombinedOpenEndedV1Module():
|
||||
if self.current_task_number > 0:
|
||||
last_response_data = self.get_last_response(self.current_task_number - 1)
|
||||
current_response_data = self.get_current_attributes(self.current_task_number)
|
||||
|
||||
if (current_response_data['min_score_to_attempt'] > last_response_data['score']
|
||||
or current_response_data['max_score_to_attempt'] < last_response_data['score']):
|
||||
or current_response_data['max_score_to_attempt'] < last_response_data['score']):
|
||||
self.state = self.DONE
|
||||
self.ready_to_reset = True
|
||||
|
||||
@@ -307,7 +308,7 @@ class CombinedOpenEndedV1Module():
|
||||
Output: A dictionary that can be rendered into the combined open ended template.
|
||||
"""
|
||||
task_html = self.get_html_base()
|
||||
#set context variables and render template
|
||||
# set context variables and render template
|
||||
|
||||
context = {
|
||||
'items': [{'content': task_html}],
|
||||
@@ -499,7 +500,6 @@ class CombinedOpenEndedV1Module():
|
||||
"""
|
||||
changed = self.update_task_states()
|
||||
if changed:
|
||||
#return_html=self.get_html()
|
||||
pass
|
||||
return return_html
|
||||
|
||||
@@ -730,15 +730,15 @@ class CombinedOpenEndedV1Module():
|
||||
max_score = None
|
||||
score = None
|
||||
if self.is_scored and self.weight is not None:
|
||||
#Finds the maximum score of all student attempts and keeps it.
|
||||
# Finds the maximum score of all student attempts and keeps it.
|
||||
score_mat = []
|
||||
for i in xrange(0, len(self.task_states)):
|
||||
#For each task, extract all student scores on that task (each attempt for each task)
|
||||
# For each task, extract all student scores on that task (each attempt for each task)
|
||||
last_response = self.get_last_response(i)
|
||||
max_score = last_response.get('max_score', None)
|
||||
score = last_response.get('all_scores', None)
|
||||
if score is not None:
|
||||
#Convert none scores and weight scores properly
|
||||
# Convert none scores and weight scores properly
|
||||
for z in xrange(0, len(score)):
|
||||
if score[z] is None:
|
||||
score[z] = 0
|
||||
@@ -746,19 +746,19 @@ class CombinedOpenEndedV1Module():
|
||||
score_mat.append(score)
|
||||
|
||||
if len(score_mat) > 0:
|
||||
#Currently, assume that the final step is the correct one, and that those are the final scores.
|
||||
#This will change in the future, which is why the machinery above exists to extract all scores on all steps
|
||||
#TODO: better final score handling.
|
||||
# Currently, assume that the final step is the correct one, and that those are the final scores.
|
||||
# This will change in the future, which is why the machinery above exists to extract all scores on all steps
|
||||
# TODO: better final score handling.
|
||||
scores = score_mat[-1]
|
||||
score = max(scores)
|
||||
else:
|
||||
score = 0
|
||||
|
||||
if max_score is not None:
|
||||
#Weight the max score if it is not None
|
||||
# Weight the max score if it is not None
|
||||
max_score *= float(self.weight)
|
||||
else:
|
||||
#Without a max_score, we cannot have a score!
|
||||
# Without a max_score, we cannot have a score!
|
||||
score = None
|
||||
|
||||
score_dict = {
|
||||
@@ -833,7 +833,7 @@ class CombinedOpenEndedV1Descriptor():
|
||||
expected_children = ['task', 'rubric', 'prompt']
|
||||
for child in expected_children:
|
||||
if len(xml_object.xpath(child)) == 0:
|
||||
#This is a staff_facing_error
|
||||
# This is a staff_facing_error
|
||||
raise ValueError(
|
||||
"Combined Open Ended definition must include at least one '{0}' tag. Contact the learning sciences group for assistance. {1}".format(
|
||||
child, xml_object))
|
||||
@@ -848,6 +848,7 @@ class CombinedOpenEndedV1Descriptor():
|
||||
|
||||
return {'task_xml': parse_task('task'), 'prompt': parse('prompt'), 'rubric': parse('rubric')}
|
||||
|
||||
|
||||
def definition_to_xml(self, resource_fs):
|
||||
'''Return an xml element representing this definition.'''
|
||||
elt = etree.Element('combinedopenended')
|
||||
|
||||
@@ -57,13 +57,13 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
self.queue_name = definition.get('queuename', self.DEFAULT_QUEUE)
|
||||
self.message_queue_name = definition.get('message-queuename', self.DEFAULT_MESSAGE_QUEUE)
|
||||
|
||||
#This is needed to attach feedback to specific responses later
|
||||
# This is needed to attach feedback to specific responses later
|
||||
self.submission_id = None
|
||||
self.grader_id = None
|
||||
|
||||
error_message = "No {0} found in problem xml for open ended problem. Contact the learning sciences group for assistance."
|
||||
if oeparam is None:
|
||||
#This is a staff_facing_error
|
||||
# This is a staff_facing_error
|
||||
raise ValueError(error_message.format('oeparam'))
|
||||
if self.child_prompt is None:
|
||||
raise ValueError(error_message.format('prompt'))
|
||||
@@ -95,14 +95,14 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
grader_payload = oeparam.find('grader_payload')
|
||||
grader_payload = grader_payload.text if grader_payload is not None else ''
|
||||
|
||||
#Update grader payload with student id. If grader payload not json, error.
|
||||
# Update grader payload with student id. If grader payload not json, error.
|
||||
try:
|
||||
parsed_grader_payload = json.loads(grader_payload)
|
||||
# NOTE: self.system.location is valid because the capa_module
|
||||
# __init__ adds it (easiest way to get problem location into
|
||||
# response types)
|
||||
except TypeError, ValueError:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
log.exception(
|
||||
"Grader payload from external open ended grading server is not a json object! Object: {0}".format(
|
||||
grader_payload))
|
||||
@@ -148,7 +148,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
survey_responses = event_info['survey_responses']
|
||||
for tag in ['feedback', 'submission_id', 'grader_id', 'score']:
|
||||
if tag not in survey_responses:
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
return {'success': False,
|
||||
'msg': "Could not find needed tag {0} in the survey responses. Please try submitting again.".format(
|
||||
tag)}
|
||||
@@ -158,14 +158,14 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
feedback = str(survey_responses['feedback'].encode('ascii', 'ignore'))
|
||||
score = int(survey_responses['score'])
|
||||
except:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
error_message = (
|
||||
"Could not parse submission id, grader id, "
|
||||
"or feedback from message_post ajax call. "
|
||||
"Here is the message data: {0}".format(survey_responses)
|
||||
)
|
||||
log.exception(error_message)
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
return {'success': False, 'msg': "There was an error saving your feedback. Please contact course staff."}
|
||||
|
||||
xqueue = system.get('xqueue')
|
||||
@@ -201,14 +201,14 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
body=json.dumps(contents)
|
||||
)
|
||||
|
||||
#Convert error to a success value
|
||||
# Convert error to a success value
|
||||
success = True
|
||||
if error:
|
||||
success = False
|
||||
|
||||
self.child_state = self.DONE
|
||||
|
||||
#This is a student_facing_message
|
||||
# This is a student_facing_message
|
||||
return {'success': success, 'msg': "Successfully submitted your feedback."}
|
||||
|
||||
def send_to_grader(self, submission, system):
|
||||
@@ -249,7 +249,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
'submission_time': qtime,
|
||||
}
|
||||
|
||||
#Update contents with student response and student info
|
||||
# Update contents with student response and student info
|
||||
contents.update({
|
||||
'student_info': json.dumps(student_info),
|
||||
'student_response': submission,
|
||||
@@ -369,21 +369,21 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
|
||||
for tag in ['success', 'feedback', 'submission_id', 'grader_id']:
|
||||
if tag not in response_items:
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
return format_feedback('errors', 'Error getting feedback from grader.')
|
||||
|
||||
feedback_items = response_items['feedback']
|
||||
try:
|
||||
feedback = json.loads(feedback_items)
|
||||
except (TypeError, ValueError):
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
log.exception("feedback_items from external open ended grader have invalid json {0}".format(feedback_items))
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
return format_feedback('errors', 'Error getting feedback from grader.')
|
||||
|
||||
if response_items['success']:
|
||||
if len(feedback) == 0:
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
return format_feedback('errors', 'No feedback available from grader.')
|
||||
|
||||
for tag in do_not_render:
|
||||
@@ -393,7 +393,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
feedback_lst = sorted(feedback.items(), key=get_priority)
|
||||
feedback_list_part1 = u"\n".join(format_feedback(k, v) for k, v in feedback_lst)
|
||||
else:
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
feedback_list_part1 = format_feedback('errors', response_items['feedback'])
|
||||
|
||||
feedback_list_part2 = (u"\n".join([format_feedback_hidden(feedback_type, value)
|
||||
@@ -470,7 +470,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
try:
|
||||
score_result = json.loads(score_msg)
|
||||
except (TypeError, ValueError):
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
error_message = ("External open ended grader message should be a JSON-serialized dict."
|
||||
" Received score_msg = {0}".format(score_msg))
|
||||
log.error(error_message)
|
||||
@@ -478,7 +478,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
return fail
|
||||
|
||||
if not isinstance(score_result, dict):
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
error_message = ("External open ended grader message should be a JSON-serialized dict."
|
||||
" Received score_result = {0}".format(score_result))
|
||||
log.error(error_message)
|
||||
@@ -487,13 +487,13 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
|
||||
for tag in ['score', 'feedback', 'grader_type', 'success', 'grader_id', 'submission_id']:
|
||||
if tag not in score_result:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
error_message = ("External open ended grader message is missing required tag: {0}"
|
||||
.format(tag))
|
||||
log.error(error_message)
|
||||
fail['feedback'] = error_message
|
||||
return fail
|
||||
#This is to support peer grading
|
||||
# This is to support peer grading
|
||||
if isinstance(score_result['score'], list):
|
||||
feedback_items = []
|
||||
rubric_scores = []
|
||||
@@ -529,7 +529,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
feedback = feedback_items
|
||||
score = int(median(score_result['score']))
|
||||
else:
|
||||
#This is for instructor and ML grading
|
||||
# This is for instructor and ML grading
|
||||
feedback, rubric_score = self._format_feedback(score_result, system)
|
||||
score = score_result['score']
|
||||
rubric_scores = [rubric_score]
|
||||
@@ -608,9 +608,9 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
}
|
||||
|
||||
if dispatch not in handlers:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
log.error("Cannot find {0} in handlers in handle_ajax function for open_ended_module.py".format(dispatch))
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
return json.dumps({'error': 'Error handling action. Please try again.', 'success': False})
|
||||
|
||||
before = self.get_progress()
|
||||
@@ -659,10 +659,10 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
self.send_to_grader(get['student_answer'], system)
|
||||
self.change_state(self.ASSESSING)
|
||||
else:
|
||||
#Error message already defined
|
||||
# Error message already defined
|
||||
success = False
|
||||
else:
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
error_message = "There was a problem saving the image in your submission. Please try a different image, or try pasting a link to an image into the answer box."
|
||||
|
||||
return {
|
||||
@@ -679,7 +679,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
"""
|
||||
queuekey = get['queuekey']
|
||||
score_msg = get['xqueue_body']
|
||||
#TODO: Remove need for cmap
|
||||
# TODO: Remove need for cmap
|
||||
self._update_score(score_msg, queuekey, system)
|
||||
|
||||
return dict() # No AJAX return is needed
|
||||
@@ -690,7 +690,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
|
||||
Input: Modulesystem object
|
||||
Output: Rendered HTML
|
||||
"""
|
||||
#set context variables and render template
|
||||
# set context variables and render template
|
||||
eta_string = None
|
||||
if self.child_state != self.INITIAL:
|
||||
latest = self.latest_answer()
|
||||
@@ -749,7 +749,7 @@ class OpenEndedDescriptor():
|
||||
"""
|
||||
for child in ['openendedparam']:
|
||||
if len(xml_object.xpath(child)) != 1:
|
||||
#This is a staff_facing_error
|
||||
# This is a staff_facing_error
|
||||
raise ValueError(
|
||||
"Open Ended definition must include exactly one '{0}' tag. Contact the learning sciences group for assistance.".format(
|
||||
child))
|
||||
|
||||
@@ -54,7 +54,7 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
@param system: Modulesystem
|
||||
@return: Rendered HTML
|
||||
"""
|
||||
#set context variables and render template
|
||||
# set context variables and render template
|
||||
if self.child_state != self.INITIAL:
|
||||
latest = self.latest_answer()
|
||||
previous_answer = latest if latest is not None else ''
|
||||
@@ -93,9 +93,9 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
}
|
||||
|
||||
if dispatch not in handlers:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
log.error("Cannot find {0} in handlers in handle_ajax function for open_ended_module.py".format(dispatch))
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
return json.dumps({'error': 'Error handling action. Please try again.', 'success': False})
|
||||
|
||||
before = self.get_progress()
|
||||
@@ -129,7 +129,7 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
elif self.child_state in (self.POST_ASSESSMENT, self.DONE):
|
||||
context['read_only'] = True
|
||||
else:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
raise ValueError("Self assessment module is in an illegal state '{0}'".format(self.child_state))
|
||||
|
||||
return system.render_template('{0}/self_assessment_rubric.html'.format(self.TEMPLATE_DIR), context)
|
||||
@@ -155,7 +155,7 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
elif self.child_state == self.DONE:
|
||||
context['read_only'] = True
|
||||
else:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
raise ValueError("Self Assessment module is in an illegal state '{0}'".format(self.child_state))
|
||||
|
||||
return system.render_template('{0}/self_assessment_hint.html'.format(self.TEMPLATE_DIR), context)
|
||||
@@ -190,10 +190,10 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
self.new_history_entry(get['student_answer'])
|
||||
self.change_state(self.ASSESSING)
|
||||
else:
|
||||
#Error message already defined
|
||||
# Error message already defined
|
||||
success = False
|
||||
else:
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
error_message = "There was a problem saving the image in your submission. Please try a different image, or try pasting a link to an image into the answer box."
|
||||
|
||||
return {
|
||||
@@ -227,12 +227,12 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
for i in xrange(0, len(score_list)):
|
||||
score_list[i] = int(score_list[i])
|
||||
except ValueError:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
log.error("Non-integer score value passed to save_assessment ,or no score list present.")
|
||||
#This is a student_facing_error
|
||||
# This is a student_facing_error
|
||||
return {'success': False, 'error': "Error saving your score. Please notify course staff."}
|
||||
|
||||
#Record score as assessment and rubric scores as post assessment
|
||||
# Record score as assessment and rubric scores as post assessment
|
||||
self.record_latest_score(score)
|
||||
self.record_latest_post_assessment(json.dumps(score_list))
|
||||
|
||||
@@ -272,7 +272,7 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
try:
|
||||
rubric_scores = json.loads(latest_post_assessment)
|
||||
except:
|
||||
#This is a dev_facing_error
|
||||
# This is a dev_facing_error
|
||||
log.error("Cannot parse rubric scores in self assessment module from {0}".format(latest_post_assessment))
|
||||
rubric_scores = []
|
||||
return [rubric_scores]
|
||||
@@ -306,7 +306,7 @@ class SelfAssessmentDescriptor():
|
||||
expected_children = []
|
||||
for child in expected_children:
|
||||
if len(xml_object.xpath(child)) != 1:
|
||||
#This is a staff_facing_error
|
||||
# This is a staff_facing_error
|
||||
raise ValueError(
|
||||
"Self assessment definition must include exactly one '{0}' tag. Contact the learning sciences group for assistance.".format(
|
||||
child))
|
||||
|
||||
@@ -62,7 +62,7 @@ class SequenceModule(SequenceFields, XModule):
|
||||
progress = reduce(Progress.add_counts, progresses)
|
||||
return progress
|
||||
|
||||
def handle_ajax(self, dispatch, get): # TODO: bounds checking
|
||||
def handle_ajax(self, dispatch, get): # TODO: bounds checking
|
||||
''' get = request.POST instance '''
|
||||
if dispatch == 'goto_position':
|
||||
self.position = int(get['position'])
|
||||
|
||||
@@ -55,7 +55,7 @@ class CustomTagDescriptor(RawDescriptor):
|
||||
params = dict(xmltree.items())
|
||||
|
||||
# cdodge: look up the template as a module
|
||||
template_loc = self.location._replace(category='custom_tag_template', name=template_name)
|
||||
template_loc = self.location.replace(category='custom_tag_template', name=template_name)
|
||||
|
||||
template_module = modulestore().get_instance(system.course_id, template_loc)
|
||||
template_module_data = template_module.data
|
||||
|
||||
@@ -15,7 +15,7 @@ from xblock.core import XBlock, Scope, String, Integer, Float, ModelType
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def dummy_track(event_type, event):
|
||||
def dummy_track(_event_type, _event):
|
||||
pass
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ class XModule(XModuleFields, HTMLSnippet, XBlock):
|
||||
'''
|
||||
return self.icon_class
|
||||
|
||||
### Functions used in the LMS
|
||||
# Functions used in the LMS
|
||||
|
||||
def get_score(self):
|
||||
"""
|
||||
@@ -272,7 +272,7 @@ class XModule(XModuleFields, HTMLSnippet, XBlock):
|
||||
'''
|
||||
return None
|
||||
|
||||
def handle_ajax(self, dispatch, get):
|
||||
def handle_ajax(self, _dispatch, _get):
|
||||
''' dispatch is last part of the URL.
|
||||
get is a dictionary-like object '''
|
||||
return ""
|
||||
@@ -647,13 +647,13 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
|
||||
# 1. A select editor for fields with a list of possible values (includes Booleans).
|
||||
# 2. Number editors for integers and floats.
|
||||
# 3. A generic string editor for anything else (editing JSON representation of the value).
|
||||
type = "Generic"
|
||||
editor_type = "Generic"
|
||||
values = [] if field.values is None else copy.deepcopy(field.values)
|
||||
if isinstance(values, tuple):
|
||||
values = list(values)
|
||||
if isinstance(values, list):
|
||||
if len(values) > 0:
|
||||
type = "Select"
|
||||
editor_type = "Select"
|
||||
for index, choice in enumerate(values):
|
||||
json_choice = copy.deepcopy(choice)
|
||||
if isinstance(json_choice, dict) and 'value' in json_choice:
|
||||
@@ -662,11 +662,11 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
|
||||
json_choice = field.to_json(json_choice)
|
||||
values[index] = json_choice
|
||||
elif isinstance(field, Integer):
|
||||
type = "Integer"
|
||||
editor_type = "Integer"
|
||||
elif isinstance(field, Float):
|
||||
type = "Float"
|
||||
editor_type = "Float"
|
||||
metadata_fields[field.name] = {'field_name': field.name,
|
||||
'type': type,
|
||||
'type': editor_type,
|
||||
'display_name': field.display_name,
|
||||
'value': field.to_json(value),
|
||||
'options': values,
|
||||
@@ -862,7 +862,7 @@ class ModuleSystem(object):
|
||||
|
||||
class DoNothingCache(object):
|
||||
"""A duck-compatible object to use in ModuleSystem when there's no cache."""
|
||||
def get(self, key):
|
||||
def get(self, _key):
|
||||
return None
|
||||
|
||||
def set(self, key, value, timeout=None):
|
||||
|
||||
@@ -56,7 +56,6 @@ def get_metadata_from_xml(xml_object, remove=True):
|
||||
if meta is None:
|
||||
return ''
|
||||
dmdata = meta.text
|
||||
#log.debug('meta for %s loaded: %s' % (xml_object,dmdata))
|
||||
if remove:
|
||||
xml_object.remove(meta)
|
||||
return dmdata
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pylint: disable=C0111
|
||||
#pylint: disable=W0621
|
||||
# pylint: disable=C0111
|
||||
# pylint: disable=W0621
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
|
||||
@@ -112,12 +112,12 @@ def assert_problem_has_answer(step, problem_type, answer_class):
|
||||
|
||||
|
||||
@step(u'I reset the problem')
|
||||
def reset_problem(step):
|
||||
def reset_problem(_step):
|
||||
world.css_click('input.reset')
|
||||
|
||||
|
||||
@step(u'I press the button with the label "([^"]*)"$')
|
||||
def press_the_button_with_label(step, buttonname):
|
||||
def press_the_button_with_label(_step, buttonname):
|
||||
button_css = 'button span.show-label'
|
||||
elem = world.css_find(button_css).first
|
||||
assert_equal(elem.text, buttonname)
|
||||
@@ -125,7 +125,7 @@ def press_the_button_with_label(step, buttonname):
|
||||
|
||||
|
||||
@step(u'The "([^"]*)" button does( not)? appear')
|
||||
def action_button_present(step, buttonname, doesnt_appear):
|
||||
def action_button_present(_step, buttonname, doesnt_appear):
|
||||
button_css = 'section.action input[value*="%s"]' % buttonname
|
||||
if doesnt_appear:
|
||||
assert world.is_css_not_present(button_css)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pylint: disable=C0111
|
||||
#pylint: disable=W0621
|
||||
# pylint: disable=C0111
|
||||
# pylint: disable=W0621
|
||||
|
||||
from lettuce import world, step
|
||||
from lettuce.django import django_url
|
||||
@@ -7,7 +7,7 @@ from common import TEST_COURSE_ORG, TEST_COURSE_NAME
|
||||
|
||||
|
||||
@step('I register for the course "([^"]*)"$')
|
||||
def i_register_for_the_course(step, course):
|
||||
def i_register_for_the_course(_step, course):
|
||||
cleaned_name = TEST_COURSE_NAME.replace(' ', '_')
|
||||
url = django_url('courses/%s/%s/%s/about' % (TEST_COURSE_ORG, course, cleaned_name))
|
||||
world.browser.visit(url)
|
||||
@@ -20,13 +20,13 @@ def i_register_for_the_course(step, course):
|
||||
|
||||
|
||||
@step(u'I should see an empty dashboard message')
|
||||
def i_should_see_empty_dashboard(step):
|
||||
def i_should_see_empty_dashboard(_step):
|
||||
empty_dash_css = 'section.empty-dashboard-message'
|
||||
assert world.is_css_present(empty_dash_css)
|
||||
|
||||
|
||||
@step(u'I should( NOT)? see the course numbered "([^"]*)" in my dashboard$')
|
||||
def i_should_see_that_course_in_my_dashboard(step, doesnt_appear, course):
|
||||
def i_should_see_that_course_in_my_dashboard(_step, doesnt_appear, course):
|
||||
course_link_css = 'section.my-courses a[href*="%s"]' % course
|
||||
if doesnt_appear:
|
||||
assert world.is_css_not_present(course_link_css)
|
||||
@@ -35,7 +35,7 @@ def i_should_see_that_course_in_my_dashboard(step, doesnt_appear, course):
|
||||
|
||||
|
||||
@step(u'I unregister for the course numbered "([^"]*)"')
|
||||
def i_unregister_for_that_course(step, course):
|
||||
def i_unregister_for_that_course(_step, course):
|
||||
unregister_css = 'section.info a[href*="#unenroll-modal"][data-course-number*="%s"]' % course
|
||||
world.css_click(unregister_css)
|
||||
button_css = 'section#unenroll-modal input[value="Unregister"]'
|
||||
|
||||
@@ -8,12 +8,12 @@ from common import TEST_COURSE_NAME, TEST_SECTION_NAME, i_am_registered_for_the_
|
||||
|
||||
|
||||
@step('when I view the video it has autoplay enabled')
|
||||
def does_autoplay(step):
|
||||
def does_autoplay(_step):
|
||||
assert(world.css_find('.video')[0]['data-autoplay'] == 'True')
|
||||
|
||||
|
||||
@step('the course has a Video component')
|
||||
def view_video(step):
|
||||
def view_video(_step):
|
||||
coursename = TEST_COURSE_NAME.replace(' ', '_')
|
||||
i_am_registered_for_the_course(step, coursename)
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ def get_module_for_descriptor_internal(user, descriptor, model_data_cache, cours
|
||||
student_module.max_grade = event.get('max_value')
|
||||
student_module.save()
|
||||
|
||||
#Bin score into range and increment stats
|
||||
# Bin score into range and increment stats
|
||||
score_bucket = get_score_bucket(student_module.grade, student_module.max_grade)
|
||||
org, course_num, run = course_id.split("/")
|
||||
|
||||
@@ -472,13 +472,13 @@ def modx_dispatch(request, dispatch, location, course_id):
|
||||
inputfiles = request.FILES.getlist(fileinput_id)
|
||||
|
||||
if len(inputfiles) > settings.MAX_FILEUPLOADS_PER_INPUT:
|
||||
too_many_files_msg = 'Submission aborted! Maximum %d files may be submitted at once' %\
|
||||
too_many_files_msg = 'Submission aborted! Maximum %d files may be submitted at once' % \
|
||||
settings.MAX_FILEUPLOADS_PER_INPUT
|
||||
return HttpResponse(json.dumps({'success': too_many_files_msg}))
|
||||
|
||||
for inputfile in inputfiles:
|
||||
if inputfile.size > settings.STUDENT_FILEUPLOAD_MAX_SIZE: # Bytes
|
||||
file_too_big_msg = 'Submission aborted! Your file "%s" is too large (max size: %d MB)' %\
|
||||
if inputfile.size > settings.STUDENT_FILEUPLOAD_MAX_SIZE: # Bytes
|
||||
file_too_big_msg = 'Submission aborted! Your file "%s" is too large (max size: %d MB)' % \
|
||||
(inputfile.name, settings.STUDENT_FILEUPLOAD_MAX_SIZE / (1000 ** 2))
|
||||
return HttpResponse(json.dumps({'success': file_too_big_msg}))
|
||||
p[fileinput_id] = inputfiles
|
||||
|
||||
Reference in New Issue
Block a user