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:
...
@@ -18,13 +18,12 @@ If use_targets is false:
{
{
"use_targets": false,
"use_targets": false,
"draggable": [
"draggable": [
{ "image1": "
(10, 20)
" },
{ "image1": "
[10, 20]
" },
{ "ant": "
(30, 40)
" },
{ "ant": "
[30, 40]
" },
{ "molecule": "
(100, 200)
" },
{ "molecule": "
[100, 200]
" },
]
]
}
}
values are (x,y) coordinates of centers of dragged images.
values are (x,y) coordinates of centers of dragged images.
"""
"""
import
json
import
json
...
@@ -32,55 +31,58 @@ from collections import OrderedDict
...
@@ -32,55 +31,58 @@ from collections import OrderedDict
class
PositionsCompare
(
list
):
class
PositionsCompare
(
list
):
"""Inputs are: "abc" - target
""" Class for comparing positions.
Args:
list or string::
"abc" - target
[10, 20] - list of integers
[10, 20] - list of integers
[[10,20], 200] list of list and integer
[[10,20], 200] list of list and integer
"""
"""
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
# Default lists behaviour is convers "abc" to ["a", "b", "c"].
""" Compares two arguments.
# We will use that.
# import ipdb; ipdb.set_trace()
#check if self or other is not empty list (empty lists = false)
Default lists behavior is conversion of string "abc" to list
if
not
self
or
not
other
:
["a", "b", "c"]. We will use that.
return
False
# check correct input types
If self or other is empty - returns False.
if
(
not
isinstance
(
self
[
0
],
(
str
,
unicode
,
list
,
int
,
float
))
or
not
isinstance
(
other
[
0
],
(
str
,
unicode
,
list
,
int
,
float
))):
Args:
print
'Incorrect input type'
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
return
False
if
(
isinstance
(
self
[
0
],
(
list
,
int
,
float
))
and
if
(
isinstance
(
self
[
0
],
(
list
,
int
,
float
))
and
isinstance
(
other
[
0
],
(
list
,
int
,
float
))):
isinstance
(
other
[
0
],
(
list
,
int
,
float
))):
print
'Numerical position compare'
return
self
.
coordinate_positions_compare
(
other
)
return
self
.
coordinate_positions_compare
(
other
)
elif
(
isinstance
(
self
[
0
],
(
unicode
,
str
))
and
elif
(
isinstance
(
self
[
0
],
(
unicode
,
str
))
and
isinstance
(
other
[
0
],
(
unicode
,
str
))):
isinstance
(
other
[
0
],
(
unicode
,
str
))):
print
'Targets compare'
return
''
.
join
(
self
)
==
''
.
join
(
other
)
return
''
.
join
(
self
)
==
''
.
join
(
other
)
else
:
else
:
# improper argument types
# we do not have ints or lists of lists or two string/unicode lists
# Now we have no (float / int or lists of list and float / int pair)
# on both sides
# or two string / unicode lists pair
print
type
(
self
[
0
]),
type
(
other
[
0
]),
"not correct"
return
False
return
False
def
__ne__
(
self
,
other
):
def
__ne__
(
self
,
other
):
return
not
self
.
__eq__
(
other
)
return
not
self
.
__eq__
(
other
)
def
coordinate_positions_compare
(
self
,
other
,
r
=
10
):
def
coordinate_positions_compare
(
self
,
other
,
r
=
10
):
""" Checks if
pos1 is equal to pos2 inside radiu
s
""" Checks if
self is equal to other inside radius of forgivenes
s
of forgiveness
(default 10 px).
(default 10 px).
Args:
Args:
self, other: [x, y] or [[x, y], r], where
self, other: [x, y] or [[x, y], r], where
r is radius of
r is radius of
forgiveness;
forgiveness;
x, y, r: int
x, y, r: int
Returns: bool.
Returns: bool.
"""
"""
print
'I am called'
,
self
,
other
# get max radius of forgiveness
# get max radius of forgiveness
if
isinstance
(
self
[
0
],
list
):
# [(x, y), r] case
if
isinstance
(
self
[
0
],
list
):
# [(x, y), r] case
r
=
max
(
self
[
1
],
r
)
r
=
max
(
self
[
1
],
r
)
...
@@ -101,62 +103,56 @@ class PositionsCompare(list):
...
@@ -101,62 +103,56 @@ class PositionsCompare(list):
class
DragAndDrop
(
object
):
class
DragAndDrop
(
object
):
""" Grader for drag and drop inputtype.
"""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
correct_groups
=
OrderedDict
()
# groups
self
.
correct_groups
=
OrderedDict
()
# correct groups from xml
self
.
correct_positions
=
OrderedDict
()
# positions of comparing
self
.
correct_positions
=
OrderedDict
()
# correct positions for comparing
self
.
user_groups
=
OrderedDict
()
self
.
user_groups
=
OrderedDict
()
# will be populated from user answer
self
.
user_positions
=
OrderedDict
()
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
self
.
incorrect
=
False
def
grade
(
self
):
def
grade
(
self
):
'''
''' Grader user answer.
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)
Args:
If use_targets is True - checks if every draggable isplaced on proper
user_input, correct_answer: json. Format:
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:
Returns: bool.
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.
'''
'''
if
self
.
incorrect
:
if
self
.
incorrect
:
# user answer has more draggables than correct answer
return
False
return
False
# checks if we have same groups of draggables
if
sorted
(
self
.
correct_groups
.
keys
())
!=
sorted
(
self
.
user_groups
.
keys
()):
if
sorted
(
self
.
correct_groups
.
keys
())
!=
sorted
(
self
.
user_groups
.
keys
()):
return
False
return
False
# checks if for every groups draggables names are same
for
groupname
,
draggable_ids
in
self
.
correct_groups
.
items
():
for
groupname
,
draggable_ids
in
self
.
correct_groups
.
items
():
if
sorted
(
draggable_ids
)
!=
sorted
(
self
.
user_groups
[
groupname
]):
if
sorted
(
draggable_ids
)
!=
sorted
(
self
.
user_groups
[
groupname
]):
return
False
return
False
# from now self.correct_groups and self.user_groups are equal if
# from now self.correct_groups and self.user_groups are equal if
# order is ignored
# order is ignored
# Check
fo every group that positions of every group
element are equal
# Check
s in every group that user positions of every
element are equal
# with
positions
# with
correct positions for every rule
# 'denied' rule
for
group
in
self
.
correct_groups
:
# 'denied' rule
denied_positions
=
[
item
for
g
in
self
.
correct_groups
.
keys
()
if
not
self
.
compare_positions
(
self
.
correct_positions
[
group
]
.
get
(
for
item
in
self
.
correct_positions
[
g
]
.
get
(
'denied'
,
[])]
'denied'
,
[]),
self
.
user_positions
[
group
][
'user'
],
flag
=
'denied'
):
all_user_positions
=
[
item
for
g
in
self
.
correct_groups
.
keys
()
return
False
for
item
in
self
.
user_positions
[
g
][
'user'
]]
if
not
self
.
compare_positions
(
denied_positions
,
all_user_positions
,
flag
=
'denied'
):
return
False
no_exact
,
no_allowed
,
no_anyof
=
False
,
False
,
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
self
.
correct_positions
[
groupname
]
.
get
(
'exact'
,
[]):
if
not
self
.
compare_positions
(
if
not
self
.
compare_positions
(
self
.
correct_positions
[
groupname
][
'exact'
],
self
.
correct_positions
[
groupname
][
'exact'
],
...
@@ -165,8 +161,7 @@ class DragAndDrop(object):
...
@@ -165,8 +161,7 @@ class DragAndDrop(object):
else
:
else
:
no_exact
=
True
no_exact
=
True
# 'allowed' rule
for
groupname
in
self
.
correct_groups
:
# 'allowed' rule
for
groupname
in
self
.
correct_groups
:
if
self
.
correct_positions
[
groupname
]
.
get
(
'allowed'
,
[]):
if
self
.
correct_positions
[
groupname
]
.
get
(
'allowed'
,
[]):
if
not
self
.
compare_positions
(
if
not
self
.
compare_positions
(
self
.
correct_positions
[
groupname
][
'allowed'
],
self
.
correct_positions
[
groupname
][
'allowed'
],
...
@@ -260,7 +255,17 @@ class DragAndDrop(object):
...
@@ -260,7 +255,17 @@ class DragAndDrop(object):
def
grade
(
user_input
,
correct_answer
):
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
):
if
isinstance
(
correct_answer
,
dict
):
dnd
=
DragAndDrop
()
dnd
=
DragAndDrop
()
else
:
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