(***********************************************************************
This file was generated automatically by the Mathematica front end.
It contains Initialization cells from a Notebook file, which typically
will have the same name as this file except ending in ".nb" instead of
".m".

This file is intended to be loaded into the Mathematica kernel using
the package loading commands Get or Needs.  Doing so is equivalent to
using the Evaluate Initialization Cells menu command in the front end.

DO NOT EDIT THIS FILE.  This entire file is regenerated automatically 
each time the parent Notebook file is saved in the Mathematica front end.
Any changes you make to this file will be overwritten.
***********************************************************************)





(* ICTCM12 - Burlingame, CA, 1999 *)
(* file vdencipher.m: validator for function encipher *)
(* Copyright \[Copyright] 1999 by Murray Eisenberg *)

Begin["special`temp`"]	(* encapsulate whole file *)

(* Check for needed globals *)

vdencipher`check`fname = "encipher";

(* checking myID and fname *)

vdencipher`check`checking::noID = "\nYou forgot to define myID!";
vdencipher`check`checking::badID = 
  "\nmyID must be a string, enclosed in quotes, consisting \
of the digits of your student ID number.";
vdencipher`check`checking::nomainfn = 
  "\nFunction `1` is not yet defined.\nDefine it and all "<>
  "objects it references before trying to validate!";

vdencipher`check`checkingNoID = 
	If[Names["myID"] === {}, True, False];

vdencipher`check`checkingOK =
	If[vdencipher`check`checkingNoID, 
		Message[vdencipher`check`checking::noID]; False,
	If[!StringQ@ToExpression@"myID", 
		Message[vdencipher`check`checking::badID]; False,
	If[(!Apply[And, 
			Map[MemberQ[Characters@"0123456789", #]&, 
				Characters@ToExpression@"myID"]])
		|| (0 == StringLength@ToExpression@"myID"), 
		Message[vdencipher`check`checking::badID]; False, 
	If[!NameQ[vdencipher`check`fname], 
		Message[vdencipher`check`checking::nomainfn, 
			vdencipher`check`fname]; False,
		True
	]]]
];

(* validator package *)

If[vdencipher`check`checkingOK,
	BeginPackage["vdencipher`"]
]

If[vdencipher`check`checkingOK,
	Begin["`Private`"]
]

If[vdencipher`check`checkingOK,
	Print["\nPreparing test data....\n"]
]

(* SETUP AND TEST ... *)

If[vdencipher`check`checkingOK,

(* Names and number of tests *)

fname = vdencipher`check`fname;
othernames = "";
arity = 2;
ntests = 8;

(* PREPARE TEST DATA *)

(* Functions used to generate test data *)

SeedRandom[Floor[0.123456 * 	
	ToExpression@ToExpression@"Global`myID"]];

Options[roll] = {dice \[Rule] 0};
roll[n_Integer?Positive,  opts___?OptionQ] := Module[{k},
	k = dice/.{opts} /. Options[roll];                          
   	If[k == 0, Random[Integer, {1, n}],                    
		Table[Random[Integer, {1, n}], {k}]
	]
];
roll[m_Integer, n_Integer, opts___?OptionQ] := Module[{k},
	k = dice/.{opts} /. Options[roll];                  
    If[k == 0, Random[Integer, {m, n}], 
		Table[Random[Integer, {m, n}],{k}]
	]
];

deal[elts_List, k_] := 
	{elts\[LeftDoubleBracket]roll[Length[elts]]\[RightDoubleBracket]} /; k == 1;

deal[elts_List, k_] := Module[{one= deal[elts, 1]},  
	Join[one, deal[Complement[elts, one], k-1]]
] /; k > 1;

makeRandomModMat[n_, m_] := 
	Mod[Partition[roll[0, m - 1, dice \[Rule] n^2], n], m];

(* Generate test data *)

smalldbase = {"LINEAR ALGEBRAISTS DO IT BASICALLY.",
	"SOME MATRICES ARE ELEMENTARY",
	"PITY THE POOR LEAST SQUARE",
	"SOME DIMENSIONS ARE RANK",
	"HOW CAN A FUNCTION BE A VECTOR?",
	"AMANAPLANACANALPANAMA",
	"SQUARE MATRICES HAVE POWERS",
	"HEY.DIDDLE  DIDDLE",
	"PREVENT CRUELTY TO CASTOUT VECTORS"
};

testdata[i_] :=  {smalldbase\[LeftDoubleBracket]roll[Length@smalldbase]\[RightDoubleBracket],
	makeRandomModMat[{3,5,7,9}\[LeftDoubleBracket]roll[4]\[RightDoubleBracket], 29]} /; 
	MemberQ[{6,7,8}, i];
	
testdata[1] = {"OTTO BRETSCHER WROTE IT",
	makeRandomModMat[5, 29]};

testdata[2] = {"WHEN DID CRAMER RULE?",
	makeRandomModMat[3, 29]};

testdata[3] = {"IFORGOTSPACESHERE",
	makeRandomModMat[2, 29]};

testdata[4] = {" BUT NOT HERE ",
	makeRandomModMat[2, 29]};

testdata[5] = {"SHORT",
	makeRandomModMat[11, 29]};

(* CORRECT VERSION of main function and auxiliary fns *)

(* My function *)

encipher[txt_String, mat_?MatrixQ] := 
	Module[{m = Length[alf], n = Length[mat], i},
	i = matFromVect[numsFromChars[txt], n];
	i = Mod[mat . i, m];
	charsFromNums@vectFromMat[i]
	];	

(* My auxiliary definitions *)

alf = Characters["ABCDEFGHIJKLMNOPQRSTUVWXYZ.? "];

numsFromChars[txt_String] := 
	Flatten@Map[Position[alf, #] - 1&, Characters@txt];

charsFromNums[ints_List] := StringJoin@alf\[LeftDoubleBracket]ints + 1\[RightDoubleBracket];

vectFromMat[mat_?MatrixQ] := Flatten@Transpose[mat];

matFromVect[vect_List, n_Integer?Positive] := 
	Module[{v = vect, r, q},
		r = Mod[Length@v, n]; (* number of entries left over *)
		v = Join[v, Table[Last[v], {Sign[r]*(n - r)}]]; (* pad *)
		q = Length[v] / n;
		Transpose@Partition[v, n]
	];

(* secure my definitions *)

SetAttributes[{encipher, numsFromChars, charsFromNums, vectFromMat, matFromVect, alf}, {ReadProtected}]; 

(* END CORRECT  VERSION *)

(* General validator object definitions *)

caution = "";
junk = "                           CAUTION"<>
	"                           \n\n"<>
	"The validator may print numbers with more or less "<>
	"precision than they really have (so what you see may "<>
	"not be quite the actual values).   Hence the validator "<>
	"may tell you that your answer is wrong and yet show a "<>
	"correct answer that seems to be the same as yours but "<>
	"is really not!\n";

startline[fn_, id_] := 
"\n=========== Validation of "<>fn<>" for ID #"<>id<>
	" ===========";

endline[] := 
"\n=========== Validation ended "<>tstamp[Date[]]<>
	" ===========\n";

tstamp[when_] := Module[{t, year, month, day, hour, minute}, 
	t = If[Length[when] == 0, Date[], when];
	t\[LeftDoubleBracket]1\[RightDoubleBracket] = Mod[t\[LeftDoubleBracket]1\[RightDoubleBracket], 100];
	{year, day, hour, minute} = Map[ToString, t\[LeftDoubleBracket]{1, 3, 4, 5}\[RightDoubleBracket]];
	minute = StringTake["0"<>minute,-2];
	month = {"Jan","Feb","Mar","Apr","May","Jun",
		"Jul","Aug","Sep","Oct","Nov","Dec"}\[LeftDoubleBracket]t\[LeftDoubleBracket]2\[RightDoubleBracket]\[RightDoubleBracket];
	day<>" "<>month<>" "<>year<>"  "<>hour<>":"<>minute];

itsshape[x_] := Module[{s = Dimensions[x], rank}, 
	rank = Length[s];
    Which[rank==0, "scalar", 
		rank==1, "length "<>ToString[Length@x] <> " vector", 
		rank== 2, ToString[s\[LeftDoubleBracket]1\[RightDoubleBracket]]<>"-by-"<>ToString[s\[LeftDoubleBracket]2\[RightDoubleBracket]]<>
			" matrix", 
		rank >2, " array"]];

stringtypeQ[x_] := Apply[And, Map[StringQ, Flatten@{x}]];
numbertypeQ[x_] := Apply[And, Map[NumericQ, Flatten@{x}]];
emptylistQ[x_] := ListQ[x] && (Length[x] == 0);

datatype[x_] := 
	Which[emptylistQ[x], "empty list",
		StringQ[x], "length "<>ToString[StringLength[x]]<>
			" string", 
		stringtypeQ[x], "character "<>ToString[itsshape[x]], 
		numbertypeQ[x], "numeric "<>ToString[itsshape[x]], 
		True, ToString[itsshape[x]]];

vdmsg[fn_String, other_String] := 
	"\nTurn in the preceding record of validation along with"<>
	" listings of your "<>fn<>
	" and all your objects that it references"<>
	If[StringLength[other] > 0, "\n(e.g., "<>other<>").", "."];

(* vdx: does the validation *)

vdx[fn_, arity_, ntests_, testdata_, id_] := 
	Module[{i, j, args, s, rslt, xcute, ans, correct, numOK = 0},
	Print[caution];
	Print[startline[fn, ToString@ToExpression@ToExpression@id]];
	Do [Print["\nTest #", i];			(* Do each test... *)
		args = testdata[i];
		If[arity == 1,
				Print["Argument is the ", 
					datatype@args\[LeftDoubleBracket]1\[RightDoubleBracket], ":"]; 
				Print[args\[LeftDoubleBracket]1\[RightDoubleBracket]]
			, (* else arity > 1 *)
			Do[ If[j == 1, Print["Argument 1 is the ", 											datatype@args\[LeftDoubleBracket]1\[RightDoubleBracket]],
					Print["and argument ", j, " is the ", 
								datatype@args\[LeftDoubleBracket]j\[RightDoubleBracket]]
				];
				Print[args\[LeftDoubleBracket]j\[RightDoubleBracket]];
				, {j, 1, arity}
			];
			xcute = False; correct = False;
			Check[rslt = 
					Apply[ToExpression["Global`"<>fn], args];
				xcute = True, xcute = False
			];
			If[xcute, Print["Your function's result is the ",
					datatype@rslt]; Print[rslt],
				Print["Your function did not evaluate "<>
					"to return a result!"]
			];
			ans = Apply[ToExpression[fn], args]
		];		(* end If arity... *)
		If[xcute, correct = SameQ[rslt, ans];
			If[correct, 
				Print["which seems to be correct."];numOK++,
				Print["which seems to be WRONG!"]
			]
		];
		If[(xcute && !correct) || !xcute, 
			Print["Correct result is the ",	datatype@ans, ":"]; 				Print[ans]
		]	
	, {i, 1, ntests}
	];									(* end Do *)
	Print["\nYour function passed "<>ToString[numOK]<>
		" out of "<>ToString[ntests]<>" tests."];
	Print[endline[]];
	Print[vdmsg[fname, othernames]];
	];									(* end Module vdx *)

(* Validate it! *)

vdx[fname, arity, ntests, testdata, "Global`myID"];
]		(* endIf -- end setup and test *)

If[vdencipher`check`checkingOK,
	End[]	(* end Private *)
]

If[vdencipher`check`checkingOK,
	EndPackage[]
]

(* clean up  *)

(* clean up in case myID was not defined *)
If[vdencipher`check`checkingNoID, 
	Remove[myID]
]

(* Don't leave package context in $ContextPath! *)
If[vdencipher`check`checkingOK,
	$ContextPath= Drop[$ContextPath, 1]
]

Remove["vdencipher`check`*"]	(* clean up `check` objects *)

Off[Remove::rmnsm];
Remove["special`temp`*"]	(* remove all locals in this file *)
On[Remove::rmnsm]

End[];	(* end special`temp` *)

(* end of validator *)



