Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to pl-matrix-output element #1453

Merged
merged 30 commits into from Mar 31, 2019
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
89a673f
Closes #1365 and will add local digit control
eliving2 Mar 7, 2019
1761d22
Added local digit control
eliving2 Mar 7, 2019
a254d7e
Added to changelog and readme, fixed python lint
eliving2 Mar 7, 2019
3af704b
Requested changes to element and doc
lizliv Mar 12, 2019
488dca9
New example question outline started
lizliv Mar 12, 2019
94ca689
Merge branch 'master' into matrix-ouput-update
nwalters512 Mar 12, 2019
b0caa5a
Added matrix output boxes to example question
eliving2 Mar 12, 2019
f523389
Completed example question/Added tab-display attributes
lizliv Mar 12, 2019
6b04794
Style fix
lizliv Mar 12, 2019
a90e3a6
Added language='mathematica' to pl.string_from_2darray
eliving2 Mar 12, 2019
57b56ec
Update ChangeLod.md
eliving2 Mar 12, 2019
06829a5
Style fix
eliving2 Mar 12, 2019
ed47197
Requested changes implemented
eliving2 Mar 13, 2019
3e92f09
Fixed up example question
eliving2 Mar 13, 2019
9b286b8
More sensical tab control
eliving2 Mar 13, 2019
93a7818
Changed element to pl-variable-output
lizliv Mar 14, 2019
befa2fa
Small style/typo fixes
lizliv Mar 14, 2019
7b8ddca
Added 1D vector support for the element
eliving2 Mar 14, 2019
37c5633
Python lint...
eliving2 Mar 14, 2019
9e2bf10
Fixed selection of default tab
eliving2 Mar 14, 2019
9e9884e
Changed active tab control to also be an array
eliving2 Mar 14, 2019
4263152
Reverted to previous indentation
eliving2 Mar 14, 2019
c6ac880
Small fixes to pl-variable-output
eliving2 Mar 17, 2019
5e20a18
Changed `string_from_2darray` to `string_from_numpy`
eliving2 Mar 18, 2019
18b0f99
Fixed comment spacing and made variables in example unique
eliving2 Mar 18, 2019
fb9dd95
Merge branch 'master' into matrix-ouput-update
eliving2 Mar 30, 2019
99d5db2
Merged master into branch, fixed changelog spacing
eliving2 Mar 30, 2019
b4f694a
Added deprecated `string_from_2darray()`
eliving2 Mar 30, 2019
caa9f15
Added to/reworded changes in changelog
eliving2 Mar 30, 2019
846d035
Python lint
eliving2 Mar 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions ChangeLog.md
Expand Up @@ -51,6 +51,12 @@

* Add student file storage for scratch paper scans (Matt West).

* Add Mathematica language option to `string_from_2darray` (Liz Livingston).

* Add Mathematica tab and optional display attribute to `pl-matrix-output` (Liz Livingston).

* Add comment and child digit control for `pl-matrix-output`, optional `comment` and `digits` (Liz Livingston).

* Change "Save & Grade" button text and alignment (Dave Mussulman).

* Change Ace editor to use source files from npm and upgrade to 1.4.1 from 1.2.8 (Nathan Walters).
Expand Down
17 changes: 14 additions & 3 deletions doc/elements.md
Expand Up @@ -207,25 +207,36 @@ Attributes for `<pl-matrix-output`:
Attribute | Type | Default | Description
--- | --- | --- | ---
`digits` | integer | — | Number of digits to display after the decimal.
`default-tab` | string | 'matlab' | Select the active tab.
`show-matlab` | boolean | True | Toggles the display of the Matlab tab.
`show-mathetmatica` | boolean | True | Toggles the display of the Mathematica tab.
eliving2 marked this conversation as resolved.
Show resolved Hide resolved
`show-python` | boolean | True | Toggles the display of the Python tab.

Attributes for `<variable>` (one of these for each variable to display):

Attribute | Type | Default | Description
--- | --- | --- | ---
`params-name` | string | — | Name of variable in `data['params']` to display.
`comment` | string | — | Comment to add after the displayed variable.
`digits` | integer | — | Number of digits to display after the decimal for the variable.

This element displays a list of variables inside `<pre>` tags that are formatted for import into either MATLAB or python (the user can switch between the two). Each variable must be either a scalar or a 2D numpy array (expressed as a list). Each variable will be prefixed by the text that appears between the `<variable>` and `</variable>` tags, followed by ` = `.
This element displays a list of variables inside `<pre>` tags that are formatted for import into either MATLAB, Mathematica, or Python (the user can switch between them). Each variable must be either a scalar or a 2D numpy array (expressed as a list). Each variable will be prefixed by the text that appears between the `<variable>` and `</variable>` tags, followed by ` = `.

