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
ba9280f3
Commit
ba9280f3
authored
Nov 28, 2012
by
Victor Shnayder
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1010 from MITx/feature/alex/regions
Feature/alex/regions
parents
b63a787a
b0a85fde
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
109 additions
and
18 deletions
+109
-18
brew-formulas.txt
+1
-0
common/lib/capa/capa/responsetypes.py
+52
-15
common/lib/capa/capa/tests/test_files/imageresponse.xml
+19
-0
common/lib/capa/capa/tests/test_responsetypes.py
+35
-2
create-dev-env.sh
+1
-1
requirements.txt
+1
-0
No files found.
brew-formulas.txt
View file @
ba9280f3
...
...
@@ -8,3 +8,4 @@ yuicompressor
node
graphviz
mysql
geos
common/lib/capa/capa/responsetypes.py
View file @
ba9280f3
...
...
@@ -23,6 +23,7 @@ import abc
import
os
import
subprocess
import
xml.sax.saxutils
as
saxutils
from
shapely.geometry
import
Point
,
MultiPoint
# specific library imports
from
calc
import
evaluator
,
UndefinedVariable
...
...
@@ -1717,15 +1718,38 @@ class ImageResponse(LoncapaResponse):
which produces an [x,y] coordinate pair. The click is correct if it falls
within a region specified. This region is a union of rectangles.
Lon-CAPA requires that each <imageresponse> has a <foilgroup> inside it. That
doesn't make sense to me (Ike). Instead, let's have it such that <imageresponse>
should contain one or more <imageinput> stanzas. Each <imageinput> should specify
a rectangle, given as an attribute, defining the correct answer.
Lon-CAPA requires that each <imageresponse> has a <foilgroup> inside it.
That doesn't make sense to me (Ike). Instead, let's have it such that
<imageresponse> should contain one or more <imageinput> stanzas.
Each <imageinput> should specify a rectangle(s) or region(s), given as an
attribute, defining the correct answer.
<imageinput src="/static/images/Lecture2/S2_p04.png" width="811" height="610"
rectangle="(10,10)-(20,30);(12,12)-(40,60)"
regions="[[[10,10], [20,30], [40, 10]], [[100,100], [120,130], [110,150]]]"/>
Regions is list of lists [region1, region2, region3, ...] where regionN
is disordered list of points: [[1,1], [100,100], [50,50], [20, 70]].
If there is only one region in the list, simpler notation can be used:
regions="[[10,10], [30,30], [10, 30], [30, 10]]" (without explicitly
setting outer list)
Returns:
True, if click is inside any region or rectangle. Otherwise False.
"""
snippets
=
[{
'snippet'
:
'''<imageresponse>
<imageinput src="image1.jpg" width="200" height="100" rectangle="(10,10)-(20,30)" />
<imageinput src="image2.jpg" width="210" height="130" rectangle="(12,12)-(40,60)" />
<imageinput src="image2.jpg" width="210" height="130" rectangle="(10,10)-(20,30);(12,12)-(40,60)" />
<imageinput src="image1.jpg" width="200" height="100"
rectangle="(10,10)-(20,30)" />
<imageinput src="image2.jpg" width="210" height="130"
rectangle="(12,12)-(40,60)" />
<imageinput src="image3.jpg" width="210" height="130"
rectangle="(10,10)-(20,30);(12,12)-(40,60)" />
<imageinput src="image4.jpg" width="811" height="610"
rectangle="(10,10)-(20,30);(12,12)-(40,60)"
regions="[[[10,10], [20,30], [40, 10]], [[100,100], [120,130], [110,150]]]"/>
<imageinput src="image5.jpg" width="200" height="200"
regions="[[[10,10], [20,30], [40, 10]], [[100,100], [120,130], [110,150]]]"/>
</imageresponse>'''
}]
response_tag
=
'imageresponse'
...
...
@@ -1738,14 +1762,12 @@ class ImageResponse(LoncapaResponse):
def
get_score
(
self
,
student_answers
):
correct_map
=
CorrectMap
()
expectedset
=
self
.
get_answers
()
for
aid
in
self
.
answer_ids
:
# loop through IDs of <imageinput>
fields in our stanza
for
aid
in
self
.
answer_ids
:
# loop through IDs of <imageinput>
#
fields in our stanza
given
=
student_answers
[
aid
]
# this should be a string of the form '[x,y]'
correct_map
.
set
(
aid
,
'incorrect'
)
if
not
given
:
# No answer to parse. Mark as incorrect and move on
continue
# parse given answer
m
=
re
.
match
(
'
\
[([0-9]+),([0-9]+)]'
,
given
.
strip
()
.
replace
(
' '
,
''
))
if
not
m
:
...
...
@@ -1753,8 +1775,10 @@ class ImageResponse(LoncapaResponse):
'error grading
%
s (input=
%
s)'
%
(
aid
,
given
))
(
gx
,
gy
)
=
[
int
(
x
)
for
x
in
m
.
groups
()]
rectangles
,
regions
=
expectedset
if
rectangles
[
aid
]:
# rectangles part - for backward compatibility
# Check whether given point lies in any of the solution rectangles
solution_rectangles
=
expectedset
[
aid
]
.
split
(
';'
)
solution_rectangles
=
rectangles
[
aid
]
.
split
(
';'
)
for
solution_rectangle
in
solution_rectangles
:
# parse expected answer
# TODO: Compile regexp on file load
...
...
@@ -1770,12 +1794,25 @@ class ImageResponse(LoncapaResponse):
if
(
llx
<=
gx
<=
urx
)
and
(
lly
<=
gy
<=
ury
):
correct_map
.
set
(
aid
,
'correct'
)
break
if
correct_map
[
aid
][
'correctness'
]
!=
'correct'
and
regions
[
aid
]:
parsed_region
=
json
.
loads
(
regions
[
aid
])
if
parsed_region
:
if
type
(
parsed_region
[
0
][
0
])
!=
list
:
# we have [[1,2],[3,4],[5,6]] - single region
# instead of [[[1,2],[3,4],[5,6], [[1,2],[3,4],[5,6]]]
# or [[[1,2],[3,4],[5,6]]] - multiple regions syntax
parsed_region
=
[
parsed_region
]
for
region
in
parsed_region
:
polygon
=
MultiPoint
(
region
)
.
convex_hull
if
(
polygon
.
type
==
'Polygon'
and
polygon
.
contains
(
Point
(
gx
,
gy
))):
correct_map
.
set
(
aid
,
'correct'
)
break
return
correct_map
def
get_answers
(
self
):
return
dict
([(
ie
.
get
(
'id'
),
ie
.
get
(
'rectangle'
))
for
ie
in
self
.
ielements
])
return
(
dict
([(
ie
.
get
(
'id'
),
ie
.
get
(
'rectangle'
))
for
ie
in
self
.
ielements
]),
dict
([(
ie
.
get
(
'id'
),
ie
.
get
(
'regions'
))
for
ie
in
self
.
ielements
]))
#-----------------------------------------------------------------------------
# TEMPORARY: List of all response subclasses
# FIXME: To be replaced by auto-registration
...
...
common/lib/capa/capa/tests/test_files/imageresponse.xml
View file @
ba9280f3
...
...
@@ -18,4 +18,23 @@ Hello</p></text>
<text><p>
Use conservation of energy.
</p></text>
</hintgroup>
</imageresponse>
<imageresponse
max=
"1"
loncapaid=
"12"
>
<imageinput
src=
"/static/Physics801/Figures/Skier-conservation of energy.jpg"
width=
"560"
height=
"388"
rectangle=
"(490,11)-(556,98)"
regions=
"[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"
/>
<imageinput
src=
"/static/Physics801/Figures/Skier-conservation of energy.jpg"
width=
"560"
height=
"388"
rectangle=
"(490,11)-(556,98)"
regions=
'[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]'
/>
<imageinput
src=
"/static/Physics801/Figures/Skier-conservation of energy.jpg"
width=
"560"
height=
"388"
regions=
"[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"
/>
<imageinput
src=
"/static/Physics801/Figures/Skier-conservation of energy.jpg"
width=
"560"
height=
"388"
regions=
"[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"
/>
<text>
Click on either of the two positions as discussed previously.
</text>
<imageinput
src=
"/static/Physics801/Figures/Skier-conservation of energy.jpg"
width=
"560"
height=
"388"
regions=
"[[[10,10], [20,10], [20, 30]]]"
/>
<text>
Click on either of the two positions as discussed previously.
</text>
<imageinput
src=
"/static/Physics801/Figures/Skier-conservation of energy.jpg"
width=
"560"
height=
"388"
regions=
"[[10,10], [30,30], [15, 15]]"
/>
<imageinput
src=
"/static/Physics801/Figures/Skier-conservation of energy.jpg"
width=
"560"
height=
"388"
regions=
"[[10,10], [30,30], [10, 30], [30, 10]]"
/>
<text>
Click on either of the two positions as discussed previously.
</text>
<hintgroup
showoncorrect=
"no"
>
<text><p>
Use conservation of energy.
</p></text>
</hintgroup>
</imageresponse>
</problem>
common/lib/capa/capa/tests/test_responsetypes.py
View file @
ba9280f3
...
...
@@ -52,24 +52,57 @@ class ImageResponseTest(unittest.TestCase):
def
test_ir_grade
(
self
):
imageresponse_file
=
os
.
path
.
dirname
(
__file__
)
+
"/test_files/imageresponse.xml"
test_lcp
=
lcp
.
LoncapaProblem
(
open
(
imageresponse_file
)
.
read
(),
'1'
,
system
=
test_system
)
correct_answers
=
{
'1_2_1'
:
'(490,11)-(556,98)'
,
# testing regions only
correct_answers
=
{
#regions
'1_2_1'
:
'(490,11)-(556,98)'
,
'1_2_2'
:
'(242,202)-(296,276)'
,
'1_2_3'
:
'(490,11)-(556,98);(242,202)-(296,276)'
,
'1_2_4'
:
'(490,11)-(556,98);(242,202)-(296,276)'
,
'1_2_5'
:
'(490,11)-(556,98);(242,202)-(296,276)'
,
#testing regions and rectanges
'1_3_1'
:
'rectangle="(490,11)-(556,98)"
\
regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"'
,
'1_3_2'
:
'rectangle="(490,11)-(556,98)"
\
regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"'
,
'1_3_3'
:
'regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"'
,
'1_3_4'
:
'regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"'
,
'1_3_5'
:
'regions="[[[10,10], [20,10], [20, 30]]]"'
,
'1_3_6'
:
'regions="[[10,10], [30,30], [15, 15]]"'
,
'1_3_7'
:
'regions="[[10,10], [30,30], [10, 30], [30, 10]]"'
,
}
test_answers
=
{
'1_2_1'
:
'[500,20]'
,
test_answers
=
{
'1_2_1'
:
'[500,20]'
,
'1_2_2'
:
'[250,300]'
,
'1_2_3'
:
'[500,20]'
,
'1_2_4'
:
'[250,250]'
,
'1_2_5'
:
'[10,10]'
,
'1_3_1'
:
'[500,20]'
,
'1_3_2'
:
'[15,15]'
,
'1_3_3'
:
'[500,20]'
,
'1_3_4'
:
'[115,115]'
,
'1_3_5'
:
'[15,15]'
,
'1_3_6'
:
'[20,20]'
,
'1_3_7'
:
'[20,15]'
,
}
# regions
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_2_1'
),
'correct'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_2_2'
),
'incorrect'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_2_3'
),
'correct'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_2_4'
),
'correct'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_2_5'
),
'incorrect'
)
# regions and rectangles
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_3_1'
),
'correct'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_3_2'
),
'correct'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_3_3'
),
'incorrect'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_3_4'
),
'correct'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_3_5'
),
'correct'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_3_6'
),
'incorrect'
)
self
.
assertEquals
(
test_lcp
.
grade_answers
(
test_answers
)
.
get_correctness
(
'1_3_7'
),
'correct'
)
class
SymbolicResponseTest
(
unittest
.
TestCase
):
def
test_sr_grade
(
self
):
...
...
create-dev-env.sh
View file @
ba9280f3
...
...
@@ -99,7 +99,7 @@ NUMPY_VER="1.6.2"
SCIPY_VER
=
"0.10.1"
BREW_FILE
=
"
$BASE
/mitx/brew-formulas.txt"
LOG
=
"/var/tmp/install-
$(
date +%Y%m%d-%H%M%S
)
.log"
APT_PKGS
=
"pkg-config curl git python-virtualenv build-essential python-dev gfortran liblapack-dev libfreetype6-dev libpng12-dev libxml2-dev libxslt-dev yui-compressor nodejs npm graphviz graphviz-dev mysql-server libmysqlclient-dev"
APT_PKGS
=
"pkg-config curl git python-virtualenv build-essential python-dev gfortran liblapack-dev libfreetype6-dev libpng12-dev libxml2-dev libxslt-dev yui-compressor nodejs npm graphviz graphviz-dev mysql-server libmysqlclient-dev
libgeos-dev
"
if
[[
$EUID
-eq
0
]]
;
then
error
"This script should not be run using sudo or as the root user"
...
...
requirements.txt
View file @
ba9280f3
...
...
@@ -54,3 +54,4 @@ dogstatsd-python
# Taking out MySQL-python for now because it requires mysql to be installed, so breaks updates on content folks' envs.
# MySQL-python
sphinx
Shapely
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