You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(486) |
Jul
(201) |
Aug
(194) |
Sep
(87) |
Oct
(72) |
Nov
(72) |
Dec
(4) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(6) |
Feb
(41) |
Mar
(22) |
Apr
(4) |
May
(12) |
Jun
|
Jul
|
Aug
(42) |
Sep
(21) |
Oct
(14) |
Nov
(10) |
Dec
|
2007 |
Jan
(14) |
Feb
(34) |
Mar
(61) |
Apr
(54) |
May
(140) |
Jun
(184) |
Jul
(164) |
Aug
(130) |
Sep
(241) |
Oct
(175) |
Nov
(148) |
Dec
(96) |
2008 |
Jan
(5) |
Feb
(38) |
Mar
(30) |
Apr
(46) |
May
(25) |
Jun
(22) |
Jul
(5) |
Aug
(17) |
Sep
(2) |
Oct
(100) |
Nov
(83) |
Dec
(33) |
2009 |
Jan
(127) |
Feb
(43) |
Mar
(86) |
Apr
(34) |
May
(50) |
Jun
(168) |
Jul
(48) |
Aug
(66) |
Sep
(38) |
Oct
(75) |
Nov
(113) |
Dec
(72) |
2010 |
Jan
(123) |
Feb
(68) |
Mar
(26) |
Apr
(11) |
May
(39) |
Jun
(131) |
Jul
(56) |
Aug
(79) |
Sep
(69) |
Oct
(17) |
Nov
(166) |
Dec
(32) |
2011 |
Jan
(21) |
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
(1) |
Nov
(8) |
Dec
|
2012 |
Jan
(2) |
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Chris S. <san...@us...> - 2005-07-14 08:47:04
|
Update of /cvsroot/stack/stack-1-0/lang/en In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15328/lang/en Modified Files: stack.php Log Message: Moved the documentation Index: stack.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/lang/en/stack.php,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** stack.php 8 Jul 2005 16:36:10 -0000 1.7 --- stack.php 14 Jul 2005 08:46:53 -0000 1.8 *************** *** 225,228 **** --- 225,229 ---- $string['menu_AnswerT'] = 'Answer tests'; $string['menu_FAQ'] = 'FAQ'; + $string['menu_FAF'] = 'Fact sheet'; $string['menu_Maxima'] = 'Maxima'; $string['menu_CAS_Fn'] = 'CAS functions'; |
Update of /cvsroot/stack/stack-1-0/lang/en/doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15328/lang/en/doc Modified Files: student_factsformula.php Added Files: about_develop.php about_general.php about_install.php author_answertest.php author_commonsyntax.php author_factsformula.php author_faq.php author_gettingstarted.php author_maxima.php author_options.php author_potresp.php author_questionfields.php en_doc.php help_popup.php stackcvs.png student_assessmentmode.php student_forbidden.php student_input.php student_overview.php student_practicemode.php student_understandingoutput.php Log Message: Moved the documentation --- NEW FILE: about_install.php --- <?php /** * Details of how to install STACK. * * @package documentation * @subpackage STACK * */ ?> <h1>Installing STACK</h1> STACK is a collection of PHP scripts, which link together the user, a CAS, and a database over the internet. Hence the system itself requires of a number of extra components. <h3>Platform</h3> The scripts currently released will run on a Linux (or unix) machine or a Microsoft (Windows) platform. <ul> <li><b>Linux:</b> STACK has been tested on a <a href="http://fedora.redhat.com/">Fedora</a> based Linux system running the Apache web server.</li> <li><b>Microsoft:</b> STACK has been tested on Windows XP and Windows 2000 using IIS and <a href="http://www.easyphp.org/">EasyPHP</a>. EasyPHP is by far the easiest platform on which to install STACK. However, this does not seem to be as efficient as Linux and may not be suitable for a production server.</li> </ul> <h3>Components</h3> Regardless of which operating system used, you will need the following components. <ul> <li>A web server, such as <a href="http://www.apache.org/">Apache</a>, running <a href="http://www.php.net/">PHP</a> (at least version 4.3.9), <!--(version 5 if using the CAS Pool)--></li> and <a href="http://www.mysql.com/">MySQL</a> server (at least version 4.1).<br /> Windows users could use <a href="http://www.easyphp.org/">EasyPHP</a>.</li> <li>You need to convex LaTeX to HTML with <a href="http://hutchinson.belmont.ma.us/tth/">TtH</a>. <li>The computer algebra system (<a href="#cas">see below</a>) <a href="http://maxima.sourceforge.net/">Maxima</a>. Version 5.9.1 (or later) is needed to include graphical support. (Note, for those on a Microsoft platform, the <a href="http://wxmaxima.sourceforge.net/">wxMaxima</a> front end is much better than that distributed with Maxima itself and is well worth installing for testing CAS code outside STACK)</li> <li>For graphical support we have used the <a href="http://www.gnuplot.info/">GNUPLOT</a> package, version 4.0. (Note, this is already supplied on Fedora 3 distributions, and comes with Maxima 5.9.1 on Windows) </ul> Finally of course <ul> <li>The STACK scripts themselves.</li> </ul> <p>The <em>latest</em> stack scripts can be obtained from the CVS on <tt>sourceforge</tt>. For example, anonymous access is via</p> <p><tt>cvs -z3 -d:pserver:ano...@cv...:/cvsroot/stack co -P <?php echo $stack_ver['cvsmodule'] ?> </tt></p> <p> Developer access can be obtained via SSH by</p> <p><tt>export CVS_RSH=ssh<br /> cvs -z3 -d:ext:</tt><em>developername</em><tt>@cvs.sourceforge.net:/cvsroot/stack co -P <?php echo $stack_ver['cvsmodule'] ?> </tt></p> <p>Users of a Microsoft platform should consider using the <a href="http://www.tortoisecvs.org/">tortoise CVS</a> application to obtain the scripts. Details of fields to fill in are available on this <a href="doc/stackcvs.png">screen shot</a>. Note: the module name (underlined in red) should read <font color="red"><?php echo $stack_ver['cvsmodule'] ?></font> <h2>Security</h2> <p><font color="red">WARNING! What these scripts attempt to do is inherently insecure.</font> This system is designed to execute arbitrary third party CAS code on your server, to create mathematical questions. This is inherently insecure, and you should be aware of the dangers. These are <em>in addition</em> to the normal security problems associated with interactive, database driven web sites.</p> <p>The array <pre>$stack_cas['globalForbid']</pre> is generated automatically and contains strings the system attempts not to execute. You should look at the file <tt>scripts/maxima/maximafun.php</tt> and the array distributed, together with the CAS documentation, to decide which CAS commands you wish to prevent from being executed on your server. This list is not comprehensive, and you should make your own decisions here. <font color="red"><em>You have been warned!</em></font> <h2><a href="http://www.php.net/">PHP</a></h2> STACK needs no special PHP settings, although the function <tt>proc_open</tt> must be available to establish a connection with the external applications. <p>For mail, use the <a href="http://pear.php.net/">pear class</a>. For example in Linux, to install this from the command line, type <tt>pear install mail</tt>, for example.<br /> You will need to install, <tt>mail, NET_Socket, NET_SMTP, Auth_SASL</tt>.</p> <!-- <p>There are two ways to use the scripts, as follows.</p> <h3>1. A direct connection with the CAS.</h3> <p>This is the method used when <tt>$stack_os</tt> is set to be either of <tt>'win'</tt> or <tt>'unix'</tt>. Each request to the CAS starts up and shuts down a CAS process. Note, each item may use the CAS on many occasions when traversing the potential response tree to mark a student's answer. <h3>2. Starting a pool of CAS processes.</h3> <p>This method uses command line PHP to open and manage a pool of CAS processes. The scripts then connect to the pool using sockets on the local machine. To use this method, <tt>$stack_os</tt> is set to be <tt>'unix-pool'</tt>. </p> <p>This removes the overhead of starting a new CAS process each time, and hence loading and compiling all the libraries. However, this requires PHP 5 to get access to the process control functions to fork etc, and needs command line access to start and stop the scripts. </p> --> <p> You might also consider the other components of your PHP system. In particular, if you are integrating STACK with a VLE (eg <a href="http://moodle.org/">Moodle</a>, or <a href="http://www.logicampus.com/">Logicampus</a>), then you may need to have installed zlib and libpng (in that order) from downloads.</p> <p>For reference, the Linux test system adopted the following options. <br /><tt>./configure --with-mysql --with-apache --with-gd --with-zlib</tt> </p> <!--<br />For use with a pool of CAS process, the PHP 5 process control functions are required. <br /><tt>./configure --with-mysql --with-apache --with-gd --with-zlib --enable-sockets --enable-pcntl</tt> --> <h2><a href="http://www.mysql.com/">MySQL</a></h2> Please refer to the specific documentation for installing MySQL. There are no special requirements for STACK. If you wish to install STACK with an alternative database, this should be possible. All the interactions with the database are contained in the script <pre>$stack_root/scripts/stackDatabase.php</pre> <h2>Display via the LaTeX system</h2> <p>The basic route to convert the output from the CAS, into a form which is suitable for display has so far been to force the CAS to output LaTeX, and convert this on the fly to HTML. This conversion could be done in a number of ways. Support currently exists for <a href="http://hutchinson.belmont.ma.us/tth/">TtH</a> This is just one solution to the problem of displaying mathematics on the internet. TtH is a closed-source system, but the binary distribution is available for download. There are no special requirements.</p> <p>The package <a href="http://pauillac.inria.fr/~maranget/hevea/">HeVeA</a> could also be used in place of TtH. If you wish to do this, please contact the developers.</p> <p>It would also be possible to have the CAS output MathML, and convert any LaTeX in questions to MathML and HTML using a converter such as TtM. While we have designed STACK with this in mind, we have as yet not implemented this functionality.</p> <h2><a name='cas'>The computer algebra system Maxima</a></h2> <p>STACK has been designed to work with the <a href="http://maxima.sourceforge.net/">Maxima</a> computer algebra system although it should be possible to provide support for others such as <a href="http://www.nongnu.org/axiom/">AXIOM</a>. <p>Maxima is the preferred open source CAS. Version 5.9.1, or later, is needed, to work with the <a href="http://www.gnuplot.info/">GNUPLOT</a> package, for graphical support. <p><b>Linux only:</b> Please read the Maxima documentation carefully, since this package is itself supported in a number of different Lisp implementations. <p><b>Windows only:</b> Setting the PATH in Windows can be a problem, see below for advice with this. <p>Note, for those on a Microsoft platform, the <a href="http://wxmaxima.sourceforge.net/">wxMaxima</a> front end is much better than that distributed with Maxima itself and is well worth installing for testing CAS code outside STACK. <!-- <h3>Other CAS systems</h3> <p>To use STACK with different CAS systems is certainly possible. The functions which interact with the CAS are contained in the file <pre>$stack_root/scripts/CASPool/stackCAS.php</pre> If you wish do this, please let the developers know and we may be able to offer more specific support. --> <h2>Installing the PHP scripts and setting up STACK itself</h2> <ol> <li>Place all scripts in a directory visible to the web server. This directory will be referred to as <tt>$stack_root</tt>.</li> <li>Copy the file <tt>$stack_root/stackstd.php.dist</tt> to <tt>$stack_root/stackstd.php</tt><br />This file will contain all your local settings.</li> <li>Edit <tt>$stack_root/stackstd.php</tt> to reflect your local settings. This is the only file you should have to edit, so read carefully the instructions it contains.</li> <li>Create a directory for locally and dynamically generated files. For example, <tt>/home/stack/stacklocal</tt>. Ensure the webserver can write to this, and update the variable, eg <pre>$stack_logfiles = "/home/stack/stacklocal"; </pre> in <tt>stackstd.php</tt>.</li> <li>Create a directory for dynamically generated plots. This needs to be available to users of the internet, so the webserver should be able to serve files from this directory. The default value is assumed to be <pre>$maximalocal['IMAGE_DIR'] = $stack_root.'/tmp/';</pre> ie, you need to create the directory <tt>$stack_root/tmp</tt>. Ensure the webserver can write to this directory. <li><b>Windows: </b>Setting the Windows PATH variable can be a problem. For STACK to work you need to be able to call the following external applications: <ol><li>TtH</li> <li>Maxima</li> <li>gnuplot</li> </ol> Create a directory for these applications, such as <tt>c:\Programe Files\bin</tt>, add this to your PATH, and copy the executables into this. TtH and gnuplot are single executable applications - gnuplot is distributed with Maxima and is the binary file <tt>C:\Program Files\Maxima-5.9.1\bin\wgnuplot.exe</tt> <p> For Maxima, a batch file has been provided: <tt>$stack_root/scripts/install/stackmaxima.bat</tt>. Copy this file into a directory on your Windows PATH, and edit it to point to your current version of Maxima. </li> <li>In <tt>stackstd.php</tt>, edit the entries for the variables which hold information about the MySQL user and database which is to be created and used for STACK. <pre> $stack_mysql['host'] = 'localhost'; $stack_mysql['user'] = 'stack'; $stack_mysql['pswd'] = ''; $stack_mysql['stackdb'] = 'stack'; </pre> In particular you will need to add a password for the mysql user. </li> <li> The MySQL database is setup using the script <tt><a href='scripts/install/stackInstall.php'>$stack_root/scripts/install/stackInstall.php</a></tt>. <p><font color="red">WARNING!</font> This is disabled by default, for obvious reasons, and will do nothing. Edit the file, and comment out line 9, (ie add // to the beginning of the line). When the install is complete, reinstate the line to prevent future third party execution of this script.</p> </ol> <!-- <h3>MySQL setup</h3> Remember that a clean MySQL install requires you to set the root password. For example, <pre> mysql -u root mysql> set password for 'root'@'localhost' = password('newpassword'); mysql> set password for 'root'@'host' = password('newpassword'); mysql> exit </pre> Then reboot. <h3>Starting the Pool of CAS processes</h3> <p>Only if you have chosen <tt>$stack_os='unix-pool';</tt>, you will need to start the pool of CAS processes from the command line. In order to link the pool of CAS processes with the internet it is necessary to run a command line PHP script.</p> <ol> <li> Copy the files <tt>$stack_root/scripts/CASPool/startsocket.php</tt> and <tt>$stack_root/scripts/CASPool/startsocket.php</tt> to somewhere the webserver cannot see.</li> <li>Edit these files to remove the die(); commands.</li> <li>Add a path to <tt>$stack_root</tt></li> <li>To start the pool, execute <pre>php startsocket.php</pre></li> <li>To stop the sockets, run <pre>php stopsocket.php</pre></li> </ol> Everytime <tt>startsocket</tt> is executed, the file <tt>$stack_root/scripts/maxima/initmaxima.php</tt> is also executed once before the sockets are started. This does the following. <ol> <li>Writes the file <tt>CASkeywords.php</tt> which contains the three arrays, explained in the security section below.</li> <li>Generates the file <tt>maximalocal.mac</tt>, which contains settings from <tt>stackstd.php</tt> in a form suitable for the CAS. For example, what is the gnuplot command? Where should plot files be written to? etc.</li> </ol> <p>To run these scripts in the background, the unix utility <a href="http://www.kuro5hin.org/story/2004/3/9/16838/14935"><tt>screen</tt></a> is useful.</p> --> <h2>Ready to test!</h2> <p>If all the steps above were a success you should be ready to <?php echo "<a href='$stack_web_url'>test the system.</a>"; ?></p> <p>Note, some sample questions are distributed in the file <tt>scripts/install/sample_questions.xml</tt> which you can upload into stack to get you started. You need to <ol> <li>login as the "admin" user, </li> <li>go to the question bank, </li> <li>choose "Upload XML",</li> <li>browse the file system to find the XML file.</li> </ol> <p>No quizzes are created by default at the moment.</p> <h2>Security and Maxima</h2> <p>For the Maxima CAS, the commands are divided into four groups. In the first three cases, the system checks to see if the entries in this list are a substring of anything going to the CAS, and takes the appropriate action.</p> <p>For students' input, or guest input in a CAS chat session (or the like) we operate in a mode which allows only specified strings. For teachers' input, we would like to enable arbitrarily named functions and variables to be present, subject to the naming restrictions of the CAS of course. Hence we basically divide all Maxima commands into the following four groups. <ol> <li><tt>$stack_cas['globalForbid']</tt><br/> Never sent to the CAS. Could also trigger a potential attack warning, although this is not currently implemented.</li> <li><tt>$stack_cas['teacherNotAllow']</tt><br/> These commands have side effects in the Maxima environment, and hence are not allowed. There may be no good reason why a command is here, but there we are. </li> <li><tt>$stack_cas['studentAllow'] </tt><br/> Student's input is divided into strings, and only if all occur in this array is their response processed.</li> <li><tt>The rest</tt></li> </ol> These classifications are given in the file, <tt>maximafun.php</tt>, which you can and should edit. <em>Once you have edited this file, you need to execute the file <tt>initmaxima.php</tt> to re-create <tt>CASkeywords.php</tt>.</em> (This in turn has been generated directly from the Maxima docs using another script, which you need not use). </p> --- NEW FILE: student_forbidden.php --- <a name="forbid"><h2>Forbidden words</h2></a> Suppose that Stack asked you to calculate sin(<font face="SYMBOL">p</font>/4) (for which the answer is of course 2<sup>-1/2</sup>). One cunning plan that might occur to you would be to just enter <tt><font color="GREEN">sin(pi/4)</font></tt> as your answer, leaving the CAS to do all the real work. If this worked, it would remove the whole point, so Stack prevents it. For each question, there are certain "forbidden words" that you are not allowed to use as part of your answer; in the example above, the word "sin" would be forbidden. If you give an answer involving a forbidden word, Stack will tell you, and you will be able to go back and change it without any penalty. --- NEW FILE: author_options.php --- <?php /** * Describes the data structure stackOption * * @package documentation * @subpackage Stack */ include('en_doc.php'); ?> <h1>Options documentation</h1> <p>A stackOption is the basic way to affect the system. They are an efficient way to transfer information between various parts of the code. There is a cascading system of options. Starting with the system default values, and options actually set at a lower level wil override the current values. </p> <p>In this way we obtain the maximum flexibility, with the maximum consistencey enforced very easily with the minimum of fuss. Note, that changing an option at, for example the quiz level, will alter the behaviour of all questions at a lower level. Hence care needs to be exercised when doing this.</p> <p>Below are details of all the options. Of course it may make no sense to alter options at some levels in the system. The option structure simply defines a coherent mechanism for moving the information around.</p> <?php foreach( $stackOptions as $field => $q_field) { $fd = 'stackOptions_'.$field; $fd = get_string($fd,'stack',''); echo "<h3>$fd</h3>"; echo $q_field['doc']; echo "<p>"; echo "Name of field: <font color=orange><tt>$field</tt></font>. Type of field: <font color=orange><tt>{$q_field['type']}</tt></font>. "; if (is_array($q_field['values'])) { echo "Permissable values: <font color=orange><tt>"; show_array($q_field['values']); echo "</tt></font>"; } $default = $q_field['default']; if ('' == $default) { $default = '[none]'; } if ('html' == $q_field['type']) { echo 'System default value: <br /><font color=orange><tt>'.htmlspecialchars($default).'</tt></font><br />('.$default.').'; } else { echo "System default value: <font color=orange><tt>$default</tt></font>."; } } ?> --- NEW FILE: about_general.php --- <?php /** * A short blurb about what STACK is. * * @package documentation * @subpackage Stack */ ?> <p>The STACK system is a computer aided assessment package for mathematics.</p> <p>In computer aided assessment (CAA), there are two classes of <em>question types</em>. <ul> <li><em>Teacher-provided answer questions</em><br /> In these questions, a student makes a selection from, or interacts with, potential answers which the teacher has selected. Examples include multiple choice, multiple response and so on. </li> <li><em>Student-provided answer questions</em><br /> In these questions the student's answer contains the content. It is not a selection. Examples of these are numeric questions. </li> </ul> STACK concentrates on student-provided answers which are mathematical expressions. For example, a student might respond to a question with a polynomial or matrix. Essantially STACK asks for mathematical expressions and evaluates these using computer algebra. The prototype test is the following pseudo-code. <pre>If simplify(student_answer-teacher_answer) = 0 then mark = 1, else mark = 0. </pre> A CAS provides a library of functions with which to manipulate students' answers and generate outcomes such as providing feedback. Establishing algebraic equivalence with a correct answer is only one kind of manipluation which is possible. Using CAS can also help generate random yet structured problems, and corresponding worked solutions. <p>In STACK a lot of attention has been paid to allowing teachers to author and manage their own questions. You can try this for yourself by looking at the question bank demo, authoring guide and other options available here.</p> <!-- Please do not remove this public credit. CJS, June 2005 --> <p>This system is the brain child of <a href='email:ch...@sa...'>Chris Sangwin</a>.</p> --- NEW FILE: about_develop.php --- <?php /** * Details of how to Develop STACK. * * @package documentation * @subpackage Stack */ ?> <h1>Developing STACK</h1> <p>This document is intended for people who wish to develop the code for STACK. Contributions are welcome, please contact the developers at <a href="http://sourceforge.net/projects/stack">sourceforge</a> for more information. <h3>History</h3> STACK has its roots in the AiM CAA system. The original motivation for the project, and core development is by <a href="mailto:ch...@sa...">Chris Sangwin</a>. If you are using STACK please do contact Chris, as it is always a pleasure to hear from users. <table cellpadding='2' border='1'> <tr><td>Nov 2004-April 2005</td><td>Stack 1.0</td><td>STACK project started as part of the Serving Mathematics in a Distributed e-Learning Environment project funded by JISC.</td></tr> <tr><td>Summer 2004</td><td>Previous work</td><td>Core original code written by <a href="mailto:ch...@sa...">Chris Sangwin</a> and Laura Naismith, at the Centre for Educational Technology and Distance Learning, at the University of Birmingham</td></tr> </table> <h2>Obtaining the STACK code</h2> STACK code is hosted on <a href="http://sourceforge.net/projects/stack">sourceforge</a>. The <a href="http://phpdoc.org/index.php">PHPDoc</a> auto-generated documentation is available <a href="api/">here</a>. <h2>Areas in which you can help</h2> Collaborators of all kinds are welcome to come and help out with this project. There are a number of areas in which you can contribute. For example: <UL> <li>Writing and contributing questions.</li> <li>Developing the front end - stand alone or in a VLE <li>Translations to non-English languages</li> <li>New question types and formats <li>New answer tests in Maxima's language. <li>Documentation and authoring guides.</li> </ul> <h2>Coding Guidelines</h2> <p>These have been copied and adapted from the <a href="http://moodle.org/">Moodle</a> coding guidelines and they are here to provide a goal for all code to strive to. It's true that some code falls short in a few areas, but it will all be fixed eventually. All new code definitely must adhere to these standards as closely as possible.</p> <h2>General Rules</h2> <ol class="normaltext"> <li class="spaced">All code files should use the .php extension.</li> <li class="spaced">All template files should use the .html extension.</li> <li class="spaced">All text files should use Unix-style text format (most text editors have this as an option).</li> <li class="spaced">All php tags must be 'full' tags like <font color="#339900"><?php ?></font> ... not 'short' tags like <font color="#339900"><? ?></font>. </li> <li class="spaced">All existing copyright notices must be retained. You can add your own if necessary.</li> <li class="spaced">Each file should include the main stackstd.php configuration file.</li> <li class="spaced">Each frontend file should check that the user is authenticated correctly.</li> <li class="spaced">All variables should be initialised or at least tested for existence using isset() or empty() before they are used.</li> </li> </ol> <h2>Coding Style</h2> <p>I know it can be a little annoying to change your style if you're used to something else, but balance that annoyance against the annoyance of all the people trying later on to make sense of STACK code with mixed styles. There are obviously many good points for and against any style that people use, but the current style just <strong>is</strong>, so please stick to it. </p> <ol class="normaltext"> <li class="spaced"><strong>Indenting</strong> should be consistently 4 spaces. Don't use tabs AT ALL. </li> <li class="spaced"><strong>Variable names</strong> should always be easy-to-read, meaningful lowercase English words. If you really need more than one word then run them together, but keep them short as possible. Use plural names for arrays of objects. <p class="examplecode"><font color="#006600">GOOD: $quiz<br /> GOOD: $errorstring<br /> GOOD: $assignments (for an array of objects)<br /> GOOD: $i (but only in little loops)<br /> <br /> BAD: $Quiz <br /> BAD: $aReallyLongVariableNameWithoutAGoodReason<br /> BAD: $error_string</font></p> </li> <li class="spaced"><strong>Function names</strong> should be simple English lowercase words, and start with the name of the stack and then the module to avoid conflicts, either with othe parts of the code or future applications. Words should be separated by underscores. Parameters should always have sensible defaults if possible. Note there is no space between the function name and the following (brackets). <br /> <p class="examplecode"> <font color="#007700">function </font><font color="#0000BB">forum_set_display_mode</font><font color="#007700">(</font><font color="#0000BB">$mode</font><font color="#007700">=</font><font color="#0000BB">0</font><font color="#007700">) {<br /> global </font><font color="#0000BB">$USER</font><font color="#007700">, </font><font color="#0000BB">$CFG</font><font color="#007700">;<br /> <br /> if (</font><font color="#0000BB">$mode</font><font color="#007700">) {<br /> </font><font color="#0000BB">$USER</font><font color="#007700">-></font><font color="#0000BB">mode </font><font color="#007700">= </font><font color="#0000BB">$mode</font><font color="#007700">;<br /> } else if (empty(</font><font color="#0000BB">$USER</font><font color="#007700">-></font><font color="#0000BB">mode</font><font color="#007700">)) {<br /> </font><font color="#0000BB">$USER</font><font color="#007700">-></font><font color="#0000BB">mode </font><font color="#007700">= </font><font color="#0000BB">$CFG</font><font color="#007700">-></font><font color="#0000BB">forum_displaymode</font><font color="#007700">;<br /> }<br /> }</font></p> </li> <li class="spaced"><strong>Blocks</strong> must always be enclosed in curly braces (even if there is only one line). STACK uses Moodle's style: <p class="examplecode"> <font color="#006600">if (</font><font color="#0000CC">$quiz</font><font color="#006600">-></font><font color="#0000CC">attempts</font><font color="#006600">) {<br /> if (</font><font color="#0000CC">$numattempts </font><font color="#006600">> </font><font color="#0000CC">$quiz</font><font color="#006600">-></font><font color="#0000CC">attempts</font><font color="#006600">) {<br /> </font><font color="#0000CC">error</font><font color="#006600">(</font><font color="#0000BB">$strtoomanyattempts</font><font color="#006600">, </font><font color="#CC0000">"view.php?id=$cm</font><font color="#006600">-></font><font color="#CC0000">id"</font><font color="#006600">);<br /> }<br /> }</font></p> </li> <li class="spaced"><strong>Strings</strong> should be defined using single quotes where possible, for increased speed.<br /> <p class="examplecode"> <font color="#006600">$var = 'some text without any variables';<br /> $var = "with special characters like a new line \n";<br /> $var = 'a very, very long string with a '.$single.' variable in it';<br /> $var = "some $text with $many variables $within it"; </font></p> </li> <li class="spaced"><strong>Comments</strong> should use two or three slashes and line up nicely with the code. <p class="examplecode"><font color="#006600">function </font><font color="#0000BB">forum_get_ratings_mean</font><font color="#007700">(</font><font color="#0000BB">$postid</font><font color="#007700">, </font><font color="#0000BB">$scale</font><font color="#007700">, </font><font color="#0000BB">$ratings</font><font color="#007700">=</font><font color="#0000BB">NULL</font><font color="#007700">) {<br /> </font><font color="#FF8000">/// Return the mean rating of a post given to the current user by others.<br /> /// Scale is an array of possible ratings in the scale<br /> /// Ratings is an optional simple array of actual ratings (just integers)<br /> <br /> </font><font color="#007700">if (!</font><font color="#0000BB">$ratings</font><font color="#007700">) {<br /> </font><font color="#0000BB">$ratings </font><font color="#007700">= array(); </font><font color="#FF8000">// Initialize the empty array</font><font color="#007700"><br /> if (</font><font color="#0000BB">$rates </font><font color="#007700">= </font><font color="#0000BB">get_records</font><font color="#007700">(</font><font color="#DD0000">"forum_ratings"</font><font color="#007700">, </font><font color="#DD0000">"post"</font><font color="#007700">, </font><font color="#0000BB">$postid</font><font color="#007700">)) {<br /> </font><font color="#FF8000">// Process each rating in turn</font><font color="#007700"><br /> foreach (</font><font color="#0000BB">$rates </font><font color="#007700">as </font><font color="#0000BB">$rate</font><font color="#007700">) {</font> <br /> ....etc </p> </li> <li class="spaced"><strong>Space</strong> should be used liberally - don't be afraid to spread things out a little to gain some clarity. Generally, there should be one space between brackets and normal statements, but no space between brackets and variables or functions:<br /> <p class="examplecode"> <font color="#007700">foreach (</font><font color="#0000BB">$objects </font><font color="#007700">as </font><font color="#0000BB">$key </font><font color="#007700">=></font><font color="#0000BB"> $thing</font><font color="#007700">)</font><font color="#006600"> {<br /> </font><font color="#007700"> </font><font color="#0000BB">process($thing);</font><font color="#006600"> <br /> } <br /> <br /> </font><font color="#007700">if (</font><font color="#0000BB">$x </font><font color="#007700">== </font><font color="#0000BB">$y</font><font color="#007700">)</font><font color="#006600"> {<br /> </font><font color="#007700"> </font><font color="#0000BB">$a </font><font color="#007700">= </font><font color="#0000BB">$b</font><font color="#007700">;</font><font color="#006600"><br /> } else if (</font><font color="#0000BB">$x </font><font color="#007700">== </font><font color="#0000BB">$z</font><font color="#006600">) {<br /> </font><font color="#007700"> </font><font color="#0000BB">$a </font><font color="#007700">= </font><font color="#0000BB">$c</font><font color="#007700">;</font><font color="#006600"><br /> } else {<br /> </font><font color="#007700"> </font><font color="#0000BB">$a </font><font color="#007700">= </font><font color="#0000BB">$d</font><font color="#007700">;</font><font color="#006600"><br /> } </font></p> </li> </ol> <p> </p> --- NEW FILE: author_questionfields.php --- <?php /** * Describes the data structure stackQuestion * * @package documentation * @subpackage Stack */ include('en_doc.php'); ?> <h1>Question documentation</h1> <p>A <tt>stackQuestion</tt> is the basic object in the system. Indeed, STACK is designed as a vehicle to manage these questions. Each question contains a number of fields. This page is a reference for each field. </p> <p>If you would like some examples of how to author questions, please refer to the authoring guide instead.</p> <p>Each field in the question has attributes. There is a <tt>type</tt>, and whether or not the field is <tt>required</tt> in a valid question. (Note, the type of a field, should not be confused with the "type" of a question!)</p> <h3><tt>type</tt></h3> There are four main types which occur in a <tt>stackQuestion</tt>. Other types occur as required. <ul> <li> <tt>casstring</tt> is an expression which will be processed by the cas, and is required to be in CAS syntax. Hence in a particular question, this information may well be (indeed is likely to be) cas-specific. <br />When processed by the cas, the result is stored as an array containing the <tt>value</tt>, essentially an un-parsed form of the evaluated expression suitable to be fed back to the CAS, together with a <tt>display</tt> field which is the HTML (or MathML) code for the displayed expression. An <tt>errors</tt> field may or may not be present. There are two processes of checking for errors. <ol> <li> PHP-side processing. This checks for mis-matched parentheses, missing * signs and generally does its best not to attempt to evaluate a syntactically incorrect expression.</li> <li> cas-side processing, of course may generate errors when the evaluation takes place. </li></ol> <li> <tt>castext</tt> is a LaTeX string in which some computer algebra strings have been embedded. These strings are embedded between @ characters. Each of these is treated as a <tt>casstring</tt>. For example, <pre> The expansion of $(x-1)^6$ is @expand( (x-1)^6 )@.</pre> There is a filter which processes <tt>castext</tt> in the context in which it occurs. This context includes a list of variables, and options for the display. </li> <li> <tt>rawkeyval</tt> and <tt>keyval</tt> pair. These fields always occur together. The former is the string input, typed by the user. The latter is the PHP array of values. An example is the field <tt>questionVars</tt>. </li> <li> <tt>meta</tt> These fields are information <em>about</em> the question. For example, the questionID number, who edited the question and so on. These fields appear in the database directlty, while the others are serialized together and stored in the <font color=orange><tt>questionBody</tt></font>. Indeed, this field is used to create the database tables in the first place. </li> </ul> <?php foreach( $stackQuestion as $field => $q_field) { $fd = 'stackQuestion_'.$field; $fd = get_string($fd,'stack',''); echo "<h3>$fd</h3>"; echo $q_field['doc']; echo "<p>"; echo "Name of field: <font color=orange><tt>$field</tt></font>. Type of field: <font color=orange><tt>$q_field[type]</tt></font>. Required: <font color=orange><tt>$q_field[required]</tt></font>."; } ?> <h2>Data type stackQuestionInst</h2> <p>A <tt>stackQuestionInst</tt> is an instantiated version of a <tt>stackQuestion</tt>. It inherits many fields from the <tt>stackQuestion</tt>. There are also many fields with the string \"<tt>Inst</tt>\" appended to the field name, to indicate they are instantiated versions. <p>For example, <font color=orange><tt>questionVarsInst</tt></font> are the <font color=orange><tt>questionVars</tt></font> with their values assigned. <p>Fields in a <tt>stackQuestion</tt> of type <font color=orange><tt>rawkeyvals</tt></font> are <em> not inherited</em> by the </tt>stackQuestionInst</tt>. There is no point storing stings, when we have the parsed, validated <font color=orange><tt>keyvals</tt></font> fields to work with. <?php foreach( $stackQuestionInst as $field => $q_field) { if (array_key_exists('doc',$q_field)) { echo '<br />'.$q_field['doc']; } echo "<p>"; echo "Name of field: <font color=orange><tt>$field</tt></font>. Type of field: <font color=orange><tt>$q_field[type]</tt></font>. Required: <font color=orange><tt>$q_field[required]</tt></font>."; } ?> <h2>Data type stackQuestionAttempt</h2> This holds data about each student's attempts as a particular <font color=orange><tt>questionInst</tt></font>. Note that in a fully correct relational database, these would be held in a separate table. However, since each student will generate a new instance, it seems better to store the attempts as an array subfield of the <font color=orange><tt>questionInst</tt></font> itself. This field is <?php foreach( $stackQuestionAttempt as $field => $q_field) { echo "<p>Name of field: <font color=orange><tt>$field</tt></font>. Type of field: <font color=orange><tt>$q_field[type]</tt></font>. <br />"; if (array_key_exists('doc',$q_field)) { echo '<br />'.$q_field['doc']; } } //echo "<pre>";print_r($stackQuestionInst);echo "</pre>"; ?> --- NEW FILE: author_gettingstarted.php --- <?php /** * An authoring guide for STACK questions. * * @package documentation * @subpackage Stack */ require('html/trypopupform.html'); include_once("$stack_root/scripts/stackAuthor.php"); include_once("{$stack_root}/scripts/maxima/maximafun.php"); /** * Display an example of the stack question * * * @question The question to be displayed. * */ function stack_doc_dispexample($question) { global $stackQuestion; //show_array($question); echo "<table border='1'>\n"; foreach ($question as $key => $val) { $fieldname = 'stackQuestion_'.$key; $descript = get_string($fieldname,'stack'); echo "<tr>\n <td>"; echo "<a href=\"javascript:HelpPopup('$key','stackQuestion');\">{$descript}</a></td>\n"; echo " <td><tt>$val</tt> </td>\n</tr>\n"; } echo "</table>\n"; } /** * Display, with hyperlinking, the STACK question field name and a link to the help pop-up. * * * @param string $command The command to be displayed * @param string $stackhelp Optional: the help file which contains the field. */ function stack_doc_dispstackqfield($command,$stackhelp='stackQuestion') { global $stackQuestion,$stackQuestionPotResp,$stackOptions; if ('stackQuestion' == $stackhelp) { $fieldname = 'stackQuestion_'.$command; $descript = get_string($fieldname,'stack'); } else if ('stackQuestionPotResp' == $stackhelp) { $fieldname = 'stackQuestion_PR_'.$command; $descript = get_string($fieldname,'stack'); } else if ('stackOptions' == $stackhelp) { $fieldname = 'stackOptions_'.$command; $descript = get_string($fieldname,'stack'); } echo "<a href=\"javascript:HelpPopup('$command','$stackhelp');\">$descript</a> "; } /** * Display, with hyper-linking, the STACK command * * * @param string $command The command to be displayed */ function stack_doc_dispstackcommand($command) { echo "<a href=\"#STACK_command_{$command}\"><font color=\"orange\"><tt>$command</tt></font></a> "; } ?> <h1><a name=\"author\">Authoring a STACK question</a></h1> <p>A <tt>stackQuestion</tt> is the basic object in the system. Indeed, STACK is designed as a vehicle to manage these questions. This page explains the process of authoring a question, by working through an example. This example uses the online form method. It is possible to edit XML files directly, but this process is not explained here.</p> <h2>A minimal example</h2> <p>Start with a <a href="javascript:NewPopup();">New question</a>. This link will open a pop-up window in which you can edit the question. This link also occurs in the Demonstration >> Question Bank page. Do not be put off by the fact this form looks complicated. There are lots of fields, but only two are compulsory: <ol> <li>The <?php stack_doc_dispstackqfield('questionStem'); ?> is the string actually displayed to the student. ie this is "the question".</li> <li>The <?php stack_doc_dispstackqfield('questionAns'); ?> is the answer to the question.</li> </ol> </p> <p>We are now ready to edit a new question. Into these two fields, enter the following information. It should be possible to cut and paste. <?php $question = array(); $question['questionStem'] = 'Differentiate $(x-1)^3$ with respect to $x$.'; $question['questionAns'] = '3*(x-1)^2'; stack_doc_dispexample($question); ?> Scroll down and click the "edit question" link. Now check for any errors, which should appear under the respective field in red, if so correct them and press "edit question" again. When you are in a position to, click the "Try this question" link. This will take you into another view: the "teacher's view" mode. Click on "validate" and "mark" with different answers. Of course, you can return to the edit form by pressing "edit". The "new_version" is to create a different random version, something we shall cover in a moment.</p> <p>You now have a minimal question working.</p> <p>Note, this question will only remain as long as you are in a session. In order to store the question in STACK's database you need to be logged in as the admin user. Note that currently if you want to store a question you need to login <em>before</em> you start to edit. If you forget to do this all is not lost: download your temporary question as an XML file from the question edit page, and login. They you can import is back to the database.</p> <h2>CAS-enabled text: <tt>castext</tt></h2> <p>Before we consider in detail how to add more features to the question we introduce a datatype <tt>castext</tt>. Many of the fields in a STACK question, such as the <?php stack_doc_dispstackqfield('questionStem'); ?> are of this nominal type, which can be thought of as <em>CAS-enabled text</em>. This is simply LaTeX text, in which CAS commands can be embedded. These CAS commands are executed before the question is displayed to the user.</p> <p><em>Use only simple LaTeX structures, and equations.</em> Only core LaTeX is supported, and experienced users may feel a little disappointed that not all the more complex environments, work. If you do not know how to use LaTeX, some simple examples are given in the <a href="#FAQ">FAQ</a>. </p> <p>The following things to remember about <tt>castext</tt>: <ul> <li>Anything enclosed between @ symbols is evaluated by the CAS, and displayed using the display option as an inline equation. This is analogous to using LaTeX's $'s. Note however, that you don't need to use <tt>$@ stuff @$</tt>, and that <tt>@ stuff @</tt> is sufficient.</li> <li>To get a displayed equation centered on a line of its own, use either <tt>$$@ stuff @$$</tt>, <tt>\[@ stuff @\]</tt>,as in LaTeX.</li> <li> Anything between <tt>< html> stuff < html></tt> structures is kept as HTML, and not interpreted as LaTeX. This enables URL's to be included in the text, as well as external images etc. </li> </ul></p> <h2>Random questions</h2> <p>It is common to want to use random numbers in questions. This is straight forward to do, and we make use of the optional <?php stack_doc_dispstackqfield('questionVarsRaw'); ?> field. Please click on the link to the left to read the specific documentation on this field. More examples are given in the documentation for <?php stack_doc_dispstackqfield('questionVarsRaw'); ?> <p>To create a random question we need to modify the previous one slightly so that the fields consist of the following. Note, that while a little more complex, this question is no different from the one before. <?php $question = array(); $question['questionVarsRaw'] = 'p = (x-1)^3'; $question['questionStem'] = 'Differentiate @p@ with respect to $x$.'; $question['questionAns'] = 'diff(p,x)'; stack_doc_dispexample($question); ?> Notice that now we have defined a local variable <em>p</em>, and used the <em>value</em> of this in the <?php stack_doc_dispstackqfield('questionStem'); ?>. Hence, the user will not see a "<em>p</em>" on the screen when the question is instantiated, but the <em>value</em> of <em>p</em>.</p> <p>Notice also that in the <?php stack_doc_dispstackqfield('questionAns'); ?>, there is a CAS command to differentiate the value of <em>p</em> with respect to <em>x</em>. It is necessary for the CAS to work out the answer in a random question.</p> <p>We are now in a position to generate a random question. Use the data, as follows.</p> <?php $question = array(); $question['questionVarsRaw'] = "n = 2+rand(3); p = (x-1)^n"; $question['questionStem'] = 'Differentiate @p@ with respect to $x$.'; $question['questionAns'] = 'diff(p,x)'; stack_doc_dispexample($question); ?> <p>In this new example, we have an extra variable <em>n</em> which is defined to be a random number. This is then used to define the variable <em>p</em> which is in turn used in the question itself. Edit your trial question, and in the Teacher's trial window use the "new version" button to get new random versions of the question.</p> <p>When generating random questions in CAA we talk about <em>random numbers</em> when we really mean <em>pseudo-random numbers</em>. To keep track of which random numbers are generated for each user, there is a special command in STACK, which you should use instead of Maxima's random command. This is the <?php stack_doc_dispstackcommand("rand"); ?> command which is a general "random thing" generator. It can be used to generate random numbers and also to make selections from a list. <p>As a specific example of some of these features, try the question illustrated below. This contains random numbers, and also examples of variables and expressions selected from a list. <?php $question = array(); $question['questionVarsRaw'] = "n = rand(5)+3; v = rand([x,s,t]); p = rand([sin(n*v),cos(n*v)])"; $question['questionStem'] = 'Differentiate @p@ with respect to @v@.'; $question['questionAns'] = 'diff(p,v)'; stack_doc_dispexample($question); ?> </p> <h2><a name="author_potential_response">Better feedback via the potential response tree</a></h2> <p>So far we have just compared the student's answer with that of the teacher. This gives the minimum possible feedback, along the lines of "correct" or "incorrect". STACK has a mechanism for you to provide better feedback, and this facility is one of STACK's more important features. In our question we need to find the section of the form which looks like <hr /> <a href="#author_potential_response">Add</a> <input type="input" name="questionPotResp[add]" value="0" size="3" /> <a href="javascript:HelpPopup('all','stackQuestionPotResp');">potential responses.</a> (distracters etc).<br /> <hr /> In this change the 0 to a 2 in the box on the question edit form (not above!) and activate either the "Add" or "Edit question" links. The question edit form will become quite significantly more complex as now you have just added two <a href="javascript:HelpPopup('all','stackQuestionPotResp');">potential responses.</a> It is worth reading the documentation about the <a href="javascript:HelpPopup('all','stackQuestionPotResp');">potential responses</a> before we proceed to examples which illustrate this.</p> <p>As an example, we shall provide feedback which checks <ol> <li>For the correct answer.</li> <li>To see if the student integrated by mistake.</li> </ol> First, check that a variable name appears in the <?php stack_doc_dispstackqfield('questionAnsKey'); ?>, it will probably read <tt>ans1</tt>. Use this variable name to refer to the student's answer in all subsequent work.</p> <p>Ignore, for now, the <?php stack_doc_dispstackqfield('questionAnsVarsRaw'); ?> field, since we do not need to process the student's answer yet.</p> <p>Check the first potential response box, indexed with a No. 0 in the top left hand corner. Assuming you have been following this tutorial, you should find that the box <?php stack_doc_dispstackqfield('SAns','stackQuestionPotResp'); ?> contains the student's answer, expressed as <tt>ans1</tt> and that <?php stack_doc_dispstackqfield('TAns','stackQuestionPotResp'); ?> contains the teacher's answer <tt>diff(p,x)</tt>. Notice that this depends on the variable <tt>p</tt> and also contains a CAS command <tt>diff</tt>, as before.</p> <p>Change the <?php stack_doc_dispstackqfield('AnsTest','stackOptions'); ?> to be <tt>AlgEquiv</tt> (algebraic equivalence test), since although this is the default, we now want to be certain this test is actually used. Leave the <?php stack_doc_dispstackqfield('AnsTestOpt','stackOptions'); ?> blank, since in this case we need no options for the Answer Test.</p> <p><em>DO NOT check the Del box!</em> which would result in this potential response being deleted on the next edit cycle.</p> <p>We are now in a position to decide what outcomes we would like. If the result of this answer test is true, we have established the student's answer is correct. Hence we would like to give one mark. This is achieved by setting the <?php stack_doc_dispstackqfield('RawMarkMod','stackQuestionPotResp'); ?> (labelled "Mark") to be '=', and the <?php stack_doc_dispstackqfield('RawMark','stackQuestionPotResp'); ?> to be 1. Notice, these fields already assume these values by default, so you should not need to do anything. Since we have established that the answer is correct we end the process by choosing the Next field to be -1. Again it already is.</p> <p>What if the answer test was false? We would like to check that the student has not integrated by mistake, and we achieve this by applying another answer test in the potential response node No. 1. To jump to this node, from the false branch of Node No 0., make sure that the "Next" field is set to be 1. This fragment is shown below. <hr /> <table> <tr align=top><td>If...</td> <td><a href="javascript:HelpPopup('RawMarkMod','stackQuestionPotResp');">Mark</a></td> <td><a href="javascript:HelpPopup('RawMark','stackQuestionPotResp');">Value</a></td> <td><a href="javascript:HelpPopup('Penalty','stackQuestionPotResp');">Penalty</a></td> <td colspan='2'><a href="javascript:HelpPopup('FeedBack','stackQuestionPotResp');">Feedback</a></td> <td><a href="javascript:HelpPopup('ApLat','stackQuestionPotResp');">Next</a></td> <td></td></tr> <tr> <td colspan = '4'>............</td></tr> <tr><td>false</td><td> <select name="questionPotResp[0][false][RawMarkMod]"> <option value="=" selected>=</option> <option value="+">+</option> <option value="-">-</option> <option value="=AT">=AT</option> </select></td> <td><input type='text' name='questionPotResp[0][false][RawMark]' size ='4' value='0' /></td> <td><input type='text' name='questionPotResp[0][false][Penalty]' value ='' size =' 3' /></td> <td colspan='2'><textarea name='questionPotResp[0][false][FeedBack]' rows ='1' cols='50'></textarea></td> <td> <select name="questionPotResp[0][false][ApLat]"> <option value="-1">-1</option> <option value="0">0</option> <option value="1" selected>1</option> </selected></td> </tr></table><hr /> We are now in a position to implement the second test, before we do this we need to decide what we want.</p> <p>If the student has integrated, they may or may not have added a constant of integration. If that have added such a constant we don't know what they have used! So, the best way to solve this problem is to differentiate their answer and compare it to the question. This is achieved with the following potential response node. You should examine this carefully, and transfer the values to your question template. <?php $pr = array( 'SAns' => 'diff(ans1,x)','TAns' => 'p','AnsTest' => 'AlgEquiv', 'order' => '1', 'true' => array( 'RawMarkMod' => '=', 'RawMark' => '0', 'FeedBack' => 'It looks like you have integrated instead! Please try again.', 'ApLat' => '-1'), 'false' => array( 'RawMarkMod' => '=', 'RawMark' => '0', 'ApLat' => '-1') ); $errors = array(); @stack_question_edit_potresp('1',$pr,'2',$errors); ?> <p>Another common problem is that, even if the student has given the correct answer, they may have used a quite inappropriate method. For example, they may have expanded out the polynomial and hence give the answer in unfactored form. In this situation, we might like to provide some encouraging feedback to explain to the student what they have done wrong.</p> <p>First, we need to add another potential response: after all, we need to apply another answer test. To do this, go back and Add 1 potential response in a similar way as before. After you have re-loaded the page with the "Add" or "Edit question" link, you should have three potential responses for this question.</p> <p>To use this potential response, edit Node 0, and now change the true branch to make the Next node point to the new Node 2. If we enter Node 2, we know the student has the correct answer. We only need to establish if it is factored or not.</p> <p>To establish that the student's answer is factored we need to use a different <?php stack_doc_dispstackqfield('AnsTest','stackOptions'); ?> In this case we choose <tt>SA_factored</tt> which establishes that the Student's Answer is in factored form. Note that this is similar to the <tt>FacForm</tt> answer test, but it does not provide feedback. Since the purpose of this question is not to see if a student can factor the answer we wish to provide our own feedback. We need to add <tt>x</tt> to the <?php stack_doc_dispstackqfield('AnsTestOpt','stackOptions'); ?> to indicate which variable we are using.</p> <p>We also need to update the marks, since we know the student has the answer correct, we should make sure they get marks in both branches of the potential response node.</p> <p>Last, but certainly not least, we add some positive and encouraging feedback to the false branch. For reference, my node 2. is shown below.</p> <?php $pr = array( 'SAns' => 'ans1','TAns' => 'diff(p,x)','AnsTest' => 'SA_factored', 'AnsTestOpt' => 'x', 'order' => '2', 'true' => array( 'RawMarkMod' => '=', 'RawMark' => '1', 'ApLat' => '-1'), 'false' => array( 'RawMarkMod' => '=', 'RawMark' => '1', 'FeedBack' => 'You should keep your answer in factored form. In this case there is no need to expand out your answer, since the chain rule will help you to differentiate the expression directly.', 'ApLat' => '-1') ); $errors = array(); @stack_question_edit_potresp('1',$pr,'2',$errors); ?> <p>Of course, you can continue to add more potential responses as the need arises. These can test for more subtle errors, based upon the common mistakes student's make. In each case an <?php stack_doc_dispstackqfield('AnsTest','stackOptions'); ?> can be used to make a different kind of distinction between answers. You can also define <?php stack_doc_dispstackqfield('questionAnsVarsRaw'); ?> before the response processing tree is traversed to perform calculations on the student's answer. </p> <h2>Options</h2> <p>There is a tension between system flexibility and the simplicity of the question authoring process. At one end of this spectrum, it should be possible in each question to alter every system feature, from the question stem, answer and number of marks available right through to the fonts used, teacher's email address and the URL for a help page. At the other end of the spectrum, questions need to be authored with a maximum of efficiency. Really, the only compulsory fields need be: <ol> <li>the question stem: i.e. the actual "question" posed to the student, and</li> <li>the answer.</li> </ol> One challenge was to make it possible to author a viable question by only entering this information, and provide a mechanism for other features to adopt sensible default values taken from a context.</p> <p>The solution is a cascading options structure. Options are essentially global variables available for use by questions and quizzes. They assume a default value at the system level which can be overridden at the quiz level, or again at the question level. Although we conceived of a "subject", "quiz", "question" hierarchy, the cascading options structure is flexible enough to cope with any navigation system which is essentially a tree structure. When authoring a question or quiz, you can use the default values to create new questions and quizzes quickly and consistently. In fact, most things turn out to be best represented as an option, including the <?php stack_doc_dispstackqfield('QuVal','stackOptions'); ?> (no. of marks), <?php stack_doc_dispstackqfield('Penalty','stackOptions'); ?>, and even the <?php stack_doc_dispstackqfield('AnsTest','stackOptions'); ?>. There are a wide variety of options, with specific documentation available <a href="index.php?action=help&field=stackOptions">here</a>. </p> <p>The options allow a single question to behave in quite different ways, depending on the values set. Adding new options is a reasonably straightforward, and if STACK does not behave in the way you would like, please propose an alternative and it may be added as an option for others to enjoy. Note that this option structure is somewhat at odds with the ISM Question and Test Interpretability (QTI) view of an assessment item as being entirely self contained. </p> <?php // Examples and documentation for the Question Variables. $descript = get_string('stackQuestion_questionVarsRaw','stack'); echo "<h2><a name=\"qvars_ex\">$descript: Examples</a></h2>\n"; echo $stackQuestion['questionVarsRaw']['doc']; ?> <p>Simple assignments are of the form <tt>key = value</tt>, for example, <pre>n = rand(3)+2 p = (n-1)^n</pre> Of course, these assignments can make use of Maxima's functions to manipulate expressions. <pre>p = expand( (x-3)*(x-4) )</pre></p> <p>You can use Maxima's looping structures within Question variables, although the syntax requires this to be of the form <tt>key = value</tt>. In this case, the <tt>key</tt> will be assigned the value <tt>DONE</tt> at the end of the process, unless another value is returned. For example <pre>n = 1 dum1 = FOR a:-3 THRU 26 STEP 7 DO n:n+a </pre> Note, you must use Maxima's syntax <tt>a:-3</tt> here for assignment of <tt>-3</tt> to the variable <tt>a</tt>. The assignment to the dummy variable <tt>dum1</tt> is to ensure every command is of the form <tt>key = value</tt>. Please look at Maxima's documentation for the command <?php $url = $maxima_cmd['DO']['urls'][0]; echo " <a href='maximadocs/maxdoc/$url'>DO</a>.</p> "; ?> You should also look at Maxima's <?php $url = $maxima_cmd['BLOCK']['urls'][0]; echo " <a href='maximadocs/maxdoc/$url'>BLOCK</a>"; ?> which may be useful here for more complex manipulations. Here is another example, which generates a random polynomial. <pre> m = rand([y,x,t]) p = rand(7)+1 q = 0 dum1 = block(for i:1 while i<=p do (q:q+rand(9)*m^p,p:p-1),return(q)) r = int(q,m) </pre> <p>It is also possible to define functions within the Question Variables for use within a question. This is not recommended, and has not been widely... [truncated message content] |
From: Chris S. <san...@us...> - 2005-07-14 08:47:01
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15328 Modified Files: documentation.php Log Message: Moved the documentation Index: documentation.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/documentation.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** documentation.php 20 Jun 2005 15:42:52 -0000 1.3 --- documentation.php 14 Jul 2005 08:46:52 -0000 1.4 *************** *** 47,51 **** include($stack_root.'/maximadocs/functions.php'); } else if ('' != $action) { // Other documentation ! include($stack_root."/doc/{$action}.php"); } --- 47,52 ---- include($stack_root.'/maximadocs/functions.php'); } else if ('' != $action) { // Other documentation ! $file_name = $stack_root.'/lang/'.$options['Language']."/doc/{$action}.php"; ! include($file_name); } |
From: Chris S. <san...@us...> - 2005-07-14 08:47:01
|
Update of /cvsroot/stack/stack-1-0/html In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15328/html Modified Files: admin-menu.txt Log Message: Moved the documentation Index: admin-menu.txt =================================================================== RCS file: /cvsroot/stack/stack-1-0/html/admin-menu.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** admin-menu.txt 8 Jul 2005 16:36:10 -0000 1.11 --- admin-menu.txt 14 Jul 2005 08:46:52 -0000 1.12 *************** *** 17,20 **** --- 17,21 ---- ..menu_AnswerT|documentation.php?action=author_answertest ..menu_PR|documentation.php?action=author_potresp + ..menu_FAF|documentation.php?action=author_factsformula ..menu_FAQ|documentation.php?action=author_faq ..menu_Maxima|documentation.php?action=author_maxima |
From: Chris S. <san...@us...> - 2005-07-14 07:35:05
|
Update of /cvsroot/stack/stack-1-0/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2449 Modified Files: stackUnix.php Log Message: Index: stackUnix.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackUnix.php,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** stackUnix.php 14 Jul 2005 07:27:04 -0000 1.12 --- stackUnix.php 14 Jul 2005 07:34:56 -0000 1.13 *************** *** 158,162 **** * @return array List of instantiated local variables. */ function stack_process_vars($locals,$seed,$options,&$err) { ! $errors = ''; $cpCAS = new Maxima(); --- 158,162 ---- * @return array List of instantiated local variables. */ function stack_process_vars($locals,$seed,$options,&$err) { ! $errors = ''; $cpCAS = new Maxima(); |
Update of /cvsroot/stack/stack-1-0/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv976/scripts Modified Files: stackAuthor.php stackDatabase.php stackQuestion.php stackSocketSend.php stackUnix.php stackUtility.php stackWin.php Log Message: Index: stackDatabase.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackDatabase.php,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** stackDatabase.php 8 Jul 2005 16:56:23 -0000 1.30 --- stackDatabase.php 14 Jul 2005 07:27:03 -0000 1.31 *************** *** 104,107 **** --- 104,108 ---- } + /** * List all the questions in the database and allow access to all functions, including editing. Outputs question *************** *** 257,261 **** echo "<tr><td><input type=\"checkbox\" name=\"questionsToAdd[$qID][add]\" value=\"ticked\" /></td>\n"; ! echo "<td>$qID</td><td>$name</td><td>$qkw</td> </tr>\n"; // Descriptions on a new line. --- 258,269 ---- echo "<tr><td><input type=\"checkbox\" name=\"questionsToAdd[$qID][add]\" value=\"ticked\" /></td>\n"; ! echo "<td>$qID</td><td>$name</td><td>$qkw</td> "; ! ! // List any quizzes in which the question is used. ! echo "<td>"; ! echo stack_db_question_quiz_list_printquizname($qID); ! echo "</td>"; ! ! echo " </tr>\n"; // Descriptions on a new line. *************** *** 324,328 **** function stack_db_question_filter_tablehead($action,$filter,$quizid=0) { ! // The following is JAVA script to select all the questions in a quiz. // Note the fix to prevent all check boxes being selected. echo "<script> --- 332,336 ---- function stack_db_question_filter_tablehead($action,$filter,$quizid=0) { ! // The following is JAVAscript to select all the questions in a quiz. // Note the fix to prevent all check boxes being selected. echo "<script> *************** *** 407,415 **** ! echo "<tr>\n<td></td>\n<td><b>ID</b></td><td align='center'><b>Name</b></td> <td align='center'><b>Key words</b></td> <td></td>"; if ('edit'==$action) { ! echo "<td align='center'><b>Last edit</b></td>"; } else { ! echo '<td></td><td></td>'; } --- 415,423 ---- ! echo "<tr>\n<td></td>\n<td><b>ID</b></td><td align='center'><b>Name</b></td> <td align='center'><b>Key words</b></td>"; if ('edit'==$action) { ! echo "<td></td><td align='center'><b>Last edit</b></td>"; } else { ! echo '<td><b>In quiz?</b></td><td></td>'; } *************** *** 508,512 **** * @return int $result the questionID of the question in the database, new or not. */ ! function stack_db_addquestion($question,$newq=FALSE) { // Add a question to the DB. // If a question has an ID number, and $newq = FALSE, then we update the existing question. --- 516,520 ---- * @return int $result the questionID of the question in the database, new or not. */ ! function stack_db_question_add($question,$newq=FALSE) { // Add a question to the DB. // If a question has an ID number, and $newq = FALSE, then we update the existing question. *************** *** 659,685 **** /** - * Confirms a question still exists in the database. - * - * @param int $questionID The questionID of the question. - * @return boolean - */ - function stack_db_confirm_question_exists($questionID) { - - $exists = FALSE; - - if ('' != $questionID ) { - $query = 'SELECT questionDateLastEdited FROM stackQuestion WHERE questionID='.$questionID; - $result= stack_db_query($query); - - if(0 != mysql_num_rows($result)) { - $exists = TRUE; - } - } - - return $exists; - } - - - /** * Returns the question from the database with the given id. * --- 667,670 ---- *************** *** 741,744 **** --- 726,809 ---- /** + * Confirms a question still exists in the database. + * + * @param int $questionID The questionID of the question. + * @return boolean + */ + function stack_db_question_confirm_exists($questionID) { + + $exists = FALSE; + + if ('' != $questionID ) { + $query = 'SELECT questionDateLastEdited FROM stackQuestion WHERE questionID='.$questionID; + $result= stack_db_query($query); + + if(0 != mysql_num_rows($result)) { + $exists = TRUE; + } + } + + return $exists; + } + + /** + * Returns an array of quizID's, indicating in which quizzes a question is used. + * + * @param int $questionID The questionID of the question. + * @return array $quizList + */ + function stack_db_question_quiz_list($questionID) { + + $quizList = array(); + + if ('' != $questionID ) { + $query = 'SELECT quizID FROM quiz_question WHERE questionID='.$questionID; + $result= stack_db_query($query); + + if(0 != mysql_num_rows($result)) { + for ($i = 0; $i < mysql_num_rows($result); $i++) { + $row = mysql_fetch_row($result); + $quizList[] = $row[0]; + } + } + } + + return $quizList; + } + + + /** + * Returns a string in a printable form, giving a comma separated list of quiz names + * in which the question occurs + * + * @param int $questionID The questionID of the question. + * @return array $quizList + */ + function stack_db_question_quiz_list_printquizname($questionID) { + + $quizList = ''; + + if ('' != $questionID ) { + $quiz_used = stack_db_question_quiz_list($questionID); + if (!empty($quiz_used)) { + foreach($quiz_used as $i) { + $quizDetails = stack_db_quiz_get($i); + $quizName = $quizDetails['quizName']; + if (strlen($quizName)>15) { + $quizName = substr($quizName,0,15).'...'; + } + $quizList .= ", (".$i.") ".$quizName; + } + $quizList = substr($quizList,1,strlen($quizList)-1); + } + } + + + + return $quizList; + } + + + /** * Deletes a question from the database with the given id. * *************** *** 746,756 **** * @return string The result from the MySQL database */ ! function stack_db_dropquestion($questionID) { // Deletes a question from the database with this id. global $stackQuestion,$stack_mysql; $query='DELETE FROM stackQuestion WHERE questionID='.$questionID; $result= stack_db_query($query); return $result; } --- 811,826 ---- * @return string The result from the MySQL database */ ! function stack_db_question_drop($questionID) { // Deletes a question from the database with this id. global $stackQuestion,$stack_mysql; + // (0) delete the question itself $query='DELETE FROM stackQuestion WHERE questionID='.$questionID; $result= stack_db_query($query); + // (1) Delete question from any quizzes in which it is in. + $query = "DELETE FROM quiz_question WHERE questionID = '$questionID'"; + $result = stack_db_query($query); + return $result; } *************** *** 1280,1286 **** if ('' != $quizid ) { $query = "DELETE FROM stackQuiz WHERE quizid = '$quizid'"; ! $result= stack_db_query($query); ! } } --- 1350,1363 ---- if ('' != $quizid ) { + // (0) Delete the quiz itself $query = "DELETE FROM stackQuiz WHERE quizid = '$quizid'"; ! $result = stack_db_query($query); ! ! // (1) Delete all questions attached to the quiz ! $query = "DELETE FROM quiz_question WHERE quizID = '$quizid'"; ! $result = stack_db_query($query); ! ! } ! } Index: stackAuthor.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackAuthor.php,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** stackAuthor.php 21 Jun 2005 14:52:25 -0000 1.25 --- stackAuthor.php 14 Jul 2005 07:27:03 -0000 1.26 *************** *** 680,684 **** $qo = nsf($qu,'order'); // Get the question with the body encoded. ! $qID_exists_in_DB = stack_db_confirm_question_exists($qID); if ($qID_exists_in_DB) { $question = stack_db_getquestion($qID,TRUE); --- 680,684 ---- $qo = nsf($qu,'order'); // Get the question with the body encoded. ! $qID_exists_in_DB = stack_db_question_confirm_exists($qID); if ($qID_exists_in_DB) { $question = stack_db_getquestion($qID,TRUE); *************** *** 827,831 **** // HACK need a regular expression to confirm $quID is a number only! ! if (stack_db_confirm_question_exists($quID)) { stack_db_quiz_add_question($quizid,$quID); $quiz['questions'][] = array('questionID'=>$quID); --- 827,831 ---- // HACK need a regular expression to confirm $quID is a number only! ! if (stack_db_question_confirm_exists($quID)) { stack_db_quiz_add_question($quizid,$quID); $quiz['questions'][] = array('questionID'=>$quID); Index: stackUtility.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackUtility.php,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** stackUtility.php 27 Jun 2005 08:26:40 -0000 1.24 --- stackUtility.php 14 Jul 2005 07:27:04 -0000 1.25 *************** *** 10,13 **** --- 10,17 ---- // HACK these should go in stackstd.php. They are in stackstd.php.dist // but old installs will break. Remove in next release. + // + // Also in the new release. + // (1) remove stackData.php - and its reference in stackstd.php + // (2) remove stackSocketSend.php - and its reference in stackstd.php if ($stack_stand_alone) { require_once("{$stack_root}/scripts/moodlelib.php"); *************** *** 17,20 **** --- 21,26 ---- require_once("{$stack_root}/frontend_general/frontend_util.php"); + + /** * Displays the contents of an array for HTML display. Index: stackSocketSend.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackSocketSend.php,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** stackSocketSend.php 31 Mar 2005 09:39:49 -0000 1.5 --- stackSocketSend.php 14 Jul 2005 07:27:04 -0000 1.6 *************** *** 1,8 **** <?php /** ! * Important utility functions for connecting to sockets and other ! * external progammes. The functions in this file are needed by the ! * stand alone installs, the rqp servers but should not be needed by the ! * Moodle quiz module via the rqp client. * * @package scripts --- 1,5 ---- <?php /** ! * This file is no longer needed. It should be removed at the next major update. * * @package scripts *************** *** 10,238 **** */ - /** - * Instantiate a list of local variables through the CAS. - * - * This function performs the following tasks: - * 1. Checks each local for a PHP error - * 2. If no errors, sends them to the CAS - * 3. Checks for CAS errors - * - * @param array $locals List of local variables to instantiate. - * @param int $seed The random number seed to use - * @param array $options STACK options - * @param array &$err Repository for errors. - * @return array List of instantiated local variables. - */ - function stack_process_vars($locals,$seed,$options,&$err) { - global $stack_os; - - // Make sure ?'s are replaced by qmchar's - if (is_array($locals)) { - foreach ($locals as $key=> $val) { - $locals[$key] = str_replace('?','qmchar',$val); - } - } - - if ('unix' == $stack_os) { - - $locals_inst = stack_process_vars_unix($locals,$seed,$options,$err); - - } else if ('win' == $stack_os) { - - $locals_inst = stack_process_vars_win($locals,$seed,$options,$err); - //show_array($locals_inst); - - } else if ('unix-pool' == $stack_os) { - - if (isset($errors['ProcessVars'])) { - unset($errors['ProcessVars']); - } - - // generate a StackRequest and send it - $webRequest = new StackRequest('PROCESSVARS'); - $webRequest->crData = array('locals' => $locals, 'display' => $options['Display'], 'randseed' => $seed ); - $webResponse = stack_socket_send($webRequest); - - // acknowledge the received StackResponse - $ackRequest = new StackRequest('FINISH'); - $ackRequest->crPID = $webResponse->crPID; - stack_socket_send($ackRequest); - - if (FALSE === $webResponse->crError) { - $locals_inst = $webResponse->crReturn; - } else { - // We have some socket generated error! - // (1) Give back the locals un-instantiated. - $locals_inst = $locals; - $err['stack_process_vars'] = $webResponse->crError; - } - - } else { - echo "\n\n Warning! Could not determing which operating system you are using.\n Given ($stack_os)"; - } - - //show_array($locals_inst); - return($locals_inst); - } - - - // ************************************************************* - // ** LaTeX to HTML - // ************************************************************* - - /** - * Use an external program to convert a LaTeX string to HTML - * - * @see TexProcess - * @param string $tex_string The LaTeX string - * @return string|boolean The converted HTML string or FALSE if there was an error. - */ - function stack_latex_to_html($tex_string) { - global $stack_os,$stack_web_root,$stack_web_services; - - // Takes a pure LaTeX string and returns HTML. - $tex_string = str_replace('\sp', "^", $tex_string); - $tex_string = str_replace('qmchar', '?', $tex_string); - - // create StackRequest object - $request = new StackRequest('TEXCOMMAND'); - $request->crData = $tex_string; - - if ('unix' == $stack_os) { - - $html_string = stack_latex_to_html_unix($tex_string); - - } else if ('win' == $stack_os) { - - $html_string = stack_latex_to_html_win($tex_string); - - } else { - // create a new TeX process - $texProcess = new TexProcess(); - $texReady = $texProcess->CPInitialise(); - - //print_r($texReady); - //echo "<pre>$tex_string</pre>"; - if ($texReady) { - $response = $texProcess->CPSend($request); - $html_string = $response->crData; - $texProcess->CPClose(); - } else { - // process could not be initialised, return an error - return FALSE; - } - } - - return $html_string; - } - - - // ************************************************************* - // ** Connect to CAS: processing vars and connect to socket - // ************************************************************* - - /** - * Connect to a socket to send and receive information. - * - * @see StackSocket - * @see StackRequest - * @see StackResponse - * @param StackRequest $socketRequest - * @return StackResponse - */ - function stack_socket_send($socketRequest) { - - // get the socket parameters from stacksettings.inc - global $stack_socket; - $socketResponse=''; - - // if the port is not set, set it to send to the parent stack socket - if (!is_int($socketRequest->crPort)) { - $socketRequest->crPort = $stack_socket['port']; - } - - // serialize the request for transmission - $request = serialize($socketRequest); - - // open a socket connection - $fp = fsockopen($stack_socket['host'], $socketRequest->crPort, $errno, $errstr); - - // return error immediately if no socket connection can be made - if(!$fp) { - $socketResponse = new StackResponse(); - $socketResponse->crError['SOCKET-CONNECT'] = TRUE; - $socketResponse->crReturn = "Error: $errstr"; - } else { - //send command - fputs($fp, $stack_socket['inputStartTag'].$request.$stack_socket['inputEndTag']); - - //wait for output - $response = ''; - - while (!feof($fp)) { - $response .= fgets($fp, 512); - } - - // close communication socket - fclose($fp); - - // check for start and end tags - $start = strpos($response, $stack_socket['inputStartTag']); - $end = strpos ($response, $stack_socket['inputEndTag']); - - // if start and end tags found, strip them off - if ($start !== FALSE && $end !== FALSE) { - - //strip off outer tags - $startCmd = strpos($response, $stack_socket['inputStartTag']) + strlen($stack_socket['inputStartTag']); - $endCmd = strpos($response, $stack_socket['inputEndTag']); - $command = substr($response, $startCmd, $endCmd-$startCmd); - - $socketResponse = unserialize($command); - } - } - - // result is a StackResponse object - return $socketResponse; - } - - /** - * Similar to stack_socket_send, but don't wait for a response - * - * @see stack_socket_send() - * @param StackRequest $socketRequest - * @return boolean True if message sent, false if no connection could be made. - */ - function stack_socket_send_noresp($socketRequest) { - - // get the socket parameters from stacksettings.inc - global $stack_socket; - - // if the port is not set, set it to send to the parent stack socket - if (!is_int($socketRequest->crPort)) { - $socketRequest->crPort = $stack_socket['port']; - } - - // serialize the request for transmission - $request = serialize($socketRequest); - - // open a socket connection - $fp = fsockopen($stack_socket['host'], $socketRequest->crPort, $errno, $errstr); - - // return error immediately if no socket connection can be made - if(!$fp) { - return FALSE; - } else { - //send command - fputs($fp, $stack_socket['inputStartTag'].$request.$stack_socket['inputEndTag']); - - // close communication socket - fclose($fp); - - return TRUE; - } - } - - - ?> --- 7,9 ---- Index: stackQuestion.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackQuestion.php,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** stackQuestion.php 21 Jun 2005 14:52:26 -0000 1.21 --- stackQuestion.php 14 Jul 2005 07:27:03 -0000 1.22 *************** *** 118,238 **** $stackOptions['ShowSol']['default']='On request'; - /** - * Validates options, removing any blank or default values. - * This should also eventually validate the value of each option. - * - * @param array The options array - * @return void - */ - function stack_options_validate(&$options) { - global $stackOptions; - - // Do we have an array of options? - if (is_array($options)) { - - foreach ($stackOptions as $opt => $fields) { - if (array_key_exists($opt,$options)) { - // Option is set in the $options - if (''==trim($options[$opt]) or 'default'==trim($options[$opt])) { - // But, the option has no value, or is specified 'default' - unset($options[$opt]); // Get rid of this from the question. - } - } - } // end foreach - // Do we have anything left? - if (NULL == array_keys($options)) { - $options=NULL; - } - } - - } - - - /** - * Sets the cascading options, first taking the defaults, then using the subject - * quiz, and finally question values. - * - * @param array &$question The STACK question, required - * @param array &$quiz_options The STACK quiz options array *NOT* the whole quiz, optional - * @param array &$subject The STACK subject options array *NOT* the whole quiz, optional - * @return array The list of options - */ - function stack_options_set($question,$quiz_options=NULL,$subject=NULL) { - global $stackOptions; - - $options = array(); - - //(0) Set the default options. - foreach ($stackOptions as $opnam => $fields) { - $options[$opnam] = $fields['default']; - } - - //(1) Now look in the $question. - if (is_array($question)) { - if (array_key_exists('questionOptions',$question)) { - $qOpt = $question['questionOptions']; - - // Do we have any set options? - if (is_array($qOpt)){ - foreach ($stackOptions as $opt => $fields) { - if (array_key_exists($opt,$qOpt)) { - // Actually take the option which is set, and use it! - $options[$opt] = $qOpt[$opt]; - } - } // end foreach - } - } - } - - //(2) Now look in the $quiz_options - if (is_array($quiz_options)) { - foreach ($stackOptions as $opt => $fields) { - if (array_key_exists($opt,$quiz_options)) { - // Actually take the option which is set, and use it! - $options[$opt] = $quiz_options[$opt]; - } - } // end foreach - } - - return($options); - } - - /** - * Build an array of forbidden strings - * - * @param array $options The STACK option settings - * @return array The list of forbidden words - */ - function stack_options_forbidden($options) { - // Build an array of forbidden strings. - // The fields 'Forbid' and 'Allow' should be in the $options, - // Even if empty strings. - - if (''!= trim($options['Forbid']) ) { // There is at least one forbidden word - $forb = explode(',',$options['Forbid']); - $forb = array_unique(array_map('trim',$forb)); - } else { - $forb = ''; - } - - if (''!= trim($options['Allow']) ) { // There is at least one allowed word - $allow = explode(',',$options['Allow']); - $allow = array_unique(array_map('trim',$allow)); - } else { - $allow = ''; - } - - if (is_array($forb)) { // There are some forbidden words - if (is_array($allow)) {// There are some allowed words - $forbid = array_diff($forb,$allow); // Take out the allowed ones. - } else { - $forbid = $forb; - } - } else { - $forbid = ''; - } // No forbidden words - - return($forbid); - } --- 118,121 ---- *************** *** 533,536 **** --- 416,544 ---- $stackOptions['AnsTest']['values'] = $ats; + /** + * Validates options, removing any blank or default values. + * This should also eventually validate the value of each option. + * + * @param array The options array + * @return void + */ + function stack_options_validate(&$options) { + global $stackOptions; + + // Do we have an array of options? + if (is_array($options)) { + + foreach ($stackOptions as $opt => $fields) { + if (array_key_exists($opt,$options)) { + // Option is set in the $options + if (''==trim($options[$opt]) or 'default'==trim($options[$opt])) { + // But, the option has no value, or is specified 'default' + unset($options[$opt]); // Get rid of this from the question. + } + } + } // end foreach + // Do we have anything left? + if (NULL == array_keys($options)) { + $options=NULL; + } + } + + } + + + /** + * Sets the cascading options, first taking the defaults, then using the subject + * quiz, and finally question values. + * + * @param array &$question The STACK question, required + * @param array &$quiz_options The STACK quiz options array *NOT* the whole quiz, optional + * @param array &$subject The STACK subject options array *NOT* the whole quiz, optional + * @return array The list of options + */ + function stack_options_set($question,$quiz_opts=NULL,$subject_opts=NULL) { + global $stackOptions; + + $options = array(); + $question_opts = NULL; + + //(0) Set the default options. + foreach ($stackOptions as $opnam => $fields) { + $options[$opnam] = $fields['default']; + } + + //(1) Now look in the $question. + if (is_array($question)) { + if (array_key_exists('questionOptions',$question)) { + $question_opts = $question['questionOptions']; + + } + } + + // (2) Set the options - in the reverse order. + stack_options_set_onepass($options,$subject_opts); + stack_options_set_onepass($options,$quiz_opts); + stack_options_set_onepass($options,$question_opts); + + return($options); + } + + + /** + * One pass at adding an array of options to an existing options array. + * + * @param array $opt_toset The options to be set. + * @param array &$options The array holding the existing option. + * @return NULL + */ + function stack_options_set_onepass(&$options,$opt_toset) { + global $stackOptions; + + if (is_array($opt_toset)) { + foreach ($stackOptions as $opt => $fields) { + if (array_key_exists($opt,$opt_toset)) { + $options[$opt] = $opt_toset[$opt]; + } + } + } + } + + /** + * Build an array of forbidden strings + * + * @param array $options The STACK option settings + * @return array The list of forbidden words + */ + function stack_options_forbidden($options) { + // Build an array of forbidden strings. + // The fields 'Forbid' and 'Allow' should be in the $options, + // Even if empty strings. + + if (''!= trim($options['Forbid']) ) { // There is at least one forbidden word + $forb = explode(',',$options['Forbid']); + $forb = array_unique(array_map('trim',$forb)); + } else { + $forb = ''; + } + + if (''!= trim($options['Allow']) ) { // There is at least one allowed word + $allow = explode(',',$options['Allow']); + $allow = array_unique(array_map('trim',$allow)); + } else { + $allow = ''; + } + + if (is_array($forb)) { // There are some forbidden words + if (is_array($allow)) {// There are some allowed words + $forbid = array_diff($forb,$allow); // Take out the allowed ones. + } else { + $forbid = $forb; + } + } else { + $forbid = ''; + } // No forbidden words + + return($forbid); + } + //****************************************************** *************** *** 1055,1077 **** * Apply an Answer Test. * ! * Currently supported answer tests include: ! * - AlgEquiv : algebraic equivalence check (CAS required) ! * - FacForm : factored form check (CAS required) ! * - Num_tol_relative : Numerical Tolerance Relative (CAS required) ! * - Num_tol_absolute : Numerical Tolerance Absolute (CAS required) ! * - SA_True : Use of a CAS function with a boolean result (CAS required) ! * - String : strict string comparison (case-sensitive) ! * - StringSloppy : loose string comparison (case and whitespace ignored) ! * - RegExp : regular expression match ! * - True : Result is always true ! * For the full list, refer to the stackData.php file, in which these are documented. ! * ! * @param string $sa The student's answer ! * @param string $ta The teacher's answer ! * @param string $atest The name of the answer test ! * @param array $atest_ops The answer test optons ! * @param string $disp The display option ! * @param array &$errors Repository for errors ! * @return array A $stackQuestionAttempt data structure containing the information for this attempt */ function stack_apply_answertest($sa,$ta,$atest,$atest_ops,$disp,&$errors) { --- 1063,1073 ---- * Apply an Answer Test. * ! * @param string $sa The student's answer ! * @param string $ta The teacher's answer ! * @param string $atest The name of the answer test ! * @param array $atest_ops The answer test options ! * @param string $disp The display option ! * @param array &$errors Repository for errors ! * @return array $stackQuestionAttempt data structure containing the information for this attempt. */ function stack_apply_answertest($sa,$ta,$atest,$atest_ops,$disp,&$errors) { *************** *** 1132,1173 **** } ! // For the windows demonstration file.... ! if ('unix' == $stack_os) { ! ! $sa = $webRequest->crData['exp1']; ! $ta = $webRequest->crData['exp2']; ! ! $this_attempt = CPProcessAnsTest_unix($sa,$ta,$atest,$disp,$errors); ! ! } else if ('win' == $stack_os) { ! ! $sa = $webRequest->crData['exp1']; ! $ta = $webRequest->crData['exp2']; ! ! $this_attempt = CPProcessAnsTest_win($sa,$ta,$atest,$disp,$errors); ! ! } else { ! $webResponse = stack_socket_send($webRequest); ! ! $ackRequest = new StackRequest('FINISH'); ! $ackRequest->crPID = $webResponse->crPID; ! stack_socket_send($ackRequest); ! ! if ($webResponse->crError !== FALSE) { ! $errors[$atest] = $webResponse->crReturn; ! ! $this_attempt['Valid'] = 'false'; ! $this_attempt['Ans']['key'] = 'ans'; ! $this_attempt['Ans']['value'] = $sa; ! $this_attempt['Ans']['display'] = $sa; ! foreach ($webResponse->crError as $key => $val) { ! $this_attempt['AnswerNote'] .= $key.' '; ! } ! $this_attempt['FeedBack'] = 'There was an error (Specifically: '. $this_attempt['AnswerNote'] .') during the attempt to process your answer. \\ Please contact your teacher. \par For diagnostic purposes, the error was: '. $webResponse->crReturn; ! ! } else { ! $this_attempt = $webResponse->crReturn; ! } ! } // Clean up the CAS dependent scripts here --- 1128,1134 ---- } ! $sa = $webRequest->crData['exp1']; ! $ta = $webRequest->crData['exp2']; ! $this_attempt = CPProcessAnsTest($sa,$ta,$atest,$disp,$errors); // Clean up the CAS dependent scripts here Index: stackUnix.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackUnix.php,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** stackUnix.php 12 Jun 2005 16:10:00 -0000 1.11 --- stackUnix.php 14 Jul 2005 07:27:04 -0000 1.12 *************** *** 19,25 **** * @return string|boolean The converted HTML string or FALSE if there was an error. */ ! function stack_latex_to_html_unix($strin) { global $stack_logfiles,$stack_latex,$stack_root; ! $ret = FALSE; $descriptors = array( --- 19,29 ---- * @return string|boolean The converted HTML string or FALSE if there was an error. */ ! function stack_latex_to_html($strin) { global $stack_logfiles,$stack_latex,$stack_root; ! ! $strin = str_replace('\sp', "^", $strin); ! $strin = str_replace('qmchar', '?', $strin); ! ! $ret = FALSE; $ret = FALSE; $descriptors = array( *************** *** 52,56 **** /** ! * Connect dorectly to the CAS, and return the raw string result. * This does not use sockets, but calls a new CAS session each time. * Hence, this is not likely to be efficient. --- 56,60 ---- /** ! * Connect directly to the CAS, and return the raw string result. * This does not use sockets, but calls a new CAS session each time. * Hence, this is not likely to be efficient. *************** *** 153,157 **** * @param array &$err Repository for errors. * @return array List of instantiated local variables. ! */ function stack_process_vars_unix($locals,$seed,$options,&$err) { $errors = ''; --- 157,161 ---- * @param array &$err Repository for errors. * @return array List of instantiated local variables. ! */ function stack_process_vars($locals,$seed,$options,&$err) { $errors = ''; *************** *** 241,248 **** * @return array $parsed An array structure, which is used to build the student's attempt. */ ! function CPProcessAnsTest_unix($exp1,$exp2,$test,$disp,&$err) { // create a StackResponse object $varResponse = new StackResponse(); ! $cpCAS = new Maxima(); $t = time(); --- 245,252 ---- * @return array $parsed An array structure, which is used to build the student's attempt. */ ! function CPProcessAnsTest($exp1,$exp2,$test,$disp,&$err) { // create a StackResponse object $varResponse = new StackResponse(); ! $cpCAS = new Maxima(); $t = time(); Index: stackWin.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackWin.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** stackWin.php 20 Jun 2005 15:42:55 -0000 1.3 --- stackWin.php 14 Jul 2005 07:27:04 -0000 1.4 *************** *** 19,26 **** * @return string|boolean The converted HTML string or FALSE if there was an error. */ ! function stack_latex_to_html_win($strin) { ! // A Windows version, which uses files and direct execution. Not sockets. ! global $stack_logfiles,$stack_latex,$stack_root; $ret = FALSE; --- 19,28 ---- * @return string|boolean The converted HTML string or FALSE if there was an error. */ ! function stack_latex_to_html($strin) { global $stack_logfiles,$stack_latex,$stack_root; + + $strin = str_replace('\sp', "^", $strin); + $strin = str_replace('qmchar', '?', $strin); + $ret = FALSE; *************** *** 56,60 **** /** ! * Connect dorectly to the CAS, and return the raw string result. * This does not use sockets, but calls a new CAS session each time. * Hence, this is not likely to be efficient. --- 58,62 ---- /** ! * Connect directly to the CAS, and return the raw string result. * This does not use sockets, but calls a new CAS session each time. * Hence, this is not likely to be efficient. *************** *** 142,146 **** * @param array &$err Repository for errors. * @return array List of instantiated local variables. ! */ function stack_process_vars_win($locals,$seed,$options,&$err) { // Make sure ?'s are replaced by qmchar's --- 144,148 ---- * @param array &$err Repository for errors. * @return array List of instantiated local variables. ! */ function stack_process_vars($locals,$seed,$options,&$err) { // Make sure ?'s are replaced by qmchar's *************** *** 159,163 **** $winRequest->crData = array('locals' => $locals, 'display' => $options['Display'], 'randseed' => $seed ); ! $locals_inst = CPProcessVars_win($winRequest); --- 161,165 ---- $winRequest->crData = array('locals' => $locals, 'display' => $options['Display'], 'randseed' => $seed ); ! $locals_inst = CPProcessVars($winRequest); *************** *** 178,185 **** * @return StackResponse $varResponse $crReturn contains the instantiated values */ ! function CPProcessVars_win($varRequest) { // create a StackResponse object $varResponse = new StackResponse(); ! $cpCAS = new Maxima(); // local variables to be processed will be stored in --- 180,187 ---- * @return StackResponse $varResponse $crReturn contains the instantiated values */ ! function CPProcessVars($varRequest) { // create a StackResponse object $varResponse = new StackResponse(); ! $cpCAS = new Maxima(); // local variables to be processed will be stored in *************** *** 264,277 **** } - //$errors = ''; - //$seed = time(); - //$options['Display']='LaTeX'; - - //$locals[] = array('key' => 'p', 'value' =>'diff(x/(1+x^2),x)'); - //$locals[] = array('key' => 'p', 'value' =>'diff(x/(1+x^4),x)'); - //$locals[] = array('key' => 'p', 'value' =>'(fc(n):=sum(cos(k*x)/k!,k,0,n), p:makelist(fc(n),n,0,6), plot(p,[x,-2*%Pi,2*%Pi]))'); - - //$varInst = stack_process_vars_win($locals,$seed,$options,$errors); - /** --- 266,269 ---- *************** *** 284,288 **** * @return array $this_attempt An array structure, which is used to build the student's attempt. */ ! function CPProcessAnsTest_win($exp1,$exp2,$test,$disp,&$err) { // create a StackResponse object $varResponse = new StackResponse(); --- 276,280 ---- * @return array $this_attempt An array structure, which is used to build the student's attempt. */ ! function CPProcessAnsTest($exp1,$exp2,$test,$disp,&$err) { // create a StackResponse object $varResponse = new StackResponse(); |
From: Chris S. <san...@us...> - 2005-07-14 07:27:12
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv976 Modified Files: analysis.php index.php question_bank.php quiz.php stackstd.php.dist Log Message: Index: stackstd.php.dist =================================================================== RCS file: /cvsroot/stack/stack-1-0/stackstd.php.dist,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** stackstd.php.dist 5 Jul 2005 16:29:24 -0000 1.18 --- stackstd.php.dist 14 Jul 2005 07:27:03 -0000 1.19 *************** *** 27,38 **** $stack_os = 'unix'; ! /* Option (2): A pool of CAS processes is started */ ! /* and these wait in the background. */ ! //$stack_os = 'unix-pool'; ! ! /* SEE the install docs for how to use these two */ ! /* options. */ ! ! // Option (3): Windows // This is unsuitable for a production server. // It is *very* insecure. --- 27,31 ---- $stack_os = 'unix'; ! // Option (2): Windows // This is unsuitable for a production server. // It is *very* insecure. *************** *** 163,176 **** /***************************************************/ - /* CAS-pool socket configuration (CAS Pool usage) */ - /***************************************************/ - $stack_socket['host'] = "localhost"; - $stack_socket['port'] = 10010; // For the main socket connection - $stack_socket['childports'] = array(10011, 10012); // for the cas socket connections - $stack_socket['queuedConnAllowed'] = 5; - $stack_socket['inputStartTag'] = "<stack>"; - $stack_socket['inputEndTag'] = "</stack>"; - - /***************************************************/ /* Load standard library files */ /***************************************************/ --- 156,159 ---- *************** *** 184,192 **** require_once("{$stack_root}/scripts/stackDatabase.php"); require_once("{$stack_root}/scripts/stackSocketSend.php"); - - require_once("{$stack_root}/scripts/CASpool/stackProcess.php"); ! // Set the default language. ! $stackOptions['Language']['default'] = $stack_defaultlang; if ('unix' == $stack_os) { --- 167,172 ---- require_once("{$stack_root}/scripts/stackDatabase.php"); require_once("{$stack_root}/scripts/stackSocketSend.php"); ! require_once("{$stack_root}/scripts/CASpool/stackProcess.php"); if ('unix' == $stack_os) { *************** *** 198,201 **** --- 178,186 ---- } + + // Set the default language. + $stackOptions['Language']['default'] = $stack_defaultlang; + + if ($stack_stand_alone) { require_once("{$stack_root}/scripts/moodlelib.php"); Index: analysis.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/analysis.php,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** analysis.php 8 Jul 2005 16:36:08 -0000 1.14 --- analysis.php 14 Jul 2005 07:27:03 -0000 1.15 *************** *** 237,241 **** if ($qi != $qID) { // Does the question still exist in the database? ! $qID_exists_in_DB = stack_db_confirm_question_exists($qID); if ($qID_exists_in_DB) { $qidisp = "<a href=\"javascript:EditPopup('$qID');\">$qID</a>"; --- 237,241 ---- if ($qi != $qID) { // Does the question still exist in the database? ! $qID_exists_in_DB = stack_db_question_confirm_exists($qID); if ($qID_exists_in_DB) { $qidisp = "<a href=\"javascript:EditPopup('$qID');\">$qID</a>"; *************** *** 299,303 **** $query = 'SELECT questionID, questionName, questionDescription, questionKeywords ! FROM stackQuestion ORDER BY questionKeywords, questionID '; $questions = stack_db_query($query); --- 299,303 ---- $query = 'SELECT questionID, questionName, questionDescription, questionKeywords ! FROM stackQuestion ORDER BY questionID '; $questions = stack_db_query($query); *************** *** 309,318 **** if (''==$questionID or '(none)' == $questionID ) { echo " <option value=\"(none)\" selected>(none)</option>\n"; } echo " <option value=\"ALL\" >ALL</option>\n"; for ($i = 0; $i < mysql_num_rows($questions); $i++) { $row = mysql_fetch_row($questions); ! $qn = base64_unserialize($row[1]); if ($row[0] == $questionID) { echo " <option value=\"{$row[0]}\" selected>{$row[0]}: $qn </option>\n"; --- 309,326 ---- if (''==$questionID or '(none)' == $questionID ) { echo " <option value=\"(none)\" selected>(none)</option>\n"; + } else { + echo " <option value=\"(none)\">(none)</option>\n"; } + + if ('ALL' == $questionID ) { + echo " <option value=\"ALL\" selected>ALL</option>\n"; + } else { echo " <option value=\"ALL\" >ALL</option>\n"; + } + for ($i = 0; $i < mysql_num_rows($questions); $i++) { $row = mysql_fetch_row($questions); ! $qn = $row[1]; if ($row[0] == $questionID) { echo " <option value=\"{$row[0]}\" selected>{$row[0]}: $qn </option>\n"; Index: quiz.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/quiz.php,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** quiz.php 20 Jun 2005 15:42:52 -0000 1.23 --- quiz.php 14 Jul 2005 07:27:03 -0000 1.24 *************** *** 133,143 **** // (4.5) Reconstruct $quizInst from previous data if ('continue_quiz' == $action) { ! // Check for the necessary informtaion incoming. ! $userinfo = stack_db_quiz_quizattempt_getlast($quizid,$user['id']); if (is_array($userinfo)) { // We have attempted the quiz before with ! $seed = $userinfo['seed']; $quiz['seed'] = $seed; --- 133,142 ---- // (4.5) Reconstruct $quizInst from previous data if ('continue_quiz' == $action) { ! $userinfo = stack_db_quiz_quizattempt_getlast($quizid,$user['id']); if (is_array($userinfo)) { // We have attempted the quiz before with ! $seed = $userinfo['seed']; $quiz['seed'] = $seed; *************** *** 153,158 **** foreach ($quiz_questions as $key => $qID) { ! $qInst = stack_question_reconstruct($qID,$seed,$user['id'],$quiz_options,$errors); ! $quizInst[]=$qInst; // Make the $RawAns array equal to the student's last answer, if --- 152,157 ---- foreach ($quiz_questions as $key => $qID) { ! $qInst = stack_question_reconstruct($qID,$seed+$key,$user['id'],$quiz_options,$errors); ! $quizInst[] = $qInst; // Make the $RawAns array equal to the student's last answer, if *************** *** 187,191 **** if ( '' == $errors["qu$key"] ) { ! $quizInst[] = stack_question_inst($question,$seed,$options,$errors["qu$key"]); } else { $question = NULL; --- 186,193 ---- if ( '' == $errors["qu$key"] ) { ! // We add an offset to the quiz $seed here to make sure each question in the quiz ! // is created with a different seed. A question may appear more than once, ! // if it is instantiated with the same seed we are in trouble. ! $quizInst[] = stack_question_inst($question,$seed+$key,$options,$errors["qu$key"]); } else { $question = NULL; Index: question_bank.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/question_bank.php,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** question_bank.php 20 Jun 2005 15:42:52 -0000 1.4 --- question_bank.php 14 Jul 2005 07:27:03 -0000 1.5 *************** *** 181,197 **** switch ($action) { - case 'delete': - $questionID = $_POST['questionID']; - if ($admin) { - stack_db_dropquestion($questionID); - } - $action = 'questionbank_screen'; - break; case 'save': ! stack_db_addquestion($question); $action = 'questionbank_screen'; break; case 'save_as': ! stack_db_addquestion($question,TRUE); $action = 'questionbank_screen'; break; --- 181,190 ---- switch ($action) { case 'save': ! stack_db_question_add($question); $action = 'questionbank_screen'; break; case 'save_as': ! stack_db_question_add($question,TRUE); $action = 'questionbank_screen'; break; *************** *** 211,214 **** --- 204,219 ---- switch ($action) { + case 'delete': + $questionID = $_POST['questionID']; + if ($admin) { + $quiz_list = stack_db_question_quiz_list($questionID); + if (!empty($quiz_list)) { + echo '<font color="red">Question ID '.$questionID.' has been deleted, it was used in the following quiz(zes)'; + echo stack_db_question_quiz_list_printquizname($questionID)."</font>\n"; + } + stack_db_question_drop($questionID); + } + $action = 'questionbank_screen'; + break; case 'uploaded_xml': if ($upload_successful) { Index: index.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/index.php,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** index.php 8 Jul 2005 16:56:23 -0000 1.20 --- index.php 14 Jul 2005 07:27:03 -0000 1.21 *************** *** 66,70 **** if ('welcome' == $action) { echo "<h1>Welcome</h1> <p>Welcome to STACK, {$user['firstname']} {$user['lastname']}.</p>"; ! $action = 'choose_quiz'; } --- 66,72 ---- if ('welcome' == $action) { echo "<h1>Welcome</h1> <p>Welcome to STACK, {$user['firstname']} {$user['lastname']}.</p>"; ! if ('admin' != $user['username']) { ! $action = 'choose_quiz'; ! } } |
From: Chris S. <san...@us...> - 2005-07-14 07:27:12
|
Update of /cvsroot/stack/stack-1-0/frontend_general In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv976/frontend_general Modified Files: loginregister.php process_input.php qb_display.php Log Message: Index: qb_display.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/qb_display.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** qb_display.php 20 Jun 2005 15:42:58 -0000 1.2 --- qb_display.php 14 Jul 2005 07:27:03 -0000 1.3 *************** *** 111,115 **** stack_question_validate($quiz[$key],$errs[$key]); ! $qu['questionID'] = stack_db_addquestion($qu); echo "<tr>\n <td>".sf($qu,'questionID')."</td> <td>".sf($qu,'questionName')." </td> <td>".sf($qu,'questionDescription')." </td> <td>".sf($qu,'questionKeywords')." </td>"; $errc = FALSE; --- 111,115 ---- stack_question_validate($quiz[$key],$errs[$key]); ! $qu['questionID'] = stack_db_question_add($qu); echo "<tr>\n <td>".sf($qu,'questionID')."</td> <td>".sf($qu,'questionName')." </td> <td>".sf($qu,'questionDescription')." </td> <td>".sf($qu,'questionKeywords')." </td>"; $errc = FALSE; Index: loginregister.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/loginregister.php,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** loginregister.php 8 Jul 2005 16:56:22 -0000 1.4 --- loginregister.php 14 Jul 2005 07:27:03 -0000 1.5 *************** *** 37,40 **** --- 37,42 ---- $action = 'welcome'; } else { + include_once($stack_root."/scripts/stackUser.php"); + $user = stack_user_blank(); $action = 'loginerr'; } Index: process_input.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/process_input.php,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** process_input.php 8 Jul 2005 16:36:09 -0000 1.4 --- process_input.php 14 Jul 2005 07:27:03 -0000 1.5 *************** *** 86,88 **** --- 86,89 ---- $options = stack_options_set(NULL); + ?> |
From: Chris S. <san...@us...> - 2005-07-12 11:08:04
|
Update of /cvsroot/stack/stack-1-0/doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1710/doc Modified Files: about_install.php Log Message: Index: about_install.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/doc/about_install.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** about_install.php 4 Jul 2005 16:15:01 -0000 1.3 --- about_install.php 12 Jul 2005 11:07:55 -0000 1.4 *************** *** 46,51 **** front end is much better than that distributed with Maxima itself and is well worth installing for testing CAS code outside STACK)</li> ! <li>For graphical support we have used the <a href="http://www.gnuplot.info/">GNUPLOT</a> package. (Note, this ! is already supplied on Fedora 3 distributions, and comes with Maxima 5.9.1 on Windows) </ul> Finally of course --- 46,51 ---- front end is much better than that distributed with Maxima itself and is well worth installing for testing CAS code outside STACK)</li> ! <li>For graphical support we have used the <a href="http://www.gnuplot.info/">GNUPLOT</a> package, version 4.0. ! (Note, this is already supplied on Fedora 3 distributions, and comes with Maxima 5.9.1 on Windows) </ul> Finally of course |
From: Chris S. <san...@us...> - 2005-07-08 16:56:39
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23487 Modified Files: index.php Log Message: Index: index.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/index.php,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** index.php 8 Jul 2005 16:36:08 -0000 1.19 --- index.php 8 Jul 2005 16:56:23 -0000 1.20 *************** *** 35,38 **** --- 35,39 ---- include($stack_root.'/frontend_general/process_input.php'); + /////////////////////////////////////////////////////////////// // (2) Take any actions required |
From: Chris S. <san...@us...> - 2005-07-08 16:56:39
|
Update of /cvsroot/stack/stack-1-0/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23487/scripts Modified Files: stackDatabase.php stackUser.php Log Message: Index: stackDatabase.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackDatabase.php,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** stackDatabase.php 8 Jul 2005 16:36:10 -0000 1.29 --- stackDatabase.php 8 Jul 2005 16:56:23 -0000 1.30 *************** *** 1218,1224 **** if (array_key_exists('id',$user)) { ! $userid = $user['id']; unset($user['id']); ! } $qu = ''; --- 1218,1224 ---- if (array_key_exists('id',$user)) { ! $userid = $user['id']; unset($user['id']); ! } $qu = ''; *************** *** 1227,1230 **** --- 1227,1232 ---- if ('' != trim ($user[$key])) { $qu .= ", $key = '".addslashes($user[$key])."' "; + } else { + $qu .= ", $key = NULL "; } } *************** *** 1236,1244 **** // GET the last ID ! $result= stack_db_query('SELECT LAST_INSERT_ID() FROM stackUser'); ! $row = mysql_fetch_row($result); $result = $row[0]; ! return $user; } --- 1238,1246 ---- // GET the last ID ! $result = stack_db_query('SELECT LAST_INSERT_ID() FROM stackUser'); ! $row = mysql_fetch_row($result); $result = $row[0]; ! return $result; } Index: stackUser.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackUser.php,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** stackUser.php 8 Jul 2005 16:36:11 -0000 1.10 --- stackUser.php 8 Jul 2005 16:56:23 -0000 1.11 *************** *** 154,162 **** $user[$key] = $val; } stack_user_information_validate($user,$errors); if (!nsf($errors,'user')) { if ('' != trim($user['password'])) { ! $user = stack_db_user_update($user); } else { $errors['user']['password'] = '<font color="red">Password must be non-empty.</font>'; --- 154,164 ---- $user[$key] = $val; } + $user['id'] = $userID; + stack_user_information_validate($user,$errors); if (!nsf($errors,'user')) { if ('' != trim($user['password'])) { ! $mysqlrow = stack_db_user_update($user); } else { $errors['user']['password'] = '<font color="red">Password must be non-empty.</font>'; *************** *** 166,170 **** } - $user['id'] = $userID; } --- 168,171 ---- |
From: Chris S. <san...@us...> - 2005-07-08 16:56:38
|
Update of /cvsroot/stack/stack-1-0/frontend_general In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23487/frontend_general Modified Files: loginregister.php Log Message: Index: loginregister.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/loginregister.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** loginregister.php 8 Jul 2005 16:36:09 -0000 1.3 --- loginregister.php 8 Jul 2005 16:56:22 -0000 1.4 *************** *** 79,83 **** // Update user info if ('userupdate' == $action and $user['loggedin']) { ! $user = stack_user_updateinfo($errors); } --- 79,85 ---- // Update user info if ('userupdate' == $action and $user['loggedin']) { ! $user = stack_user_updateinfo($errors); ! $user['loggedin'] = TRUE; ! $action = 'update_info'; } |
From: Chris S. <san...@us...> - 2005-07-08 16:36:50
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13324 Modified Files: analysis.php index.php Added Files: user.php Log Message: Index: analysis.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/analysis.php,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** analysis.php 27 Jun 2005 08:29:40 -0000 1.13 --- analysis.php 8 Jul 2005 16:36:08 -0000 1.14 *************** *** 58,67 **** $user = stack_user_guest(); } ! // Do we need analysis of one question? if (array_key_exists('questionID',$_POST)) { $questionID = $_POST['questionID']; } ! include('html/pagehead.php'); //////////////////////////////////////////////// // Carry out the analysis requested in $_POST --- 58,84 ---- $user = stack_user_guest(); } ! ! $questionID = ''; // Do we need analysis of one question? if (array_key_exists('questionID',$_POST)) { $questionID = $_POST['questionID']; } ! ! // Do we need analysis of one user? ! $userID = ''; ! if (array_key_exists('userID',$_POST)) { ! $userID = $_POST['userID']; ! } ! ! $etimestr = ''; ! if (array_key_exists('EndTime',$_POST)) { ! $etimestr = $_POST['EndTime']; ! } ! $stimestr = ''; ! if (array_key_exists('StartTime',$_POST)) { ! $stimestr = $_POST['StartTime']; ! } ! ! include('html/pagehead.php'); //////////////////////////////////////////////// // Carry out the analysis requested in $_POST *************** *** 269,273 **** echo "<hr /><p>Enter the information for the student answers that you would like to see:</p>\n ! <form name='stackanalysisform' action='{$_PHP_SELF}' method='POST'>\n"; echo "<table>\n"; --- 286,290 ---- echo "<hr /><p>Enter the information for the student answers that you would like to see:</p>\n ! <form name='stackanalysisform' action='' method='POST'>\n"; echo "<table>\n"; *************** *** 275,313 **** // Add a list of users // HACK - $query = 'SELECT id, username, firstname, lastname FROM stackUser'; - - $stack_users = stack_db_query($query); - - if(0 != mysql_num_rows($stack_users)) { - - echo "<tr><td><span id=SectionText>User ID</span></td>\n"; - echo "<td><select name=\"userID\">\n"; - - $spec_users=array('(any)','>0'); - - echo "userID"; - foreach ($spec_users as $su) { - $sup = htmlspecialchars($su); - if ($su == $userID ) { - echo " <option value=\"$sup\" selected>$sup</option>\n"; - } else { - echo " <option value=\"$sup\" >$sup</option>\n"; - } - } - - - for ($i = 0; $i < mysql_num_rows($stack_users); $i++) - { - $row = mysql_fetch_row($stack_users); - if ($row[0] == $userID) { - echo " <option value=\"{$row[0]}\" selected>{$row[0]} {$row[1]} ({$row[2]} {$row[3]})</option>\n"; - } else { - echo " <option value=\"{$row[0]}\">{$row[0]} {$row[1]} ({$row[2]} {$row[3]})</option>\n"; - } - } - echo "</select> </td></tr>"; - - } // Add a list of questions --- 292,298 ---- // Add a list of users // HACK + // Produce a form fragment to get a dropdown list of users. + stack_user_select_formfrag($userID); // Add a list of questions *************** *** 341,354 **** // Add action requested - unset($s); if (array_key_exists('actionreq',$_POST)) { $s[$_POST['actionreq']]='selected'; ! } echo "<tr><td><span id=SectionText>Action requested</span></td>\n"; echo "<td><select name=\"actionreq\">\n ! <option value='any' {nsf($s,'any')}>Any</option>\n ! <option value='validate' {nsf($s,'validate')}>Validate</option>\n ! <option value='mark' {nsf($s,'mark')}>Mark</option></select></td></tr>"; --- 326,340 ---- // Add action requested if (array_key_exists('actionreq',$_POST)) { $s[$_POST['actionreq']]='selected'; ! } else { ! $s['any'] = 'selected'; ! } echo "<tr><td><span id=SectionText>Action requested</span></td>\n"; echo "<td><select name=\"actionreq\">\n ! <option value='any' ".nsf($s,'any').">Any</option>\n ! <option value='validate' ".nsf($s,'validate').">Validate</option>\n ! <option value='mark' ".nsf($s,'mark').">Mark</option></select></td></tr>"; *************** *** 357,366 **** if (array_key_exists('Valid',$_POST)) { $s[$_POST['Valid']]='selected'; ! } echo "<tr><td><span id=SectionText>Valid</span></td>\n"; echo "<td><select name=\"Valid\">\n ! <option value='any' {nsf($s,'any')}>Any</option>\n ! <option value='true' {nsf($s,'true')}>Valid only</option>\n ! <option value='false' {nsf($s,'false')}>Invalid only</option></select></td></tr>"; // Add mark --- 343,355 ---- if (array_key_exists('Valid',$_POST)) { $s[$_POST['Valid']]='selected'; ! } else { ! $s['any'] = 'selected'; ! } ! echo "<tr><td><span id=SectionText>Valid</span></td>\n"; echo "<td><select name=\"Valid\">\n ! <option value='any' ".nsf($s,'any').">Any</option>\n ! <option value='true' ".nsf($s,'true').">Valid only</option>\n ! <option value='false' ".nsf($s,'false').">Invalid only</option></select></td></tr>"; // Add mark *************** *** 368,378 **** if (array_key_exists('RawMark',$_POST)) { $s[$_POST['RawMark']]='selected'; ! } echo "<tr><td><span id=SectionText>Marks obtained</span></td>\n"; echo "<td><select name=\"RawMark\">\n ! <option value='any' {nsf($s,'any')}>Any</option>\n ! <option value='full' {nsf($s,'full')}>Full marks</option>\n ! <option value='nonzero' {nsf($s,'nonzero')}>Non zero</option> ! <option value='zero' {nsf($s,'zero')}>Zero</option> </select></td></tr> <tr><td>Start time</td> --- 357,370 ---- if (array_key_exists('RawMark',$_POST)) { $s[$_POST['RawMark']]='selected'; ! } else { ! $s = ''; ! } ! echo "<tr><td><span id=SectionText>Marks obtained</span></td>\n"; echo "<td><select name=\"RawMark\">\n ! <option value='any' ".nsf($s,'any').">Any</option>\n ! <option value='full' ".nsf($s,'full').">Full marks</option>\n ! <option value='nonzero' ".nsf($s,'nonzero').">Non zero</option> ! <option value='zero' ".nsf($s,'zero').">Zero</option> </select></td></tr> <tr><td>Start time</td> Index: index.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/index.php,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** index.php 20 Jun 2005 15:42:52 -0000 1.18 --- index.php 8 Jul 2005 16:36:08 -0000 1.19 *************** *** 52,56 **** $errps = stack_get_errps($err); - ////////////////////////////////////////////////////////////// // (2) Print the page. --- 52,55 ---- *************** *** 69,72 **** --- 68,77 ---- } + if ('loginerr' == $action) { + echo "<h1>Problems with your login.</h1> <p>You could not be logged into STACK as <tt>{$user['username']}</tt> for the following reason.</p>"; + echo $errors['user']; + $action = 'loginscreen'; + } + switch ($action) { case 'loginscreen': *************** *** 79,84 **** case 'update_info': if (stack_is_logged_in($user) and !stack_user_is_guest($user)) { ! $err = stack_get_err2($errors); ! stack_display_main_update_userinfo($user, $err, $errors); } else { echo '<h1>Update user information</h1>'; --- 84,88 ---- case 'update_info': if (stack_is_logged_in($user) and !stack_user_is_guest($user)) { ! stack_user_update_info($user, $errors); } else { echo '<h1>Update user information</h1>'; --- NEW FILE: user.php --- <?php /** * * Welcome to STACK. A system for teaching and assessment using a * computer algebra kernel. * <br> * This file is licensed under the GPL License. * <br> * A copy of the license is in your STACK distribution called * license.txt. If you are missing this file you can obtain * it from: * http://www.stack.bham.ac.uk/license.txt * <br> * Copyright (c) 2005, Christopher James Sangwin * * @author Chris Sangwin C.J...@bh... * * @package Stack */ /////////////////////////////////////////////////////////////// // (1) Process Input - this sets $action, $user and $username /////////////////////////////////////////////////////////////// session_start(); include('stackstd.php'); $default_action = 'none'; include_once($stack_root.'/frontend_general/front_end_display.php'); include($stack_root.'/frontend_general/process_input.php'); /////////////////////////////////////////////////////////////// // (2) Take any actions required /////////////////////////////////////////////////////////////// // Note that we need to unset the user before printing the header. if ('admin' != $user['username'] and $user['loggedin']) { echo "Only the admin user may access this page."; die(); } if ('userupdate' == $action) { $user_stu = stack_user_updateinfo($errors); } // Do we need analysis of one user? $userID = ''; if ('userupdate_choose' == $action) { $userID = $_POST['userID']; $user_stu = stack_db_user_get_ID($userID); $action = 'userupdate'; } ////////////////////////////////////////////////////////////// // (2) Print the page. ////////////////////////////////////////////////////////////// include('html/pagehead.php'); switch ($action) { case 'none': echo "<h1>User management</h1>\n"; echo "<form name='stackuserform' action='' method='POST'>\n"; echo "<table>"; stack_user_select_formfrag($userID,FALSE); $s[$action] = 'selected'; echo "<td>Action</td>"; echo "<td><select name=\"action\">\n <option value='userupdate_choose' {nsf($s,'update')}>Update</option>\n <option value='delete' {nsf($s,'delete')}>Delete</option></select></td></tr>"; echo "</table>"; echo "<input type=\"submit\" name=\"submit\" value=\"Submit\">"; echo "</form>"; break; case 'userupdate': stack_user_update_info($user_stu,$errors,TRUE); break; case 'delete': echo 'Not yet implemented.'; break;} include('html/pagefoot.php'); ?> |
From: Chris S. <san...@us...> - 2005-07-08 16:36:35
|
Update of /cvsroot/stack/stack-1-0/frontend_general In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13324/frontend_general Modified Files: front_end_display.php frontend_util.php loginregister.php process_input.php Log Message: Index: frontend_util.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/frontend_util.php,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** frontend_util.php 3 Jul 2005 14:50:15 -0000 1.6 --- frontend_util.php 8 Jul 2005 16:36:09 -0000 1.7 *************** *** 30,42 **** // ********************************************************** - /* - * Returns the username associated with a user - * @param array $user, The user - * @return string $username The username - */ - function stack_user_get_name($user) { - return nsf('username',$user); - } - /* --- 30,33 ---- *************** *** 56,74 **** } - /* - * Returns TRUE if the user is the admin user, FALSE otherwise - * @param array $errors, The errors array - * @return string $err - */ - function stack_get_err2($errors) { - $err = ''; - if (is_array($errors)) { - if (array_key_exists('user',$errors)) { - $err = $errors['user']; - } - } - - return $err; - } /* --- 47,50 ---- Index: loginregister.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/loginregister.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** loginregister.php 20 Jun 2005 15:42:58 -0000 1.2 --- loginregister.php 8 Jul 2005 16:36:09 -0000 1.3 *************** *** 36,39 **** --- 36,41 ---- if ($user['loggedin']) { $action = 'welcome'; + } else { + $action = 'loginerr'; } } else { *************** *** 77,99 **** // Update user info if ('userupdate' == $action and $user['loggedin']) { ! if (array_key_exists('user',$_POST)) { ! // We have an incoming form with new user information ! // Merge posted info with new infor ! foreach ($_POST['user'] as $key => $val) { ! $user[$key] = $val; ! } ! ! stack_user_information_validate($user,$errors); ! ! if (!nsf($errors,'user')) { ! if ('' != trim($user['password'])) { ! $user = stack_db_user_update($user); ! } else { ! $errors['user']['password'] = '<font color="red">Password must be non-empty.</font>'; ! $error = $errors['user']['password']; ! $action = 'error'; ! } ! } ! } } --- 79,83 ---- // Update user info if ('userupdate' == $action and $user['loggedin']) { ! $user = stack_user_updateinfo($errors); } Index: process_input.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/process_input.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** process_input.php 23 Jun 2005 08:03:21 -0000 1.3 --- process_input.php 8 Jul 2005 16:36:09 -0000 1.4 *************** *** 77,88 **** } else { // Make sure the user is logged in as a Guest. ! // Is a blank user a guest user??? ! // CJS: no. A blank user is not a guest user. See stackUser.php, where these are defined. include_once($stack_root."/scripts/stackUser.php"); ! $user = stack_user_blank(); } - $username = stack_user_get_name($user); - $options = stack_options_set(NULL); --- 77,87 ---- } else { // Make sure the user is logged in as a Guest. ! // A blank user is not a guest user. Blank users stop errors with empty fields. ! // See stackUser.php, where these are defined. include_once($stack_root."/scripts/stackUser.php"); ! $user = stack_user_blank(); ! $username = $user['username']; } $options = stack_options_set(NULL); Index: front_end_display.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/frontend_general/front_end_display.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** front_end_display.php 20 Jun 2005 15:42:58 -0000 1.2 --- front_end_display.php 8 Jul 2005 16:36:09 -0000 1.3 *************** *** 62,77 **** /* ! * Displays the update user info form ! * @param array $username ! * @param string $err ! * @param array $errors * @return void */ ! function stack_display_main_update_userinfo($user, $err, $errors) { echo '<h1>Update user information</h1>'; ! echo "<form action=\"index.php?\" method=\"post\" name=\"register\" id=\"register\">"; echo '<p>To update your information, please complete the following form.<p>'; ! echo '<table><tr><td>Username </td><td><input type="hidden" name="user[username]" size="25" value="'.stack_s($user['username']).'" alt="User name" />'.stack_s($user['username']).'</td><td>'.nsf($err,'username').'</td></tr>'; ! stack_user_edit_form($user,$errors); echo '</table><input type="hidden" name="action" value="userupdate" /><input type="submit" value="Update" /></form>'; } --- 62,77 ---- /* ! * Displays the update user info form. ! * @param array $user The array containing the information about the user. ! * @param array $errors The usual errors array. ! * @param boolean $admin Is this being used by the admin user to edit a student's login details? * @return void */ ! function stack_user_update_info($user, $errors,$admin=FALSE) { echo '<h1>Update user information</h1>'; ! echo "<form action=\"\" method=\"post\" name=\"register\" id=\"register\">"; echo '<p>To update your information, please complete the following form.<p>'; ! echo '<table><tr><td>Username </td><td><input type="hidden" name="user[username]" size="25" value="'.stack_s($user['username']).'" alt="User name" />'.stack_s($user['username']).'</td><td></td></tr>'; ! stack_user_edit_form($user,$errors,$admin); echo '</table><input type="hidden" name="action" value="userupdate" /><input type="submit" value="Update" /></form>'; } |
From: Chris S. <san...@us...> - 2005-07-08 16:36:34
|
Update of /cvsroot/stack/stack-1-0/html In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13324/html Modified Files: admin-menu.txt Log Message: Index: admin-menu.txt =================================================================== RCS file: /cvsroot/stack/stack-1-0/html/admin-menu.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** admin-menu.txt 22 Jun 2005 13:14:35 -0000 1.10 --- admin-menu.txt 8 Jul 2005 16:36:10 -0000 1.11 *************** *** 8,11 **** --- 8,12 ---- ..menu_New|editquiz.php?action=quiz_new .menu_Reporting|analysis.php + .menu_User|user.php .menu_Logout|index.php?action=logout .menu_Help|documentation.php |
From: Chris S. <san...@us...> - 2005-07-08 16:36:34
|
Update of /cvsroot/stack/stack-1-0/lang/en In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13324/lang/en Modified Files: stack.php Log Message: Index: stack.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/lang/en/stack.php,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** stack.php 4 Jul 2005 16:15:02 -0000 1.6 --- stack.php 8 Jul 2005 16:36:10 -0000 1.7 *************** *** 106,110 **** $string['IncorrectPassword'] = 'Incorrect password!'; - $string['IncorrectAdminPsd'] = 'Incorrect Admin password'; $string['UnknownUserName'] = 'Username does not exist!'; $string['MisMatchPassword'] = 'Your two passwords did not match!'; --- 106,109 ---- *************** *** 258,261 **** --- 257,261 ---- $string['menu_Qfields'] = 'Question fields'; $string['menu_PR'] = 'Potential responses'; + $string['menu_User'] = 'User'; |
From: Chris S. <san...@us...> - 2005-07-08 16:36:34
|
Update of /cvsroot/stack/stack-1-0/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13324/scripts Modified Files: stackDatabase.php stackUser.php Log Message: Index: stackDatabase.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackDatabase.php,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** stackDatabase.php 4 Jul 2005 16:24:11 -0000 1.28 --- stackDatabase.php 8 Jul 2005 16:36:10 -0000 1.29 *************** *** 1147,1150 **** --- 1147,1176 ---- * Takes the itemSource and returns a PHP array containing the item. * + * @param string $username The username of the student. + * @return array $user Full information about the user themselves. + */ + function stack_db_user_get_ID($userID) { + global $stackUser; + + $user = FALSE; + $stackUserKeys = array_keys($stackUser); + + $query = "SELECT * FROM stackUser WHERE id = $userID"; + + $result = stack_db_query($query); + + if(0 != mysql_num_rows($result)) { + $row = mysql_fetch_row($result); + foreach ($row as $key => $val) { + $user[$stackUserKeys[$key]] = stripslashes($val); + } + } + + return $user; + } + + /** + * Takes the itemSource and returns a PHP array containing the item. + * * @param array $user The array containing the user. * @return number $user_id The ID of the new user in the DB. Index: stackUser.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackUser.php,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** stackUser.php 20 Jun 2005 15:42:55 -0000 1.9 --- stackUser.php 8 Jul 2005 16:36:11 -0000 1.10 *************** *** 107,112 **** $_SESSION['user'] = $user; } else { ! $errors['user']['password'] = '<font color="red">'.get_string('IncorrectAdminPsd','stack','').'</font>'; ! $user = stack_user_guest(); } --- 107,113 ---- $_SESSION['user'] = $user; } else { ! $errors['user'] = '<font color="red">'.get_string('IncorrectPassword','stack','').'</font>'; ! $user['loggedin'] = FALSE; ! $user['username'] = $username; } *************** *** 117,121 **** $_SESSION['user'] = $user; } else { ! $errors['user']['password'] = '<font color="red">'.get_string('IncorrectPassword','stack','').'</font>'; $user['loggedin'] = FALSE; $user['username'] = $username; --- 118,122 ---- $_SESSION['user'] = $user; } else { ! $errors['user'] = '<font color="red">'.get_string('IncorrectPassword','stack','').'</font>'; $user['loggedin'] = FALSE; $user['username'] = $username; *************** *** 124,128 **** } else { ! $errors['user']['username'] = '<font color="red">'.get_string('UnknownUserName','stack','').'</font>'; $user = stack_user_blank(); $user['loggedin'] = FALSE; --- 125,129 ---- } else { ! $errors['user'] = '<font color="red">'.get_string('UnknownUserName','stack','').'</font>'; $user = stack_user_blank(); $user['loggedin'] = FALSE; *************** *** 135,138 **** --- 136,178 ---- /** + * Update the information of a particular user. + * + * @param array $errors The array to hold any errors + * @return array $user The user's information. + */ + function stack_user_updateinfo(&$errors) { + + $user = ''; + if (array_key_exists('user',$_POST)) { + // We have an incoming form with new user information + // Get default info. + $userID = $_POST['user']['id']; + $user = stack_db_user_get_ID($userID); + + // Merge posted info with new infor + foreach ($_POST['user'] as $key => $val) { + $user[$key] = $val; + } + stack_user_information_validate($user,$errors); + + if (!nsf($errors,'user')) { + if ('' != trim($user['password'])) { + $user = stack_db_user_update($user); + } else { + $errors['user']['password'] = '<font color="red">Password must be non-empty.</font>'; + $error = $errors['user']['password']; + $action = 'error'; + } + } + + $user['id'] = $userID; + } + + return $user; + + } + + + /** * Validates the information supplied by a user * *************** *** 184,188 **** * @return void */ ! function stack_user_edit_form($user,$errors=array()) { $err = ''; --- 224,228 ---- * @return void */ ! function stack_user_edit_form($user,$errors=array(),$admin=FALSE) { $err = ''; *************** *** 195,200 **** echo '<input type="hidden" name="user[id]" value="'.sf($user,'id').'" />'; ! echo '<tr><td>'.get_string('USR_NewPassword','stack','').'</td><td><input type="password" name="user[password1]" size="15" value="" alt="Password" /></td></tr>'; ! echo '<tr><td>'.get_string('USR_ConfirmPsswd','stack','').'</td><td><input type="password" name="user[password2]" size="15" value="" alt="Confirm Password" /></td></tr>'; echo '<tr><td>'.get_string('USR_FirstName','stack','').'</td><td><input type="text" name="user[firstname]" size="25" value="'.sf($user,'firstname').'" alt="First name" /></td><td>'.nsf($err,'firstname').'</td></tr>'; echo '<tr><td>'.get_string('USR_LastName','stack','').'</td><td><input type="text" name="user[lastname]" size="25" value="'.sf($user,'lastname').'" alt="Last name" /></td><td>'.nsf($err,'lastname').'</td></tr>'; --- 235,251 ---- echo '<input type="hidden" name="user[id]" value="'.sf($user,'id').'" />'; ! if ($admin) { ! echo '<tr><td>ID</td><td>'.sf($user,'id').'</td></tr>'; ! } ! ! if ($admin) { ! $pswd = $user['password']; ! echo '<tr><td>'.get_string('USR_NewPassword','stack','').'</td><td><input type="text" name="user[password1]" size="15" value="'.$pswd.'" alt="Password" /></td></tr>'; ! echo '<tr><td>'.get_string('USR_ConfirmPsswd','stack','').'</td><td><input type="text" name="user[password2]" size="15" value="'.$pswd.'" alt="Confirm Password" /></td></tr>'; ! } else { ! echo '<tr><td>'.get_string('USR_NewPassword','stack','').'</td><td><input type="password" name="user[password1]" size="15" value="" alt="Password" /></td></tr>'; ! echo '<tr><td>'.get_string('USR_ConfirmPsswd','stack','').'</td><td><input type="password" name="user[password2]" size="15" value="" alt="Confirm Password" /></td></tr>'; ! } ! echo '<tr><td>'.get_string('USR_FirstName','stack','').'</td><td><input type="text" name="user[firstname]" size="25" value="'.sf($user,'firstname').'" alt="First name" /></td><td>'.nsf($err,'firstname').'</td></tr>'; echo '<tr><td>'.get_string('USR_LastName','stack','').'</td><td><input type="text" name="user[lastname]" size="25" value="'.sf($user,'lastname').'" alt="Last name" /></td><td>'.nsf($err,'lastname').'</td></tr>'; *************** *** 209,214 **** --- 260,311 ---- } + /** + * Build the form fragment to produce a dropdown list of current users. + * Note, this builds a whole table row. + * + * @param array $userID The user ID number of the current user. + * @param boolean $anyUser Adds an "any non-guest user" field to the list + * @return void + */ + function stack_user_select_formfrag($userID,$anyUser=TRUE){ + + $query = 'SELECT id, username, firstname, lastname FROM stackUser'; + + $stack_users = stack_db_query($query); + + if(0 != mysql_num_rows($stack_users)) { + + echo "<tr><td>User ID</td>\n"; + echo "<td><select name=\"userID\">\n"; + echo "userID"; + if ($anyUser) { + $spec_users=array('(any)','>0'); + + foreach ($spec_users as $su) { + $sup = htmlspecialchars($su); + if ($su == $userID ) { + echo " <option value=\"$sup\" selected>$sup</option>\n"; + } else { + echo " <option value=\"$sup\" >$sup</option>\n"; + } + } + } + + for ($i = 0; $i < mysql_num_rows($stack_users); $i++) + { + $row = mysql_fetch_row($stack_users); + if ($row[0] == $userID) { + echo " <option value=\"{$row[0]}\" selected>{$row[0]} {$row[1]} ({$row[2]} {$row[3]})</option>\n"; + } else { + echo " <option value=\"{$row[0]}\">{$row[0]} {$row[1]} ({$row[2]} {$row[3]})</option>\n"; + } + } + echo "</select> </td></tr>"; + + } + + } ?> |
From: Chris S. <san...@us...> - 2005-07-05 16:29:33
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10418 Modified Files: stackstd.php.dist Log Message: Index: stackstd.php.dist =================================================================== RCS file: /cvsroot/stack/stack-1-0/stackstd.php.dist,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** stackstd.php.dist 5 Jul 2005 13:50:00 -0000 1.17 --- stackstd.php.dist 5 Jul 2005 16:29:24 -0000 1.18 *************** *** 132,137 **** if ('win' == $stack_os) { $maximalocal['DEL_CMD'] = "del"; ! $maximalocal['GNUPLOT_CMD' ] = "wgnuplot"; ! // $maximalocal['GNUPLOT_CMD'] = '"c:\Program Files\Maxima-5.9.1\bin\wgnuplot.exe"'; } else { $maximalocal['DEL_CMD'] = "rm"; --- 132,137 ---- if ('win' == $stack_os) { $maximalocal['DEL_CMD'] = "del"; ! $maximalocal['GNUPLOT_CMD'] = '"c:\Program Files\Maxima-5.9.1\bin\wgnuplot.exe"'; ! //$maximalocal['GNUPLOT_CMD' ] = "wgnuplot"; } else { $maximalocal['DEL_CMD'] = "rm"; |
From: Chris S. <san...@us...> - 2005-07-05 16:29:32
|
Update of /cvsroot/stack/stack-1-0/scripts/install In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10418/scripts/install Modified Files: stacktest.php Log Message: Index: stacktest.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/install/stacktest.php,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** stacktest.php 3 Jun 2005 17:42:44 -0000 1.1 --- stacktest.php 5 Jul 2005 16:29:23 -0000 1.2 *************** *** 82,89 **** /************************************************/ ! /* Test write to $maximalocal['IMAGE_DIR']. */ /************************************************/ ! echo "<h2>Test the CAS system</h2>"; $strin = "The derivative of @ x^4/(1+x^4) @ is \[ @ diff(x^4/(1+x^4),x) @ \] --- 82,89 ---- /************************************************/ ! /* Test call to the CAS. */ /************************************************/ ! echo "<h2>4. Test the CAS system</h2>"; $strin = "The derivative of @ x^4/(1+x^4) @ is \[ @ diff(x^4/(1+x^4),x) @ \] |
From: Chris S. <san...@us...> - 2005-07-05 15:55:15
|
Update of /cvsroot/stack/stack-1-0/scripts/install In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26771/scripts/install Modified Files: testsuite.php Log Message: Index: testsuite.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/install/testsuite.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** testsuite.php 5 Jul 2005 13:12:26 -0000 1.2 --- testsuite.php 5 Jul 2005 15:54:58 -0000 1.3 *************** *** 6,9 **** --- 6,10 ---- session_start(); require_once('../../stackstd.php'); + require_once($stack_root.'/scripts/stackAuthor.php'); $docs = $stack_root.'/doc/en_doc.php'; *************** *** 118,122 **** $testsuite[] = stack_testsuite_construct('SA_factored','(1-x)^2','(x-1)^2',1,'x',''); - $testsuite[] = stack_testsuite_construct('SA_expanded','1/0','0',1,'',''); $testsuite[] = stack_testsuite_construct('SA_expanded','x^2-1','0',1,'',''); --- 119,122 ---- *************** *** 124,147 **** ! $AnswerTestlist = array('AlgEquiv','Diff','Int','FacForm','SA_factored','SA_expanded'); ! //$AnswerTestlist = array('Int'); ! //$AnswerTestlist = array('FacForm','SA_factored'); // Now perform the tests, and display the results. ! $disp = 'LaTeX'; ! $errors = array(); ! echo "<h1>Test suite for the AnswerTests</h1>\n"; ! foreach( $AnswerTestlist as $atest) { ! echo "<h2>$atest</h2>\n"; ! echo $stackAnswerTest[$atest]['doc']; ! $all_passed = TRUE; ! echo "<table border='1' cellpadding='2'>\n\n"; // (4) Sort out and display the output echo "<tr> <th> pass? </th> --- 124,163 ---- ! /* ********************************************************** */ ! /* Get incoming data, process this, print the form and set up */ ! /* all options in order to choose one test suite. */ ! /* ********************************************************** */ // Now perform the tests, and display the results. ! $disp = 'LaTeX'; ! $errors = array(); ! $AnsTest = ''; ! if (array_key_exists('AnsTest',$_POST)) { ! $AnsTest = $_POST['AnsTest']; ! } + // ! echo "<h2>Please choose an answer test.</h2>"; ! echo "<form name=\"ChooseAnsTest\" action=\"\" method=\"POST\">\n"; ! echo stack_question_edit_option_form('AnsTest','AnsTest',$AnsTest,''); ! echo '<input type="submit" value="Submit" />'; ! echo "</form>"; ! if ('' == $AnsTest) { ! die(); ! } ! ! echo "<hr /><h1>Test suite for $AnsTest</h1>\n"; ! ! echo $stackAnswerTest[$AnsTest]['doc']; ! ! $all_passed = TRUE; ! ! echo "<p><table border='1' cellpadding='2'>\n\n"; // (4) Sort out and display the output echo "<tr> <th> pass? </th> *************** *** 160,164 **** // (0) Check this is the required AnswerTest. ! if ($ts['AnswerTest'] == $atest) { $err = ''; --- 176,180 ---- // (0) Check this is the required AnswerTest. ! if ($ts['AnswerTest'] == $AnsTest) { $err = ''; *************** *** 245,250 **** } echo "<hr />\n"; ! ! } ?> --- 261,268 ---- } echo "<hr />\n"; ! ! /* ****************************************** */ ! ! include($stack_root.'/html/pagefoot.php'); ?> |
From: Chris S. <san...@us...> - 2005-07-05 13:50:22
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31293 Modified Files: stackstd.php.dist Log Message: Index: stackstd.php.dist =================================================================== RCS file: /cvsroot/stack/stack-1-0/stackstd.php.dist,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** stackstd.php.dist 23 Jun 2005 10:43:15 -0000 1.16 --- stackstd.php.dist 5 Jul 2005 13:50:00 -0000 1.17 *************** *** 133,136 **** --- 133,137 ---- $maximalocal['DEL_CMD'] = "del"; $maximalocal['GNUPLOT_CMD' ] = "wgnuplot"; + // $maximalocal['GNUPLOT_CMD'] = '"c:\Program Files\Maxima-5.9.1\bin\wgnuplot.exe"'; } else { $maximalocal['DEL_CMD'] = "rm"; |
From: Chris S. <san...@us...> - 2005-07-05 13:36:08
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23546 Modified Files: chat_mathml.php Log Message: Index: chat_mathml.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/chat_mathml.php,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** chat_mathml.php 5 Jul 2005 13:29:20 -0000 1.4 --- chat_mathml.php 5 Jul 2005 13:35:52 -0000 1.5 *************** *** 66,76 **** <p>This page allows you execute computer algebra system commands. </p> ! <p>You need to type in <tt>CASText</tt>. This is LaTeX code, with any text enclosed beteen two @'s being processed by the CAS. For example, try </p> <pre>The derivative of @ x^4/(1+x^4) @ is \[ @ diff(x^4/(1+x^4),x) @ \] - We can plot them both @plot([x^4/(1+x^4),diff(x^4/(1+x^4),x)],[x,-3,3])@ </pre> <?php include('stackstd.php'); --- 66,77 ---- <p>This page allows you execute computer algebra system commands. </p> ! <p>You need to type in plain text enclosed beteen two @'s being processed by the CAS. For example, try </p> <pre>The derivative of @ x^4/(1+x^4) @ is \[ @ diff(x^4/(1+x^4),x) @ \] </pre> + Please note, that LaTeX will break the system. Please only use simple text and CAS commands. + <?php include('stackstd.php'); *************** *** 200,210 **** @</tt> will do.</p> - <p> - <?php - echo stack_s("Anything between <html> stuff <html> structures is kept as HTML, and not - interpreted as LaTeX. This enables URL's to be included in the text, as well as external images etc."); - ?> - </p> - <a href="index.php">Stack home page</a> --- 201,204 ---- |
From: Chris S. <san...@us...> - 2005-07-05 13:29:33
|
Update of /cvsroot/stack/stack-1-0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20751 Modified Files: chat_mathml.php Log Message: Index: chat_mathml.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/chat_mathml.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** chat_mathml.php 27 Jun 2005 08:29:40 -0000 1.3 --- chat_mathml.php 5 Jul 2005 13:29:20 -0000 1.4 *************** *** 9,12 **** --- 9,13 ---- */ session_start(); + include('stackstd.php'); |
From: Chris S. <san...@us...> - 2005-07-05 13:12:45
|
Update of /cvsroot/stack/stack-1-0/scripts/install In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13331/scripts/install Modified Files: testsuite.php Log Message: Index: testsuite.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/install/testsuite.php,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** testsuite.php 1 Jul 2005 15:22:40 -0000 1.1 --- testsuite.php 5 Jul 2005 13:12:26 -0000 1.2 *************** *** 5,9 **** */ session_start(); ! require_once('../../../stackstd.php'); $docs = $stack_root.'/doc/en_doc.php'; --- 5,9 ---- */ session_start(); ! require_once('../../stackstd.php'); $docs = $stack_root.'/doc/en_doc.php'; *************** *** 124,129 **** ! //$AnswerTestlist = array('AlgEquiv','Diff','Int','FacForm','SA_factored','SA_expanded'); ! $AnswerTestlist = array('Int'); //$AnswerTestlist = array('FacForm','SA_factored'); --- 124,129 ---- ! $AnswerTestlist = array('AlgEquiv','Diff','Int','FacForm','SA_factored','SA_expanded'); ! //$AnswerTestlist = array('Int'); //$AnswerTestlist = array('FacForm','SA_factored'); |
From: Chris S. <san...@us...> - 2005-07-04 16:24:25
|
Update of /cvsroot/stack/stack-1-0/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1604/scripts Modified Files: stackDatabase.php Log Message: Index: stackDatabase.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackDatabase.php,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** stackDatabase.php 4 Jul 2005 16:15:02 -0000 1.27 --- stackDatabase.php 4 Jul 2005 16:24:11 -0000 1.28 *************** *** 78,82 **** if (!$connection=mysql_connect($host,$user,$pswd)) { $msg = mysql_error(); ! echo "<b>Could not connet to the MYSQL database on host '$host', as user '$user'. The attempt to connect generated the MYSQL Error ".mysql_errno().": ".mysql_error()."</b>"; die(); } --- 78,82 ---- if (!$connection=mysql_connect($host,$user,$pswd)) { $msg = mysql_error(); ! echo "<b>Could not connet to MYSQL on host '$host', as user '$user'. The attempt to connect generated the MYSQL Error ".mysql_errno().": ".mysql_error()."</b>"; die(); } *************** *** 84,87 **** --- 84,92 ---- $db = mysql_select_db($stackdb,$connection); + if (!$db) { + echo "<b>Could not connet to the MYSQL database '$stackdb' (on host '$host', as user '$user'). The attempt to connect generated the MYSQL Error ".mysql_errno().": ".mysql_error()."</b>"; + die(); + } + $result = mysql_query($query); |