Here is an example of MATLAB format:
```
A = [1.23; 4.56];
A = [1.23; 4.56]; % matrix
```

Here is an example of the Mathematica format:
```
A = [1.23; 4.56]; (* matrix *)
```

Here is an example of python format:
```
import numpy as np

A = np.array([[1.23], [4.56]])
A = np.array([[1.23], [4.56]]) # matrix
```

If a variable `v` is a complex object, you should use `import prairielearn as pl` and `data['params'][params-name] = pl.to_json(v)`.
Expand Down
17 changes: 13 additions & 4 deletions elements/pl-matrix-output/pl-matrix-output.mustache
Expand Up @@ -7,19 +7,28 @@
<div id="pl-matrix-output-{{uuid}}" class="card mb-4">
<div class="card-header">
<ul class="nav nav-tabs card-header-tabs" role="tablist">
<li class="nav-item" role="presentation"><a class="nav-link{{#default_is_matlab}} active{{/default_is_matlab}}" href="#matlab-{{uuid}}" aria-controls="matlab-{{uuid}}" role="tab" data-toggle="pill">matlab</a></li>
<li class="nav-item" role="presentation"><a class="nav-link{{#default_is_python}} active{{/default_is_python}}" href="#python-{{uuid}}" aria-controls="python-{{uuid}}" role="tab" data-toggle="pill">python</a></li>
{{#display_matlab_tab}}<li class="nav-item" role="presentation"><a class="nav-link{{#active_tab_matlab}} active{{/active_tab_matlab}}" href="#matlab-{{uuid}}" aria-controls="matlab-{{uuid}}" role="tab" data-toggle="pill">Matlab</a></li>{{/display_matlab_tab}}

{{#display_mathematica_tab}}<li class="nav-item" role="presentation"><a class="nav-link{{#active_tab_mathematica}} active{{/active_tab_mathematica}}" href="#mathematica-{{uuid}}" aria-controls="mathematica-{{uuid}}" role="tab" data-toggle="pill">Mathematica</a></li>{{/display_mathematica_tab}}

{{#display_python_tab}}<li class="nav-item" role="presentation"><a class="nav-link{{#active_tab_python}} active{{/active_tab_python}}" href="#python-{{uuid}}" aria-controls="python-{{uuid}}" role="tab" data-toggle="pill">Python</a></li>{{/display_python_tab}}
</ul>
</div>
<div class="card-body">
<div class="tab-content">
<div role="tabpanel" class="tab-pane {{#default_is_matlab}}active{{/default_is_matlab}}" id="matlab-{{uuid}}">
<div role="tabpanel" class="tab-pane {{#active_tab_matlab}}active{{/active_tab_matlab}}" id="matlab-{{uuid}}">
<pre class="bg-dark text-white rounded p-2" id="matlab-data-{{uuid}}">{{matlab_data}}</pre>
<button type="button" class="btn btn-secondary btn-sm copy-button" data-clipboard-target="#matlab-data-{{uuid}}">
copy this text
</button>
</div>
<div role="tabpanel" class="tab-pane {{#default_is_python}}active{{/default_is_python}}" id="python-{{uuid}}">
<div role="tabpanel" class="tab-pane {{#active_tab_mathematica}}active{{/active_tab_mathematica}}" id="mathematica-{{uuid}}">
<pre class="bg-dark text-white rounded p-2" id="mathematica-data-{{uuid}}">{{mathematica_data}}</pre>
<button type="button" class="btn btn-secondary btn-sm copy-button" data-clipboard-target="#mathematica-data-{{uuid}}">
copy this text
</button>
</div>
<div role="tabpanel" class="tab-pane {{#active_tab_python}}active{{/active_tab_python}}" id="python-{{uuid}}">
<pre class="bg-dark text-white rounded p-2" id="python-data-{{uuid}}">{{python_data}}</pre>
<button type="button" class="btn btn-secondary btn-sm copy-button" data-clipboard-target="#python-data-{{uuid}}">
copy this text
Expand Down
76 changes: 71 additions & 5 deletions elements/pl-matrix-output/pl-matrix-output.py
Expand Up @@ -6,19 +6,49 @@

def prepare(element_html, data):
element = lxml.html.fragment_fromstring(element_html)
pl.check_attribs(element, required_attribs=[], optional_attribs=['digits'])
required_attribs = []
optional_attribs = ['digits', 'default-tab', 'show-matlab', 'show-mathematica', 'show-python']
pl.check_attribs(element, required_attribs, optional_attribs)


def render(element_html, data):
element = lxml.html.fragment_fromstring(element_html)
digits = pl.get_integer_attrib(element, 'digits', 2)
display_matlab_tab = pl.get_boolean_attrib(element, 'show-matlab', True)
display_mathematica_tab = pl.get_boolean_attrib(element, 'show-mathematica', True)
display_python_tab = pl.get_boolean_attrib(element, 'show-python', True)
default_tab = pl.get_string_attrib(element, 'default-tab', 'matlab')
eliving2 marked this conversation as resolved.
Show resolved Hide resolved
eliving2 marked this conversation as resolved.
Show resolved Hide resolved

# Default active tab
if default_tab == 'matlab':
active_tab_matlab = True
eliving2 marked this conversation as resolved.
Show resolved Hide resolved
active_tab_mathematica = False
active_tab_python = False
elif default_tab == 'mathematica':
active_tab_matlab = False
active_tab_mathematica = True
active_tab_python = False
elif default_tab == 'python':
active_tab_matlab = False
active_tab_mathematica = False
active_tab_python = True

# If Matlab Display is False, will cycle through to next displayed tab
# If Mathematica and Python are displayed, and Python is specificed as the default, this statement is skipped
if display_matlab_tab is False and default_tab != 'python':
active_tab_matlab = False
if display_mathematica_tab is True:
active_tab_mathematica = True
elif display_python_tab is True:
active_tab_python = True
eliving2 marked this conversation as resolved.
Show resolved Hide resolved

matlab_data = ''
mathematica_data = ''
python_data = 'import numpy as np\n\n'
for child in element:
if child.tag == 'variable':
# Raise exception of variable does not have a name
pl.check_attribs(child, required_attribs=['params-name'], optional_attribs=[])
pl.check_attribs(child, required_attribs=['params-name'], optional_attribs=['comment', 'digits'])

# Get name of variable
var_name = pl.get_string_attrib(child, 'params-name')
Expand All @@ -32,6 +62,23 @@ def render(element_html, data):
# back to a standard type (otherwise, do nothing)
var_data = pl.from_json(var_data)

# Get comment, if it exists
var_matlab_comment = ''
var_mathematica_comment = ''
var_python_comment = ''
if pl.has_attrib(child, 'comment'):
var_comment = pl.get_string_attrib(child, 'comment')
var_matlab_comment = '% {}'.format(var_comment)
var_mathematica_comment = '(* {} *)'.format(var_comment)
var_python_comment = '# {}'.format(var_comment)
eliving2 marked this conversation as resolved.
Show resolved Hide resolved

# Get digit for child, if it exists
if pl.has_attrib(child, 'digits') is False:
var_digits = digits
else:
var_digits = pl.get_string_attrib(child, 'digits')

# Assembling Python array formatting
if np.isscalar(var_data):
prefix = ''
suffix = ''
Expand All @@ -45,13 +92,32 @@ def render(element_html, data):
prefix = 'np.array('
suffix = ')'

# Mathematica reserved letters: C D E I K N O
mathematica_reserved = ['C', 'D', 'E', 'I', 'K', 'N', 'O']
if pl.inner_html(child) in mathematica_reserved:
mathematica_suffix = 'm'
else:
mathematica_suffix = ''

# Create string for matlab and python format
matlab_data += pl.inner_html(child) + ' = ' + pl.string_from_2darray(var_data, language='matlab', digits=digits) + ';\n'
python_data += pl.inner_html(child) + ' = ' + prefix + pl.string_from_2darray(var_data, language='python', digits=digits) + suffix + '\n'
var_name_disp = pl.inner_html(child)
var_matlab_data = pl.string_from_2darray(var_data, language='matlab', digits=var_digits)
var_mathematica = pl.string_from_2darray(var_data, language='mathematica', digits=var_digits)
var_python_data = pl.string_from_2darray(var_data, language='python', digits=var_digits)

matlab_data += '{} = {}; {}\n'.format(var_name_disp, var_matlab_data, var_matlab_comment)
mathematica_data += '{}{}= {}; {}\n'.format(var_name_disp, mathematica_suffix, var_mathematica, var_mathematica_comment)
python_data += '{} = {}{}{} {}\n'.format(var_name_disp, prefix, var_python_data, suffix, var_python_comment)

html_params = {
'default_is_matlab': True,
'active_tab_matlab': active_tab_matlab,
'active_tab_mathematica': active_tab_mathematica,
'active_tab_python': active_tab_python,
'display_matlab_tab': display_matlab_tab,
'display_mathematica_tab': display_mathematica_tab,
'display_python_tab': display_python_tab,
'matlab_data': matlab_data,
'mathematica_data': mathematica_data,
'python_data': python_data,
'uuid': pl.get_uuid()
}
Expand Down
@@ -1,45 +1,46 @@
{
"uuid": "69aa799b-9492-4db2-9102-7753263f3863",
"type": "Homework",
"title": "PrairieLearn element example gallery",
"set": "Homework",
"number": "4",
"allowAccess": [
{
"mode": "Public",
"credit": 120,
"startDate": "2014-04-07T00:00:01",
"endDate": "2014-07-10T23:59:59"
},
{
"mode": "Public",
"credit": 100,
"startDate": "2014-07-07T00:00:01",
"endDate": "2024-07-10T23:59:59"
},
{
"mode": "Public",
"credit": 80,
"startDate": "2014-07-07T00:00:01",
"endDate": "2024-08-10T23:59:59"
},
{
"mode": "Public",
"credit": 50,
"startDate": "2014-07-07T00:00:01",
"endDate": "2024-09-10T23:59:59"
}
],
"zones": [
{
"questions": [
{"id": "examplesCheckbox", "points": 2, "maxPoints": 10},
{"id": "examplesStringInput", "points": 2, "maxPoints": 10},
{"id": "elementsMatrixLatexDisplay", "points": 2, "maxPoints": 10},
{"id": "examplesMatrixInput", "points": 2, "maxPoints": 10},
{"id": "examplesSymbolicInput", "points": 2, "maxPoints": 10},
{"id": "examplesNumberInput", "points": 2, "maxPoints": 10}
]
}
]
"uuid": "69aa799b-9492-4db2-9102-7753263f3863",
eliving2 marked this conversation as resolved.
Show resolved Hide resolved
"type": "Homework",
"title": "PrairieLearn element example gallery",
"set": "Homework",
"number": "4",
"allowAccess": [
{
"mode": "Public",
"credit": 120,
"startDate": "2014-04-07T00:00:01",
"endDate": "2014-07-10T23:59:59"
},
{
"mode": "Public",
"credit": 100,
"startDate": "2014-07-07T00:00:01",
"endDate": "2024-07-10T23:59:59"
},
{
"mode": "Public",
"credit": 80,
"startDate": "2014-07-07T00:00:01",
"endDate": "2024-08-10T23:59:59"
},
{
"mode": "Public",
"credit": 50,
"startDate": "2014-07-07T00:00:01",
"endDate": "2024-09-10T23:59:59"
}
],
"zones": [
{
"questions": [
{"id": "examplesCheckbox", "points": 2, "maxPoints": 10},
{"id": "examplesStringInput", "points": 2, "maxPoints": 10},
{"id": "elementsMatrixLatexDisplay", "points": 2, "maxPoints": 10},
{"id": "examplesMatrixInput", "points": 2, "maxPoints": 10},
{"id": "examplesSymbolicInput", "points": 2, "maxPoints": 10},
{"id": "examplesNumberInput", "points": 2, "maxPoints": 10},
{"id": "examplesMatrixOutput", "points": 2, "maxPoints": 10}
]
}
]
}
1 change: 1 addition & 0 deletions exampleCourse/infoCourse.json
Expand Up @@ -26,6 +26,7 @@
{"name": "balamut2", "color": "orange1", "description": "Question originally written by balamut2"},
{"name": "mfsilva", "color": "orange1", "description": "Question originally written by mfsilva"},
{"name": "ressick2", "color": "gray1", "description": "Question originally written by ressick2"},
{"name": "eliving2", "color": "gray1", "description": "Question originally written by eliving2"},
{"name": "tpl101", "color": "gray1", "description": "Question originally written for the XC 101 example course"},
{"name": "fa17", "color": "gray1", "description": "Question written in Fall 2017"},
{"name": "sp18", "color": "gray1", "description": "Question written in Spring 2018"},
Expand Down
7 changes: 7 additions & 0 deletions exampleCourse/questions/examplesMatrixOutput/info.json
@@ -0,0 +1,7 @@
{
"uuid": "cc99f57c-1a13-4161-b052-1cd795011d98",
"title": "Examples showing matrix and scalar output via pl-matrix-output",
"topic": "Test",
"tags": ["eliving2", "Sp19", "tpl101", "v3", "numeric"],
"type": "v3"
}