MCtools (June 8, 2002)
This package can be used (and we will use) to format problems using MCtools[tagit].
To use it, open up the section, put your cursor on the top red line and press enter. Then close the section.
>
MCtools:=table([]):
vers:="6/8/02";
readlib(spline):
>
MCtools[mcprint]:= proc()
local fmt,fmtnl,ARGS,c;
c:=proc(g) convert(g,string) end:
ARGS:=map(c,[args]):
fmt := "%s";
fmtnl:="%s\n":
printf(cat(seq(fmt,i=1..nargs-1),fmtnl),seq(ARGS[j],j=1..nargs));
end:
MCtools[PARAMS]:=proc(Defaults,Args)
local Ndefs,Nargs,In_args,j,k,Not_in_args,PLOTOPTIONS,Nopts,In_PLOTOPTIONS,ARGS,NARGS,In_ARGS:
PLOTOPTIONS:=[adaptive,axes,axesfont,color,coords,discont,filled,font,labels,labeldirections,labelfont,legend,linestyle,numpoints,resolution,sample,scaling,style,symbol,symbolsize,thickness,tickmarks,title,titlefont,view,xtickmarks]:
Nargs:=nops(Args):
Ndefs:=nops(Defaults):
Nopts:=nops(PLOTOPTIONS):
In_PLOTOPTIONS:=NULL:
for j from 1 to Nargs do
for k from 1 to Nopts do
if convert(lhs(Args[j]),string) = convert(PLOTOPTIONS[k],string) then In_PLOTOPTIONS:=In_PLOTOPTIONS,Args[j]:fi:
od:
od:
ARGS:=[op({op(Args)} minus {In_PLOTOPTIONS})]:
NARGS:=nops(ARGS):
In_ARGS:=NULL:
for j from 1 to NARGS do
for k from 1 to Ndefs do
if convert(lhs(ARGS[j]),string) = convert(lhs(Defaults[k]),string) then In_ARGS:=In_ARGS,Defaults[k]:fi:
od:
od:
Not_in_args:=[op({op(Defaults)} minus {In_ARGS})]:
[op(ARGS),op(Not_in_args)],[In_PLOTOPTIONS]:
end:
MCtools[PT]:= proc(LOCATION,TXT)
local Args,defaults,ARGS,FONTSIZE,CLR,PLOTOPTIONS:
defaults:=location=[0,0], fontsize=14,clr=black:
Args:=seq([args][j],j=3..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args])[1]:
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[Args])[2]):
FONTSIZE:=subs(ARGS,fontsize):
CLR:=subs(ARGS,clr):
if nops(LOCATION)=3 then
plots[textplot3d]([LOCATION[1],LOCATION[2],LOCATION[3],TXT],font=[TIMES,ROMAN,FONTSIZE], color=CLR,PLOTOPTIONS)
else
plots[textplot]([LOCATION[1],LOCATION[2],TXT],font=[TIMES,ROMAN,FONTSIZE], color=CLR,PLOTOPTIONS)
fi:
end:
MCtools[colors] := proc()
local Showthem,CLRS, SIZE, STEP, colorlist, i, ARGS, defaults:
defaults:=showthem=`no`:
ARGS:=PARAMS([defaults],[args]):
Showthem:=subs(ARGS,showthem):
MCtools[mcprint]("aquamarine black, blue navy, coral, cyan, brown, gold, green, gray, grey, khaki, magenta, maroon, orange, pink, plum, red, sienna, tan,turquoise, violet, wheat, white, yellow.");
MCtools[mcprint](" "):
MCtools[mcprint]("In addition one can define colors. See help on \"plot,color\". "):
colorlist:=[black, blue, navy, coral, cyan, brown, gold, green, gray, grey, khaki, magenta, maroon, orange, pink, plum, red, sienna, tan, turquoise, violet, wheat, white, yellow]:
if Showthem=`yes` then
SIZE:=16:
STEP:=6:
CLRS:=NULL:
for i from 1 to nops(colorlist) do
CLRS:=CLRS,MCtools[PT]([0,i*STEP],cat(`This is `, colorlist[i]), fontsize=16,clr =colorlist[i]):
plots[display](CLRS,axes=none):
od:
fi:
end:
MCtools[DL]:=proc(A,B)
local Thknss,Styl,Clr,ARGS,defaults,Args,lsf,rsf,TMP,Hashlocation,Hashnum,lngth,Hashspacing,prp,midpt,hashmarks,Hashlength,PLOTOPTIONS:
defaults:=thknss=2,styl=1,clr=blue,rightshrinkfactor=0,leftshrinkfactor=0,hashnum=0,hashlength=.3,hashlocation=.5,hashspacing=.1:
Args:=seq([args][i],i=3..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args])[1]:
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[Args])[2]):
Thknss:=subs(ARGS,thknss):
Styl:=subs(ARGS,styl):
Clr:=subs(ARGS,clr):
lsf:=subs(ARGS,leftshrinkfactor):
rsf:=subs(ARGS,rightshrinkfactor):
Hashnum:=subs(ARGS,hashnum):
Hashlocation:=subs(ARGS,hashlocation):
Hashspacing:=subs(ARGS,hashspacing):
Hashlength:=subs(ARGS,hashlength):
if
nops(A) =3 and nops(B)=3
then
TMP:=plots[polygonplot3d]([(1-lsf)*A+lsf*B,rsf*A+(1-rsf)*B],style = LINE, linestyle=Styl,thickness=Thknss,color=Clr,PLOTOPTIONS):
plots[display]([TMP]):
elif
nops(A) =2 and nops(B)=2
then
prp:= expand(B-A):
lngth:=evalf(1/sqrt(prp[1]^2+prp[2]^2)):
prp:=expand(lngth*[prp[2],-prp[1]]):
midpt:=expand(.5*(A+B)):
if ((Hashnum mod 2) = 0) then
hashmarks:= seq(plots[polygonplot](
[A+(Hashlocation-(Hashnum/2-1)*Hashspacing/2 +j*Hashspacing)*(B-A) - .5*Hashlength*prp,A+(Hashlocation-(Hashnum/2-1)*Hashspacing/2+j*Hashspacing)*(B-A) + .5*Hashlength*prp],linestyle=1,thickness=1,color=black),j=0..Hashnum-1):elif
((Hashnum mod 2) = 1) then
hashmarks:= seq(plots[polygonplot](
[A+(Hashlocation+j*Hashspacing)*(B-A) - .5*Hashlength*prp,A+(Hashlocation+j*Hashspacing)*(B-A) + .5*Hashlength*prp],linestyle=1,thickness=1,color=black),j=-(Hashnum-1)/2..(Hashnum-1)/2):
fi:
TMP:=plots[polygonplot]([(1-lsf)*A+lsf*B,rsf*A+(1-rsf)*B],style = LINE, linestyle=Styl,thickness=Thknss,color=Clr,PLOTOPTIONS):
plots[display]([TMP,hashmarks]):
else RETURN(`bad data`)
fi:
end:
MCtools[GP]:=proc()
local V,H,axes,i,LLcorner,Width,Height,TMFont,Res,Defaults,Axescolor,ARGS,defaults,PLOTOPTIONS:
defaults:=llcorner=[-5,-5],width=10,height=10,resolution=2,tickmarkfont=12,axescolor=red:
ARGS:=MCtools[PARAMS]([defaults],[args])[1]:
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[args])[2]):
LLcorner:=subs(ARGS,llcorner):
Width:=subs(ARGS,width):
Height:=subs(ARGS,height):
Res:=subs(ARGS,resolution):
TMFont:=subs(ARGS,tickmarkfont):
Axescolor:=subs(ARGS,axescolor):
V := seq(plot([[LLcorner[1]+i/Res,
LLcorner[2]],[LLcorner[1]+i/Res,LLcorner[2]+Height]],
color=black,PLOTOPTIONS),i=0..Width*Res):
axes:=MCtools[DL]([LLcorner[1],0],[LLcorner[1]+Width,0],thknss=3,styl=1,clr=Axescolor),MCtools[DL]([0,LLcorner[2]],[0,LLcorner[2]+Height],thknss=3,styl=1,clr=Axescolor):
>
H :=seq(plot([[LLcorner[1] ,LLcorner[2]+i/Res],
[LLcorner[1]+Width,LLcorner[2]+i/Res]],color=black),
i=0..Height*Res):
if TMFont=`NTM` then
plots[display]([V,H],xtickmarks =[], ytickmarks =[]):
elif
TMFont=0 then
plots[display]([V,H],xtickmarks =[], ytickmarks =[],axes=none):
else
plots[display]([axes,V,H], xtickmarks =[seq(i, i=LLcorner[1]..LLcorner[1]+Width)], ytickmarks =
[seq(i, i=LLcorner[2]..LLcorner[2]+Height)], axesfont=[TIMES,BOLD,TMFont]):
fi:
end:
MCtools[GP2]:=proc()
local Args,ARGS,defaults,vals,V, H, i,gopts;
defaults:=llhc = [-5,-5],width=10,height=10,xres=1,yres=1,clrs=[black,black],xlabl=`x`, ylabl=`y`,TMfont=NTM,thkns=[1,1]:
Args:=[llhc, width, height, xres,yres,clrs,xlabl,ylabl, TMfont,thkns];
ARGS:=MCtools[PARAMS]([defaults],[args]):
vals := subs(ARGS[1],Args);
gopts:=op(ARGS[2]);
V := plot([seq(
[[vals[1][1] + i*vals[4], vals[1][2]], [vals[1][1] + i*vals[4], vals[1][2] + vals[3]]],
i = 0 .. vals[2]/vals[4])],color = vals[6][1],thickness=vals[10][1]);
H := plot([seq(
[[vals[1][1], vals[1][2] + i*vals[5]], [vals[1][1] + vals[2], vals[1][2] + i*vals[5]]],
i = 0 .. vals[3]/vals[5])],color = vals[6][2],thickness=vals[10][2]);
if TMfont = NTM then plots[display]([V, H],xtickmarks = [seq(vals[1][1]+i*vals[4],i=0..vals[2]/vals[4])], ytickmarks = [seq(vals[1][2]+i*vals[5],i=0..vals[3]/vals[4])],gopts)
elif TMfont = 0 then plots[display]([V, H], xtickmarks = [], ytickmarks = [], axes = none,gopts)
else plots[display]([V, H],labels=[vals[7],vals[8]], xtickmarks = [seq(vals[1][1]+i*vals[4],i=0..vals[2]/vals[4])], ytickmarks = [seq(vals[1][2]+i*vals[5],i=0..vals[3]/vals[5])],
axesfont = [TIMES, BOLD, vals[9]],
labelfont=[TIMES,BOLD,vals[9]],gopts)
fi
end:
MCtools[GP3]:=proc()
local Args,ARGS,defaults,vals,V, H, K, i,j,levs,verts,gopts;
defaults:=llhc= [0,0,0],width=10,height=10,depth= 10, xres=10/3,yres=10/3, zres = 10/3,
clrs =[black,red,blue],xlabl=`x`, ylabl=`y`,zlabl = `z`, TMfont=NTM,thkns=[1,1,1]:
Args:=[llhc, width, height,depth, xres,yres,zres,clrs,xlabl,ylabl, zlabl,TMfont,thkns];
ARGS:=MCtools[PARAMS]([defaults],[args]):
vals := subs(ARGS[1],Args);
gopts:=op(ARGS[2]);
levs := NULL:
for j from 0 to vals[4]/vals[7] do
levs := levs, seq(
[[vals[1][1] + i*vals[5], vals[1][2],vals[1][3]+j*vals[7]], [vals[1][1] + i*vals[5], vals[1][2] + vals[3],vals[1][3]+j*vals[7]]],
i = 0 .. vals[2]/vals[5]) :
>
od:
V := plots[polygonplot3d]({levs},style=wireframe,color = vals[8][1],thickness=vals[13][1]);
levs := NULL:
for j from 0 to vals[4]/vals[7] do
levs := levs, seq(
[[vals[1][1], vals[1][2] + i*vals[6] ,vals[1][3]+j*vals[7]], [vals[1][1] + vals[2], vals[1][2] + i*vals[6],vals[1][3]+j*vals[7]]],
i = 0 .. vals[3]/vals[6]) :
>
od:
H := plots[polygonplot3d]({levs},style=wireframe,color = vals[8][2],thickness=vals[13][2]);
verts := NULL:
for i from 0 to vals[2]/vals[5] do for j from 0 to vals[3]/vals[6] do
verts := verts,[[vals[1][1]+i*vals[5],vals[1][2]+j*vals[6],vals[1][3]],
[vals[1][1]+i*vals[5],vals[1][2]+j*vals[6],vals[1][3]+vals[4]]]:
K := plots[polygonplot3d]({verts},style=wireframe,color = vals[8][3],thickness=vals[13][3]) od od;
if vals[12] = NTM then plots[display]([V, H,K], tickmarks = map(round,[vals[2]/vals[5], vals[3]/vals[6], vals[4]/vals[7]]),axes=normal,gopts)
elif vals[12] = 0 then plots[display]([V, H,K],axes = none,gops)
else plots[display]([V, H,K],labels=[vals[9],vals[10],vals[11]],
tickmarks = [vals[2]/vals[5], vals[3]/vals[6], vals[4]/vals[7]] ,
axesfont = [TIMES, BOLD, vals[12]],
labelfont=[TIMES,BOLD,vals[12]],axes=normal,gopts)
fi
end:
>
MCtools[MM] := proc()
local Args,ARGS,defaults,vals,f,step,gopts,x,i;
f := proc(t) plot((x/t)^2,x=-1..1) end;
defaults:=partslist=f,tinter=[1,2],numframes=5,speed=1;
Args:=[partslist,tinter,numframes,speed];
ARGS:=MCtools[PARAMS]([defaults],[args]):
vals := subs(ARGS[1],Args);
step := (vals[2][2]-vals[2][1])/(vals[3]-1):
gopts :=insequence=true,scaling=constrained,op(ARGS[2]);
plots[display]([seq(plots[display](
vals[1](vals[2][1]+floor(i/vals[4])*step)),i=0..vals[4]*(vals[3]-1))],gopts)
end:
>
MCtools[PP]:=proc(Location,Radius)
local Args,f,defaults,ARGS,Clr,sf,PLOTOPTIONS:
defaults:= clr=blue,scalefactor=1:
Args:=seq([args][j],j=3..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args]):
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[Args])[2]):
Clr:=subs(ARGS,clr):
sf:=subs(ARGS,scalefactor):
f:=plottools[transform]((x,y)->
[Location[1]+x,Location[2]+y*sf]):
plots[display](f(plottools[disk]([0,0],Radius,color=Clr,PLOTOPTIONS)))
end:
MCtools[ARRW]:=proc()
local Dhgap,Length,Doublearrowtxt,Fontsize,Txtclr,TXT,TMP,Arrowtype,Tail,Head,Headwidth,Headlength,Shaftthickness,Clr,defaults,ARGS,PLOTOPTIONS:
defaults:=tail=[0,0],head=[1,2],headwidth=3,headlength=4,shaftthickness=.03,clr=green,arrowtype=`DH`,doublearrowtxt="texthere",fontsize=16,txtclr=black,dhgap=1/3:
ARGS:=MCtools[PARAMS]([defaults],[args]):
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[args])[2]):
Tail:=subs(ARGS,tail):
Head:=subs(ARGS,head):
Headwidth:=subs(ARGS,headwidth):
Headlength:=subs(ARGS,headlength):
Shaftthickness:=subs(ARGS,shaftthickness):
Clr:=subs(ARGS,clr):
Arrowtype:=subs(ARGS,arrowtype):
Doublearrowtxt:=subs(ARGS,doublearrowtxt):
Fontsize:=subs(ARGS,fontsize):
Txtclr:=subs(ARGS,txtclr):
Dhgap:=subs(ARGS,dhgap):
Length:=sqrt((Head-Tail)[1]^2 +(Head-Tail)[2]^2):
TXT:=MCtools[PT](.5*(Head+Tail),Doublearrowtxt,fontsize=Fontsize,clr=Txtclr,PLOTOPTIONS):
if (Arrowtype = `SH`) then
TMP:=plottools[arrow](Tail,Head,Shaftthickness*Length,Headwidth*Length*Shaftthickness,Headlength*Length*Shaftthickness,color=Clr,PLOTOPTIONS):
elif (Arrowtype = `DH`) then
TMP:=
plottools[arrow](Tail+(1-Dhgap)/2*(Head-Tail),Tail,Shaftthickness*Length,
Headwidth*Length*Shaftthickness,Headlength*Length*Shaftthickness,color=Clr,PLOTOPTIONS),
plottools[arrow](Head+(1-Dhgap)/2*(Tail-Head),Head,Shaftthickness*Length,Headwidth*Length*Shaftthickness,Headlength*Length*Shaftthickness,color=Clr,PLOTOPTIONS):
fi:
plots[display]([TMP,TXT]);
end:
MCtools[CARR] := proc()
local Args,ARGS,defaults,vals,gopts,f,k,i,j,n,di,len,radi,x,y,z,band, z0, z1, dir, A, B, C, d;
f := proc(t) plot((x/t)^2,x=-1..1) end;
defaults:=pts=[[0,0,0],[1,0,0],[1,1,0],[1,1,1]],clr=gray,rad=.02,
hdlen=.2,hdwid=.1,spltp=[cubic,cubic,cubic],mesh=8;
Args:=[pts,clr,rad,hdlen,hdwid,spltp,mesh];
ARGS:=MCtools[PARAMS]([defaults],[args]):
vals := subs(ARGS[1],Args);
gopts:=op(ARGS[2]);
n := nops(vals[1]);
di := nops(vals[1][1]);
if di = 3 then
len := 0:
for i from 2 to n do
len := len+ evalf(sqrt(sum((vals[1][i][j]-vals[1][i-1][j])^2,j=1..di))) od:
x := unapply(spline([seq(i,i=0..n-1)],
[seq(vals[1][i][1],i=1..n)],t,vals[6][1]),t):
y := unapply(spline([seq(i,i=0..n-1)],
[seq(vals[1][i][2],i=1..n)],t,vals[6][2]),t):
z := unapply(spline([seq(i,i=0..n-1)],
[seq(vals[1][i][3],i=1..n)],t,vals[6][3]),t):
k:=floor((1.-vals[4])*(n-1.));
radi := unapply(spline([seq(i,i=0..k-2),k-.01,k,n-1],[seq(vals[3]*len,i=0..k-1),vals[5]*len,0],t,linear),t);
plots[tubeplot]([x(t),y(t),z(t)],t=0..n-1,radius=radi(t),color=vals[2],gopts)
else
len := 0:
for i from 2 to n do
len := len+ evalf(sqrt(sum((vals[1][i][j]-vals[1][i-1][j])^2,j=1..di))) od:
x := unapply(spline([seq(i,i=0..n-1)],
[seq(vals[1][i][1],i=1..n)],t,vals[6][1]),t):
y := unapply(spline([seq(i,i=0..n-1)],
[seq(vals[1][i][2],i=1..n)],t,vals[6][2]),t):
k:=floor((1.-vals[4])*(n-1.));
band := NULL:
z0 := x(0)+I*y(0):z1 := x(1./vals[7])+I*y(1./vals[7]);
dir := evalf(evalc((z1-z0)/abs(z1-z0)));
A := evalc(z0+I*vals[3]*dir): B := evalc(z0-I*vals[3]*dir):
A := [Re(A),Im(A)]: B:= [Re(B),Im(B)]:
for i from 2 to vals[7]*(k) do
z0 := z1: z1 := x(i/vals[7])+I*y(i/vals[7]);
dir := evalf(evalc((z1-z0)/abs(z1-z0)));
C := evalc(z0+I*vals[3]*dir): d := evalc(z0-I*vals[3]*dir):
C := [Re(C),Im(C)]: d := [Re(d),Im(d)]:
band := band,[A,B,d,C];
A := C: B := d;
od:
for i from k*vals[7]+1 to (n-1)*vals[7] do
z0 := z1: z1 := x(1.*i/vals[7])+I*y(1.*i/vals[7]);
dir := evalf(evalc((z1-z0)/abs(z1-z0)));
C := evalc(z0+I*vals[5]*(n-1-i/vals[7])/(n-1-k)*dir):
d := evalc(z0-I*vals[5]*(n-1-i/vals[7])/(n-1-k)*dir):
C := [Re(C),Im(C)]: d := [Re(d),Im(d)]:
band := band,[A,B,d,C];
A := C: B := d;
od:
plots[polygonplot]({band},color=vals[2]);
fi;
end:
MCtools[DV]:=proc()
local Args,ARGS,defaults,vals,len,tang,nor,mid,plts;
defaults:=tail=[0,0],head=[2,2],clr=black,name=``;
Args:=[tail,head,clr,name];
ARGS:=MCtools[PARAMS]([defaults],[args]):
vals := subs(ARGS[1],Args);
plts := MCtools[ARRW](head=vals[1],tail=vals[2],clr=vals[3],arrowtype=SH,doublearrowtxt=""):
if nops(vals[1]) = 3 then len:= evalf(sqrt((vals[2][3]-vals[1][3])^2+(vals[2][2]-vals[1][2])^2+(vals[2][1]-vals[1][1])^2))
else len:= evalf(sqrt((vals[2][2]-vals[1][2])^2+(vals[2][1]-vals[1][1])^2)) fi;
tang := (vals[2]-vals[1])/len:
if nops(vals[1])=2 then
nor := [-tang[2],tang[1]] else
nor := [-tang[2],tang[1],0] fi;
mid := (vals[1]+3*vals[2])/4 + .07*len*nor;
plts := plts,MCtools[PT](mid,vals[4]);
plots[display]([plts],scaling=constrained)
end:
MCtools[PC]:=proc(Center,Radius)
local Args,Thknss,Styl,Clr,Scalefactor,ARGS,defaults,PLOTOPTIONS:
defaults:=radius=.1, thknss=2, styl=1, clr=black,scalefactor=1:
Args:=seq([args][j],j=3..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args]):
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[Args])[2]):
Thknss:=subs(ARGS,thknss):
Styl :=subs(ARGS,styl):
Clr:=subs(ARGS,clr):
Scalefactor:=subs(ARGS,scalefactor):
plot([t->Center[1]+Radius*cos(t),t->Center[2]+Scalefactor*Radius*sin(t),0..2.*Pi],thickness=Thknss,linestyle=Styl,color=Clr,PLOTOPTIONS):
end:
MCtools[PA]:=proc(Center,Radius,Theta1,Theta2)
local Args,Thknss,Styl,Clr,Scalefactor,ARGS,defaults,PLOTOPTIONS:
defaults:= thknss=2,styl=1, clr=black, scalefactor=1:
Args:=seq([args][j],j=5..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args])[1]:
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[Args])[2]):
Thknss:=subs(ARGS,thknss):
Styl:=subs(ARGS,styl):
Clr:=subs(ARGS,clr):
Scalefactor:=subs(ARGS,scalefactor):
plot([t->Center[1]+Radius*cos(t),t->Center[2]+Scalefactor*Radius*sin(t),evalf(Theta1)..evalf(Theta2)],thickness=Thknss,linestyle=Styl,color=Clr,PLOTOPTIONS): end:
MCtools[roundto]:=proc(x)
local top,j, temp,n,ans,ARGS,defaults,Args,Places:
defaults:=places=3:
Args:=seq([args][j],j=2..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args])[1]:
Places:=subs(ARGS,places):
temp:=evalf(10^(Places)*x):
top:=convert(abs(round(temp)),symbol):
n:=length(top):
if n < Places then ans:=cat(`.`,seq(`0`,j=1..Places-n),top): else
ans:=cat(substring(top,1.. (length(top)-Places)),`.`,substring(top,-Places..-1)):
fi:
if evalf(x)<0 then ans:=cat(`-`,ans): fi:
if (parse(ans)=0) then ans:=cat(`.`,seq(`0`,j=1..Places)): fi:
ans:
end:
MCtools[hashang]:=proc(A,B,C)
local defaults,Args,bas,leg,basang,legang,joe,arcs,Radius,Numhashes,Headthickness,Headlength,Hashspacing,ARGS,PLOTOPTIONS,Arrowhead,ARROWHEAD,Withhead,Clr,Reversehead,Otherway,Fliphead:
defaults:=radius=1,numhashes=3,hashspacing=.1,withhead=`NO`,headthickness=1,headlength=1,clr=black,reversehead=`NO`,otherway=`NO`,fliphead=`NO`:
Args:=seq([args][j],j=4..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args])[1]:
PLOTOPTIONS:=op(MCtools[PARAMS]([defaults],[Args])[2]):
Radius:=subs(ARGS,radius):
Numhashes:=subs(ARGS,numhashes):
Hashspacing:=subs(ARGS,hashspacing):
Headthickness:=subs(ARGS,headthickness):
Headlength:=subs(ARGS,headlength):
Withhead:=subs(ARGS,withhead):
Clr:=subs(ARGS,clr):
Reversehead:=subs(ARGS,reversehead):
Otherway:=subs(ARGS,otherway):
Fliphead:=subs(ARGS,fliphead):
bas:=expand(A-B);leg:=expand(C-B);
basang:=evalf(arctan(bas[2],bas[1])):
legang:=evalf(arctan(leg[2],leg[1])):
if legang<basang then legang:=legang+2*Pi:fi:
if basang<0 then basang:=basang+2*Pi: legang:=legang+2*Pi: fi:
if Otherway<>`NO` then basang:=basang+2*Pi:fi:
if Fliphead<>`NO` then Fliphead:=1 else Fliphead:=-1: fi:
print(1.*basang,1.*legang);
if (Withhead=`NO`) then
arcs:=seq( plot([B[1]+(Radius+j*Hashspacing)*cos(t),B[2]+(Radius+j*Hashspacing)*sin(t), t = legang..basang],thickness=1,color=black,PLOTOPTIONS),j=0..Numhashes-1);
plots[display]([arcs]);
elif (Withhead<>`NO`) then
if Reversehead=`NO` then
Arrowhead:=[[B[1]+(Radius)*cos(basang),B[2]+(Radius)*sin(basang)],[B[1]+(Radius-.01*Headthickness)*cos(basang-.01*Fliphead*Headlength),B[2]+(Radius-.01*Headthickness)*sin(basang-.01*Fliphead*Headlength)],[B[1]+(Radius+.01*Headthickness)*cos(basang-.01*Fliphead*Headlength),B[2]+(Radius+.01*Headthickness)*sin(basang-.01*Fliphead*Headlength)]]:
arcs:=plot([B[1]+(Radius)*cos(t),B[2]+(Radius)*sin(t), t = legang..basang],thickness=1,color=Clr,PLOTOPTIONS):
ARROWHEAD:=plots[polygonplot](Arrowhead,color=Clr,style=patchnogrid,PLOTOPTIONS):
plots[display]([ARROWHEAD,arcs]):
elif
Reversehead<>`NO` then
Arrowhead:=[[B[1]+(Radius)*cos(legang),B[2]+(Radius)*sin(legang)],[B[1]+(Radius-.01*Headthickness)*cos(legang-.01*Fliphead*Headlength),B[2]+(Radius-.01*Headthickness)*sin(legang-.01*Fliphead*Headlength)],[B[1]+(Radius+.01*Headthickness)*cos(legang-.01*Fliphead*Headlength),B[2]+(Radius+.01*Headthickness)*sin(legang-.01*Fliphead*Headlength)]]:
arcs:=plot([B[1]+(Radius)*cos(t),B[2]+(Radius)*sin(t), t = legang..basang],thickness=1,color=Clr,PLOTOPTIONS):
ARROWHEAD:=plots[polygonplot](Arrowhead,color=Clr,style=patchnogrid,PLOTOPTIONS):
plots[display]([ARROWHEAD,arcs]):
fi:
fi:
end:
MCtools[RANDANS]:=proc(answers)
local Answerstyle,ANSWERS, ANS_TAG,ANS,answer,RNDANS,i,j,letters,defaults,Args,ARGS,Choices,Rightans,Ansform,NUMCHOICES,TMP_anstag,TMP_mcans,ANSWERCODE,k:
ANSWERS:=[seq(convert(answers[i],string),i=1..nops(answers))]:
letters:=["A","B","C","D","E","F","G","H","I","J","K","L","M"]:
defaults:=rightans=1,choices=letters,answerstyle=mulchoice_labeled:
Args:=seq([args][j],j=2..nargs):
ARGS:=MCtools[PARAMS]([defaults],[Args])[1]:
Choices:=subs(ARGS,choices):
Rightans:=subs(ARGS,rightans):
Answerstyle:=subs(ARGS,answerstyle):
Choices:=[seq(Choices[i],i=1..nops(ANSWERS))]:
NUMCHOICES:=nops(Choices):
ANS := [seq((ANSWERS[i]),i = 1 .. nops(Choices))];
if (nops([op({op(ANS)})]) < NUMCHOICES) then print("Warning: Duplicate Answer") fi;
RNDANS := combinat[randperm](ANS);
TMP_anstag:=NULL:
for i from 1 to NUMCHOICES-1 do
TMP_anstag:=TMP_anstag,cat(RNDANS[1],";"):
od:
TMP_anstag:=cat(TMP_anstag,RNDANS[NUMCHOICES]):
TMP_anstag:=seq(cat(RNDANS[i],";"),i=1..NUMCHOICES-1):
TMP_anstag:=cat(TMP_anstag,RNDANS[NUMCHOICES]):
TMP_mcans:="NULL":
TMP_mcans:=cat(Choices[1],". "),RNDANS[1]:
for i from 2 to NUMCHOICES-1 do
TMP_mcans:=TMP_mcans,cat(", ",Choices[i],". "),RNDANS[i]:
od:
TMP_mcans:=TMP_mcans,
cat(", ",Choices[NUMCHOICES],". "),RNDANS[NUMCHOICES]:
TMP_mcans:=cat(TMP_mcans):
if Answerstyle=mulchoice_labeled then
ANSWERCODE:=";":
for i from 1 to nops(ANS) do
if ( nops( [op({RNDANS[i],ANS[1]})]) =1) then
ANSWERCODE:= cat(ANSWERCODE,Choices[i]):
ANS_TAG:=NULL:
for i from 1 to NUMCHOICES-1 do
ANS_TAG:=cat(ANS_TAG,Choices[i],";") od:
ANS_TAG:=cat(ANS_TAG,Choices[NUMCHOICES]):
RETURN([ANSWERCODE,ANS_TAG,TMP_mcans]): fi:
od:
fi:
if Answerstyle<>mulchoice_labeled then
if (Answerstyle=AB) then
ANSWERCODE:=NULL:
for i to NUMCHOICES do
ANSWERCODE:=cat(ANSWERCODE,";"):
for k from 1 to Rightans do
if ( nops( [op({RNDANS[i],ANS[k]})]) =1) then
ANSWERCODE:= cat(ANSWERCODE,RNDANS[i]) fi:
od:
od:
else ANSWERCODE:=cat(";",ANS[1]):
fi:
RETURN([ANSWERCODE,cat(TMP_anstag)]);
fi:
end:
MCtools[Axes]:= proc()
local Args,ARGS,defaults,vals,pl1,pl2,x,y;
defaults:=xrng=[-5,10],yrng=[-5,10],clrs=[blue,blue],thkns=2,head=[.5,.2];
Args:=[xrng,yrng,clrs,thkns,head];
ARGS:=MCtools[PARAMS]([defaults],[args]):
vals := subs(ARGS[1],Args);
x := vals[1]: y := vals[2]:
pl1:=plot({[[x[1],0],[x[2],0]],
[[x[2]-vals[5][1],vals[5][2]],[x[2],0],[x[2]-vals[5][1],-vals[5][2]]]},color=vals[3][1],thickness=vals[4]);pl2:=plot({[[0,y[1]],[0,y[2]]],
[[vals[5][2],y[2]-vals[5][1]],[0,y[2]],[-vals[5][2],y[2]-vals[5][1]]]},color=vals[3][2],thickness=vals[4]);plots[display](pl1,pl2,view=[x[1]..x[2],y[1]..y[2]]) end:
Header := proc(n)
if member(n,{0,1,2,3}) then MCtools[mcprint]("AH_[",n,"]") else MCtools[mcprint]("AH_") fi: NULL
end:
>
generator := proc()
global QMline,probline;
local vals,ARGS,Args,defaults,p,ansline,i,j,ij,k,atype,line,subline,sp,nm,
M,r,c,ah,e,err,anstypes,L,S,cc,ce;
ah := table([]);
ah["0_"]:=0;ah["1_"]:=1;ah["2_"]:=2;ah["3_"]:=3;
defaults:=brks=0,hidden=no,pretext=none,
problem=[["What is 2 + 3?"],plots[display]([plottools[disk]([0,0],4,color=yellow),MCtools[PT]([0,0],"2 + 3 = ?",clr=magenta,fontsize=24,font=[TIMES,BOLD,24],axes=none)]),matrix([[`two plus three equals what`]]),["There is only one answer."]],
aftertext=none,
answers=[3,10,9,5],
rightanswers=5,
ansmat=matrix([[1,2]]),
incidmat=matrix([[1,0]]),
Alabels=[A,B,C,D,E,F,G,H],
anstype=radio,
call=only,
txtboxsize=4,
precision=0,
funstuff="3;x;y;z;5;0;1;5;2;3;7;-1;2",
randomize=yes,
matsize=[1,3],
cellcolor=white,
tableoptions="border=0",
Flabels=["color=red","color=red","color=red","color=red","color=red","color=red","color=red","color=red"]; Args:=[problem,answers,brks,rightanswers,Alabels,anstype,pretext,call,hidden,txtboxsize,precision,ansmat,incidmat,funstuff,randomize,aftertext,matsize,cellcolor,tableoptions,Flabels];
for e in [args] do if not member(lhs(e),{op(Args)}) then ERROR("The option ",lhs(e)," is not in the list of options -- check spelling. Current options:",Args); fi od;
ARGS:=MCtools[PARAMS]([defaults],[args]):
vals := subs(ARGS[1],Args);
anstypes:=[numberbox,textbox,wordbox,complex,ungraded,userdefined,tablebox,spreadbox,functionbox,integralbox,mfunctionbox,crossword,radio,selection,checkbox,radiolabelled,radiospread,radiospreadvert,radiospreadhorz,checkboxlabelled,checkboxspread,checkboxspreadvert,checkboxspreadhorz];
if not member(vals[6],{op(anstypes)}) then err:="The anstype ",vals[6]," is not in the list of answer types -- check spelling. Current answer types:",anstypes; ERROR(err) fi ;
if nops({op(vals[2][1..-1])}) < nops(vals[2][1..-1]) then
print(vals[2][1..-1]); ERROR("duplicate answers.") fi;
if vals[15]=yes then
p := combinat[randperm]([seq(i,i=1..nops(vals[2]))]) else p := [seq(i,i=1..nops(vals[2]))] fi;
if member(vals[8],{first,only}) then QMline:= NULL fi;
if vals[6]=textbox or vals[6]=numberbox then
ansline:="AC_[",convert(vals[10],string),"]";
QMline:=QMline,";",convert(vals[4],string);
fi;
if vals[6]=complex then
ansline:="AC_[",convert(vals[10],string),"]\n + i\nAC_[",convert(vals[10],string),"]";
QMline:=QMline,";",convert(Re(vals[4]),string),";",convert(Im(vals[4]),string)
fi;
if vals[6]=wordbox then
ansline:="AW_[",convert(vals[10],string),"]";
QMline:=QMline,";",convert(vals[4],string);
fi;
if vals[6]=ungraded then
if vals[8] <> only then ERROR("questions with ungraded answers must occur alone.") fi;
ansline:="AX_[",convert(vals[10],string),"]";
QMline:=QMline,";Your answer will be mailed to the teacher.";
fi;
if vals[6]=userdefined then
ansline:=vals[2]; QMline:= QMline,vals[4] fi;
if vals[6] = tablebox or vals[6]=spreadbox or vals[6]=crossword then
M := (vals[12]);
r := linalg[rowdim](M);
c := linalg[coldim](M);
if linalg[rowdim](vals[13])<>r or linalg[coldim](vals[13])<>c then ERROR(print(ansmat=vals[12],incidmat=vals[13]),"The dimensions of ansmat and incidmat are unequal") fi;
if not vals[6]=crossword then
ansline:="AT_[",vals[10],";",r,";",c;
for i from 1 to r do for j from 1 to c do
if vals[13][i,j]=1 then
QMline := QMline,";",M[i,j] ;
if vals[6]=tablebox then M[i,j]:=NULL else M[i,j] := AC_[vals[10]] fi fi;
ansline:=ansline,";",M[i,j];
od od;
ansline:=ansline,"]";
else
ansline:=["lt_table ",vals[19]," gt_"];
for i from 1 to r do
ansline:=ansline,["tr_"];
for j from 1 to c do
cc := vals[18]:
if vals[13][i,j]=1 and member(nops(M[i,j]),{3,4}) then
if nops(M[i,j])=4 then cc := M[i,j][4] fi:
ansline:=ansline,["lt_td bgcolor=",cc," gt_\nA",M[i,j][1],"_[",M[i,j][2],"]"];
QMline:=QMline,";",M[i,j][3];
elif member(nops(M[i,j]),{1,2}) then
ce := M[i,j][1]:
if nops(M[i,j])=2 then cc := M[i,j][2] fi:
if type(M[i,j][1],string) then ce:= [M[i,j][1]] fi;
ansline:= ansline,["lt_td bgcolor=",cc," gt_"], ce
else ERROR("Cell ",[i,j]," has an error.")
fi;
ansline:=ansline,[" dt_"];
od;
ansline:=ansline,["rt_ "];
od;
ansline:=ansline,["lt_/table gt_ "];
fi;
fi;
if vals[6]=functionbox then
QMline := QMline,";",vals[4]; ansline:="AF_[",vals[10],";",vals[14][1],";",vals[14][2],";",vals[14][3],";",vals[14][4],"]";
fi;
if vals[6]=integralbox then
QMline := QMline,";",vals[4]; ansline:="AI_[",vals[10],";",vals[14][1],";",vals[14][2],";",vals[14][3],";",vals[14][4],"]";
fi;
if vals[6]=mfunctionbox then
QMline := QMline,";",vals[4];
ansline:="AE_[",vals[10],";",vals[14],"]";
fi;
if member(vals[6],{checkboxspread,radio,selection,checkbox, radiospread,checkboxspreadvert,checkboxspreadhorz,radiospreadvert,radiospreadhorz})
then if type(vals[4],list) then if nops(vals[4]) <> nops(vals[2]) then ERROR(mcprint(answers=vals[2],"\n",rightanswers=vals[4]),"the list of rightanswers must be the same length as the list of answers") fi fi fi;
if member(vals[6],{radiospread,checkboxspread,radiolabelled,checkboxlabelled}) and
nops(vals[5])<nops(vals[2]) then ERROR("Need more labels") fi;
if vals[6]=radio or vals[6]=selection then
if vals[6]=radio then atype := L else atype:=S fi;
ansline:="A",atype,"_[",convert(vals[2][p[1]],string);
for i from 2 to nops(vals[2]) do
ansline:= ansline,";",convert(vals[2][p[i]],string) od:
ansline:=ansline,"]";
if type(vals[4],list) then for i from 1 to nops(vals[4]) do
if vals[4][p[i]]=1 then QMline:=QMline,";",convert(vals[2][p[i]],string) fi od
else QMline:=QMline,";",convert(vals[4],string) fi;
fi;
if vals[6]=checkbox then atype:=B;
ansline:="A",atype,"_[",convert(vals[2][p[1]],string);
if vals[4][p[1]]=1 then
QMline:=QMline,";",convert(vals[2][p[1]],string)
else QMline:=QMline,";" fi;
for i from 2 to nops(vals[2]) do
ansline:= ansline,";",convert(vals[2][p[i]],string);
if vals[4][p[i]]=1 then
QMline:=QMline,";",convert(vals[2][p[i]],string)
else QMline:=QMline,";" fi;
od;
ansline:=ansline,"]";
fi;
if vals[6]=radiolabelled then
atype:=L;
sp := " spc_ ":
line :=["lt_table gt_tr_ lt_td ",vals[20][1][1]," gt_ lt_font ",
vals[20][1][2] ," gt_ ",vals[5][1],". amp_nbsp lt_/font gt_dt_td_"],
vals[2][p[1]],[" dt_"]; ansline:="A",atype,"_[",convert(vals[5][1],string);
for i from 2 to nops(vals[2]) do ansline:= ansline,";",convert(vals[5][i],string);
if iquo(i,vals[17][2])>0 and irem(i,vals[17][2])=1 then line:=line,["tr_rt_"] fi:
line:= line,["lt_td ",vals[20][1][1]," gt_ lt_font ",
vals[20][1][2] ," gt_ ",vals[5][i],". amp_nbsp lt_/font gt_dt_td_"],
vals[2][p[i]],["dt_"] od:
line := line,["rt_lt_/table gt_"];
ansline := line,["\n"],[ansline,"]"];
if type(vals[4],list) then for i from 1 to nops(vals[4]) do
if vals[4][p[i]]=1 then QMline:=QMline,";",convert(vals[5][i],string) fi od
else
for i from 1 to nops(vals[2]) do
if convert(vals[4],string)=convert(vals[2][p[i]],string) then QMline:=QMline,";",convert(vals[5][i],string) fi;
od fi
fi;
if vals[6]=radiospreadvert or vals[6] = radiospreadhorz then
atype:=L;
line:=NULL;
if type(vals[4],list) then for i from 1 to nops(vals[4]) do
if vals[4][p[i]]=1 then QMline:=QMline,";",convert(vals[5][i],string) fi od
else
for i from 1 to nops(vals[2]) do
if convert(vals[4],string)=convert(vals[2][p[i]],string) then QMline:=QMline,";",convert(vals[5][i],string) fi;
od fi;
if vals[6]=radiospreadvert then
line:= [convert(cat(vals[5][1],"."),symbol),vals[2][p[1]]]
else line := convert(cat(vals[5][1],"."),symbol),vals[2][p[1]] fi; ansline:="A",atype,"_[",convert(vals[5][1],string);
for i from 2 to nops(vals[2]) do
ansline:= ansline,";",convert(vals[5][i],string);
if vals[6]=radiospreadvert then
line:= line,[convert(cat(vals[5][i],"."),symbol),vals[2][p[i]]] else line := line, convert(cat(vals[5][i],"."),symbol),vals[2][p[i]] fi;
od:
ansline:=ansline,"]";
fi;
if vals[6]=checkboxlabelled then
atype:=B;
sp := " spc_ ":
line := vals[5][1],".",sp,vals[2][p[1]];
ansline:="A",atype,"_[",convert(vals[5][1],string);
if vals[4][p[1]]=1 then
QMline:=QMline,";",convert(vals[5][1],string)
else QMline:=QMline,";" fi;
for i from 2 to nops(vals[2]) do
if vals[4][p[i]]=1 then
QMline:=QMline,";",convert(vals[5][i],string)
else QMline:=QMline,";" fi;
ansline:= ansline,";",convert(vals[5][i],string);
line:= line,sp,vals[5][i],".",sp,vals[2][p[i]] od:
ansline := line,"\n",ansline,"]";
fi;
>
if vals[6]=checkboxspreadvert or vals[6]=checkboxspreadhorz then
atype:=B;
sp := " spc_ ":
if vals[6]=checkboxspreadvert then
line:= [convert(cat(vals[5][1],". "),symbol),vals[2][p[1]]]
else line := convert(cat(vals[5][1],". "),symbol),vals[2][p[1]] fi; ansline:="A",atype,"_[",convert(vals[5][1],string);
if vals[4][p[1]]=1 then
QMline:=QMline,";",convert(vals[5][1],string)
else QMline:=QMline,";" fi;
for i from 2 to nops(vals[2]) do
if vals[4][p[i]]=1 then
QMline:=QMline,";",convert(vals[5][i],string)
else QMline:=QMline,";" fi;
ansline:= ansline,";",convert(vals[5][i],string);
if vals[6]=checkboxspreadvert then
line:= line,[convert(cat(vals[5][i],". "),symbol),vals[2][p[i]]]
else line := line, convert(cat(vals[5][i],". "),symbol),vals[2][p[i]] fi;
od:
ansline:=ansline,"]";
fi;
if vals[6]=checkboxspread or vals[6]=radiospread then
if vals[6] = checkboxspread then atype:=B else atype:=L fi;
line := NULL: nm := vals[17][1]*vals[17][2]:
if nops(vals[2]) > nm then vals[17]:=[1,nops(vals[2])] fi;
for i from 1 to vals[17][1] do
subline := NULL:
for j from 1 to vals[17][2] do
ij := (i-1)*vals[17][2]+j:
if ij <= nops(vals[2]) then
subline:= subline,convert(cat(vals[5][ij],"."),symbol),vals[2][p[ij]]
else subline :=subline,` `,` ` fi;
od;
line := line,[subline]
od;
ansline:="A",atype,"_[",convert(vals[5][1],string);
if vals[4][p[1]]=1 then
QMline:=QMline,";",convert(vals[5][1],string)
elif vals[4][p[1]]=0 and vals[6] = checkboxspread then QMline:=QMline,";" fi;
for i from 2 to nops(vals[2]) do
if vals[4][p[i]]=1 then
QMline:=QMline,";",convert(vals[5][i],string)
elif vals[4][p[i]]=0 and vals[6]=checkboxspread then QMline:=QMline,";" fi;
ansline:= ansline,";",convert(vals[5][i],string);
od:
ansline:=ansline,"]";
fi;
>
if member(vals[3],{0, none,`n`}) then vals[3]:="0_";
elif member(vals[3],{1,after,`a`}) then vals[3]:="1_"
elif member(vals[3],{2,before,`b`}) then vals[3]:="2_"
elif member(vals[3],{3,afterbefore,beforeafter,`ab`,`ba`}) then vals[3]:="3_" fi;
if vals[8] = first or vals[8] = only then
probline := vals[3],op(vals[1]) fi ;
if vals[8] = middle or vals[8] = last then probline := probline,vals[3],op(vals[1]) fi;
>
>
if member(vals[6],{checkboxspread, radiospread,checkboxspreadvert,checkboxspreadhorz,radiospreadvert,radiospreadhorz})
then if member(vals[6],{checkboxspreadhorz,radiospreadhorz}) then
line := matrix([[line]]) else line:= matrix([line]) fi;
probline := probline,line, [ansline,"\n"] ;
elif vals[6] = spreadbox then
probline:=probline,["TABLEOPTIONS_",vals[19],"_"],op(M),["TABLEOPTIONS_border=0_"]
elif vals[6]=crossword or vals[6]=radiolabelled then
probline:=probline,ansline
else
probline:= probline, [ansline] fi;
if vals[16]<>none then probline:=probline,op(vals[16]) fi;
>
>
if vals[8]=last or vals[8] = only then
if vals[7]<>none then MCtools[mcprint]("T_\n");
for i from 1 to nops(vals[7]) do
if type(vals[7][i],list) then MCtools[mcprint](op(vals[7][i]))
elif type(vals[7][i],matrix) then
nm:=cat(jack,convert(rand(),string));
Spread[CreateSpreadsheet](nm);
Spread[SetMatrix](nm,vals[7][i])
else print(vals[7][i]);
fi od;
fi;
QMline:=convert(vals[11],string),QMline;
if vals[6]=ungraded then QMline:="QN_[",QMline
elif vals[9]<>no then QMline:="QM_N[",QMline else QMline:="QM_[",QMline fi;
MCtools[mcprint](QMline,"]\n");
for i from 1 to nops([probline]) do
if member(probline[i],{"0_","1_","2_","3_"}) then MCtools[mcprint]("\nAH_[",ah[probline[i]],"]")
elif probline[i]=NULL then next
elif type(probline[i],list) then MCtools[mcprint](op(probline[i]))
elif type(probline[i],matrix) then
nm:=cat(jack,convert(time(),string),convert(rand(),string));
Spread[CreateSpreadsheet](nm);
Spread[SetMatrix](nm,probline[i])
else print(probline[i]);
fi od;
MCtools[mcprint]("\nSKIP_\n");
QMline:='QMline': probline:='probline':
fi;
RETURN(NULL)
end:
>
>
>
MCtools[tagit] := proc()
local n,i,plist,defaults,retain,clean;
retain:={hidden,precision,anstype,answers,rightanswers,brks,Alabels,txtboxsize,funstuff,randomize,matsize,pretext};
clean := proc(inlist,keepin)
local i,tlist;
tlist := NULL;
for i from 1 to nops(inlist) do
if member(lhs(inlist[i]),{op(keepin)}) then tlist := tlist,inlist[i] fi od;
[tlist] end:
if nargs=0 then
plist:=[problem=[["What is 2 + 3?"]],anstype=textbox,rightanswers=5],
[problem=[["What is 7 - 3?"]],anstype=radio,answers=[4,3,6,2,5],rightanswers=4] else
plist := args fi;
n := nops([plist]);
if n > 1 then
defaults:=plist[1];
generator(op(plist[1]),call=first);
if n > 2 then for i from 2 to n-1 do
defaults:=clean(defaults,retain);
defaults:=PARAMS(defaults,plist[i])[1];
generator(op(defaults),call=middle) od fi;
defaults:=clean(defaults,retain);
defaults:=PARAMS(defaults,plist[n])[1];
generator(op(defaults),call=last)
else
generator(op(plist)) fi;
end:
MCtools[zipit] := proc(infil,path)
local z,Args,vals, zname,hfile,zfile,outfile,cpfile,response,line,n,wqspath,original,orighref,audiohint,wrtohint,bds,mn,nm,mathclass,title,magic,web,tableopts,ARGS,defaults,infile,app,zip,zpath;
infile := infil;
zpath:=StringTools[SubString](path,1..StringTools[FirstFromRight]("/",path)-1);
if StringTools[SubString](infile,-4..-1) = "html" then
original:= StringTools[SubString](infile,1..StringTools[FirstFromLeft](".",infile)-2)
else original := infile; infile := cat(infile,"1.html") fi;
ARGS:=select(type,[args],`=`);
if nargs = 3 and not type(args[3],`=`) then app := args[3] else app:="whs" fi;
defaults:=Zname=cat(original,app),Magic=76,Zip=yes,Webpagezip=no:
Args:=[Magic,Zname,Zip,Webpagezip];
ARGS:=MCtools[PARAMS]([defaults],ARGS):
vals := subs({op(ARGS[1])},Args);
zname:=vals[2]:
zip := vals[3]:
magic := vals[1]:
web := vals[4]:
wrtohint:= "false";
tableopts:="border=0";
outfile:=cat(zname,".html");
orighref := cat("<a href=\"",original);
currentdir(path);
if vals[4]=no then
mcprint(cat("Your files for this homework should be in ",currentdir(),"."));
mathclass :=
cat("<a href=\"https://www.mathclass.org/Homes/",magic,"/hws/",zname,"/");
audiohint :=cat("https://www.mathclass.org/Homes/",magic,"/hws/",zname);
wqspath:=cat(mathclass,original);
else
mcprint(cat("Your files for this webpage should be in ",currentdir(),"."));
mathclass:=cat("<a href=\"http://www.mathclass.org/Homepages/",magic,"/",original);
wqspath:=mathclass;
fi;
try
fopen(infile,READ,TEXT)
catch "file already open":
fclose(infile);
fopen(infile,READ,TEXT);
end try;
try
fopen(outfile,WRITE,TEXT)
catch "file already open":
fclose(outfile);
fopen(outfile,WRITE,TEXT);
end try;
line := readline(infile);
while line <> 0 do
if StringTools[Search]("BEGINHINT_",line)>0 then
bds := StringTools[SearchAll]("_",line);
if nops([bds])<3 then fclose(infile); fclose(outfile); ERROR("Hint problem. close the MCtools section and re-export to html before using zipit."); fi;
hfile:=StringTools[SubString](line,bds[1]+1..bds[2]-1);
title:=StringTools[SubString](line,bds[2]+1..bds[3]-1);
hfile:=cat(hfile,".html");
fopen(hfile,WRITE,TEXT);
writeline(outfile,cat(mathclass,hfile,"\"><p align=left>"));
writeline(outfile,
cat("<b><font color=#000000 size=3>",title,"</font></b>"));
writeline(outfile,"</p></a>");
wrtohint := "true";
line:=readline(infile);
fi;
if StringTools[Search]("ENDHINT_",line)>0 then
fclose(hfile); wrtohint:="false"; line := readline(infile) fi;
if StringTools[Search]("hint.wav",line)>0 then line:=StringTools[Substitute](line,"http:/",audiohint)
else line:=StringTools[Substitute](line,orighref,wqspath) fi;
if StringTools[Search]("TABLEOPTIONS_",line)>0
then bds := StringTools[SearchAll]("_",line);
if nops([bds])=2 then
tableopts:=StringTools[SubString](line,bds[1]+1..bds[2]-1);
line:=StringTools[Substitute](line,cat("TABLEOPTIONS_",StringTools[SubString](line,bds[1]+1..bds[2]))," ") fi;
fi;
line:= StringTools[SubstituteAll](line,"border=1",tableopts);
line:= StringTools[SubstituteAll](line,"spc_"," ");
line:= StringTools[SubstituteAll](line,"lt_","<");
line:= StringTools[SubstituteAll](line,"gt_",">");
line:= StringTools[SubstituteAll](line,"amp_","&");
line:= StringTools[SubstituteAll](line,"cup_","∪");
line:= StringTools[SubstituteAll](line,"cap_","∩");
line:= StringTools[SubstituteAll](line,"sub_","⊂");
line:= StringTools[SubstituteAll](line,"sup_","⊃");
line:= StringTools[SubstituteAll](line,"nsub_","⊄");
line:= StringTools[SubstituteAll](line,"supe_","⊇");
line:= StringTools[SubstituteAll](line,"sube_","⊆");
line:= StringTools[SubstituteAll](line,"isin_","∈");
line:= StringTools[SubstituteAll](line,"notin_","∉");
line:= StringTools[SubstituteAll](line,"ge_","≥");
line:= StringTools[SubstituteAll](line,"le_","≤");
line:= StringTools[SubstituteAll](line,"ni_","∋");
line:= StringTools[SubstituteAll](line,"bld_","<b>");
line:= StringTools[SubstituteAll](line,"dlb_","</b>");
line:= StringTools[SubstituteAll](line,"unl_","<u>");
line:= StringTools[SubstituteAll](line,"lnu_","</u>");
line:= StringTools[SubstituteAll](line,"itl_","<I>");
line:= StringTools[SubstituteAll](line,"lti_","</I>");
line:= StringTools[SubstituteAll](line,"tr_","<tr>");
line:= StringTools[SubstituteAll](line,"rt_","</tr>");
line:= StringTools[SubstituteAll](line,"td_","<td>");
line:= StringTools[SubstituteAll](line,"dt_","</td>");
line:= StringTools[SubstituteAll](line,"up_","<sup>");
line:= StringTools[SubstituteAll](line,"pu_","</sup>");
line:= StringTools[SubstituteAll](line,"dn_","<sub>");
line:= StringTools[SubstituteAll](line,"nd_","</sub>");
line:= StringTools[SubstituteAll](line,"f_red_","<font color=red>");
line:= StringTools[SubstituteAll](line,"f_stp_","</font>");
line:= StringTools[SubstituteAll](line,"<br>"," ");
line:= StringTools[SubstituteAll](line,"<tt>"," ");
line:= StringTools[SubstituteAll](line,"</tt>"," ");
line:= StringTools[SubstituteAll](line,"<pre>"," ");
line:= StringTools[SubstituteAll](line,"</pre>"," ");
if wrtohint = "false" then writeline(outfile,line) else writeline(hfile,line) fi;
line := readline(infile)
od;
fclose(infile); fclose(outfile);
#cpfile := cat("copy ",outfile," ",infile);
#(system(`cpfile`));
if zip=yes then
zfile := file;
zfile :=cat("zip -r ..\\",zname," *");
system(`zfile`);
mcprint(cat("A zipfile ",zname,".zip has been created in ",zpath,". Now install the homework via mathclass"));
else
mcprint(cat("The html file ",zname,".html has been created in ",path,". \nNow zip the files in that directory with the name ",zname,".zip and install the homework on WHS.")) fi:
end:
MCtools[tableit] := proc()
local i,j,r,tbl,tops,cols,lst;
if nargs<1 then ERROR("Need the number of columns and the list of entries") fi;
if type(args[1],integer) then cols:=args[1]: lst:= args[2] else cols := args[2]: lst:=args[1] fi:
r := ceil(nops(lst)/cols);
if nargs>2 then tops:=(args[-1]) else tops:="" fi;
tbl := ["lt_table ",tops," gt_"];
for i from 1 to r do tbl := tbl, [" tr_td_ "] ; for j from 1 to cols do
if j < cols then
if (i-1)*cols+j <= nops(lst) then
tbl := tbl,(lst[(i-1)*cols+j]),[" dt_td_ "] else tbl := tbl,[" dt_td_ "] fi;
else
if (i-1)*cols+j <= nops(lst) then
tbl := tbl,(lst[(i-1)*cols+j]),[" dt_rt_ "] else tbl := tbl,[" dt_rt_ "] fi;
fi od
od;
tbl := tbl,[" lt_/table gt_"];
tbl end:
MCtools[lineit] := proc(lst)
local i,j,cols,tbl,defaults,vals,Args,ARGS;
defaults:=cellfmts=["td_", "td_","td_","td_","td_","td_"],flag="noansend",tops="";
Args:=[cellfmts,flag,tops];
ARGS:=MCtools[PARAMS]([defaults],select(type,[args],equation)):
vals := subs(ARGS[1],Args);
cols := nops(lst);
tbl := ["lt_table ",vals[3]," gt_tr_",vals[1][1]];
for j from 1 to cols-1 do
tbl := tbl,lst[j],[" dt_",vals[1][j+1]] od;
tbl := tbl,lst[cols],[" dt_ "];
if vals[2] = "noansend" then
tbl := tbl,["rt_ lt_/table gt_"] else tbl:=tbl,[" td_ "] fi;
tbl end:
MCtools[addlink] := proc(link,text)
cat("lt_a href=\"http://",link,"\" gt_ ",text," lt_/a gt_lt_/p gt_") end:
MCtools[addsectionhint] := proc(title,text,cols)
local mn,t,nm,bill;
mn:=cat("hint",convert(ceil(rand()+time()),string));
bill:=["\nBEGINHINT_",mn,"_",title,"_"];
bill := bill,tableit(text,cols);
bill:=bill,["ENDHINT_",mn,"_"];
end:
###NOTE THE FOLLOWING MUST BE THE LAST IN THIS EXECUTION GROUP
with(MCtools):
MCtools[mctools]:=proc()
local TMP,txt:
TMP:=with(MCtools);
TMP:=op(sort(with(MCtools))):
mcprint("MCtools, version ",vers,".");
if (args=NULL or nargs>1) then
mcprint(" "):
mcprint("Current choices are ",[TMP],".");
mcprint(" "):
mcprint("\"mctools(X)\" gives syntax and defaults for \"X\""):
mcprint(" "):
RETURN():
fi:
txt:=args[1]:
if
txt =PARAMS then mcprint("PARAMS(Defaults,Args)"):
elif txt =PT then mcprint("PT(Location,txt,fontsize=16,clr=black) ");
elif txt =clors then mcprint(" colors() to see colors use \"colors(showthem = yes)\".");
elif txt = DL then mcprint("DL(A,B,thknss=2, styl=1,clr=blue,leftshrinkfactor=0,rightshrinkfactor=0,hashnum=3,hashlength=.3,hashspacing=.1,hashlocation=.5) ");
elif txt = DV then mcprint("DV(Head=[0,0],Tail=[2,2],Clr=black,name=``)");
elif txt =GP then mcprint("GP(llcorner=[-5,-5], width=10, height=10, resolution=2, tickmarkfont=12, axescolor=red) ");
elif txt=GP2 then mcprint("GP2(llhc = [-5,-5],width=10,height=10,xres=1,yres=1,clrs=[black,black],xlabl=`x`, ylabl=`y`,TMfont=NTM)");
elif txt = GP3 then mcprint("GP3(llhc= [0,0,0],width=10,height=10,depth= 10, xres=10/3,yres=10/3, zres = 10/3, clrs =[black,red,blue],xlabl=`x`, ylabl=`y`,zlabl = `z`, TMfont=NTM)");
elif txt = MM then mcprint("MM(partslist=f,tinter=[1,2],numframes=5,speed=1)");
elif txt =PP then mcprint("PP(location,radius, clr=blue,scalefactor=1) ");
elif txt =ARRW then mcprint("ARRW(tail=[0,0],head=[1,2],headwidth=3,headlength=4,shaftthickness=.03,clr=green,arrowtype=`DH`,doublearrowtxt=\"texthere\",fontsize=16,txtclr=black,dhgap=1/3) ");
elif txt = CARR then mcprint("CARR(pts=[[0,0,0],[1,0,0],[1,1,0],[1,1,1]],clr=gray,rad=.02,hdlen=.2,hdwid=.1,spltp=[cubic,cubic,cubic])\nalso CARR(pts=[[0,0],[1,0],[1.3,1],[1,2]]) gives a 2-d curvilinear arrow.");
elif txt =PC then mcprint("PC(center,radius, thknss=2, styl=1, clr=black,scalefactor=1) ");
elif txt = PA then mcprint("PA(center,radius,theta1,theta2, thknss=3, styl=1, clr=black,scalefactor=1) ");
elif txt = roundto then mcprint("roundto(x,places=3) ");
elif txt =hashang then mcprint("hashang(A,B,C,radius=1,numhashes=3,hashspacing=.1,withhead=`NO`,headthickness=1,headlength=1,clr=black,reversehead=`NO`,otherway=`NO`,fliphead=`NO`) ");
elif txt = RANDANS then mcprint("RANDANS(ANSWERS,rightans=1,choices=letters,answerstyle=mulchoice_labeled)")
elif txt = mfunction then
mcprint("funstuff=\"3;x;y;z;5;0;1;5;2;3;7;-1;2\",rightanswers=x+y+z,precision=0:`.001`")
elif txt = generator or txt=tagit then mcprint("tagit(
[problem=[[\"What is 2 + 3?\"]],anstype=textbox,rightanswers=5],
[problem=[[\"What is 7 - 3?\"]],rightanswers=4]);
The procedure tagit takes a sequence of problems (see just above for a two problem example), and formats a WHS question. Certain options carried over from one part to the next. These options are hidden, precision, anstype,txtboxsize,brks,Alabels,randomize, funstuff,
and matsize.
So each list is a sequence of equations of the form option=stuff, where option is one of the following: (Also see the example above.)
brks=0/n/none:::1/a/after:::2/b/before:::3/ab/afterbefore, #
problem=[[\"What is 2 + 3?\"] #A problem is a list. Each term is a list of strings and expression,or a matrix, or a plot structure
anstype= #14 types, grouped into
multiple choice
radio:::radiolabelled:::radiospread:::selection:::
checkbox:::checkboxlabelled:::checkboxspread::
and data entry
textbox:::wordbox:::tablebox:::spreadbox::
mfunctionbox:::integralbox::crossword,
answers=[3,10,9,5]:::#Use with multiple choice questions
rightanswers=[0,0,0,1]:::#Use with multiple choice questions ansmat=matrix([[1,2]]),#Use with spreadbox
incidmat=matrix([[1,0]])#use with spreadbox
matsize=[1,5]:::#sets the array size of alternatives in checkboxspread or radiospread
Alabels=[A,B,C,D,E,F,G,H]:::[I,II,III] #use with radiolabelled, radiospread,
checkboxlabelled, or checkboxspread
hidden=no:::yes, #right answer is/is not provided on feedback sheet.
txtboxsize=4:::1:::2:::30, #use with data entry answers
precision=0:`.001`,#use with anstype=textbox or spreadbox
funstuff=\"3;x;y;z;5;0;1;2;3;-1;2\" #use this with anstype mfunctionbox
randomize=yes:::no #use with multiple choice anstypes
pretext=none:::[[\"Choose the correct answer\"]], #puts text before the problem number
aftertext=none, #puts text after the answer section of a problem.")
elif txt=Axes then
mcprint("Axes(xrng=[-5,10],yrng=[-5,10],clrs=[blue,blue],thkns=2,head=[.5,.2])")
elif txt=zipit then mcprint("zipit(\"sample\",\"full path to zip file directory\"); where sample.mws is the name of your source worksheet. A modified verison of the file sample1.html is written to samplewhs.html. Then ordinarily
a zipfile named samplewhs.zip is created in the zip file directory, which can then to be installed on mathclass. By setting the option Zip=no, the creation of the zipfile is bypassed.
Two other options:
1. Zname = stuff, the name for your zipfile. By default it it set to samplewhs.
2. Magic=76 is the number that occurs just after Homes in the url that you can read while your mathclass homework is loading. Set this if you have a sectionhint to include.")
elif txt=installit then mcprint("installit(where) where where is the full path to the directory you want MCtools.m put.")
elif txt=javaviewit then mcprint("javaviewit(p,name,where,dir) where p is a plot structure, name is the name of the graphic file, where is the full path to the directory you want to save the graphic file, and dir is the relative path from your public JavaView to the installed graphic file. You can specify this by changing the hard coded public path or setting the option public =\"your path to Javaview/jars\" in your command. Also the dimensions of the javaviewit window can be reset with height=y and width=x in the command.")
elif txt=addlink then mcprint("addlink(url,title), where url is the full path to the hyperlink (except for http://) and title is the text to be clicked. This word is written to be used in the problem=, pretext=, and aftertext= environments, but can be mcprinted outside those environments.")
elif txt=addsectionhint then mcprint("addsectionhint(title,text,cols), where title is the text to be clicked, text is a list of strings (including html tags), maple expressions (including graphics), and matrices (which are exported as spreadsheets). These will be fed to tableit using cols as the number of columns. This word is written to be used in the problem=, pretext=, and aftertext= environments, but can be mcprinted outside those environments.")
elif txt=tableit then mcprint("tableit(list,cols), where list is a list of things to be put in a table with cols columns. tableit is written to be used in problem= or in pretext= (or in aftertext= )")
elif txt=lineit then mcprint("lineit(list), where list is a list of things to be put in a single line. lineit is written to be used in problem= or in pretext= (or in aftertext= )
Optional 2nd or 3rd argument: a string containing the table options: e.g., \"border = 3\"
Optional 2nd argument: \"ansend\" to start an answer cell at the end of the line. The table must be finished by hand")
elif txt=crossword then mcprint("crossword(cols,clrs,prseq),
where cols is the number of columns in your crossword array, clrs is a list of cell colors, and prseq is a sequence of lists that would ordinarily be fed to tagit. Crossword cannot be fed to tagit.")
else mcprint("Sorry that's not in the list.")
fi:
end:
with(MCtools);
>
>
Warning, the names PA, PC and PP have been redefined