Skip to content
Snippets Groups Projects
Commit f6896b03 authored by Chris Sangwin's avatar Chris Sangwin
Browse files

Update the docs, and code tidy.

parent 8b6c8506
No related branches found
No related tags found
No related merge requests found
......@@ -2,7 +2,7 @@
Author Tim Lutz - University of Edinburgh and University of Education Heidelberg, 2022-23.
STACK supports inclusion of dynamic graphs using GeoGebra: [https://geogebra.org](https://geogebra.org). This page documents how to use GeoGebra applets to display visuals, and as a STACK input.
STACK supports inclusion of dynamic graphics using GeoGebra: [https://geogebra.org](https://geogebra.org). This page documents how to use GeoGebra applets both to display GeoGebra visuals, and as a STACK input.
Information from GeoGebra applets can be linked to STACK inputs and assessed by potential response trees in the normal way. To help with assessment, STACK provides a number of [geometry related maxima functions](../CAS/Geometry.md).
......@@ -26,7 +26,7 @@ For the material [https://www.geogebra.org/m/seehz3km](https://www.geogebra.org/
## Add the material_id to a new STACK task
Then include the following question text, which includes a simple `[[geogebra]]` [block](Question_blocks.md).
Then include the following question text, which includes a simple `[[geogebra]]` [question block](Question_blocks/index.md).
<p>You can show an applet:</p>
[[geogebra]]
......@@ -35,7 +35,13 @@ Then include the following question text, which includes a simple `[[geogebra]]`
## Using the sub-tags "set", "watch" and "remember"
### naming conventions
The "set", "watch" and "remember" tags to the `[[geogebra]]` question block link Maxima values to GeoGebra objects in various ways.
* "set" will set a GeoGebra object, point or value to a STACK-calculated value.
* "watch" enables a STACK input to listen to values and points in GeoGebra.
* "remember" is needed when you do not want to calculate feedback with some of the GeoGebra objects in an applet, but you do want to be able to save and restore the state of an applet when the student returns to the question later.
### Naming conventions
The sub-tag `set` parameter value is a string of (unique), comma-separated, GeoGebra-objects with latin names.
For example, the sub-tag value could look like: `set = "A,B,C,D,a2,E__fixed"` and would be placed in the block as
......@@ -45,18 +51,20 @@ For example, the sub-tag value could look like: `set = "A,B,C,D,a2,E__fixed"` a
To be able to make things easy for question authors, the following name conventions _must_ be followed:
1. Names of variables must be equal in STACK and GeoGebra.
2. Values are `int` or `float` STACK variables.
3. Points are represented as array in STACK like: e.g. `[2,3]`, which means a point with \(x=2, y=3\). The Maxima object would be for point \(D\) e.g. `D:[2,3]`.
4. Value-names must start with lower case letters.
5. Angles are used like values, and so must be named lowercase letters in Latin-Alphabet, (not Greek unicode letters!) and values are radians
6. Point-names must start with upper case letters
1. Names of variables must be equal in both STACK and GeoGebra.
2. Values must be `int` or `float` STACK variables.
3. Point-names must start with upper case letters.
4. Points are represented as a list in STACK like: e.g. `[2,3]`, which means a point with \(x=2, y=3\). The Maxima object would be for point \(D\) e.g. `D:[2,3]`.
5. Value-names must start with lower case letters.
6. Angles are used like values, and so must be named lowercase letters in Latin-Alphabet, (not Greek unicode letters!) and values must be in radians.
## Using the "set" sub-tag
With the "set" sub-tag you can set a GeoGebra object point or value to a STACK-calculated value.
With the "set" sub-tag you can set a GeoGebra object, point or value to a STACK-calculated value.
Points will be set free to manipulate, unless you add `__fixed` or other double-underscore-tags to the Point-name. A full list of available options see "set: double-underscore-tags in the "advanced use-cases"-section. Angles cannot be set directly, set points instead!
Points will be set free to manipulate, unless you add `__fixed` or other double-underscore-tags to the Point-name. A full list of available options see "set: double-underscore-tags in the "advanced use-cases"-section.
Angles cannot be set directly, set points instead!
### A minimal example
......@@ -90,7 +98,8 @@ Set the question text:
[[input:A]][[validation:A]]
[[input:b]][[validation:b]]
Note:
Recall that since `A` is upper case it must be a point, and since `b` is lower case it will be a value/angle. Note:
1. `A` _must_ be an algebraic-input and you _must_ allow floats!
2. You can access `A` in STACK for feedback as a list of values for points `A[0]->x-value`, `A[1]->y-value`
3. You can access `b` in STACK as value. If `b` represents an angle then `b` is in radians.
......
......@@ -72,3 +72,6 @@ var label = "\\({f\\left(x\\right)=\\sqrt{x}}\\)";
Note, this block is _not_ designed to output Maxima expressins in JS format. For example, this block will not convert `x^2` into `x**2`.
## GeoGebra block ##
STACK supports inclusion of dynamic graphics using GeoGebra: [https://geogebra.org](https://geogebra.org) both as static visuals and as a STACK input. This block is documented fully on the [GeoGebra page](../GeoGebra.md).
......@@ -844,7 +844,7 @@ $string['stackBlock_geogebra_link_help'] = 'You want to edit this material? If
$string['stackBlock_geogebra_heading'] = 'GeoGebra materials';
// Define the stackBlock GeoGebra strings for global admin options.
$string['stackBlock_geogebra_settingdefaultoptions'] = 'Options for GeoGebra in STACK';
$string['stackBlock_geogebra_settingdefaultoptions_desc'] = 'We recommend to read the documentation of GeoGebra and STACK';
$string['stackBlock_geogebra_settingdefaultoptions_desc'] = 'The documentation for using GeoGebra with STACK is under Authoring/GeoGebra.md';
$string['stackBlock_geogebrabaseurl'] = 'Link to GeoGebra hosting (optional)';
$string['stackBlock_geogebrabaseurl_help'] = 'Here you can add a custom link, if you host GeoGebra scripts on your own server. If you just want to use a specific GeoGebra version, use: https://www.geogebra.org/apps/5.0.498.0/web3d (e.g. for version 5.0.498.0)';
......
......@@ -22,33 +22,27 @@
*/
defined('MOODLE_INTERNAL') || die();
require_once __DIR__ . '/../block.interface.php';
require_once __DIR__ . '/../block.factory.php';
require_once(__DIR__ . '/../block.interface.php');
require_once(__DIR__ . '/../block.factory.php');
require_once __DIR__ . '/root.specialblock.php';
require_once __DIR__ . '/stack_translate.specialblock.php';
require_once(__DIR__ . '/root.specialblock.php');
require_once(__DIR__ . '/stack_translate.specialblock.php');
class stack_cas_castext2_geogebra extends stack_cas_castext2_block
{
class stack_cas_castext2_geogebra extends stack_cas_castext2_block {
private static $countgraphs = 1;
//compatibility with php 7.4: Defining "str_ends_with" if not in existence, delete this function when dropping support for php 7.4, replace all occurences of this->str_ends_with(args) by str_ends_with(args)
private function str_ends_with($word, $search_string)
{
$search_string_len = mb_strlen($search_string);
if (
mb_substr($word, -$search_string_len, $search_string_len) ==
$search_string
) {
// Compatibility with php 7.4: Defining "str_ends_with" if not in existence, delete this function when
// dropping support for php 7.4, replace all occurences of this->str_ends_with(args) by str_ends_with(args).
private function str_ends_with($word, $searchstring) {
$searchstringlen = mb_strlen($searchstring);
if (mb_substr($word, -$searchstringlen, $searchstringlen) == $searchstring) {
return true;
}
return false;
}
public function compile($format, $options): ?MP_Node
{
// We are outputting as [[iframe]], so we will generate some
// parameters for it on the side.
public function compile($format, $options): ?MP_Node {
// We are outputting as [[iframe]], so we will generate some parameters for it on the side.
$r = new MP_List([new MP_String('iframe')]);
$iparams = ['scrolling' => false];
// For now we run without the sandbox, THIS NEES TO BE FIXED WITH GEOGEBRA SIDES HELP..
......@@ -165,22 +159,23 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
$set_fixed = true;
}
if ($this->str_ends_with($geogebraname, '__preserve')) {
// Assuming: object should preserve its defintion, e.g. to be a point on an object
// Assuming: object should preserve its defintion, e.g. to be a point on an object.
$geogebraname = substr($geogebraname, 0, -10);
$set_preserve = true;
}
if ($this->str_ends_with($geogebraname, '__hide')) {
// Assuming: object should be hidden at startup
// Assuming: object should be hidden at startup.
$geogebraname = substr($geogebraname, 0, -6);
$set_hide = true;
}
if ($this->str_ends_with($geogebraname, '__show')) {
// Assuming: object should be shown at startup
// Assuming: object should be shown at startup.
$geogebraname = substr($geogebraname, 0, -6);
$set_show = true;
}
if ($this->str_ends_with($geogebraname, '__novalue')) {
// Assuming: object should not be set to a given value, keyword is useful in combination with __hide or __show
// Assuming: object should not be set to a given value,
// keyword is useful in combination with __hide or __show.
$geogebraname = substr($geogebraname, 0, -9);
$set_novalue = true;
}
......@@ -201,7 +196,8 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
$setcode->arguments[] = new MP_String("})');\n");
// appletObject.evalCommand('G= Point({{#fx#},4})');
} else if ($set_preserve) {
//Assuming point definition should be preserved while setting object: ATTENTION GGB Applet language must be English for this to work!
// Assuming point definition should be preserved while setting object:
// ATTENTION GGB Applet language must be English for this to work!
$setcode->arguments[] = new MP_String("\n appletObject.evalCommand('SetCoords(" .
$geogebraname .
',');
......@@ -210,7 +206,7 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
$setcode->arguments[] = new MP_FunctionCall(new MP_Identifier('string'), [new MP_Indexing(new MP_Identifier($geogebraname), [new MP_Integer(2)])]);
$setcode->arguments[] = new MP_String(")');\n");
} else if ($set_novalue) {
//assuming point value should not be set, useful when using __show/ __hide
// Assuming point value should not be set, useful when using __show/ __hide.
// NOOP.
} else {
// Assuming point is interactable by the user.
......@@ -233,7 +229,7 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
$setcode->arguments[] = new MP_FunctionCall(new MP_Identifier('string'), [new MP_Identifier($geogebraname)]);
$setcode->arguments[] = new MP_String(")');\n");
} else if ($set_novalue) {
//assuming value should not be set, useful when using __show/ __hide
// Assuming value should not be set, useful when using __show/ __hide.
// NOOP
} else {
$setcode->arguments[] = new MP_String("\n appletObject.evalCommand('" .
......@@ -242,17 +238,17 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
$setcode->arguments[] = new MP_String("');\n");
}
}
//end of section for setting values according to suffix
// End of section for setting values according to suffix.
//section to show or hide objects if there are according suffix readings
// Section to show or hide objects if there are according suffix readings.
if ($set_show) {
//assuming: object should be shown in view 1 (use case: if object is hidden by default)
// Assuming: object should be shown in view 1 (use case: if object is hidden by default).
$setcode->arguments[] = new MP_String(
"\n appletObject.evalCommand('SetVisibleInView(" .
$geogebraname .
",1,true)');\n");
} else if ($set_hide) {
//assuming: object should be hidden (use case: if object is shown by default)
// Assuming: object should be hidden (use case: if object is shown by default).
$setcode->arguments[] = new MP_String(
"\n appletObject.evalCommand('SetVisibleInView(" .
$geogebraname .
......@@ -293,7 +289,7 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
// All the IFRAME related parameters are no known we can add them to the output.
$r->items[] = new MP_String(json_encode($iparams));
// Then lets add some script tags to the head to load some stuff.
// Then let's add some script tags to the head to load some stuff.
$mathjax = stack_get_mathjax_url();
// Silence the MathJax message that blinks on top of every graph.
$r->items[] = new MP_List([
......@@ -382,10 +378,7 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
$commonpostcode .= "\nvar applet = new GGBApplet(params, true);";
$customgeogebrabaseurl = stack_utils::get_config()->geogebrabaseurl;
if (
isset($customgeogebrabaseurl) &&
trim($customgeogebrabaseurl) != ''
) {
if (isset($customgeogebrabaseurl) && trim($customgeogebrabaseurl) != '') {
// Use JSON-encode to ensure that should the URL have something fancy
// in it we can still survive.
$commonpostcode .=
......@@ -429,8 +422,7 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
public function is_flat(): bool
{
public function is_flat(): bool {
return false;
}
......@@ -438,8 +430,7 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
return 'This is never happening! The logic goes to [[iframe]].';
}
public function validate_extract_attributes(): array
{
public function validate_extract_attributes(): array {
// Note that all the "set" variables are actually CAS variables.
// So we should return the nosuffix versions here for checking.
// Not a major issue as the security system will stop any calls and
......@@ -448,8 +439,7 @@ class stack_cas_castext2_geogebra extends stack_cas_castext2_block
return [];
}
public function validate(&$errors = [], $options = []): bool
{
public function validate(&$errors = [], $options = []): bool {
// Basically, check that the dimensions have units we know.
// Also that the references make sense.
$valid = true;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment