1<chapter title="Introduction"> 2 3\Mathics---to be pronounced like "Mathematics" without the "emat"---is a general-purpose computer algebra system (CAS). It is meant to be a free, open-source alternative to \Mathematica. It is free both as in "free beer" and as in "freedom". There are various online mirrors running \Mathics but it is also possible to run \Mathics locally. A list of mirrors can be found at the \Mathics homepage, <url>https://mathics.org</url>. 4 5The programming language of \Mathics is meant to resemble \Wolfram\'s famous \Mathematica as much as possible. However, \Mathics is in no way affiliated or supported by \Wolfram. \Mathics will probably never have the power to compete with \Mathematica in industrial applications; yet, it might be an interesting alternative for educational purposes. 6 7For implementation details see 8<url>https://github.com/mathics/Mathics/wiki</url>. 9 10<section title="Why yet another CAS?"> 11\Mathematica is great, but it has one big disadvantage: It is not free. On the one hand, people might not be able or willing to pay hundreds of dollars for it; on the other hand, they would still not be able to see what\'s going on "inside" the program to understand their computations better. That\'s what free software is for! 12 13\Mathics aims at combining the best of both worlds: the beauty of \Mathematica backed by a free, extensible Python core which includes a rich set of Python tools numeric computation, <url>https://numpy.org/numpy</url>, and symbolic mathematics, <url>https://sympy.org</url>. 14 15Of course, there are drawbacks to the \Mathematica language, despite all its beauty. It does not really provide object orientation and especially encapsulation, which might be crucial for big software projects. Nevertheless, \Wolfram still managed to create their amazing <em>Wolfram|Alpha</em> entirely with \Mathematica, so it can\'t be too bad! 16 17However, it is not even the intention of \Mathics to be used in large-scale projects and calculations---at least not as the main framework---but rather as a tool for quick explorations and in educating people who might later switch to \Mathematica. 18</section> 19 20<section title="What does it offer?"> 21Some of the most important features of \Mathics are 22<ul> 23<li>a powerful functional programming language, 24<li>a system driven by pattern matching and rules application, 25<li>rationals, complex numbers, and arbitrary-precision arithmetic, 26<li>lots of list and structure manipulation routines, 27<li>an interactive graphical user interface right in the Web browser using MathML (apart from a command line interface), 28<li>creation of graphics (e.g. plots) and display in the browser using SVG for 2D graphics and WebGL for 3D graphics, 29<li>export of results to \LaTeX (using Asymptote for graphics), 30<li>a very easy way of defining new functions in Python, 31<li>an integrated documentation and testing system. 32</ul> 33</section> 34 35<section title="What is missing?"> 36There are lots of ways in which \Mathics could still be improved. 37 38Most notably, performance is still slow, so any serious usage in cutting-edge industry or research will fail, unfortunately. Although Cython can be used to speed up parts of \Mathics, more is needed to speed up pattern matching. Replacing recursion with iteration may help here. 39 40Apart from performance issues, new features such as more functions in various mathematical fields like calculus, number theory, or graph theory are still to be added. 41 42In the future we intend to make better use the the graphics available in the excellent packages: 43 44<ul> 45<li>sympy plotting,<url>https://docs.sympy.org/latest/modules/plotting.html</url> 46<li>mathplotlib pyplot, <url>https://matplotlib.org/api/pyplot_api.html</url>, and 47<li>networkx, <url>https://networkx.github.io/</url> 48</ul> 49 50</section> 51 52<section title="Who is behind it?"> 53\Mathics was created by Jan Pöschk in 2011. From 2013 to about 2017 it had been maintained mostly by Angus Griffith and Ben Jones. Since then, a number of others have been people involved in \Mathics; the list can be found in the <con>AUTHORS.txt</con> file, <url>https://github.com/mathics/Mathics/blob/master/AUTHORS.txt</url>. 54 55If you have any ideas on how to improve \Mathics or even want to help out yourself, please contact us! 56 57\skip 58Welcome to \Mathics, have fun! 59</section> 60 61</chapter> 62 63 64<chapter title="Installation and Running"> 65 66\Mathics runs natively on a computer that has Python or PyPy 3.6 or later installed. Since \Mathics relies on <i>sympy</i> which in turn relies on <i>numpy</i>, you will need at least those installed. 67 68Since installation may change, see <url>https://github.com/mathics/Mathics/wiki/Installing-and-Running</url> for the most recent instructions for installing from PyPI, source, or from <i>docker</i>. 69 70</chapter> 71 72 73<chapter title="Language Tutorials"> 74 75The following sections are introductions to the basic principles of the language of \Mathics. A few examples and functions are presented. Only their most common usages are listed; for a full description of a Symbols possible arguments, options, etc., see its entry in the Reference of Built-in Symbols. 76 77However if you google for "Mathematica Tutorials" you will find easily dozens of other tutorials which are applicable. Be warned though that \Mathics does not yet offer the full range and features and capabilities of \Mathematica. 78 79<section title="Basic calculations"> 80\Mathics can be used to calculate basic stuff: 81 82>> 1 + 2 83 = 3 84To submit a command to \Mathics, press 'Shift+Return' in the Web interface or 'Return' in the console interface. The result will be printed in a new line below your query. 85 86\Mathics understands all basic arithmetic operators and applies the usual operator precedence. Use parentheses when needed: 87>> 1 - 2 * (3 + 5) / 4 88 = -3 89The multiplication can be omitted: 90>> 1 - 2 (3 + 5) / 4 91 = -3 92>> 2 4 93 = 8 94Powers can be entered using '^': 95>> 3 ^ 4 96 = 81 97Integer divisions yield rational numbers: 98>> 6 / 4 99 = 3 / 2 100To convert the result to a floating point number, apply the function 'N': 101>> N[6 / 4] 102 = 1.5 103As you can see, functions are applied using square braces '[' and ']', in contrast to the common notation of '(' and ')'. At first hand, this might seem strange, but this distinction between function application and precedence change is necessary to allow some general syntax structures, as you will see later. 104 105\Mathics provides many common mathematical functions and constants, e.g.: 106>> Log[E] 107 = 1 108>> Sin[Pi] 109 = 0 110>> Cos[0.5] 111 = 0.877583 112When entering floating point numbers in your query, \Mathics will perform a numerical evaluation and present a numerical result, pretty much like if you had applied 'N'. 113 114Of course, \Mathics has complex numbers: 115>> Sqrt[-4] 116 = 2 I 117>> I ^ 2 118 = -1 119>> (3 + 2 I) ^ 4 120 = -119 + 120 I 121>> (3 + 2 I) ^ (2.5 - I) 122 = 43.663 + 8.28556 I 123>> Tan[I + 0.5] 124 = 0.195577 + 0.842966 I 125 126'Abs' calculates absolute values: 127>> Abs[-3] 128 = 3 129>> Abs[3 + 4 I] 130 = 5 131 132\Mathics can operate with pretty huge numbers: 133>> 100! 134 = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 135('!' denotes the factorial function.) 136The precision of numerical evaluation can be set: 137>> N[Pi, 100] 138 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068 139 140Division by zero is forbidden: 141>> 1 / 0 142 : Infinite expression 1 / 0 encountered. 143 = ComplexInfinity 144Other expressions involving 'Infinity' are evaluated: 145>> Infinity + 2 Infinity 146 = Infinity 147In contrast to combinatorial belief, '0^0' is undefined: 148>> 0 ^ 0 149 : Indeterminate expression 0 ^ 0 encountered. 150 = Indeterminate 151 152The result of the previous query to \Mathics can be accessed by '%': 153>> 3 + 4 154 = 7 155>> % ^ 2 156 = 49 157</section> 158 159<section title="Symbols and Assignments"> 160Symbols need not be declared in \Mathics, they can just be entered and remain variable: 161>> x 162 = x 163Basic simplifications are performed: 164>> x + 2 x 165 = 3 x 166Symbols can have any name that consists of characters and digits: 167>> iAm1Symbol ^ 2 168 = iAm1Symbol ^ 2 169 170You can assign values to symbols: 171>> a = 2 172 = 2 173>> a ^ 3 174 = 8 175>> a = 4 176 = 4 177>> a ^ 3 178 = 64 179Assigning a value returns that value. If you want to suppress the output of any result, add a ';' to the end of your query: 180>> a = 4; 181 182Values can be copied from one variable to another: 183>> b = a; 184Now changing 'a' does not affect 'b': 185>> a = 3; 186>> b 187 = 4 188Such a dependency can be achieved by using "delayed assignment" with the ':=' operator (which does not return anything, as the right side is not even evaluated): 189>> b := a ^ 2 190>> b 191 = 9 192>> a = 5; 193>> b 194 = 25 195</section> 196 197 198<section title="Comparisons and Boolean Logic"> 199Values can be compared for equality using the operator '==': 200>> 3 == 3 201 = True 202>> 3 == 4 203 = False 204The special symbols 'True' and 'False' are used to denote truth values. Naturally, there are inequality comparisons as well: 205>> 3 > 4 206 = False 207Inequalities can be chained: 208>> 3 < 4 >= 2 != 1 209 = True 210 211Truth values can be negated using '!' (logical <em>not</em>) and combined using '&&' (logical <em>and</em>) and '||' (logical <em>or</em>): 212>> !True 213 = False 214>> !False 215 = True 216>> 3 < 4 && 6 > 5 217 = True 218'&&' has higher precedence than '||', i.e. it binds stronger: 219>> True && True || False && False 220 = True 221>> True && (True || False) && False 222 = False 223</section> 224 225<section title="Strings"> 226Strings can be entered with '"' as delimiters: 227>> "Hello world!" 228 = Hello world! 229As you can see, quotation marks are not printed in the output by default. This can be changed by using 'InputForm': 230>> InputForm["Hello world!"] 231 = "Hello world!" 232 233Strings can be joined using '<>': 234>> "Hello" <> " " <> "world!" 235 = Hello world! 236Numbers cannot be joined to strings: 237>> "Debian" <> 6 238 : String expected. 239 = Debian <> 6 240They have to be converted to strings using 'ToString' first: 241>> "Debian" <> ToString[6] 242 = Debian6 243</section> 244 245<section title="Lists"> 246Lists can be entered in \Mathics with curly braces '{' and '}': 247>> mylist = {a, b, c, d} 248 = {a, b, c, d} 249There are various functions for constructing lists: 250>> Range[5] 251 = {1, 2, 3, 4, 5} 252>> Array[f, 4] 253 = {f[1], f[2], f[3], f[4]} 254>> ConstantArray[x, 4] 255 = {x, x, x, x} 256>> Table[n ^ 2, {n, 2, 5}] 257 = {4, 9, 16, 25} 258 259The number of elements of a list can be determined with 'Length': 260>> Length[mylist] 261 = 4 262Elements can be extracted using double square braces: 263>> mylist[[3]] 264 = c 265Negative indices count from the end: 266>> mylist[[-3]] 267 = b 268 269Lists can be nested: 270>> mymatrix = {{1, 2}, {3, 4}, {5, 6}}; 271There are alternate forms to display lists: 272>> TableForm[mymatrix] 273 = 1 2 274 . 275 . 3 4 276 . 277 . 5 6 278>> MatrixForm[mymatrix] 279 = 1 2 280 . 281 . 3 4 282 . 283 . 5 6 284 285There are various ways of extracting elements from a list: 286>> mymatrix[[2, 1]] 287 = 3 288>> mymatrix[[;;, 2]] 289 = {2, 4, 6} 290>> Take[mylist, 3] 291 = {a, b, c} 292>> Take[mylist, -2] 293 = {c, d} 294>> Drop[mylist, 2] 295 = {c, d} 296>> First[mymatrix] 297 = {1, 2} 298>> Last[mylist] 299 = d 300>> Most[mylist] 301 = {a, b, c} 302>> Rest[mylist] 303 = {b, c, d} 304 305Lists can be used to assign values to multiple variables at once: 306>> {a, b} = {1, 2}; 307>> a 308 = 1 309>> b 310 = 2 311 312Many operations, like addition and multiplication, "thread" over lists, i.e. lists are combined element-wise: 313>> {1, 2, 3} + {4, 5, 6} 314 = {5, 7, 9} 315>> {1, 2, 3} * {4, 5, 6} 316 = {4, 10, 18} 317It is an error to combine lists with unequal lengths: 318>> {1, 2} + {4, 5, 6} 319 : Objects of unequal length cannot be combined. 320 = {1, 2} + {4, 5, 6} 321</section> 322 323<section title="The Structure of Things"> 324Every expression in \Mathics is built upon the same principle: it consists of a <em>head</em> and an arbitrary number of <em>children</em>, unless it is an <em>atom</em>, i.e. it can not be subdivided any further. To put it another way: everything is a function call. This can be best seen when displaying expressions in their "full form": 325>> FullForm[a + b + c] 326 = Plus[a, b, c] 327Nested calculations are nested function calls: 328>> FullForm[a + b * (c + d)] 329 = Plus[a, Times[b, Plus[c, d]]] 330Even lists are function calls of the function 'List': 331>> FullForm[{1, 2, 3}] 332 = List[1, 2, 3] 333 334The head of an expression can be determined with 'Head': 335>> Head[a + b + c] 336 = Plus 337The children of an expression can be accessed like list elements: 338>> (a + b + c)[[2]] 339 = b 340The head is the 0th element: 341>> (a + b + c)[[0]] 342 = Plus 343 344The head of an expression can be exchanged using the function 'Apply': 345>> Apply[g, f[x, y]] 346 = g[x, y] 347>> Apply[Plus, a * b * c] 348 = a + b + c 349'Apply' can be written using the operator '@@': 350>> Times @@ {1, 2, 3, 4} 351 = 24 352(This exchanges the head 'List' of '{1, 2, 3, 4}' with 'Times', and then the expression 'Times[1, 2, 3, 4]' is evaluated, yielding 24.) 353'Apply' can also be applied on a certain <em>level</em> of an expression: 354>> Apply[f, {{1, 2}, {3, 4}}, {1}] 355 = {f[1, 2], f[3, 4]} 356Or even on a range of levels: 357>> Apply[f, {{1, 2}, {3, 4}}, {0, 2}] 358 = f[f[1, 2], f[3, 4]] 359'Apply' is similar to 'Map' ('/@'): 360>> Map[f, {1, 2, 3, 4}] 361 = {f[1], f[2], f[3], f[4]} 362>> f /@ {{1, 2}, {3, 4}} 363 = {f[{1, 2}], f[{3, 4}]} 364 365The atoms of \Mathics are numbers, symbols, and strings. 'AtomQ' tests whether an expression is an atom: 366>> AtomQ[5] 367 = True 368>> AtomQ[a + b] 369 = False 370The full form of rational and complex numbers looks like they were compound expressions: 371>> FullForm[3 / 5] 372 = Rational[3, 5] 373>> FullForm[3 + 4 I] 374 = Complex[3, 4] 375However, they are still atoms, thus unaffected by applying functions, for instance: 376>> f @@ Complex[3, 4] 377 = 3 + 4 I 378Nevertheless, every atom has a head: 379>> Head /@ {1, 1/2, 2.0, I, "a string", x} 380 = {Integer, Rational, Real, Complex, String, Symbol} 381 382The operator '===' tests whether two expressions are the same on a structural level: 383>> 3 === 3 384 = True 385>> 3 == 3.0 386 = True 387But 388>> 3 === 3.0 389 = False 390because '3' (an 'Integer') and '3.0' (a 'Real') are structurally different. 391</section> 392 393<section title="Functions and Patterns"> 394Functions can be defined in the following way: 395>> f[x_] := x ^ 2 396This tells \Mathics to replace every occurrence of 'f' with one (arbitrary) parameter 'x' with 'x ^ 2'. 397>> f[3] 398 = 9 399>> f[a] 400 = a ^ 2 401The definition of 'f' does not specify anything for two parameters, so any such call will stay unevaluated: 402>> f[1, 2] 403 = f[1, 2] 404 405In fact, <em>functions</em> in \Mathics are just one aspect of <em>patterns</em>: 'f[x_]' is a pattern that <em>matches</em> expressions like 'f[3]' and 'f[a]'. The following patterns are available: 406<dl> 407 <dt>'_' or 'Blank[]' 408 <dd>matches one expression. 409 <dt>'Pattern[$x$, $p$]' 410 <dd>matches the pattern $p$ and stores the value in $x$. 411 <dt>'$x$_' or 'Pattern[$x$, Blank[]]' 412 <dd>matches one expression and stores it in $x$. 413 <dt>'__' or 'BlankSequence[]' 414 <dd>matches a sequence of one or more expressions. 415 <dt>'___' or 'BlankNullSequence[]' 416 <dd>matches a sequence of zero or more expressions. 417 <dt>'_$h$' or 'Blank[$h$]' 418 <dd>matches one expression with head $h$. 419 <dt>'$x$_$h$' or 'Pattern[$x$, Blank[$h$]]' 420 <dd>matches one expression with head $h$ and stores it in $x$. 421 <dt>'$p$ | $q$' or 'Alternatives[$p$, $q$]' 422 <dd>matches either pattern $p$ or $q$. 423 <dt>'$p$ ? $t$' or 'PatternTest[$p$, $t$]' 424 <dd>matches $p$ if the test '$t$[$p$]' yields 'True'. 425 <dt>'$p$ /; $c$' or 'Condition[$p$, $c$]' 426 <dd>matches $p$ if condition $c$ holds. 427 <dt>'Verbatim[$p$]' 428 <dd>matches an expression that equals $p$, without regarding patterns inside $p$. 429</dl> 430 431As before, patterns can be used to define functions: 432>> g[s___] := Plus[s] ^ 2 433>> g[1, 2, 3] 434 = 36 435 436'MatchQ[$e$, $p$]' tests whether $e$ matches $p$: 437>> MatchQ[a + b, x_ + y_] 438 = True 439>> MatchQ[6, _Integer] 440 = True 441 442'ReplaceAll' ('/.') replaces all occurrences of a pattern in an expression using a 'Rule' given by '->': 443>> {2, "a", 3, 2.5, "b", c} /. x_Integer -> x ^ 2 444 = {4, a, 9, 2.5, b, c} 445You can also specify a list of rules: 446>> {2, "a", 3, 2.5, "b", c} /. {x_Integer -> x ^ 2.0, y_String -> 10} 447 = {4., 10, 9., 2.5, 10, c} 448'ReplaceRepeated' ('//.') applies a set of rules repeatedly, until the expression doesn\'t change anymore: 449>> {2, "a", 3, 2.5, "b", c} //. {x_Integer -> x ^ 2.0, y_String -> 10} 450 = {4., 100., 9., 2.5, 100., c} 451 452There is a "delayed" version of 'Rule' which can be specified by ':>' (similar to the relation of ':=' to '='): 453>> a :> 1 + 2 454 = a :> 1 + 2 455>> a -> 1 + 2 456 = a -> 3 457This is useful when the right side of a rule should not be evaluated immediately (before matching): 458>> {1, 2} /. x_Integer -> N[x] 459 = {1, 2} 460Here, 'N' is applied to 'x' before the actual matching, simply yielding 'x'. With a delayed rule this can be avoided: 461>> {1, 2} /. x_Integer :> N[x] 462 = {1., 2.} 463 464While 'ReplaceAll' and 'ReplaceRepeated' simply take the first possible match into account, 'ReplaceList' returns a list of all possible matches. This can be used to get all subsequences of a list, for instance: 465>> ReplaceList[{a, b, c}, {___, x__, ___} -> {x}] 466 = {{a}, {a, b}, {a, b, c}, {b}, {b, c}, {c}} 467'ReplaceAll' would just return the first expression: 468>> ReplaceAll[{a, b, c}, {___, x__, ___} -> {x}] 469 = {a} 470 471In addition to defining functions as rules for certain patterns, there are <em>pure</em> functions that can be defined using the '&' postfix operator, where everything before it is treated as the function body and '#' can be used as argument placeholder: 472>> h = # ^ 2 &; 473>> h[3] 474 = 9 475Multiple arguments can simply be indexed: 476>> sum = #1 + #2 &; 477>> sum[4, 6] 478 = 10 479It is also possible to name arguments using 'Function': 480>> prod = Function[{x, y}, x * y]; 481>> prod[4, 6] 482 = 24 483Pure functions are very handy when functions are used only locally, e.g., when combined with operators like 'Map': 484>> # ^ 2 & /@ Range[5] 485 = {1, 4, 9, 16, 25} 486Sort according to the second part of a list: 487>> Sort[{{x, 10}, {y, 2}, {z, 5}}, #1[[2]] < #2[[2]] &] 488 = {{y, 2}, {z, 5}, {x, 10}} 489 490Functions can be applied using prefix or postfix notation, in addition to using '[]': 491>> h @ 3 492 = 9 493>> 3 // h 494 = 9 495</section> 496 497<section title="Control Statements"> 498Like most programming languages, \Mathics has common control statements for conditions, loops, etc.: 499<dl> 500<dt>'If[$cond$, $pos$, $neg$]' 501 <dd>returns $pos$ if $cond$ evaluates to 'True', and $neg$ if it evaluates to 'False'. 502<dt>'Which[$cond1$, $expr1$, $cond2$, $expr2$, ...]' 503 <dd>yields $expr1$ if $cond1$ evaluates to 'True', $expr2$ if $cond2$ evaluates to 'True', etc. 504<dt>'Do[$expr$, {$i$, $max$}]' 505 <dd>evaluates $expr$ $max$ times, substituting $i$ in $expr$ with values from 1 to $max$. 506<dt>'For[$start$, $test$, $incr$, $body$]' 507 <dd>evaluates $start$, and then iteratively $body$ and $incr$ as long as $test$ evaluates to 'True'. 508<dt>'While[$test$, $body$]' 509 <dd>evaluates $body$ as long as $test$ evaluates to 'True'. 510<dt>'Nest[$f$, $expr$, $n$]' 511 <dd>returns an expression with $f$ applied $n$ times to $expr$. 512<dt>'NestWhile[$f$, $expr$, $test$]' 513 <dd>applies a function $f$ repeatedly on an expression $expr$, until 514 applying $test$ on the result no longer yields 'True'. 515<dt>'FixedPoint[$f$, $expr$]' 516 <dd>starting with $expr$, repeatedly applies $f$ until the result no longer changes. 517</dl> 518 519>> If[2 < 3, a, b] 520 = a 521>> x = 3; Which[x < 2, a, x > 4, b, x < 5, c] 522 = c 523 524Compound statements can be entered with ';'. The result of a compound expression is its last part or 'Null' if it ends with a ';'. 525>> 1; 2; 3 526 = 3 527>> 1; 2; 3; 528 529Inside 'For', 'While', and 'Do' loops, 'Break[]' exits the loop and 'Continue[]' continues to the next iteration. 530>> For[i = 1, i <= 5, i++, If[i == 4, Break[]]; Print[i]] 531 | 1 532 | 2 533 | 3 534</section> 535 536<section title="Scoping"> 537By default, all symbols are "global" in \Mathics, i.e. they can be read and written in any part of your program. 538However, sometimes "local" variables are needed in order not to disturb the global namespace. \Mathics provides two ways to support this: 539<ul> 540<li><em>lexical scoping</em> by 'Module', and 541<li><em>dynamic scoping</em> by 'Block'. 542</ul> 543<dl> 544<dt>'Module[{$vars$}, $expr$]' 545 <dd>localizes variables by giving them a temporary name of the form 546 'name$number', where number is the current value of '$ModuleNumber'. Each time a module 547 is evaluated, '$ModuleNumber' is incremented. 548<dt>'Block[{$vars$}, $expr$]' 549 <dd>temporarily stores the definitions of certain variables, evaluates 550 $expr$ with reset values and restores the original definitions afterwards. 551</dl> 552 553Both scoping constructs shield inner variables from affecting outer ones: 554>> t = 3; 555>> Module[{t}, t = 2] 556 = 2 557>> Block[{t}, t = 2] 558 = 2 559>> t 560 = 3 561 562'Module' creates new variables: 563>> y = x ^ 3; 564>> Module[{x = 2}, x * y] 565 = 2 x ^ 3 566'Block' does not: 567>> Block[{x = 2}, x * y] 568 = 16 569Thus, 'Block' can be used to temporarily assign a value to a variable: 570>> expr = x ^ 2 + x; 571>> Block[{x = 3}, expr] 572 = 12 573>> x 574 = x 575 576'Block' can also be used to temporarily change the value of system parameters: 577>> Block[{$RecursionLimit = 30}, x = 2 x] 578 : Recursion depth of 30 exceeded. 579 = $Aborted 580 581>> f[x_] := f[x + 1]; Block[{$IterationLimit = 30}, f[1]] 582 : Iteration limit of 30 exceeded. 583 = $Aborted 584 585It is common to use scoping constructs for function definitions with local variables: 586>> fac[n_] := Module[{k, p}, p = 1; For[k = 1, k <= n, ++k, p *= k]; p] 587>> fac[10] 588 = 3628800 589>> 10! 590 = 3628800 591</section> 592 593<section title="Formatting Output"> 594The way results are formatted for output in \Mathics is rather sophisticated, as compatibility to the way \Mathematica does things is one of the design goals. It can be summed up in the following procedure: 595<ol> 596<li>The result of the query is calculated. 597<li>The result is stored in 'Out' (which '%' is a shortcut for). 598<li>Any 'Format' rules for the desired output form are applied to the result. In the console version of \Mathics, the result is formatted as 'OutputForm'; 'MathMLForm' for the 'StandardForm' is used in the interactive Web version; and 'TeXForm' for the 'StandardForm' is used to generate the \LaTeX version of this documentation. 599<li>'MakeBoxes' is applied to the formatted result, again given either 'OutputForm', 'MathMLForm', or 'TeXForm' depending on the execution context of \Mathics. This yields a new expression consisting of "box constructs". 600<li>The boxes are turned into an ordinary string and displayed in the console, sent to the browser, or written to the documentation \LaTeX file. 601</ol> 602As a consequence, there are various ways to implement your own formatting strategy for custom objects. 603 604You can specify how a symbol shall be formatted by assigning values to 'Format': 605>> Format[x] = "y"; 606>> x 607 = y 608This will apply to 'MathMLForm', 'OutputForm', 'StandardForm', 'TeXForm', and 'TraditionalForm'. 609>> x // InputForm 610 = x 611You can specify a specific form in the assignment to 'Format': 612>> Format[x, TeXForm] = "z"; 613>> x // TeXForm 614 = \text{z} 615 616Special formats might not be very relevant for individual symbols, but rather for custom functions (objects): 617>> Format[r[args___]] = "<an r object>"; 618>> r[1, 2, 3] 619 = <an r object> 620You can use several helper functions to format expressions: 621<dl> 622<dt>'Infix[$expr$, $op$]' 623 <dd>formats the arguments of $expr$ with infix operator $op$. 624<dt>'Prefix[$expr$, $op$]' 625 <dd>formats the argument of $expr$ with prefix operator $op$. 626<dt>'Postfix[$expr$, $op$]' 627 <dd>formats the argument of $expr$ with postfix operator $op$. 628<dt>'StringForm[$form$, $arg1$, $arg2$, ...]' 629 <dd>formats arguments using a format string. 630</dl> 631>> Format[r[args___]] = Infix[{args}, "~"]; 632>> r[1, 2, 3] 633 = 1 ~ 2 ~ 3 634>> StringForm["`1` and `2`", n, m] 635 = n and m 636 637There are several methods to display expressions in 2-D: 638<dl> 639<dt>'Row[{...}]' 640 <dd>displays expressions in a row. 641<dt>'Grid[{{...}}]' 642 <dd>displays a matrix in two-dimensional form. 643<dt>'Subscript[$expr$, $i1$, $i2$, ...]' 644 <dd>displays $expr$ with subscript indices $i1$, $i2$, ... 645<dt>'Superscript[$expr$, $exp$]' 646 <dd>displays $expr$ with superscript (exponent) $exp$. 647</dl> 648>> Grid[{{a, b}, {c, d}}] 649 = a b 650 . 651 . c d 652>> Subscript[a, 1, 2] // TeXForm 653 = a_{1,2} 654 655If you want even more low-level control of how expressions are displayed, you can override 'MakeBoxes': 656>> MakeBoxes[b, StandardForm] = "c"; 657>> b 658 = b 659## this will be displayed as c in the browser and LaTeX documentation 660This will even apply to 'TeXForm', because 'TeXForm' implies 'StandardForm': 661>> b // TeXForm 662 = c 663Except some other form is applied first: 664>> b // OutputForm // TeXForm 665 = b 666'MakeBoxes' for another form: 667>> MakeBoxes[b, TeXForm] = "d"; 668>> b // TeXForm 669 = d 670You can cause a much bigger mess by overriding 'MakeBoxes' than by sticking to 'Format', e.g. generate invalid XML: 671>> MakeBoxes[c, MathMLForm] = "<not closed"; 672>> c // MathMLForm 673 = <not closed 674However, this will not affect formatting of expressions involving 'c': 675>> c + 1 // MathMLForm 676 = ... 677That\'s because 'MathMLForm' will, when not overridden for a special case, call 'StandardForm' first. 678'Format' will produce escaped output: 679>> Format[d, MathMLForm] = "<not closed"; 680>> d // MathMLForm 681 = ... 682>> d + 1 // MathMLForm 683 = ... 684 685For instance, you can override 'MakeBoxes' to format lists in a different way: 686>> MakeBoxes[{items___}, StandardForm] := RowBox[{"[", Sequence @@ Riffle[MakeBoxes /@ {items}, " "], "]"}] 687>> {1, 2, 3} 688 = {1, 2, 3} 689#> {1, 2, 3} // TeXForm 690 = \left[1 2 3\right] 691However, this will not be accepted as input to \Mathics anymore: 692>> [1 2 3] 693 : Expression cannot begin with "[1 2 3]" (line 1 of "<test>"). 694>> Clear[MakeBoxes] 695By the way, 'MakeBoxes' is the only built-in symbol that is not protected by default: 696>> Attributes[MakeBoxes] 697 = {HoldAllComplete} 698 699'MakeBoxes' must return a valid box construct: 700>> MakeBoxes[squared[args___], StandardForm] := squared[args] ^ 2 701>> squared[1, 2] 702 = squared[1, 2] 703## different in LaTeX and MathML 704X> squared[1, 2] // TeXForm 705 : Power[squared[1, 2], 2] is not a valid box structure. 706 = 707The desired effect can be achieved in the following way: 708>> MakeBoxes[squared[args___], StandardForm] := SuperscriptBox[RowBox[{MakeBoxes[squared], "[", RowBox[Riffle[MakeBoxes[#]& /@ {args}, ","]], "]"}], 2] 709>> squared[1, 2] 710 = squared[1, 2] 711#> squared[1, 2] // TeXForm 712 = \text{squared}\left[1,2\right]^2 713 714You can view the box structure of a formatted expression using 'ToBoxes': 715>> ToBoxes[m + n] 716 = RowBox[{m, +, n}] 717The list elements in this 'RowBox' are strings, though string delimiters are not shown in the default output form: 718>> InputForm[%] 719 = RowBox[{"m", "+", "n"}] 720</section> 721 722<section title="Graphics Introduction Examples"> 723Two-dimensional graphics can be created using the function 'Graphics' and a list of graphics primitives. For three-dimensional graphics see the following section. The following primitives are available: 724<dl> 725<dt>'Circle[{$x$, $y$}, $r$]' 726 <dd>draws a circle. 727<dt>'Disk[{$x$, $y$}, $r$]' 728 <dd>draws a filled disk. 729<dt>'Rectangle[{$x1$, $y1$}, {$x2$, $y2$}]' 730 <dd>draws a filled rectangle. 731<dt>'Polygon[{{$x1$, $y1$}, {$x2$, $y2$}, ...}]' 732 <dd>draws a filled polygon. 733<dt>'Line[{{$x1$, $y1$}, {$x2$, $y2$}, ...}]' 734 <dd>draws a line. 735<dt>'Text[$text$, {$x$, $y$}]' 736 <dd>draws text in a graphics. 737</dl> 738 739>> Graphics[{Circle[{0, 0}, 1]}] 740 = -Graphics- 741>> Graphics[{Line[{{0, 0}, {0, 1}, {1, 1}, {1, -1}}], Rectangle[{0, 0}, {-1, -1}]}] 742 = -Graphics- 743 744Colors can be added in the list of graphics primitives to change the drawing color. The following ways to specify colors are supported: 745<dl> 746<dt>'RGBColor[$r$, $g$, $b$]' 747 <dd>specifies a color using red, green, and blue. 748<dt>'CMYKColor[$c$, $m$, $y$, $k$]' 749 <dd>specifies a color using cyan, magenta, yellow, and black. 750<dt>'Hue[$h$, $s$, $b$]' 751 <dd>specifies a color using hue, saturation, and brightness. 752<dt>'GrayLevel[$l$]' 753 <dd>specifies a color using a gray level. 754</dl> 755All components range from 0 to 1. Each color function can be supplied with an additional argument specifying the desired opacity ("alpha") of the color. There are many predefined colors, such as 'Black', 'White', 'Red', 'Green', 'Blue', etc. 756 757>> Graphics[{Red, Disk[]}] 758 = -Graphics- 759Table of hues: 760>> Graphics[Table[{Hue[h, s], Disk[{12h, 8s}]}, {h, 0, 1, 1/6}, {s, 0, 1, 1/4}]] 761 = -Graphics- 762 763Colors can be mixed and altered using the following functions: 764<dl> 765<dt>'Blend[{$color1$, $color2$}, $ratio$]' 766 <dd>mixes $color1$ and $color2$ with $ratio$, where a ratio of 0 returns $color1$ and a ratio of 1 returns $color2$. 767<dt>'Lighter[$color$]' 768 <dd>makes $color$ lighter (mixes it with 'White'). 769<dt>'Darker[$color$]' 770 <dd>makes $color$ darker (mixes it with 'Black'). 771</dl> 772 773>> Graphics[{Lighter[Red], Disk[]}] 774 = -Graphics- 775 776'Graphics' produces a 'GraphicsBox': 777>> Head[ToBoxes[Graphics[{Circle[]}]]] 778 = GraphicsBox 779</section> 780 781<section title="3D Graphics"> 782Three-dimensional graphics are created using the function 'Graphics3D' and a list of 3D primitives. The following primitives are supported so far: 783<dl> 784<dt>'Polygon[{{$x1$, $y1$, $z1$}, {$x2$, $y2$, $z3$}, ...}]' 785 <dd>draws a filled polygon. 786<dt>'Line[{{$x1$, $y1$, $z1$}, {$x2$, $y2$, $z3$}, ...}]' 787 <dd>draws a line. 788<dt>'Point[{$x1$, $y1$, $z1$}]' 789 <dd>draws a point. 790</dl> 791 792>> Graphics3D[Polygon[{{0,0,0}, {0,1,1}, {1,0,0}}]] 793 = -Graphics3D- 794 795Colors can also be added to three-dimensional primitives. 796>> Graphics3D[{Orange, Polygon[{{0,0,0}, {1,1,1}, {1,0,0}}]}, Axes->True] 797 = -Graphics3D- 798 799'Graphics3D' produces a 'Graphics3DBox': 800>> Head[ToBoxes[Graphics3D[{Polygon[]}]]] 801 = Graphics3DBox 802</section> 803 804<section title="Plotting Introduction Examples"> 805\Mathics can plot functions: 806>> Plot[Sin[x], {x, 0, 2 Pi}] 807 = -Graphics- 808You can also plot multiple functions at once: 809>> Plot[{Sin[x], Cos[x], x ^ 2}, {x, -1, 1}] 810 = -Graphics- 811 812Two-dimensional functions can be plotted using 'DensityPlot': 813>> DensityPlot[x ^ 2 + 1 / y, {x, -1, 1}, {y, 1, 4}] 814 = -Graphics- 815You can use a custom coloring function: 816>> DensityPlot[x ^ 2 + 1 / y, {x, -1, 1}, {y, 1, 4}, ColorFunction -> (Blend[{Red, Green, Blue}, #]&)] 817 = -Graphics- 818One problem with 'DensityPlot' is that it\'s still very slow, basically due to function evaluation being pretty slow in general---and 'DensityPlot' has to evaluate a lot of functions. 819 820Three-dimensional plots are supported as well: 821>> Plot3D[Exp[x] Cos[y], {x, -2, 1}, {y, -Pi, 2 Pi}] 822 = -Graphics3D- 823</section> 824 825 826</chapter> 827 828 829 830<chapter title="Examples"> 831 832<section title="Curve sketching"> 833Let\'s sketch the function 834>> f[x_] := 4 x / (x ^ 2 + 3 x + 5) 835The derivatives are 836>> {f'[x], f''[x], f'''[x]} // Together 837 = {-4 (-5 + x ^ 2) / (5 + 3 x + x ^ 2) ^ 2, 8 (-15 - 15 x + x ^ 3) / (5 + 3 x + x ^ 2) ^ 3, -24 (-20 - 60 x - 30 x ^ 2 + x ^ 4) / (5 + 3 x + x ^ 2) ^ 4} 838To get the extreme values of 'f', compute the zeroes of the first derivatives: 839>> extremes = Solve[f'[x] == 0, x] 840 = {{x -> -Sqrt[5]}, {x -> Sqrt[5]}} 841And test the second derivative: 842>> f''[x] /. extremes // N 843 = {1.65086, -0.064079} 844Thus, there is a local maximum at 'x = Sqrt[5]' and a local minimum at 'x = -Sqrt[5]'. 845Compute the inflection points numerically, chopping imaginary parts close to 0: 846>> inflections = Solve[f''[x] == 0, x] // N // Chop 847 = {{x -> -1.0852}, {x -> -3.21463}, {x -> 4.29983}} 848Insert into the third derivative: 849>> f'''[x] /. inflections 850 = {-3.67683, 0.694905, 0.00671894} 851Being different from 0, all three points are actual inflection points. 852'f' is not defined where its denominator is 0: 853>> Solve[Denominator[f[x]] == 0, x] 854 = {{x -> -3 / 2 - I / 2 Sqrt[11]}, {x -> -3 / 2 + I / 2 Sqrt[11]}} 855These are non-real numbers, consequently 'f' is defined on all real numbers. 856The behaviour of 'f' at the boundaries of its definition: 857>> Limit[f[x], x -> Infinity] 858 = 0 859>> Limit[f[x], x -> -Infinity] 860 = 0 861Finally, let\'s plot 'f': 862>> Plot[f[x], {x, -8, 6}] 863 = -Graphics- 864</section> 865 866 867<section title="Linear algebra"> 868Let\'s consider the matrix 869>> A = {{1, 1, 0}, {1, 0, 1}, {0, 1, 1}}; 870>> MatrixForm[A] 871 = 1 1 0 872 . 873 . 1 0 1 874 . 875 . 0 1 1 876 877We can compute its eigenvalues and eigenvectors: 878>> Eigenvalues[A] 879 = {2, -1, 1} 880>> Eigenvectors[A] 881 = {{1, 1, 1}, {1, -2, 1}, {-1, 0, 1}} 882This yields the diagonalization of 'A': 883>> T = Transpose[Eigenvectors[A]]; MatrixForm[T] 884 = 1 1 -1 885 . 886 . 1 -2 0 887 . 888 . 1 1 1 889>> Inverse[T] . A . T // MatrixForm 890 = 2 0 0 891 . 892 . 0 -1 0 893 . 894 . 0 0 1 895>> % == DiagonalMatrix[Eigenvalues[A]] 896 = True 897 898We can solve linear systems: 899>> LinearSolve[A, {1, 2, 3}] 900 = {0, 1, 2} 901>> A . % 902 = {1, 2, 3} 903In this case, the solution is unique: 904>> NullSpace[A] 905 = {} 906 907Let\'s consider a singular matrix: 908>> B = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; 909>> MatrixRank[B] 910 = 2 911>> s = LinearSolve[B, {1, 2, 3}] 912 = {-1 / 3, 2 / 3, 0} 913>> NullSpace[B] 914 = {{1, -2, 1}} 915>> B . (RandomInteger[100] * %[[1]] + s) 916 = {1, 2, 3} 917</section> 918 919 920<section title="Dice"> 921Let\'s play with dice in this example. A 'Dice' object shall represent the outcome of a series of rolling a dice with six faces, e.g.: 922>> Dice[1, 6, 4, 4] 923 = Dice[1, 6, 4, 4] 924Like in most games, the ordering of the individual throws does not matter. We can express this by making 'Dice' 'Orderless': 925>> SetAttributes[Dice, Orderless] 926>> Dice[1, 6, 4, 4] 927 = Dice[1, 4, 4, 6] 928A dice object shall be displayed as a rectangle with the given number of points in it, positioned like on a traditional dice: 929>> Format[Dice[n_Integer?(1 <= # <= 6 &)]] := Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{1 - p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{1 - p, p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{1 - p, 0.5}, r]}]}, ImageSize -> Tiny]] 930>> Dice[1] 931 = -Graphics- 932 933#> Definition[Dice] 934 = Attributes[Dice] = {Orderless} 935 . 936 . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], MathMLForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] 937 . 938 . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], OutputForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] 939 . 940 . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], StandardForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] 941 . 942 . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], TeXForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] 943 . 944 . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], TraditionalForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] 945 946The empty series of dice shall be displayed as an empty dice: 947>> Format[Dice[]] := Graphics[{EdgeForm[Black], White, Rectangle[]}, ImageSize -> Tiny] 948>> Dice[] 949 = -Graphics- 950Any non-empty series of dice shall be displayed as a row of individual dice: 951>> Format[Dice[d___Integer?(1 <= # <= 6 &)]] := Row[Dice /@ {d}] 952>> Dice[1, 6, 4, 4] 953 = -Graphics--Graphics--Graphics--Graphics- 954Note that \Mathics will automatically sort the given format rules according to their "generality", so the rule for the empty dice does not get overridden by the rule for a series of dice. 955We can still see the original form by using 'InputForm': 956>> Dice[1, 6, 4, 4] // InputForm 957 = Dice[1, 4, 4, 6] 958We want to combine 'Dice' objects using the '+' operator: 959>> Dice[a___] + Dice[b___] ^:= Dice[Sequence @@ {a, b}] 960The '^:=' ('UpSetDelayed') tells \Mathics to associate this rule with 'Dice' instead of 'Plus', which is protected---we would have to unprotect it first: 961>> Dice[a___] + Dice[b___] := Dice[Sequence @@ {a, b}] 962 : Tag Plus in Dice[a___] + Dice[b___] is Protected. 963 = $Failed 964We can now combine dice: 965>> Dice[1, 5] + Dice[3, 2] + Dice[4] 966 = -Graphics--Graphics--Graphics--Graphics--Graphics- 967#> Dice[1, 5] + Dice[3, 2] + Dice[4] // InputForm 968 = Dice[1, 2, 3, 4, 5] 969Let\'s write a function that returns the sum of the rolled dice: 970>> DiceSum[Dice[d___]] := Plus @@ {d} 971>> DiceSum @ Dice[1, 2, 5] 972 = 8 973And now let\'s put some dice into a table: 974>> Table[{Dice[Sequence @@ d], DiceSum @ Dice[Sequence @@ d]}, {d, {{1, 2}, {2, 2}, {2, 6}}}] // TableForm 975 = -Graphics--Graphics- 3 976 . 977 . -Graphics--Graphics- 4 978 . 979 . -Graphics--Graphics- 8 980It is not very sophisticated from a mathematical point of view, but it\'s beautiful. 981</section> 982 983</chapter> 984 985 986 987<chapter title="Django-based Web Interface"> 988 989In the future, we plan on providing an interface to Jupyter as a separate package. 990 991However currently as part \Mathics, we distribute a browser-based interface using long-term-release (LTS) Django 3.2. 992 993Since a Jupyter-based interface seems preferable to the home-grown interface described here, it is doubtful whether there will be future improvements to the this interface. 994 995When you enter Mathics in the top after the Mathics logo and the word "Mathics" you'll see a <i>menubar</i>. 996 997It looks like this: 998 999<imgpng src="menubar.png" title="Mathics Menu Bar" label="menubar"> 1000 1001 1002<section title="URIs"> 1003 1004For the most part, the application is a single-page application. 1005Assuming your are running locally or on a host called 'localhost' using the default port, 8000, here are some URLs and what they do: 1006 1007<dl> 1008 <dt><url>http://localhost:8000</url> 1009 <dd>The single-page application; the main page. 1010 <dt><url>http://localhost:8000/about</url> 1011 <dd>A page giving: 1012 <ul> 1013 <li>the software versions of this package and version information of important software this uses. 1014 <li>directory path information for the current setup 1015 <li>machine information 1016 <li>system information 1017 </ul> 1018 <dt><url>http://localhost:8000/doc</url> 1019 <dd>An on-line formatted version of the documentation, which include this text. You can see this as a right side frame of the main page, when clicking "?" on the right-hand upper corner. 1020</dl> 1021</section> 1022<section title="Saving, Loading, and Deleting Worksheets"> 1023 1024<subsection title="Saving Worksheets"> 1025 1026Worksheets exist in the browser window only and are not stored on the server, by default. To save all your queries and results, use the <em>Save</em> button which is the middle graphic of the menu bar. It looks like this: 1027 1028<imgpng src="save-button.png" title="Mathics Save Button" label="save-button"> 1029 1030Depending on browser, desktop, and OS-settings, the "Ctrl+S" key combination may do the same thing. 1031 1032<subsection title="Loading and Deleting Worksheets"> 1033 1034Saved worksheets can be loaded or deleted using the <em>File Open</em> button which is the left-most button in the menu bar. It looks like this: 1035 1036<imgpng src="file-open-button.png" title="Mathics File Open Button" label="file-open-button"> 1037 1038Depending on browser, desktop, and OS-settings, the "Ctrl+O" key combination may do the same thing. 1039 1040A popup menu should appear with the list of saved worksheets with an option to either load or delete the worksheet. 1041 1042</section> 1043 1044<section title="Persistence of Mathics Definitions in a Session"> 1045 1046When you use the Django-based Web interface of \Mathics, a browser session is created. Cookies have to be enabled to allow this. Your session holds a key which is used to access your definitions that are stored in a database on the server. As long as you don\'t clear the cookies in your browser, your definitions will remain even when you close and re-open the browser. 1047 1048This implies that you should not store sensitive, private information in \Mathics variables when using the online Web interface. In addition to their values being stored in a database on the server, your queries might be saved for debugging purposes. However, the fact that they are transmitted over plain HTTP should make you aware that you should not transmit any sensitive information. When you want to do calculations with that kind of stuff, simply install \Mathics locally! 1049 1050If you are using a public terminal, to erase all your definitions and close the browser window. When you use \Mathics in a browser, use the command <con>Quit[]</con> or its alias, <con>Exit[]</con>. 1051 1052Normally, when you reload the current page in a browser using the default url, e.g <con>http:localhost:8000</con>, all of the previous input and output disappears, even though definitions as described above do not, unless <con>Quit[]</con> or <con>Exit[]</con> is entered as described above. 1053 1054However if you want a URL that will that records the input entered the <em>Generate Input Hash</em> button does this. The button looks like this: 1055 1056<imgpng src="generate-hash-button.png" title="Mathics Generate Input Hash Button" label="generate-input-hash-button"> 1057 1058For example, assuming you have a \Mathics server running at port 8000 on <con>localhost</con>, and you enter the url <con>http://localhost:8000/#cXVlcmllcz14</con>, you should see a single line of input containing <con>x</con> entered. 1059 1060Of course, what the value of this is when evaluated depends on whether <con>x</con> has been previously defined. 1061 1062</section> 1063 1064<section title="Keyboard Commands"> 1065 1066There are some keyboard commands you can use in the Django-based Web interface of \Mathics. 1067 1068<dl> 1069<dt>'Shift+Return'</dt> 1070 <dd>This evaluates the current cell (the most important one, for sure). On the right-hand side you may also see an "=" button which can be clicked to do the same thing.</dd> 1071<dt>'Ctrl+D'</dt> 1072 <dd>This moves the cursor over to the documentation pane on the right-hand side. From here you can preform a search for a pre-defined \Mathics function, or symbol. Clicking on the "?" symbol on the right-hand side does the same thing.</dd> 1073<dt>'Ctrl+C'</dt> 1074 <dd>This moves the cursor back to document code pane area where you type \Mathics expressions</dd> 1075<dt>'Ctrl+S'</dt> 1076 <dd>Save worksheet</dd> 1077<dt>'Ctrl+O'</dt> 1078 <dd>Open worksheet</dd> 1079<dt>'Right Click' on MathML output</dt> 1080 <dd>Opens MathJax Menu</dd> 1081</dl> 1082 1083Of special note is the last item on the list: right-click to open the MathJax menu. Under "Math Setting"/"Zoom Trigger", if the zoom trigger is set to a value other then "No Zoom", then when that trigger is applied on MathML formatted output, the MathML formula pop up a window for the formula. The window can show the formula larger. Also, this is a way to see output that is too large to fit on the display since the window allows for scrolling. 1084 1085Keyboard commands behavior depends the browser used, the operating system, desktop settings, and customization. We hook into the desktop "Open the current document" and "Save the current document" functions that many desktops provide. For example see: <url>https://help.ubuntu.com/community/KeyboardShortcuts#Finding_keyboard_shortcuts</url> 1086 1087Often, these shortcut keyboard command are only recognized when a text field has focus; otherwise,the browser might do some browser-specific actions, like setting a bookmark etc. 1088 1089</section> 1090 1091</chapter> 1092