Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 141 additions & 1 deletion doc/content/stack.bib
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,100 @@ @article{Kinnear2022
keywords = {computer-aided assessment,Course design,online and blended learning,specifications grading,university mathematics},
}

@article{Cameron2024,
title = {Designing a Blended Delivery Foundation Mathematics Course: {{Targeting}} Self-Efficacy, Skill Development and Social Connectedness},
shorttitle = {Designing a Blended Delivery Foundation Mathematics Course},
author = {Cameron, Rosie A.},
year = 2024,
month = jan,
journal = {MSOR Connections},
volume = {22},
number = {1},
pages = {29--41},
issn = {2051-4220},
doi = {10.21100/msor.v22i1.1451},
}

@article{Cameron2025,
title = {`{{The}} Green Tick': How Instant Feedback Shaped Self-Efficacy in a First-Year Mathematics Course},
shorttitle = {`{{The}} Green Tick'},
author = {Cameron, Rosie A.},
year = 2025,
journal = {International Journal of Mathematical Education in Science and Technology},
pages = {1--17},
publisher = {Taylor \& Francis},
issn = {0020-739X},
doi = {10.1080/0020739X.2025.2574947},
}

@article{Gratwick2023,
title = {Using Online {{STACK}} Assessment to Teach Complex Analysis: A Prototype Course Design?},
shorttitle = {Using Online {{STACK}} Assessment to Teach Complex Analysis},
author = {Gratwick, Richard and O'Hagan, Steven},
year = 2023,
month = mar,
journal = {MSOR Connections},
volume = {21},
number = {1},
pages = {58--64},
issn = {2051-4220},
doi = {10.21100/msor.v21i1.1394},
}

@article{Lowe2026,
title = {A Decade of Computer-Algebra-Aided Online Assessment of Mathematics at the {{UK Open University}}},
author = {Lowe, Tim and Hunt, Tim},
year = 2026,
month = mar,
journal = {Teaching Mathematics and its Applications: An International Journal of the IMA},
volume = {45},
number = {1},
pages = {1--18},
issn = {0268-3679, 1471-6976},
doi = {10.1093/teamat/hraf021},
}

@article{Wallace2026,
title = {Students Writing {{STACK}} Questions: E-Assessment as the Focus of a Final-Year Project},
shorttitle = {Students Writing {{STACK}} Questions},
author = {Wallace, Clare and Fearn, Sam},
year = 2026,
month = mar,
journal = {Teaching Mathematics and Its Applications},
volume = {45},
number = {1},
pages = {124--138},
issn = {0268-3679, 1471-6976},
doi = {10.1093/teamat/hrag006},
}

@article{Chelleri2025,
title = {Assessing Student Perspectives on {{STACK}} Implementation in University Mathematics Courses},
author = {Chelleri, Elisabetta and Doz, Daniel and Juma, Zevick Otieno and {d'Assise Dogbalou}, Motognon Wastalas and Lewa{\'n}ski, Danilo},
year = 2025,
month = oct,
journal = {International Journal of Mathematical Education in Science and Technology},
pages = {1--32},
issn = {0020-739X, 1464-5211},
doi = {10.1080/0020739X.2025.2563115},
}

@article{Doz2026,
title = {Latent Class Analysis of Student Attitudes and Performance in Online Mathematics Assessments: A {{Technology Acceptance Model}} Approach},
shorttitle = {Latent Class Analysis of Student Attitudes and Performance in Online Mathematics Assessments},
author = {Doz, Daniel and {d'Assise Dogbalou}, Motognon Wastalas and Juma, Zevick Otieno and Lewa{\'n}ski, Danilo},
year = 2026,
month = may,
journal = {International Journal of Mathematical Education in Science and Technology},
volume = {57},
number = {5},
pages = {944--966},
issn = {0020-739X, 1464-5211},
doi = {10.1080/0020739X.2025.2502859},
}




@INPROCEEDINGS{WebALT2006,
author = {Sangwin, C.~J. and Grove, M.~J.},
Expand Down Expand Up @@ -256,7 +350,7 @@ @INPROCEEDINGS{Sangwin2012ICME
}

@INPROCEEDINGS{Sangwin2013HEA,
AUTHOR = {Butcher, P. and Sangwin, C.~. and Hunt, T.},
AUTHOR = {Butcher, P. and Sangwin, C. and Hunt, T.},
TITLE = {Embedding and enhancing eAssessment in the leading open source {VLE}},
BOOKTITLE = {Proceedings of the Higher Education Academy Conference, Birmingham},
YEAR = {2013},
Expand Down Expand Up @@ -395,6 +489,52 @@ @MASTERSTHESIS{CervalPena2008

% More general research about online assessment, in which STACK played a significant part.

@incollection{Iannone2026,
title = {The Transfer of Assessment from Pen and Paper to E-Assessment: {{Two}} Case Studies from One Theoretical Perspective},
shorttitle = {The Transfer of Assessment from Pen and Paper to E-Assessment},
booktitle = {Digital {{Technology}} and {{Artificial Intelligence}} in {{Mathematics Education Assessment}}},
author = {Iannone, Paola and Lemmo, Alice and Kinnear, George},
editor = {Geraniou, Eirini and Crisan, Cosette and Mavrikis, Manolis},
year = 2026,
publisher = {Routledge},
doi = {10.4324/9781003533764-2},
}
@incollection{Pinkernell2026a,
title = {Adaptive Feedback and (Digital) Assessment of Conceptual Knowledge},
booktitle = {Digital {{Technology}} and {{Artificial Intelligence}} in {{Mathematics Education Assessment}}},
author = {Pinkernell, Guido and Weigand, Hans-Georg},
editor = {Geraniou, Eirini and Crisan, Cosette and Mavrikis, Manolis},
year = 2026,
publisher = {Routledge},
doi = {10.4324/9781003533764-6},
}

@incollection{Sangwin2026a,
title = {Using Computer Algebra to Support Automatic Assessment of Mathematics},
booktitle = {Digital {{Technology}} and {{Artificial Intelligence}} in {{Mathematics Education Assessment}}},
author = {Sangwin, Christopher and Oyengo, Michael O.},
editor = {Geraniou, Eirini and Crisan, Cosette and Mavrikis, Manolis},
year = 2026,
publisher = {Routledge},
doi = {10.4324/9781003533764-12},
}


@article{Kontorovich2023b,
title = {When Learning Stumbles upon Identity and Affect: A Loaded Student--Student Collaboration in Linear Algebra},
shorttitle = {When Learning Stumbles upon Identity and Affect},
author = {Kontorovich, Igor'},
year = 2023,
month = sep,
journal = {International Journal of Mathematical Education in Science and Technology},
volume = {54},
number = {8},
pages = {1526--1540},
publisher = {Taylor \& Francis},
issn = {0020-739X},
doi = {10.1080/0020739X.2023.2173102},
}

@inproceedings{KinnearIannone2024PME,
title = {Students' Views of e-Assessment Feedback in Undergraduate Mathematics},
booktitle = {Proceedings of the 47th {{Conference}} of the {{International Group}} for the {{Psychology}} of {{Mathematics Education}}},
Expand Down
Binary file modified doc/content/stack_publications.pdf
Binary file not shown.
10 changes: 7 additions & 3 deletions doc/content/stack_publications.tex
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,19 @@ \section{Theses}
\printbibliography[heading=none]

\section{Research and conference papers}
\nocite{Gratwick2020,Akveld2024,2018Mastery,Yoshitomi2018,Barbas2016,Nakamura2016,Sangwin2015KHDM}
\nocite{Gratwick2020,Gratwick2023,Akveld2024,2018Mastery,Yoshitomi2018,Barbas2016,Nakamura2016,Sangwin2015KHDM}
\nocite{Rasila2016,Rasila2016b,Rasila2016c}
\nocite{Shirai2015a,Shirai2015b,Pavia2015,Nakamura2014,Shirai2014,Nakamura2013}
\nocite{Sangwin2012ICME,Sangwin2013HEA,Lowe2010,Sangwin2009Equality,Sangwin2010IGI,Nakamura2010b}
\nocite{Rasila2010,Sangwin2009Calculumus,Sangwin2009ICMI,Rasila2007}
\nocite{Sangwin2006CASAlgebra,WebALT2006,Sangwin2006UniServe,SangwinTMA03,SangwinHSkills02}
\nocite{lowe_mestel_2019,erskine_mestel_2018,Paiva2017}
\nocite{Kinnear2022,Kinnear2022,Kontorovich2023,Kinnear2023CERME,Kinnear2024RME,Akveld2024,KinnearIannone2024PME}
\nocite{lowe_mestel_2019,erskine_mestel_2018,Lowe2026,Paiva2017}
\nocite{Kinnear2022,Kinnear2022,Kontorovich2023,Kontorovich2023b,Kinnear2023CERME,Kinnear2024RME,Akveld2024,KinnearIannone2024PME}
\nocite{Kinnear2024FAME,Razeghpour2024FAME,Taha2024FAME}
\nocite{Iannone2026,Pinkernell2026a,Sangwin2026a}
\nocite{Chelleri2025,Doz2026}
\nocite{Wallace2026}
\nocite{Cameron2024,Cameron2025}
\printbibliography[heading=none]

\section{Proceedings of the first STACK conference, 2018}
Expand Down
18 changes: 18 additions & 0 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,21 @@ function get_latest_question_version($questionid) {
$result = reset($result);
return [$result->version, $result->questionid, $result->questionbankentryid, $versions];
}

/**
* Get the base URL for the plot.php script.
* @return string
*/
function stack_plot_url_base() {
global $CFG;
return $CFG->wwwroot . '/question/type/stack/plot.php/';
}

/**
* Get the directory path for the corsscripts directory.
* @return string
*/
function stack_cors_scripts_dir() {
global $CFG;
return $CFG->dirroot . '/question/type/stack/corsscripts/';
}
5 changes: 1 addition & 4 deletions stack/cas/castext2/blocks/jsxgraph.block.php
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,7 @@ public function validate(
) {
$valid = false;
$err[] = stack_string('stackBlock_jsxgraph_unknown_style', ['style' => $stylename]);
} else if (
!file_exists($CFG->dirroot . '/question/type/stack/corsscripts/jsxgraphstyles/' .
$stylename . '.css')
) {
} else if (!file_exists(stack_cors_scripts_dir() . 'jsxgraphstyles/' . $stylename . '.css')) {
$valid = false;
$err[] = stack_string('stackBlock_jsxgraph_unknown_style', ['style' => $stylename]);
}
Expand Down
5 changes: 1 addition & 4 deletions stack/cas/castext2/blocks/parsons.block.php
Original file line number Diff line number Diff line change
Expand Up @@ -584,10 +584,7 @@ public function validate(
) {
$valid = false;
$err[] = stack_string('stackBlock_parsons_unknown_style', ['style' => $stylename]);
} else if (
!file_exists($CFG->dirroot . '/question/type/stack/corsscripts/parsonsstyles/' .
$stylename . '.min.css')
) {
} else if (!file_exists(stack_cors_scripts_dir() . 'parsonsstyles/' . $stylename . '.min.css')) {
$valid = false;
$err[] = stack_string('stackBlock_parsons_unknown_style', ['style' => $stylename]);
}
Expand Down
34 changes: 31 additions & 3 deletions stack/cas/connector.dbcache.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ public function compute($command) {
// @codingStandardsIgnoreEnd
if (!stack_connection_helper::check_stackmaxima_version($cached->result)) {
stack_connection_helper::warn_about_version_mismatch($this->debug);
// We could consider automatically purging the cache here.
$this->delete_cached_result($cached->key);
} else {
return $cached->result;
}
return $cached->result;
}
$this->debug->log('Maxima command not found in the cache. Using the raw connection.');
$result = $this->rawconnection->compute($command);
Expand All @@ -78,7 +79,12 @@ public function json_compute($command): array {
// @codingStandardsIgnoreStart
$this->debug->log('Unpacked result found in the DB cache', print_r($cached->result, true));
// @codingStandardsIgnoreEnd
return $cached->result;
if (!$this->check_json_stackmaxima_version($cached->result)) {
stack_connection_helper::warn_about_version_mismatch($this->debug);
$this->delete_cached_result($cached->key);
} else {
return $cached->result;
}
}
$this->debug->log('Maxima command not found in the cache. Using the raw connection.');
$this->debug->log('Maxima command', $command);
Expand Down Expand Up @@ -160,6 +166,28 @@ protected function add_to_cache($command, $result, $key = null) {
$this->db->insert_record('qtype_stack_cas_cache', $data);
}

/**
* Delete a cached result by cache key.
* @param string $key the cache key to delete.
*/
protected function delete_cached_result($key) {
$this->db->delete_records('qtype_stack_cas_cache', ['hash' => $key]);
}

/**
* Check version information in JSON CAS session results.
* @param array $result the JSON result from Maxima.
* @return bool whether the cached result used compatible STACK-Maxima libraries.
*/
protected function check_json_stackmaxima_version($result) {
if (!array_key_exists('values', $result) || !is_array($result['values']) ||
!array_key_exists('__stackmaximaversion', $result['values'])) {
return true;
}

return stack_utils::get_config()->stackmaximaversion === $result['values']['__stackmaximaversion'];
}

/**
* Add description here
* @param string $command Maxima code to execute.
Expand Down
2 changes: 1 addition & 1 deletion stack/input/equiv/equiv.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ public function render_validation(stack_input_state $state, $fieldname, $lang =

if (self::INVALID == $state->status) {
$feedback .= html_writer::tag(
'span',
defined('MOODLE_INTERNAL') ? 'span' : 'div',
stack_string('studentValidation_invalidAnswer'),
['class' => 'alert alert-danger stackinputerror']
);
Expand Down
10 changes: 9 additions & 1 deletion stack/input/inputbase.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1790,7 +1790,7 @@ public function maxima_to_response_array($in) {
* This function is responsible for removing the validation tags from the question stem and replacing
* them with the validation feedback. Only the equiv input type currently does anything different here.
*/
public function replace_validation_tags($state, $fieldname, $questiontext) {
public function replace_validation_tags($state, $fieldname, $questiontext, $custom_validation = null) {

$name = $this->name;
// ISS879 Set language override to null as we should be in the question render here. It's only
Expand All @@ -1807,6 +1807,10 @@ public function replace_validation_tags($state, $fieldname, $questiontext) {
$class = "stackinputfeedback compact";
}

if ($custom_validation !== null) {
$feedback = $custom_validation;
}

if (!$feedback) {
$class .= ' empty';
}
Expand Down Expand Up @@ -1898,4 +1902,8 @@ public function get_api_solution($tavalue) {
public function get_api_solution_render($tadisplay, $ta) {
return $tadisplay;
}

public function get_name(): string {
return $this->name;
}
}
2 changes: 1 addition & 1 deletion stack/questionlibrary.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public static function render_question(object $question): string {
}

foreach ($plots as $original => $new) {
$questiontext = str_replace($original, $CFG->wwwroot . '/question/type/stack/plot.php/' . $new, $questiontext);
$questiontext = str_replace($original, stack_plot_url_base() . $new, $questiontext);
}

$formatoptions = new stdClass();
Expand Down
Loading