v.02 Complete all of the exercises in this worksheet by placing the code you write for each problem into the empty fold which is provided in each exercise section. Further information: - ADDITIONAL VARIABLES CAN BE USED IN YOUR PROGRAMS BEYOND THE VARIABLES THAT ARE SPECIFIED IN EACH PROBLEM. - All variables that are used in procedures must be make local to that procedure. - Do not use the "Echo" or "Write" procedures in your programs unless you are using them for debugging. Remove all procedures from your code that produce side effects output before submitting your worksheet. - The string "Head" is not equal to the string "HEAD". - The "truncate" attribute in a fold header limits the amount of output that a program will insert into the worksheet. This reduces the chances of crashing MathPiperIDE. - The "timeout" attribute in a fold header stops a running program after the specified number of milliseconds. This prevents programs that contain infinite loops from locking up MathPiperIDE. %group,name="Problem 1",description="Right triangle." ======================================================================================================== Problem 1 a) Create a procedure named "rightTriangle" that has the parameters ["lowerLeftX", "lowerLeftY", "height", "pointCount"]. Use nested "For" loops and a single "GeoGebraPoint" procedure to draw a solid right triangle of any width and height at the specified X,Y coordinate. The parameters lowerLeftX and lowerLeftY are the X,Y coordinate of the lower left corner of the triangle. Have all point names start with a capital "A". Use "pointCount" to make all point labels unique. It should have an initial value of 1. This procedure should not contain any number literals. b) Create a no parameter procedure named "mainProcedure" that calls the "rightTriangle" procedure to draw the triangle that is shown in figure 1 of the points_patterns_exercises_2.pdf document. The labels of the plotted points should match the labels of the points in the figures. The main procedure should contain a call to GeoGebraClear(). c) Place the following line of code at the end of your code: mainProcedure(); %mathpiper,name="Problem 1",subtype="exercise",unassign_all="true",truncate="1000",timeout="5000" Procedure("rightTriangle", ["lowerLeftX", "lowerLeftY", "height", "pointCount"]) { Local(xIndex, yIndex, xOffset); xOffset := 0; For(yIndex := lowerLeftY, yIndex <=? lowerLeftY + height, yIndex++) { For(xIndex := lowerLeftX + xOffset++, xIndex <=? lowerLeftX + height , xIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, yIndex); } } pointCount; } Procedure("mainProcedure", []) { GeoGebraClear(); rightTriangle(1,1,5,1); } mainProcedure(); %/mathpiper %output,parent="Problem 1",mpversion=".231",preserve="false" Result: 22 . %/output %mathpiper_grade,name="Problem 1" FoldGrade("MathPiper version = .224", 1, True) { StringToNumber(Version()) >=? .224; } //----------------------------------------------------------------------------------------- LocalSymbols(pointsMap) { pointsSort(list) := { Sort(list,Lambda([x,y], StringToNumber(StringSubstring(x[1], 2, Length(x[1]))) <? StringToNumber(StringSubstring(y[1], 2, Length(y[1]))))); } pointsMap := []; testGeoGebraPoint(name, x, y) := { pointsMap[name] := [x, y]; } ?foldCode := Substitute('GeoGebraPoint, 'testGeoGebraPoint) ?foldCode; ?foldCode := Substitute('GeoGebraClear(), ' 'GeoGebraClear()) ?foldCode; // -------------------------------------------------------- FoldGrade("\"mainProcedure()\" is the last expression in the fold", 1, False) { Local(mainPosition); mainPosition := Length(?foldCode[1]); If(Function?(?foldCode[1][mainPosition]) &? ?foldCode[1][mainPosition][0] =? 'mainProcedure) { Local(resultMessage); resultMessage := True; If(?foldCode[1][mainPosition] !=? 'mainProcedure()) { resultMessage := "The call to \"mainProcedure\" must have zero arguments."; } ?foldCode[1][mainPosition] := ` '('(@ ?foldCode[1][mainPosition])); resultMessage; } Else { False; } } // -------------------------------------------------------- { Local(procedures, procedureName, parameters, body); procedures := ProceduresGet(?foldCode); If(procedures !=? []) { { // rightTriangle procedureName := "rightTriangle"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has four formal parameters", 1, False) { Length(procedure["parameters"]) =? 4; } // -------------------------------------------------------- FoldGrade("The procedure uses no more than one number literal", 1, False) { Length(PositionsPattern2(procedure["body"], a_Number?)) <=? 1; } // -------------------------------------------------------- FoldGrade("Exactly two \"For\" loops are used and no other loops are used", 1, False) { Local(procedureNames, loopCount); procedureNames := FuncListAll(procedure["body"]); loopCount := Count(procedureNames,"While") + Count(procedureNames,"Until"); loopCount =? 0 &? Count(procedureNames,"For") =? 2; } // -------------------------------------------------------- FoldGrade("One \"GeoGebraPoint\" procedure is used ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"testGeoGebraPoint"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("The \"Local\" procedure is used", 1, False) { Local(procedureNames); procedureNames := FuncList(procedure["body"]); Contains?(procedureNames,"Local"); } // -------------------------------------------------------- FoldGrade("\"pointCount;\" is the last expression in the fold", 1, False) { procedure["body"][Length(procedure["body"])] =? 'pointCount; } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } { // mainProcedure procedureName := "mainProcedure"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has zero formal parameters", 1, False) { Length(procedure["parameters"]) =? 0; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"GeoGebraClear\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"GeoGebraClear"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("The procedure produces a correct result", 1, True) { Local(procedureResult, correctValue); correctValue := [["A1",[1,1]],["A2",[2,1]],["A3",[3,1]],["A4",[4,1]],["A5",[5,1]],["A6",[6,1]],["A7",[2,2]],["A8",[3,2]],["A9",[4,2]],["A10",[5,2]],["A11",[6,2]],["A12",[3,3]],["A13",[4,3]],["A14",[5,3]],["A15",[6,3]],["A16",[4,4]],["A17",[5,4]],["A18",[6,4]],["A19",[5,5]],["A20",[6,5]],["A21",[6,6]]]; ExceptionCatch( { `( Apply(Lambda(@procedure["parameters"], @procedure["body"]), []) ); procedureResult := pointsSort(pointsMap); If(procedureResult !=? correctValue) { "The following points are not in the correct position: (" ~ ToString(Difference(correctValue, procedureResult)) ~ ")"; } Else { True; } }, "", "Exception: " ~ ExceptionGet()["message"]); } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } } Else { FoldGrade("At least one procedure is defined in the fold", 0, True) { False; } } } } %/mathpiper_grade %output,parent="Problem 1",mpversion=".231",preserve="false" Result: True Side Effects: YOUR CODE SHOULD BE FORMATTED LIKE THE FOLLOWING CODE: Procedure("rightTriangle",["lowerLeftX","lowerLeftY","height","pointCount"]) { Local(xIndex,yIndex,xOffset); xOffset := 0; For(yIndex := lowerLeftY,yIndex <=? lowerLeftY + height,yIndex++ ) { For(xIndex := lowerLeftX + xOffset++ ,xIndex <=? lowerLeftX + height,xIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,yIndex); } } pointCount; } Procedure("mainProcedure",[]) { GeoGebraClear(); rightTriangle(1,1,5,1); } mainProcedure(); PASS: The code does not throw an exception when parsed. (1/1) PASS: The fold is not empty. (1/1) PASS: The ':' operator is not used. (1/1) PASS: The results of all arithmetic operations are assigned to a variable. For example 'count := (count + 1) is okay, but (count + 1) by itself not okay. (1/1) PASS: The program uses variable names that are longer than a single character. (1/1) PASS: The program uses variable names that start with a lower case letter. (1/1) PASS: The version of "Append" that does not end with a '!' is not used. (1/1) ------------------------------------------ PASS: MathPiper version = .224. (1/1) PASS: "mainProcedure()" is the last expression in the fold. (1/1) rightTriangle: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has four formal parameters. (1/1) PASS: The procedure uses no more than one number literal. (1/1) PASS: Exactly two "For" loops are used and no other loops are used. (1/1) PASS: One "GeoGebraPoint" procedure is used . (1/1) PASS: The "Local" procedure is used. (1/1) PASS: "pointCount;" is the last expression in the fold. (1/1) mainProcedure: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has zero formal parameters. (1/1) PASS: One copy of a call to "GeoGebraClear" is present . (1/1) PASS: The procedure produces a correct result. (1/1) 20/20 passes . %/output %/group %group,name="Problem 2",description="Hollow rectangle 1." ======================================================================================================== Problem 2 a) Create a procedure named "hollowRectangle1" that has the parameters ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]. Use four "For" loops and four "GeoGebraPoint" procedures to draw a hollow rectangle of any width and height at the specified X,Y coordinate. The parameters lowerLeftX and lowerLeftY are the X,Y coordinate of the lower left corner of the rectangle. Have all point names start with a capital "A". Use "pointCount" to make all point labels unique. It should have an initial value of 1. This procedure should not contain any number literals. b) Create a no parameter procedure named "mainProcedure" that calls the "hollowRectangle1" procedure to draw the hollow rectangle that is shown in figure 2 of the points_patterns_exercises_2.pdf document. The labels of the plotted points should match the labels of the points in the figures. The main procedure should contain a call to GeoGebraClear(). c) Place the following line of code at the end of your code: mainProcedure(); %mathpiper,name="Problem 2",subtype="exercise",unassign_all="true",truncate="1000",timeout="5000" Procedure("hollowRectangle1", ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]) { Local(xIndex, yIndex); // Bottom. For(xIndex := lowerLeftX, xIndex <=? lowerLeftX + width, xIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, lowerLeftY); } // Right. For(yIndex := lowerLeftY + 1, yIndex <=? lowerLeftY + height, yIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), lowerLeftX + width, yIndex); } // Top. For(xIndex := lowerLeftX + width -1, xIndex >=? lowerLeftX, xIndex--) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, lowerLeftY + height); } // Left. For(yIndex := lowerLeftY + height -1, yIndex >=? lowerLeftY + 1, yIndex--) { GeoGebraPoint("A" ~ ToString(pointCount++), lowerLeftX, yIndex); } pointCount; } Procedure("mainProcedure", []) { GeoGebraClear(); hollowRectangle1(1, 1, 5, 5, 1); } mainProcedure(); %/mathpiper %output,parent="Problem 2",mpversion=".231",preserve="false" Result: 21 . %/output %mathpiper_grade,name="Problem 2" FoldGrade("MathPiper version = .224", 0, True) { StringToNumber(Version()) >=? .224; } //----------------------------------------------------------------------------------------- LocalSymbols(pointsMap) { pointsSort(list) := { Sort(list,Lambda([x,y], StringToNumber(StringSubstring(x[1], 2, Length(x[1]))) <? StringToNumber(StringSubstring(y[1], 2, Length(y[1]))))); } pointsMap := []; testGeoGebraPoint(name, x, y) := { pointsMap[name] := [x, y]; } ?foldCode := Substitute('GeoGebraPoint, 'testGeoGebraPoint) ?foldCode; ?foldCode := Substitute('GeoGebraClear(), ' 'GeoGebraClear()) ?foldCode; // -------------------------------------------------------- FoldGrade("\"mainProcedure()\" is the last expression in the fold", 1, False) { Local(mainPosition); mainPosition := Length(?foldCode[1]); If(Function?(?foldCode[1][mainPosition]) &? ?foldCode[1][mainPosition][0] =? 'mainProcedure) { Local(resultMessage); resultMessage := True; If(?foldCode[1][mainPosition] !=? 'mainProcedure()) { resultMessage := "The call to \"mainProcedure\" must have zero arguments."; } ?foldCode[1][mainPosition] := ` '('(@ ?foldCode[1][mainPosition])); resultMessage; } Else { False; } } // -------------------------------------------------------- { Local(procedures, procedureName, parameters, body); procedures := ProceduresGet(?foldCode); If(procedures !=? []) { { // hollowRectangle1 procedureName := "hollowRectangle1"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has five formal parameters", 1, False) { Length(procedure["parameters"]) =? 5; } // -------------------------------------------------------- FoldGrade("The procedure does not use any number literals other than 1 or -1", 1, False) { Length(PositionsPattern2(procedure["body"], a_Number?::(a !=? 1 &? a !=? -1))) =? 0; } // -------------------------------------------------------- FoldGrade("Four loops are used", 1, False) { Local(procedureNames, loopCount); procedureNames := FuncListAll(procedure["body"]); loopCount := Count(procedureNames,"While") + Count(procedureNames,"Until") + Count(procedureNames,"For") ; loopCount =? 4; } // -------------------------------------------------------- FoldGrade("Four \"GeoGebraPoint\" procedures are used ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"testGeoGebraPoint"); procedureCount =? 4; } // -------------------------------------------------------- FoldGrade("The \"Local\" procedure is used", 1, False) { Local(procedureNames); procedureNames := FuncList(procedure["body"]); Contains?(procedureNames,"Local"); } // -------------------------------------------------------- FoldGrade("\"pointCount;\" is the last expression in the fold", 1, False) { procedure["body"][Length(procedure["body"])] =? 'pointCount; } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } { // mainProcedure procedureName := "mainProcedure"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has zero formal parameters", 1, False) { Length(procedure["parameters"]) =? 0; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"GeoGebraClear\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"GeoGebraClear"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("The procedure produces a correct result", 1, True) { Local(procedureResult, correctValue); correctValue := [["A1",[1,1]],["A2",[2,1]],["A3",[3,1]],["A4",[4,1]],["A5",[5,1]],["A6",[6,1]],["A7",[6,2]],["A8",[6,3]],["A9",[6,4]],["A10",[6,5]],["A11",[6,6]],["A12",[5,6]],["A13",[4,6]],["A14",[3,6]],["A15",[2,6]],["A16",[1,6]],["A17",[1,5]],["A18",[1,4]],["A19",[1,3]],["A20",[1,2]]]; ExceptionCatch( { `( Apply(Lambda(@procedure["parameters"], @procedure["body"]), []) ); procedureResult := pointsSort(pointsMap); If(procedureResult !=? correctValue) { "The following points are not in the correct position: (" ~ ToString(Difference(correctValue, procedureResult)) ~ ")"; } Else { True; } }, "", "Exception: " ~ ExceptionGet()["message"]); } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } } Else { FoldGrade("At least one procedure is defined in the fold", 0, True) { False; } } } } %/mathpiper_grade %output,parent="Problem 2",mpversion=".231",preserve="false" Result: True Side Effects: YOUR CODE SHOULD BE FORMATTED LIKE THE FOLLOWING CODE: Procedure("hollowRectangle1",["lowerLeftX","lowerLeftY","width","height","pointCount"]) { Local(xIndex,yIndex); For(xIndex := lowerLeftX,xIndex <=? lowerLeftX + width,xIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,lowerLeftY); } For(yIndex := lowerLeftY + 1,yIndex <=? lowerLeftY + height,yIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),lowerLeftX + width,yIndex); } For(xIndex := (lowerLeftX + width) - 1,xIndex >=? lowerLeftX,xIndex--) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,lowerLeftY + height); } For(yIndex := (lowerLeftY + height) - 1,yIndex >=? lowerLeftY + 1,yIndex--) { GeoGebraPoint("A" ~ ToString(pointCount++ ),lowerLeftX,yIndex); } pointCount; } Procedure("mainProcedure",[]) { GeoGebraClear(); hollowRectangle1(1,1,5,5,1); } mainProcedure(); PASS: The code does not throw an exception when parsed. (1/1) PASS: The fold is not empty. (1/1) PASS: The ':' operator is not used. (1/1) PASS: The results of all arithmetic operations are assigned to a variable. For example 'count := (count + 1) is okay, but (count + 1) by itself not okay. (1/1) PASS: The program uses variable names that are longer than a single character. (1/1) PASS: The program uses variable names that start with a lower case letter. (1/1) PASS: The version of "Append" that does not end with a '!' is not used. (1/1) ------------------------------------------ PASS: MathPiper version = .224. (0/0) PASS: "mainProcedure()" is the last expression in the fold. (1/1) hollowRectangle1: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has five formal parameters. (1/1) PASS: The procedure does not use any number literals other than 1 or -1. (1/1) PASS: Four loops are used. (1/1) PASS: Four "GeoGebraPoint" procedures are used . (1/1) PASS: The "Local" procedure is used. (1/1) PASS: "pointCount;" is the last expression in the fold. (1/1) mainProcedure: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has zero formal parameters. (1/1) PASS: One copy of a call to "GeoGebraClear" is present . (1/1) PASS: The procedure produces a correct result. (1/1) 19/19 passes . %/output %/group %group,name="Problem 3",description="Hollow rectangle 2." ======================================================================================================== Problem 3 a) Create a procedure named "hollowRectangle2" that has the parameters ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]. Use two "For" loops which each conain two "GeoGebraPoint" procedures calls to draw a hollow rectangle of any width and height at the specified X,Y coordinate. The parameters lowerLeftX and lowerLeftY are the X,Y coordinate of the lower left corner of the rectangle. Have all point names start with a capital "A". Use "pointCount" to make all point labels unique. It should have an initial value of 1. This procedure should not contain any number literals. b) Create a no parameter procedure named "mainProcedure" that calls the "hollowRectangle2" procedure to draw the hollow rectangle that is shown in figure 3 of the points_patterns_exercises_2.pdf document. The labels of the plotted points should match the labels of the points in the figures. The main procedure should contain a call to GeoGebraClear(). c) Place the following line of code at the end of your code: mainProcedure(); %mathpiper,name="Problem 3",subtype="exercise",unassign_all="true",truncate="1000",timeout="5000" Procedure("hollowRectangle2", ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]) { Local(xIndex, yIndex); // Bottom and top. For(xIndex := lowerLeftX, xIndex <=? lowerLeftX + width, xIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, lowerLeftY); GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, lowerLeftY + height); } // Left and right. For(yIndex := lowerLeftY + 1, yIndex <=? lowerLeftY + height - 1, yIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), lowerLeftX, yIndex); GeoGebraPoint("A" ~ ToString(pointCount++), lowerLeftX + width, yIndex); } pointCount; } Procedure("mainProcedure", []) { GeoGebraClear(); hollowRectangle2(1, 1, 5, 5, 1); } mainProcedure(); %/mathpiper %output,parent="Problem 3",mpversion=".231",preserve="false" Result: 21 . %/output %mathpiper_grade,name="Problem 3" FoldGrade("MathPiper version = .224", 0, True) { StringToNumber(Version()) >=? .224; } //----------------------------------------------------------------------------------------- LocalSymbols(pointsMap) { pointsSort(list) := { Sort(list,Lambda([x,y], StringToNumber(StringSubstring(x[1], 2, Length(x[1]))) <? StringToNumber(StringSubstring(y[1], 2, Length(y[1]))))); } pointsMap := []; testGeoGebraPoint(name, x, y) := { pointsMap[name] := [x, y]; } ?foldCode := Substitute('GeoGebraPoint, 'testGeoGebraPoint) ?foldCode; ?foldCode := Substitute('GeoGebraClear(), ' 'GeoGebraClear()) ?foldCode; // -------------------------------------------------------- FoldGrade("\"mainProcedure()\" is the last expression in the fold", 1, False) { Local(mainPosition); mainPosition := Length(?foldCode[1]); If(Function?(?foldCode[1][mainPosition]) &? ?foldCode[1][mainPosition][0] =? 'mainProcedure) { Local(resultMessage); resultMessage := True; If(?foldCode[1][mainPosition] !=? 'mainProcedure()) { resultMessage := "The call to \"mainProcedure\" must have zero arguments."; } ?foldCode[1][mainPosition] := ` '('(@ ?foldCode[1][mainPosition])); resultMessage; } Else { False; } } // -------------------------------------------------------- { Local(procedures, procedureName, parameters, body); procedures := ProceduresGet(?foldCode); If(procedures !=? []) { { // hollowRectangle2 procedureName := "hollowRectangle2"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has five formal parameters", 1, False) { Length(procedure["parameters"]) =? 5; } // -------------------------------------------------------- FoldGrade("The procedure does not use any number literals other than 1 or -1", 1, False) { Length(PositionsPattern2(procedure["body"], a_Number?::(a !=? 1 &? a !=? -1))) =? 0; } // -------------------------------------------------------- FoldGrade("Two loops are used", 1, False) { Local(procedureNames, loopCount); procedureNames := FuncListAll(procedure["body"]); loopCount := Count(procedureNames,"While") + Count(procedureNames,"Until") + Count(procedureNames,"For") ; loopCount =? 2; } // -------------------------------------------------------- FoldGrade("Four \"GeoGebraPoint\" procedures are used ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"testGeoGebraPoint"); procedureCount =? 4; } // -------------------------------------------------------- FoldGrade("The \"Local\" procedure is used", 1, False) { Local(procedureNames); procedureNames := FuncList(procedure["body"]); Contains?(procedureNames,"Local"); } // -------------------------------------------------------- FoldGrade("\"pointCount;\" is the last expression in the fold", 1, False) { procedure["body"][Length(procedure["body"])] =? 'pointCount; } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } { // mainProcedure procedureName := "mainProcedure"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has zero formal parameters", 1, False) { Length(procedure["parameters"]) =? 0; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"GeoGebraClear\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"GeoGebraClear"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("The procedure produces a correct result", 1, True) { Local(procedureResult, correctValue); correctValue := [["A1",[1,1]],["A2",[1,6]],["A3",[2,1]],["A4",[2,6]],["A5",[3,1]],["A6",[3,6]],["A7",[4,1]],["A8",[4,6]],["A9",[5,1]],["A10",[5,6]],["A11",[6,1]],["A12",[6,6]],["A13",[1,2]],["A14",[6,2]],["A15",[1,3]],["A16",[6,3]],["A17",[1,4]],["A18",[6,4]],["A19",[1,5]],["A20",[6,5]]]; ExceptionCatch( { `( Apply(Lambda(@procedure["parameters"], @procedure["body"]), []) ); procedureResult := pointsSort(pointsMap); If(procedureResult !=? correctValue) { "The following points are not in the correct position: (" ~ ToString(Difference(correctValue, procedureResult)) ~ ")"; } Else { True; } }, "", "Exception: " ~ ExceptionGet()["message"]); } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } } Else { FoldGrade("At least one procedure is defined in the fold", 0, True) { False; } } } } %/mathpiper_grade %output,parent="Problem 3",mpversion=".231",preserve="false" Result: True Side Effects: YOUR CODE SHOULD BE FORMATTED LIKE THE FOLLOWING CODE: Procedure("hollowRectangle2",["lowerLeftX","lowerLeftY","width","height","pointCount"]) { Local(xIndex,yIndex); For(xIndex := lowerLeftX,xIndex <=? lowerLeftX + width,xIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,lowerLeftY); GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,lowerLeftY + height); } For(yIndex := lowerLeftY + 1,yIndex <=? (lowerLeftY + height) - 1,yIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),lowerLeftX,yIndex); GeoGebraPoint("A" ~ ToString(pointCount++ ),lowerLeftX + width,yIndex); } pointCount; } Procedure("mainProcedure",[]) { GeoGebraClear(); hollowRectangle2(1,1,5,5,1); } mainProcedure(); PASS: The code does not throw an exception when parsed. (1/1) PASS: The fold is not empty. (1/1) PASS: The ':' operator is not used. (1/1) PASS: The results of all arithmetic operations are assigned to a variable. For example 'count := (count + 1) is okay, but (count + 1) by itself not okay. (1/1) PASS: The program uses variable names that are longer than a single character. (1/1) PASS: The program uses variable names that start with a lower case letter. (1/1) PASS: The version of "Append" that does not end with a '!' is not used. (1/1) ------------------------------------------ PASS: MathPiper version = .224. (0/0) PASS: "mainProcedure()" is the last expression in the fold. (1/1) hollowRectangle2: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has five formal parameters. (1/1) PASS: The procedure does not use any number literals other than 1 or -1. (1/1) PASS: Two loops are used. (1/1) PASS: Four "GeoGebraPoint" procedures are used . (1/1) PASS: The "Local" procedure is used. (1/1) PASS: "pointCount;" is the last expression in the fold. (1/1) mainProcedure: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has zero formal parameters. (1/1) PASS: One copy of a call to "GeoGebraClear" is present . (1/1) PASS: The procedure produces a correct result. (1/1) 19/19 passes . %/output %/group %group,name="Problem 4",description="Solid rectangle." ======================================================================================================== Problem 4 a) Create a procedure named "solidRectangle" that has the parameters ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]. Use two nested "For" loops and one "GeoGebraPoint" procedure to draw a solid rectangle of any width and height at the specified X,Y coordinate. The parameters lowerLeftX and lowerLeftY are the X,Y coordinate of the lower left corner of the rectangle. Have all point names start with a capital "A". Use "pointCount" to make all point labels unique. The variable "pointCount" should be returned as the result of this procedure. This procedure should not contain any number literals. b) Create a no parameter procedure named "mainProcedure" that uses a single loop and one copy of a call to "solidRectangle" procedure to draw the solid rectangles that are shown in figure 4 of the points_patterns_exercises_2.pdf document. The labels of the plotted points should match the labels of the points in the figures. The main procedure should contain a call to GeoGebraClear(). c) Place the following line of code at the end of your code: mainProcedure(); %mathpiper,name="Problem 4",subtype="exercise",unassign_all="true",truncate="1000",timeout="5000" Procedure("solidRectangle", ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]) { Local(xIndex, yIndex); For(yIndex := lowerLeftY, yIndex <=? lowerLeftY + height, yIndex++) { For(xIndex := lowerLeftX, xIndex <=? lowerLeftX + width, xIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, yIndex); } } pointCount; } Procedure("mainProcedure", []) { Local(xIndex, yIndex, pointCount); GeoGebraClear(); pointCount := 1; yIndex := 1; For(xIndex := 1, xIndex <=? 30, xIndex +:= 6) { pointCount := solidRectangle(xIndex, yIndex, 4, 5, pointCount); yIndex := yIndex + 3; } } mainProcedure(); %/mathpiper %output,parent="Problem 4",mpversion=".231",preserve="false" Result: 16 . %/output %mathpiper_grade,name="Problem 4" FoldGrade("MathPiper version = .224", 0, True) { StringToNumber(Version()) >=? .224; } //----------------------------------------------------------------------------------------- LocalSymbols(pointsMap) { pointsSort(list) := { Sort(list,Lambda([x,y], StringToNumber(StringSubstring(x[1], 2, Length(x[1]))) <? StringToNumber(StringSubstring(y[1], 2, Length(y[1]))))); } pointsMap := []; testGeoGebraPoint(name, x, y) := { pointsMap[name] := [x, y]; } ?foldCode := Substitute('GeoGebraPoint, 'testGeoGebraPoint) ?foldCode; ?foldCode := Substitute('GeoGebraClear(), ' 'GeoGebraClear()) ?foldCode; // -------------------------------------------------------- FoldGrade("\"mainProcedure()\" is the last expression in the fold", 1, False) { Local(mainPosition); mainPosition := Length(?foldCode[1]); If(Function?(?foldCode[1][mainPosition]) &? ?foldCode[1][mainPosition][0] =? 'mainProcedure) { Local(resultMessage); resultMessage := True; If(?foldCode[1][mainPosition] !=? 'mainProcedure()) { resultMessage := "The call to \"mainProcedure\" must have zero arguments."; } ?foldCode[1][mainPosition] := ` '('(@ ?foldCode[1][mainPosition])); resultMessage; } Else { False; } } // -------------------------------------------------------- { Local(procedures, procedureName, parameters, body); procedures := ProceduresGet(?foldCode); If(procedures !=? []) { { // solidRectangle procedureName := "solidRectangle"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has fi ve formal parameters", 1, False) { Length(procedure["parameters"]) =? 5; } // -------------------------------------------------------- FoldGrade("The procedure does not use any number literals", 1, False) { Length(PositionsPattern2(procedure["body"], a_Number?)) =? 0; } // -------------------------------------------------------- FoldGrade("Exactly two \"For\" loops are used and no other loops are used", 1, False) { Local(procedureNames, loopCount); procedureNames := FuncListAll(procedure["body"]); loopCount := Count(procedureNames,"While") + Count(procedureNames,"Until"); loopCount =? 0 &? Count(procedureNames,"For") =? 2; } // -------------------------------------------------------- FoldGrade("One \"GeoGebraPoint\" procedure is used ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"testGeoGebraPoint"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("The \"Local\" procedure is used", 1, False) { Local(procedureNames); procedureNames := FuncList(procedure["body"]); Contains?(procedureNames,"Local"); } // -------------------------------------------------------- FoldGrade("\"pointCount;\" is the last expression in the fold", 1, False) { procedure["body"][Length(procedure["body"])] =? 'pointCount; } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } { // mainProcedure procedureName := "mainProcedure"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has zero formal parameters", 1, False) { Length(procedure["parameters"]) =? 0; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"GeoGebraClear\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"GeoGebraClear"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("Exactly one loop is used", 1, False) { Local(procedureNames, loopCount); procedureNames := FuncListAll(procedure["body"]); loopCount := Count(procedureNames,"While") + Count(procedureNames,"Until") + Count(procedureNames,"For"); loopCount =? 1; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"solidRectangle\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"solidRectangle"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("The procedure produces a correct result", 1, True) { Local(procedureResult, correctValue); correctValue := [["A1",[1,1]],["A2",[2,1]],["A3",[3,1]],["A4",[4,1]],["A5",[5,1]],["A6",[1,2]],["A7",[2,2]],["A8",[3,2]],["A9",[4,2]],["A10",[5,2]],["A11",[1,3]],["A12",[2,3]],["A13",[3,3]],["A14",[4,3]],["A15",[5,3]],["A16",[1,4]],["A17",[2,4]],["A18",[3,4]],["A19",[4,4]],["A20",[5,4]],["A21",[1,5]],["A22",[2,5]],["A23",[3,5]],["A24",[4,5]],["A25",[5,5]],["A26",[1,6]],["A27",[2,6]],["A28",[3,6]],["A29",[4,6]],["A30",[5,6]],["A31",[7,4]],["A32",[8,4]],["A33",[9,4]],["A34",[10,4]],["A35",[11,4]],["A36",[7,5]],["A37",[8,5]],["A38",[9,5]],["A39",[10,5]],["A40",[11,5]],["A41",[7,6]],["A42",[8,6]],["A43",[9,6]],["A44",[10,6]],["A45",[11,6]],["A46",[7,7]],["A47",[8,7]],["A48",[9,7]],["A49",[10,7]],["A50",[11,7]],["A51",[7,8]],["A52",[8,8]],["A53",[9,8]],["A54",[10,8]],["A55",[11,8]],["A56",[7,9]],["A57",[8,9]],["A58",[9,9]],["A59",[10,9]],["A60",[11,9]],["A61",[13,7]],["A62",[14,7]],["A63",[15,7]],["A64",[16,7]],["A65",[17,7]],["A66",[13,8]],["A67",[14,8]],["A68",[15,8]],["A69",[16,8]],["A70",[17,8]],["A71",[13,9]],["A72",[14,9]],["A73",[15,9]],["A74",[16,9]],["A75",[17,9]],["A76",[13,10]],["A77",[14,10]],["A78",[15,10]],["A79",[16,10]],["A80",[17,10]],["A81",[13,11]],["A82",[14,11]],["A83",[15,11]],["A84",[16,11]],["A85",[17,11]],["A86",[13,12]],["A87",[14,12]],["A88",[15,12]],["A89",[16,12]],["A90",[17,12]],["A91",[19,10]],["A92",[20,10]],["A93",[21,10]],["A94",[22,10]],["A95",[23,10]],["A96",[19,11]],["A97",[20,11]],["A98",[21,11]],["A99",[22,11]],["A100",[23,11]],["A101",[19,12]],["A102",[20,12]],["A103",[21,12]],["A104",[22,12]],["A105",[23,12]],["A106",[19,13]],["A107",[20,13]],["A108",[21,13]],["A109",[22,13]],["A110",[23,13]],["A111",[19,14]],["A112",[20,14]],["A113",[21,14]],["A114",[22,14]],["A115",[23,14]],["A116",[19,15]],["A117",[20,15]],["A118",[21,15]],["A119",[22,15]],["A120",[23,15]],["A121",[25,13]],["A122",[26,13]],["A123",[27,13]],["A124",[28,13]],["A125",[29,13]],["A126",[25,14]],["A127",[26,14]],["A128",[27,14]],["A129",[28,14]],["A130",[29,14]],["A131",[25,15]],["A132",[26,15]],["A133",[27,15]],["A134",[28,15]],["A135",[29,15]],["A136",[25,16]],["A137",[26,16]],["A138",[27,16]],["A139",[28,16]],["A140",[29,16]],["A141",[25,17]],["A142",[26,17]],["A143",[27,17]],["A144",[28,17]],["A145",[29,17]],["A146",[25,18]],["A147",[26,18]],["A148",[27,18]],["A149",[28,18]],["A150",[29,18]]]; ExceptionCatch( { `( Apply(Lambda(@procedure["parameters"], @procedure["body"]), []) ); procedureResult := pointsSort(pointsMap); If(procedureResult !=? correctValue) { "The following points are not in the correct position: (" ~ ToString(Difference(correctValue, procedureResult)) ~ ")"; } Else { True; } }, "", "Exception: " ~ ExceptionGet()["message"]); } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } } Else { FoldGrade("At least one procedure is defined in the fold", 0, True) { False; } } } ?foldResult?; } %/mathpiper_grade %output,parent="Problem 4",mpversion=".231",preserve="false" Result: True Side Effects: YOUR CODE SHOULD BE FORMATTED LIKE THE FOLLOWING CODE: Procedure("solidRectangle",["lowerLeftX","lowerLeftY","width","height","pointCount"]) { Local(xIndex,yIndex); For(yIndex := lowerLeftY,yIndex <=? lowerLeftY + height,yIndex++ ) { For(xIndex := lowerLeftX,xIndex <=? lowerLeftX + width,xIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,yIndex); } } pointCount; } Procedure("mainProcedure",[]) { Local(xIndex,yIndex,pointCount); GeoGebraClear(); pointCount := 1; yIndex := 1; For(xIndex := 1,xIndex <=? 30,xIndex +:= 6) { pointCount := solidRectangle(xIndex,yIndex,4,5,pointCount); yIndex := yIndex + 3; } } mainProcedure(); PASS: The code does not throw an exception when parsed. (1/1) PASS: The fold is not empty. (1/1) PASS: The ':' operator is not used. (1/1) PASS: The results of all arithmetic operations are assigned to a variable. For example 'count := (count + 1) is okay, but (count + 1) by itself not okay. (1/1) PASS: The program uses variable names that are longer than a single character. (1/1) PASS: The program uses variable names that start with a lower case letter. (1/1) PASS: The version of "Append" that does not end with a '!' is not used. (1/1) ------------------------------------------ PASS: MathPiper version = .224. (0/0) PASS: "mainProcedure()" is the last expression in the fold. (1/1) solidRectangle: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has fi ve formal parameters. (1/1) PASS: The procedure does not use any number literals. (1/1) PASS: Exactly two "For" loops are used and no other loops are used. (1/1) PASS: One "GeoGebraPoint" procedure is used . (1/1) PASS: The "Local" procedure is used. (1/1) PASS: "pointCount;" is the last expression in the fold. (1/1) mainProcedure: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has zero formal parameters. (1/1) PASS: One copy of a call to "GeoGebraClear" is present . (1/1) PASS: Exactly one loop is used. (1/1) PASS: One copy of a call to "solidRectangle" is present . (1/1) PASS: The procedure produces a correct result. (1/1) 21/21 passes . %/output %/group %group,name="Problem 5",description="Three shapes." ======================================================================================================== Problem 5 a) Copy the procedures "solidRectangle", "rightTriangle", and "hollowRectangle2" that you created in previous exercises into this exercise fold. b) Create a no parameter procedure named "mainProcedure" that uses a single loop and the procedures from a) to draw the points that are shown in figure 5 of the points_patterns_exercises_2.pdf document. The labels of the plotted points should match the labels of the points in the figures. Only a single copy of the calls to each of the procedures in a) should be used. Use a variable named "pointCount" to make all point labels unique. It should have an initial value of 1. The main procedure should contain a call to GeoGebraClear(). c) Place the following line of code at the end of your code: mainProcedure(); %mathpiper,name="Problem 5",subtype="exercise",unassign_all="true",truncate="1000",timeout="5000" Procedure("solidRectangle", ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]) { Local(xIndex, yIndex); For(yIndex := lowerLeftY, yIndex <=? lowerLeftY + height, yIndex++) { For(xIndex := lowerLeftX, xIndex <=? lowerLeftX + width, xIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, yIndex); } } pointCount; } Procedure("rightTriangle", ["lowerLeftX", "lowerLeftY", "height", "pointCount"]) { Local(xIndex, yIndex, xOffset); xOffset := 0; For(yIndex := lowerLeftY, yIndex <=? lowerLeftY + height, yIndex++) { For(xIndex := lowerLeftX + xOffset++, xIndex <=? lowerLeftX + height , xIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, yIndex); } } pointCount; } Procedure("hollowRectangle2", ["lowerLeftX", "lowerLeftY", "width", "height", "pointCount"]) { Local(xIndex, yIndex); // Bottom and top. For(xIndex := lowerLeftX, xIndex <=? lowerLeftX + width, xIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, lowerLeftY); GeoGebraPoint("A" ~ ToString(pointCount++), xIndex, lowerLeftY + height); } // Left and right. For(yIndex := lowerLeftY + 1, yIndex <=? lowerLeftY + height - 1, yIndex++) { GeoGebraPoint("A" ~ ToString(pointCount++), lowerLeftX, yIndex); GeoGebraPoint("A" ~ ToString(pointCount++), lowerLeftX + width, yIndex); } pointCount; } Procedure("mainProcedure", []) { GeoGebraClear(); pointCount := 1; alternateCount := 1; yIndex := 1; For(xIndex := 1, xIndex <=? 35, xIndex +:= 6) { If(alternateCount =? 1) { pointCount := solidRectangle(xIndex, yIndex, 4, 5, pointCount); } Else If(alternateCount =? 2) { pointCount := rightTriangle(xIndex, yIndex, 4, pointCount); } Else If(alternateCount =? 3) { pointCount := hollowRectangle2(xIndex, yIndex, 4, 5, pointCount); } alternateCount++; If(alternateCount =? 4) { alternateCount := 1; } yIndex := yIndex + 3; } } mainProcedure(); %/mathpiper %output,parent="Problem 5",mpversion=".231",preserve="false" Result: 19 . %/output %mathpiper_grade,name="Problem 5" FoldGrade("MathPiper version = .224", 0, True) { StringToNumber(Version()) >=? .224; } //----------------------------------------------------------------------------------------- LocalSymbols(pointsMap) { pointsSort(list) := { Sort(list,Lambda([x,y], StringToNumber(StringSubstring(x[1], 2, Length(x[1]))) <? StringToNumber(StringSubstring(y[1], 2, Length(y[1]))))); } pointsMap := []; testGeoGebraPoint(name, x, y) := { pointsMap[name] := [x, y]; } ?foldCode := Substitute('GeoGebraPoint, 'testGeoGebraPoint) ?foldCode; ?foldCode := Substitute('GeoGebraClear(), ' 'GeoGebraClear()) ?foldCode; // -------------------------------------------------------- FoldGrade("\"mainProcedure()\" is the last expression in the fold", 1, False) { Local(mainPosition); mainPosition := Length(?foldCode[1]); If(Function?(?foldCode[1][mainPosition]) &? ?foldCode[1][mainPosition][0] =? 'mainProcedure) { Local(resultMessage); resultMessage := True; If(?foldCode[1][mainPosition] !=? 'mainProcedure()) { resultMessage := "The call to \"mainProcedure\" must have zero arguments."; } ?foldCode[1][mainPosition] := ` '('(@ ?foldCode[1][mainPosition])); resultMessage; } Else { False; } } // -------------------------------------------------------- { Local(procedures, procedureName, parameters, body); procedures := ProceduresGet(?foldCode); If(procedures !=? []) { { // solidRectangle procedureName := "solidRectangle"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure exists and it has the correct name", 1, True) { procedure !=? None; } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } { // rightTriangle procedureName := "rightTriangle"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure exists and it has the correct name", 1, True) { procedure !=? None; } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } { // hollowRectangle2 procedureName := "hollowRectangle2"; Echo(procedureName ~ ":"); Local(procedure); procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure exists and it has the correct name", 1, True) { procedure !=? None; } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } { // mainProcedure procedureName := "mainProcedure"; Echo(procedureName ~ ":"); Local(procedure); ?foo := procedure := procedures[procedureName]; If(procedure !=? None) { FoldGrade("The procedure does not throw an exception when defined", 1, True) { ExceptionCatch( { `( Procedure(@procedureName, @procedure["parameters"]) @procedure["body"] ); True; }, "", { ExceptionGet()["message"]; }); } // -------------------------------------------------------- FoldGrade("The procedure has zero formal parameters", 1, False) { Length(procedure["parameters"]) =? 0; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"GeoGebraClear\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"GeoGebraClear"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("Exactly one loop is used", 1, False) { Local(procedureNames, loopCount); procedureNames := FuncListAll(procedure["body"]); loopCount := Count(procedureNames,"While") + Count(procedureNames,"Until") + Count(procedureNames,"For"); loopCount =? 1; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"solidRectangle\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"solidRectangle"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"rightTriangle\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"rightTriangle"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("One copy of a call to \"hollowRectangle2\" is present ", 1, True) { Local(procedureNames, procedureCount); procedureNames := FuncListAll(procedure["body"]); procedureCount := Count(procedureNames,"hollowRectangle2"); procedureCount =? 1; } // -------------------------------------------------------- FoldGrade("The procedure produces a correct result", 1, True) { Local(procedureResult, correctValue); correctValue := [["A1",[1,1]],["A2",[2,1]],["A3",[3,1]],["A4",[4,1]],["A5",[5,1]],["A6",[1,2]],["A7",[2,2]],["A8",[3,2]],["A9",[4,2]],["A10",[5,2]],["A11",[1,3]],["A12",[2,3]],["A13",[3,3]],["A14",[4,3]],["A15",[5,3]],["A16",[1,4]],["A17",[2,4]],["A18",[3,4]],["A19",[4,4]],["A20",[5,4]],["A21",[1,5]],["A22",[2,5]],["A23",[3,5]],["A24",[4,5]],["A25",[5,5]],["A26",[1,6]],["A27",[2,6]],["A28",[3,6]],["A29",[4,6]],["A30",[5,6]],["A31",[7,4]],["A32",[8,4]],["A33",[9,4]],["A34",[10,4]],["A35",[11,4]],["A36",[8,5]],["A37",[9,5]],["A38",[10,5]],["A39",[11,5]],["A40",[9,6]],["A41",[10,6]],["A42",[11,6]],["A43",[10,7]],["A44",[11,7]],["A45",[11,8]],["A46",[13,7]],["A47",[13,12]],["A48",[14,7]],["A49",[14,12]],["A50",[15,7]],["A51",[15,12]],["A52",[16,7]],["A53",[16,12]],["A54",[17,7]],["A55",[17,12]],["A56",[13,8]],["A57",[17,8]],["A58",[13,9]],["A59",[17,9]],["A60",[13,10]],["A61",[17,10]],["A62",[13,11]],["A63",[17,11]],["A64",[19,10]],["A65",[20,10]],["A66",[21,10]],["A67",[22,10]],["A68",[23,10]],["A69",[19,11]],["A70",[20,11]],["A71",[21,11]],["A72",[22,11]],["A73",[23,11]],["A74",[19,12]],["A75",[20,12]],["A76",[21,12]],["A77",[22,12]],["A78",[23,12]],["A79",[19,13]],["A80",[20,13]],["A81",[21,13]],["A82",[22,13]],["A83",[23,13]],["A84",[19,14]],["A85",[20,14]],["A86",[21,14]],["A87",[22,14]],["A88",[23,14]],["A89",[19,15]],["A90",[20,15]],["A91",[21,15]],["A92",[22,15]],["A93",[23,15]],["A94",[25,13]],["A95",[26,13]],["A96",[27,13]],["A97",[28,13]],["A98",[29,13]],["A99",[26,14]],["A100",[27,14]],["A101",[28,14]],["A102",[29,14]],["A103",[27,15]],["A104",[28,15]],["A105",[29,15]],["A106",[28,16]],["A107",[29,16]],["A108",[29,17]],["A109",[31,16]],["A110",[31,21]],["A111",[32,16]],["A112",[32,21]],["A113",[33,16]],["A114",[33,21]],["A115",[34,16]],["A116",[34,21]],["A117",[35,16]],["A118",[35,21]],["A119",[31,17]],["A120",[35,17]],["A121",[31,18]],["A122",[35,18]],["A123",[31,19]],["A124",[35,19]],["A125",[31,20]],["A126",[35,20]]]; ExceptionCatch( { `( Apply(Lambda(@procedure["parameters"], @procedure["body"]), []) ); procedureResult := pointsSort(pointsMap); If(procedureResult !=? correctValue) { "The following points are not in the correct position: (" ~ ToString(Difference(correctValue, procedureResult)) ~ ")"; } Else { True; } }, "", "Exception: " ~ ExceptionGet()["message"]); } } Else { FoldGrade("The procedure name is correct", 0, True) { False; } } } } Else { FoldGrade("At least one procedure is defined in the fold", 0, True) { False; } } } } %/mathpiper_grade %output,parent="Problem 5",mpversion=".231",preserve="false" Result: True Side Effects: YOUR CODE SHOULD BE FORMATTED LIKE THE FOLLOWING CODE: Procedure("solidRectangle",["lowerLeftX","lowerLeftY","width","height","pointCount"]) { Local(xIndex,yIndex); For(yIndex := lowerLeftY,yIndex <=? lowerLeftY + height,yIndex++ ) { For(xIndex := lowerLeftX,xIndex <=? lowerLeftX + width,xIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,yIndex); } } pointCount; } Procedure("rightTriangle",["lowerLeftX","lowerLeftY","height","pointCount"]) { Local(xIndex,yIndex,xOffset); xOffset := 0; For(yIndex := lowerLeftY,yIndex <=? lowerLeftY + height,yIndex++ ) { For(xIndex := lowerLeftX + xOffset++ ,xIndex <=? lowerLeftX + height,xIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,yIndex); } } pointCount; } Procedure("hollowRectangle2",["lowerLeftX","lowerLeftY","width","height","pointCount"]) { Local(xIndex,yIndex); For(xIndex := lowerLeftX,xIndex <=? lowerLeftX + width,xIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,lowerLeftY); GeoGebraPoint("A" ~ ToString(pointCount++ ),xIndex,lowerLeftY + height); } For(yIndex := lowerLeftY + 1,yIndex <=? (lowerLeftY + height) - 1,yIndex++ ) { GeoGebraPoint("A" ~ ToString(pointCount++ ),lowerLeftX,yIndex); GeoGebraPoint("A" ~ ToString(pointCount++ ),lowerLeftX + width,yIndex); } pointCount; } Procedure("mainProcedure",[]) { GeoGebraClear(); pointCount := 1; alternateCount := 1; yIndex := 1; For(xIndex := 1,xIndex <=? 35,xIndex +:= 6) { If(alternateCount =? 1) { pointCount := solidRectangle(xIndex,yIndex,4,5,pointCount); } Else If(alternateCount =? 2) { pointCount := rightTriangle(xIndex,yIndex,4,pointCount); } Else If(alternateCount =? 3) { pointCount := hollowRectangle2(xIndex,yIndex,4,5,pointCount); } alternateCount++; If(alternateCount =? 4) { alternateCount := 1; } yIndex := yIndex + 3; } } mainProcedure(); PASS: The code does not throw an exception when parsed. (1/1) PASS: The fold is not empty. (1/1) PASS: The ':' operator is not used. (1/1) PASS: The results of all arithmetic operations are assigned to a variable. For example 'count := (count + 1) is okay, but (count + 1) by itself not okay. (1/1) PASS: The program uses variable names that are longer than a single character. (1/1) PASS: The program uses variable names that start with a lower case letter. (1/1) PASS: The version of "Append" that does not end with a '!' is not used. (1/1) ------------------------------------------ PASS: MathPiper version = .224. (0/0) PASS: "mainProcedure()" is the last expression in the fold. (1/1) solidRectangle: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure exists and it has the correct name. (1/1) rightTriangle: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure exists and it has the correct name. (1/1) hollowRectangle2: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure exists and it has the correct name. (1/1) mainProcedure: PASS: The procedure does not throw an exception when defined. (1/1) PASS: The procedure has zero formal parameters. (1/1) PASS: One copy of a call to "GeoGebraClear" is present . (1/1) PASS: Exactly one loop is used. (1/1) PASS: One copy of a call to "solidRectangle" is present . (1/1) PASS: One copy of a call to "rightTriangle" is present . (1/1) PASS: One copy of a call to "hollowRectangle2" is present . (1/1) PASS: The procedure produces a correct result. (1/1) 22/22 passes . %/output %/group