Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
75ff3aaa
Commit
75ff3aaa
authored
Jan 03, 2013
by
Alexander Kryklia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
docs and denied rule refactores
parent
ab951932
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
67 additions
and
62 deletions
+67
-62
common/lib/capa/capa/graders/draganddrop.py
+67
-62
No files found.
common/lib/capa/capa/graders/draganddrop.py
View file @
75ff3aaa
...
...
@@ -18,13 +18,12 @@ If use_targets is false:
{
"use_targets": false,
"draggable": [
{ "image1": "
(10, 20)
" },
{ "ant": "
(30, 40)
" },
{ "molecule": "
(100, 200)
" },
{ "image1": "
[10, 20]
" },
{ "ant": "
[30, 40]
" },
{ "molecule": "
[100, 200]
" },
]
}
values are (x,y) coordinates of centers of dragged images.
"""
import
json
...
...
@@ -32,55 +31,58 @@ from collections import OrderedDict
class
PositionsCompare
(
list
):
"""Inputs are: "abc" - target
""" Class for comparing positions.
Args:
list or string::
"abc" - target
[10, 20] - list of integers
[[10,20], 200] list of list and integer
"""
def
__eq__
(
self
,
other
):
# Default lists behaviour is convers "abc" to ["a", "b", "c"].
# We will use that.
# import ipdb; ipdb.set_trace()
""" Compares two arguments.
#check if self or other is not empty list (empty lists = false)
if
not
self
or
not
other
:
return
False
Default lists behavior is conversion of string "abc" to list
["a", "b", "c"]. We will use that.
# check correct input types
if
(
not
isinstance
(
self
[
0
],
(
str
,
unicode
,
list
,
int
,
float
))
or
not
isinstance
(
other
[
0
],
(
str
,
unicode
,
list
,
int
,
float
))):
print
'Incorrect input type'
If self or other is empty - returns False.
Args:
self, other: str, unicode, list, int, float
Returns: bool
"""
# checks if self or other is not empty list (empty lists = false)
if
not
self
or
not
other
:
return
False
if
(
isinstance
(
self
[
0
],
(
list
,
int
,
float
))
and
isinstance
(
other
[
0
],
(
list
,
int
,
float
))):
print
'Numerical position compare'
return
self
.
coordinate_positions_compare
(
other
)
elif
(
isinstance
(
self
[
0
],
(
unicode
,
str
))
and
isinstance
(
other
[
0
],
(
unicode
,
str
))):
print
'Targets compare'
return
''
.
join
(
self
)
==
''
.
join
(
other
)
else
:
# we do not have ints or lists of lists or two string/unicode lists
# on both sides
print
type
(
self
[
0
]),
type
(
other
[
0
]),
"not correct"
else
:
# improper argument types
# Now we have no (float / int or lists of list and float / int pair)
# or two string / unicode lists pair
return
False
def
__ne__
(
self
,
other
):
return
not
self
.
__eq__
(
other
)
def
coordinate_positions_compare
(
self
,
other
,
r
=
10
):
""" Checks if
pos1 is equal to pos2 inside radiu
s
of forgiveness
(default 10 px).
""" Checks if
self is equal to other inside radius of forgivenes
s
(default 10 px).
Args:
self, other: [x, y] or [[x, y], r], where
r is radius of
forgiveness;
self, other: [x, y] or [[x, y], r], where
r is radius of
forgiveness;
x, y, r: int
Returns: bool.
"""
print
'I am called'
,
self
,
other
# get max radius of forgiveness
if
isinstance
(
self
[
0
],
list
):
# [(x, y), r] case
r
=
max
(
self
[
1
],
r
)
...
...
@@ -101,62 +103,56 @@ class PositionsCompare(list):
class
DragAndDrop
(
object
):
""" Grader for drag and drop inputtype.
"""
def
__init__
(
self
):
self
.
correct_groups
=
OrderedDict
()
# groups
self
.
correct_positions
=
OrderedDict
()
# positions of comparing
self
.
user_groups
=
OrderedDict
()
self
.
user_positions
=
OrderedDict
()
self
.
correct_groups
=
OrderedDict
()
# correct groups from xml
self
.
correct_positions
=
OrderedDict
()
# correct positions for comparing
self
.
user_groups
=
OrderedDict
()
# will be populated from user answer
self
.
user_positions
=
OrderedDict
()
# will be populated from user answer
# flag to check if user answer has more draggables than correct answer
self
.
incorrect
=
False
def
grade
(
self
):
'''
Grade drag and drop problem.
If use_targets is True - checks if image placed on proper target.
If use_targets is False - checks if image placed on proper coordinates,
with setted radius of forgiveness (default is 10)
''' Grader user answer.
Args:
user_input, correct_answer: json. Format:
If use_targets is True - checks if every draggable isplaced on proper
target.
user_input: see module docstring
If use_targets is False - checks if every draggable is placed on proper
coordinates within radius of forgiveness (default is 10).
correct_answer:
if use_targets is True:
{'1': 't1', 'name_with_icon': 't2'}
else:
{'1': '[10, 10]', 'name_with_icon': '[[10, 10], 20]'}
Returns:
True or False.
Returns: bool.
'''
if
self
.
incorrect
:
if
self
.
incorrect
:
# user answer has more draggables than correct answer
return
False
# checks if we have same groups of draggables
if
sorted
(
self
.
correct_groups
.
keys
())
!=
sorted
(
self
.
user_groups
.
keys
()):
return
False
# checks if for every groups draggables names are same
for
groupname
,
draggable_ids
in
self
.
correct_groups
.
items
():
if
sorted
(
draggable_ids
)
!=
sorted
(
self
.
user_groups
[
groupname
]):
return
False
# from now self.correct_groups and self.user_groups are equal if
# order is ignored
# Check
fo every group that positions of every group
element are equal
# with
positions
# Check
s in every group that user positions of every
element are equal
# with
correct positions for every rule
# 'denied' rule
denied_positions
=
[
item
for
g
in
self
.
correct_groups
.
keys
()
for
item
in
self
.
correct_positions
[
g
]
.
get
(
'denied'
,
[])]
all_user_positions
=
[
item
for
g
in
self
.
correct_groups
.
keys
()
for
item
in
self
.
user_positions
[
g
][
'user'
]]
if
not
self
.
compare_positions
(
denied_positions
,
all_user_positions
,
flag
=
'denied'
):
return
False
for
group
in
self
.
correct_groups
:
# 'denied' rule
if
not
self
.
compare_positions
(
self
.
correct_positions
[
group
]
.
get
(
'denied'
,
[]),
self
.
user_positions
[
group
][
'user'
],
flag
=
'denied'
):
return
False
no_exact
,
no_allowed
,
no_anyof
=
False
,
False
,
False
# 'exact' rule
for
groupname
in
self
.
correct_groups
:
for
groupname
in
self
.
correct_groups
:
# 'exact' rule
if
self
.
correct_positions
[
groupname
]
.
get
(
'exact'
,
[]):
if
not
self
.
compare_positions
(
self
.
correct_positions
[
groupname
][
'exact'
],
...
...
@@ -165,8 +161,7 @@ class DragAndDrop(object):
else
:
no_exact
=
True
# 'allowed' rule
for
groupname
in
self
.
correct_groups
:
for
groupname
in
self
.
correct_groups
:
# 'allowed' rule
if
self
.
correct_positions
[
groupname
]
.
get
(
'allowed'
,
[]):
if
not
self
.
compare_positions
(
self
.
correct_positions
[
groupname
][
'allowed'
],
...
...
@@ -260,7 +255,17 @@ class DragAndDrop(object):
def
grade
(
user_input
,
correct_answer
):
""" Support 2 interfaces"""
"""Args:
user_input, correct_answer: json. Format:
user_input: see module docstring
correct_answer:
if use_targets is True:
{'1': 't1', 'name_with_icon': 't2'}
else:
{'1': '[10, 10]', 'name_with_icon': '[[10, 10], 20]'}
Support 2 interfaces"""
if
isinstance
(
correct_answer
,
dict
):
dnd
=
DragAndDrop
()
else
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment