Update of /cvsroot/aimmath/AIM/WEB-INF/maple
In directory sc8-pr-cvs1:/tmp/cvs-serv8501
Modified Files:
Aim.mpl AliceServer.mpl PackageList Random.mpl Util.mpl
Log Message:
Several new packages and modifications... see posting to developer's list
Index: Aim.mpl
===================================================================
RCS file: /cvsroot/aimmath/AIM/WEB-INF/maple/Aim.mpl,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** Aim.mpl 25 Aug 2003 21:47:18 -0000 1.3
--- Aim.mpl 1 Sep 2003 05:53:28 -0000 1.4
***************
*** 513,516 ****
--- 513,519 ----
quizcontext['QueryLink'] := subj['QueryLink'];
+ # KM
+ solnRevealed := false;
+ # END KM
if subj['IsRegistered',id] then
quizcontext['Student'] := eval(subj['GetStudent',id]);
***************
*** 520,524 ****
# this quiz, show them again until he requests a new version
seedfile := cat(quiz['RootDir'],"/records/",id,"/seed.m");
- solnRevealed := false;
if `OS/FileExists`(seedfile) and not command="NewQuizVersion" then
seed := AimCache['Load',seedfile];
--- 523,526 ----
***************
*** 538,541 ****
--- 540,545 ----
fi;
+ isguest := quizcontext['StudentIsGuest'];
+
quizcontext['Password'] := password;
quizcontext['Param'] := eval(param);
***************
*** 554,560 ****
# DIST command <> "NewQuizVersion" and
# DIST command <> "ShowQuizSolutions"
! param["Focused"] = "true"
# END KM
- );
focuslabel := param["FocusLabel"];
--- 558,565 ----
# DIST command <> "NewQuizVersion" and
# DIST command <> "ShowQuizSolutions"
! param["Focused"] = "true") and
! not (isguest and
! member(command,{"ShowQuizSolutions","NewQuizVersion"}));
# END KM
focuslabel := param["FocusLabel"];
***************
*** 594,598 ****
####################
- isguest := quizcontext['StudentIsGuest'];
mode := quiz['Mode'];
notstrict := evalb(mode <> "strict");
--- 599,602 ----
***************
*** 638,642 ****
quizcontext['UseRecordedSeed'] :=
evalb(not(isguest or (command = "NewQuizVersion")));
! quizcontext['UseSeedParameter'] := isguest;
quizcontext['GenerateSeed'] :=
evalb(isguest or (command = "NewQuizVersion"));
--- 642,650 ----
quizcontext['UseRecordedSeed'] :=
evalb(not(isguest or (command = "NewQuizVersion")));
! # KM
! # DIST quizcontext['UseSeedParameter'] := isguest;
! quizcontext['UseSeedParameter'] :=
! evalb(isguest and not(command = "NewQuizVersion"));
! # END KM
quizcontext['GenerateSeed'] :=
evalb(isguest or (command = "NewQuizVersion"));
***************
*** 644,651 ****
quizcontext['RecordSeed'] :=
# KM
- # DIST quizcontext['DeleteSeed'] := showsol;
- # TODO: Check if this still works for guests...
# DIST evalb(not(isguest) and (command = "NewQuizVersion"));
! evalb(not isguest);
quizcontext['DeleteSeed'] :=
evalb(command = "NewQuizVersion");
--- 652,658 ----
quizcontext['RecordSeed'] :=
# KM
# DIST evalb(not(isguest) and (command = "NewQuizVersion"));
! not isguest;
! # DIST quizcontext['DeleteSeed'] := showsol;
quizcontext['DeleteSeed'] :=
evalb(command = "NewQuizVersion");
***************
*** 691,695 ****
quizcontext['ShowPrevious'] := true;
quizcontext['ShowFeedback'] := showmark;
! quizcontext['ShowMark'] := showmark;
quizcontext['ShowRightAnswer'] := showsol;
quizcontext['ShowSolution'] := showsol;
--- 698,705 ----
quizcontext['ShowPrevious'] := true;
quizcontext['ShowFeedback'] := showmark;
! # KM
! # DIST quizcontext['ShowMark'] := showmark;
! quizcontext['ShowMark'] := showmark and not isguest;
! # END KM
quizcontext['ShowRightAnswer'] := showsol;
quizcontext['ShowSolution'] := showsol;
Index: AliceServer.mpl
===================================================================
RCS file: /cvsroot/aimmath/AIM/WEB-INF/maple/AliceServer.mpl,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** AliceServer.mpl 25 Aug 2003 21:47:18 -0000 1.3
--- AliceServer.mpl 1 Sep 2003 05:53:28 -0000 1.4
***************
*** 29,33 ****
interface(warnlevel = 0):
readlib(latex):
! unassign('`latex/exp`'):
unassign('`latex/ln`'):
unassign('`latex/log`'):
--- 29,35 ----
interface(warnlevel = 0):
readlib(latex):
! # KM
! # DIST unassign('`latex/exp`'):
! # END KM
unassign('`latex/ln`'):
unassign('`latex/log`'):
***************
*** 94,97 ****
--- 96,103 ----
unassign('zonefile'): # tidy up
+ # KM
+ e := exp(1);
+ _LatexSmallFractionConstant := 5000;
+ # END KM
pi := Pi:
Index: PackageList
===================================================================
RCS file: /cvsroot/aimmath/AIM/WEB-INF/maple/PackageList,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** PackageList 25 Aug 2003 21:47:18 -0000 1.2
--- PackageList 1 Sep 2003 05:53:28 -0000 1.3
***************
*** 18,21 ****
--- 18,25 ----
aim/Mark
aim/SyntaxHints
+ aim/Decimal
+ aim/SET
+ aim/Inert
+ aim/Number
aim/Diff
aim/Int
***************
*** 39,42 ****
--- 43,47 ----
aim/admin/SourceDir
aim/admin/SourceFile
+ aim/admin/CompileSubject
aim/admin/Quiz
aim/admin/Subject
Index: Random.mpl
===================================================================
RCS file: /cvsroot/aimmath/AIM/WEB-INF/maple/Random.mpl,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** Random.mpl 25 Aug 2003 21:47:18 -0000 1.3
--- Random.mpl 1 Sep 2003 05:53:28 -0000 1.4
***************
*** 55,59 ****
"Implements Ken Monks' Rand() function, a recursive random thing-maker. See the <a href=\"http://math.scranton.edu/monks/software/Rand/Rand.html\">Help file for Rand()</a> for details.",
proc()
! local f,a,n,L,wt,i,r,tot,cm,pick,s,m,w,ans,t,newargs,S,AreEqual:
global RandLevel;
--- 55,59 ----
"Implements Ken Monks' Rand() function, a recursive random thing-maker. See the <a href=\"http://math.scranton.edu/monks/software/Rand/Rand.html\">Help file for Rand()</a> for details.",
proc()
! local f,a,b,n,L,wt,i,r,tot,cm,pick,s,m,w,ans,t,newargs,S,AreEqual,R,V,F,Fargs,finished,numargs,Nops,mx,mn,treesizes,j:
global RandLevel;
***************
*** 69,78 ****
fi:
S:=StringTools[SubstituteAll](S,"%","%%");
! S:=cat(S,"\n<br/>\n");
if not type(RandLevel,integer) then RandLevel:=1;
else RandLevel:=RandLevel+1;
fi;
! S:=cat("-"$RandLevel,S);
printf(S);
fi:
--- 69,78 ----
fi:
S:=StringTools[SubstituteAll](S,"%","%%");
! S:=cat(S,"\n<br>\n");
if not type(RandLevel,integer) then RandLevel:=1;
else RandLevel:=RandLevel+1;
fi;
! S:=cat("-"$RandLevel,">",S);
printf(S);
fi:
***************
*** 113,123 ****
# fairly pick one of the args
pick:=rand(tot)()+1:
cm:=wt[1]: for i to nargs while cm<pick do cm:=cm+wt[i+1]; od:
# putting eval here allows us to pass Rand unevaluated arguments like 'x'
# which may store things that AIM can't parse,
# so they can make it here for use in Rand
r:=eval(newargs[i]):
!
# and process it
--- 113,125 ----
# fairly pick one of the args
+
pick:=rand(tot)()+1:
cm:=wt[1]: for i to nargs while cm<pick do cm:=cm+wt[i+1]; od:
+
# putting eval here allows us to pass Rand unevaluated arguments like 'x'
# which may store things that AIM can't parse,
# so they can make it here for use in Rand
r:=eval(newargs[i]):
!
# and process it
***************
*** 128,131 ****
--- 130,144 ----
elif type(r,range(integer)) then
ans:=rand(r)():
+ # "a".."b"
+ elif type(r,range(string)) then
+ a:=op(1,convert(op(1,r),bytes));
+ b:=op(1,convert(op(2,r),bytes));
+ s:=seq(convert([t],bytes),t=a..b);
+ ans:=Rand(s):
+ # 0.01..1.0
+ elif type(r,range(float)) then
+ a:=op(2,op(1,r)); b:=op(2,op(2,r)); m:=min(a,b);
+ s:=op(1,op(1,r))*10^(a-m); t:=op(1,op(2,r))*10^(b-m); L:=sort([s,t]);
+ ans:=Float(Rand(L[1]..L[2]),m):
# [...]
elif type(r,list) then
***************
*** 152,159 ****
ans:=`new/SET`(Rand(Seq(op(r))));
else
! ans:=`new/SET`(Rand(Seq(op(r),isEqual)));
fi:
# if a SET object is passed, use its list of elements
! elif type(r,table) and op(1,op(r))='SET' then
ans:=Rand(r['Elements']);
# SUM(...)
--- 165,172 ----
ans:=`new/SET`(Rand(Seq(op(r))));
else
! ans:=`new/SET`(Rand(Seq(op(r),`aim/Test`)));
fi:
# if a SET object is passed, use its list of elements
! elif type(r,'SET') then
ans:=Rand(r['Elements']);
# SUM(...)
***************
*** 194,198 ****
for i to 1000 while nops(ans)<n do
t:=Rand(a);
! if not member(t,ans) then ans:=[op(ans),eval(t)]; fi:
od:
fi;
--- 207,211 ----
for i to 1000 while nops(ans)<n do
t:=Rand(a);
! if not member(eval(t),ans) then ans:=[op(ans),eval(t)]; fi:
od:
fi;
***************
*** 230,235 ****
--- 243,349 ----
ans:=L
fi:
+ # Partition(...)
+ elif type(r,specfunc(anything,'Partition')) then
+ Nops:=nops(r);
+ if Nops=1 then
+ ans:=Rand(Permute(combinat['randpart'](Rand(op(r)))));
+ elif Nops=2 then # second argument specifies the number of terms in the partition
+ L:=NULL; n:=Rand(op(1,r)); s:=Rand(op(2,r));
+ if n<s then error "No such partition exists" fi;
+ for i to s-1 do
+ m:=Rand(1..n-(s-i));
+ L:=L,m;
+ n:=n-m;
+ od:
+ ans:=[L,n];
+ elif Nops=3 then # third argument specifies the maximum size of a term in the partition
+ L:=NULL; n:=Rand(op(1,r)); s:=Rand(op(2,r)); mx:=Rand(op(3,r));
+ if n<s or mx*s<n then error "No such partition exists" fi;
+ for i to s-1 do
+ m:=Rand(1..min(n-(s-i),mx));
+ L:=L,m;
+ n:=n-m;
+ od:
+ ans:=[L,n];
+ elif Nops=4 then # fourth argument specifies the minimum size of a term in the partition
+ L:=NULL; n:=Rand(op(1,r)); s:=Rand(op(2,r)); mx:=Rand(op(3,r)); mn:=Rand(op(4,r));
+ for i to s-1 do
+ m:=Rand(1..min(n-(s-i),mx));
+ L:=L,m;
+ n:=n-m;
+ od:
+ ans:=[L,n];
+ fi;
+ # Frac(integerpart,den)
+ elif type(r,specfunc(anything,'Frac')) then
+ if nops(r)<>2 then
+ error "Syntax: Frac(integerpart,den)";
+ fi;
+ n:=Rand(op(1,r)); m:=Rand(op(2,r)); a:=Rand(1..m-1);
+ ans:=(a+n*m)/m;
+
+ # Random Expressions from a family of operators
+ elif type(r,specfunc(anything,Expression)) then
+ R:=[op(r)];
+ n:=nops(R); # the number of Inerts to use
+ if n=0 then error "Syntax: Expression() must have at least one argument" fi:
+ # each element of R is an argument to Rand which returns
+ # a vector with two or three elements A,B,C where A is an Inert
+ # B is argument to Rand that produces elements in the
+ # domain of A. If A can have any number of args then C is an
+ # argument to Rand which produces the number of arguments to use
+ # we do not randomize the order of the args, in case the user
+ # wants to specify a particular order.
+ V:=Rand(R[1]); # take the first Inert
+ F:=V[1];
+ if not type(F,'Inert') then
+ error "Syntax: First element in vector must be an Inert"
+ fi;
+ numargs:=F['Nargs'];
+ if numargs<0 then
+ # the vector must have three components, the third being the number of arguments to use
+ if linalg[vectdim](V)<3 then
+ error "Syntax: the number of arguments must be specified for Inerts with an arbitrary number of arguments";
+ fi;
+ numargs:=V[3];
+ fi:
+ # partition the provided Inerts among the arguments to F
+ if n=1 then
+ treesizes:=[seq(0,i=1..numargs)];
+ else
+ treesizes:=Rand(Partition(n-1,1..min(numargs,n-1)));
+ treesizes:=Rand(Permute([op(treesizes),seq(0,i=1..numargs-nops(treesizes))]));
+ fi:
+ # try to find a selection that is in the domain
+ finished:=false;
+ for i to 1000 while not finished do
+ Fargs:=NULL; m:=2;
+ for j to numargs do
+ if treesizes[j]=0 then
+ if nops([Fargs])=1 then
+ Fargs:=eval(Fargs),Rand(op(2,R[1]));
+ else
+ Fargs:=Fargs,Rand(op(2,R[1]));
+ fi;
+ else
+ if nops([Fargs])=1 then
+ Fargs:=eval(Fargs),Rand(Expression(op(R[m..m+treesizes[j]-1])));
+ else
+ Fargs:=Fargs,Rand(Expression(op(R[m..m+treesizes[j]-1])));
+ fi;
+ m:=m+treesizes[j];
+ fi:
+ od:
+ if F['Domain'](Fargs) then finished:=true; fi:
+ od:
+ if i>1000 then
+ error "More than 1000 attempts failed to produce an element in the domain."
+ fi;
+ ans:=Apply(F,Fargs);
+
+ # sometimes we want Rand to return NULL
elif r='Null' then
ans:=NULL;
+
# everything else just gets returned
else
***************
*** 239,252 ****
# print debug info
if type(infolevel[`Rand`],integer) and infolevel[`Rand`]>0 then
if ans=NULL then
! S:=cat("."$RandLevel,"Rand returned null. ");
else
! S:=cat("."$RandLevel,sprintf("Rand selected: %q",eval(ans)));
fi:
if infolevel[`Rand`]=1 then
! if length(S)>250 then S:=cat(substring(S,1..250),"...") fi;
fi;
S:=StringTools[SubstituteAll](S,"%","%%");
! S:=cat(S,"\n<br/>\n");
RandLevel:=RandLevel-1;
printf(S);
--- 353,371 ----
# print debug info
if type(infolevel[`Rand`],integer) and infolevel[`Rand`]>0 then
+ S:=cat("<","."$RandLevel);
if ans=NULL then
! S:=cat(S,"Rand returned null. ");
! elif type(ans,Inert) then
! S:=cat(S,"Rand selected the Inert whose name is: ",ans['Name']);
! elif type(ans,InertExpr) then
! S:=cat(S,"Rand returned the InertExpr whose TeX string is: ",ans['TeX']);
else
! S:=cat(S,sprintf("Rand selected: %q",eval(ans)));
fi:
if infolevel[`Rand`]=1 then
! if length(S)>100 then S:=cat(substring(S,1..100),"...") fi;
fi;
S:=StringTools[SubstituteAll](S,"%","%%");
! S:=cat(S,"\n<br>\n");
RandLevel:=RandLevel-1;
printf(S);
***************
*** 273,276 ****
--- 392,578 ----
end
):
+
+ ###################################################################
+ # Generate 'Nice' Random Things
+ ###################################################################
+
+ `Package/Assign`(
+ `Nice/Monomial`::procedure,
+ "Produces a monomial of the form @a*x^n@ where @a@ is randomly selected from @arange@ and @n@ is randomly selected from @deg@ if those arguments are present. If @deg@ or @arange@ are not passed as arguments the default value is @1..3@ for both. The argument @x@ is mandatory and can be any algebraic expression or Inert Expression.",
+ proc(x::{algebraic,InertExpr},deg,arange)
+ local n,a,nr,ar;
+
+ # defaults
+ nr:=[1..3];
+ ar:=[1..3];
+ # overriden
+ if nargs>1 then nr:=deg fi;
+ if nargs>2 then ar:=arange fi;
+
+ n:=Rand(nr);
+ a:=Rand(ar);
+
+ Times(a,ToThe(x,n))
+
+ end
+ ):
+
+ `Package/Assign`(
+ `Nice/Binomial`::procedure,
+ "Produces a \"nice\" binomial from its arguments (which is more complicated than it sounds). If one looks through the problems assigned in a typical calculus or precalc book, one will notice that there are certain rules that authors tend to follow when designing \"nice\" questions. This procedure attempts to produce a \"nice\" random binomial in @x@ that is a sum of a monomial in @x@ and a constant term in a random order. The defaults for the degree of the monomial and the two coefficients can be overriden by supplying the appropriate arguments. The argument @x@ is mandatory and can be any algebraic expression or Inert Expression.",
+ proc(x::{algebraic,InertExpr},deg,arange,brange)
+ local n,a,b,nr,ar,br,i;
+
+ # defaults
+ nr:=[1,[1..3]];
+ ar:=[-3..-1,1..3];
+ br:=[-3..-1,1..3];
+ # overriden
+ if nargs>1 then nr:=deg fi;
+ if nargs>2 then ar:=arange fi;
+ if nargs>3 then br:=brange fi;
+
+ n:=Rand(nr);
+
+ # don't let them both be negative
+ for i to 20 do
+ a:=Rand(ar);
+ b:=Rand(br);
+ if `aim/StartsNegative`(a) and `aim/StartsNegative`(b) then
+ # Randomly choose who gets first opportunity to be changed
+ if Rand(true,false) then
+ if type(a,algebraic) then
+ a:=abs(a): break
+ elif type(b,algebraic) then
+ b:=abs(b): break
+ fi
+ else
+ if type(b,algebraic) then
+ b:=abs(b): break
+ elif type(b,algebraic) then
+ a:=abs(a): break
+ fi
+ fi
+ else
+ break
+ fi:
+ od:
+
+ # if its degree 1 you can use both coefficients
+ if n=1 then
+ if `aim/StartsNegative`(a) then
+ return Plus(b,Times(a,x));
+ elif `aim/StartsNegative`(b) then
+ return Plus(Times(a,x),b);
+ else
+ return Plus(Rand(Permute(Times(a,x),b)));
+ fi;
+ # otherwise we only use one coefficient unless its overriden
+ else
+ # a is negative so put it second
+ if `aim/StartsNegative`(a) then
+ # overridden... use b
+ if nargs>3 then
+ return Plus(b,Times(a,ToThe(x,n)));
+ # default.. don't use b
+ else
+ return Plus(1,Times(a,ToThe(x,n)));
+ fi;
+ # b is negative so put it second
+ elif `aim/StartsNegative`(b) then
+ # overridden... use both
+ if nargs>3 then
+ return Plus(Times(a,ToThe(x,n)),b);
+ # only a was overidden, so ignore b
+ elif nargs=3 then
+ return Plus(1,Times(a,ToThe(x,n)));
+ # default...use just one
+ else
+ return Rand(Plus(ToThe(x,n),b),Plus(1,Times(a,ToThe(x,n))))
+ fi
+ # neither are negative so it doesn't matter who is first
+ else
+ # b overridden... use both
+ if nargs>3 then
+ return Plus(Rand(Permute(b,Times(a,ToThe(x,n)))));
+ # only a was overidden, so ignore b
+ elif nargs=3 then
+ return Plus(1,Times(a,ToThe(x,n)));
+ # default...use just one in either order
+ else
+ return Rand(Plus(Rand(Permute(b,ToThe(x,n)))),Plus(1,Times(a,ToThe(x,n))));
+ fi
+ fi;
+ fi:
+ end
+ ):
+
+ `Package/Assign`(
+ `Nice/Trinomial`::procedure,
+ "Produces a \"nice\" trinomial in @x@. See #Nice/Binomial# for more info.",
+ proc(x::{algebraic,InertExpr},deg,arange,brange,crange)
+ local n,m,a,b,c,nr,ar,br,cr,i,typ;
+
+ # defaults
+ nr:=[1..3];
+ ar:=[-3..-1,1..3];
+ br:=[-3..-1,1..3];
+ cr:=[-3..-1,1..3];
+ # overriden
+ if nargs>1 then nr:=deg fi;
+ if nargs>2 then ar:=arange fi;
+ if nargs>3 then br:=brange fi;
+ if nargs>4 then cr:=crange fi;
+
+ m,n:=op(sort(Rand(List([nr],2))));
+ b:=Rand(br);
+ # don't let both a and c be negative
+ for i to 20 do
+ a:=Rand(ar);
+ c:=Rand(cr);
+ if `aim/StartsNegative`(a) and `aim/StartsNegative`(c) then
+ # Randomly choose who gets first opportunity to be changed
+ if Rand(true,false) then
+ if type(a,algebraic) then
+ a:=abs(a): break
+ elif type(c,algebraic) then
+ c:=abs(c): break
+ fi
+ else
+ if type(c,algebraic) then
+ c:=abs(c): break
+ elif type(c,algebraic) then
+ a:=abs(a): break
+ fi
+ fi
+ else
+ break
+ fi:
+ od:
+
+ # three types possible
+ if `aim/StartsNegative`(a) then
+ typ=1
+ elif `aim/StartsNegative`(c) then
+ typ=Rand(2,3)
+ else
+ typ:=Rand(1..3)
+ fi;
+
+ if typ=1 then
+ if nargs<=3 then b:=Rand(-1,1) fi;
+ if nargs<=2 then a:=Rand(-1,1) fi;
+ return Plus(c,Times(b,ToThe(x,m)),Times(a,ToThe(x,n)))
+ elif typ=2 then
+ if nargs<=2 then a:=1 fi:
+ if nargs<=4 then c:=Rand(-1,1) fi:
+ return Plus(Times(a,ToThe(x,n)),Times(b,ToThe(x,m)),c)
+ else
+ if nargs<=2 then a:=1 fi:
+ if nargs<=3 then b:=Rand(-1,1) fi:
+ return Plus(Times(a,ToThe(x,n)),Times(b,ToThe(x,m)),c)
+ fi:
+ end
+ ):
EndPackage():
Index: Util.mpl
===================================================================
RCS file: /cvsroot/aimmath/AIM/WEB-INF/maple/Util.mpl,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** Util.mpl 25 Aug 2003 21:47:18 -0000 1.3
--- Util.mpl 1 Sep 2003 05:53:28 -0000 1.4
***************
*** 61,64 ****
--- 61,74 ----
):
+ # KM
+ `Package/Assign`(
+ `Util/RemoveQuotes`::string,
+ "Removes any double quotes from a Maple string.",
+ proc(s::string)
+ StringTools:-Remove(rcurry(member,{"\""}),s);
+ end
+ ):
+ # END KM
+
######################################################################
***************
*** 557,560 ****
--- 567,586 ----
eval(util_exceptionmessage)
):
+
+ # KM
+ `Package/Assign`(
+ PercentStringToProc::procedure,
+ "Convert a string containing @%1@, @%2@, etc into a proc which substitutes the LaTeX form of @arg[i]@ for @%i@ in the string and returns the resulting string. Occurances of @%0@ are replaced by @`aim/LaTeX`(args)@.
+ ",
+ proc(S::string)
+ local SS;
+ subs(SS=S,
+ proc()
+ local d;
+ `Util/PercentSubs`(SS,seq(TeX(args[d]),d=1..nargs));
+ end);
+ end
+ ):
+ # END KM
######################################################################
|