Pyret Testing Design and Clarity Guide
Testing
- All functions require examples/test cases, including helper functions. Functions that output images require examples; all other functions require test cases.
- Examples/test cases should reflect various input scenarios so that you exercise the possible main behaviors of your function. You do not need to test every input or every input combination, but rather enough to be confident that your function works with various inputs.
- Test the “edge cases” of functions. For example, functions that take in numeric inputs and work differently depending on the range that number is in should test the boundaries of those ranges.
- Even if your function does not work as expected, you can still write examples/test cases for it and receive full testing credit.
Example of good testing:
fun abs-val(x :: Number) -> Number:
doc: ``` description: give the absolute value of the input number
inputs : x, a number
output : the absolute value of x ```
... # i never figured this function out
where:
abs-val(-4) is 4 # test the first branch of the if
abs-val(0) is 0 # 0 is an "edge case"
abs-val(3) is 3 # test the else branch of the if
end
A handin with this work would receive full testing points.
Design
- Use constants where appropriate.
rectangle(500, 300, "solid", "green")
should be rewritten to:width = 500
rectangle(width, 3/5 * width, "solid", "green")
- Use helper functions where appropriate.
stairs = beside-align("bottom", rectangle(50, 50, "solid", "gray"),
beside-align("bottom", rectangle(50, 100, "solid", "gray"),
beside-align("bottom", rectangle(50, 150, "solid", "gray"),
rectangle(50, 200, "solid", "gray"))))
could be rewritten as:
stair-width = 50
fun stair(height :: Number) -> Image:
doc: "make an individual stair given its height"
rectangle(stair-width, height, "solid", "gray")
end
stairs = beside-align("bottom", stair(50),
beside-align("bottom", stair(100),
beside-align("bottom", stair(150), stair(200))))
- Make sure your helper functions and constants are not redundant.
There is no point in making this function:fun string-lower(s :: String) -> String:
string-to-lower(s)
end
since you could always use string-to-lower
instead.
Clarity
-
Write docstrings for all functions, including helper and nested functions.
A good docstring gives a description of the function, including its input(s) and output. Ideally, by looking at the docstring you know what the function does and how to use it without looking at the function body itself.
fun three-stripes(bot-col :: String, mid-col :: String,
top-col :: String) -> Image:
doc: ```
description: make a three-striped image with the input colors
inputs:
- bot-col : the color of the bottom stripe
- mid-col : the color of the middle stripe
- top-col : the color of the top stripe
output: a three-striped image with the colors of the stripes
corresponding to the input colors
Bad docstring descriptions
doc: "helper function for flag making"
doc: "output the right image for this problem"
doc: "uses above to stack images"
- how your function body actually works is irrelevant to the docstring.
-
Give constants and helper functions useful names.
n1 = 3.1415
n2 = 500
n3 = 30
fun helper(x):
x + 3
end
should be rewritten as (for example)
pi = 3.1415
flag-width = 500
circle-radius = 30
fun add-3(x):
doc: ```
description: add three to the input
inputs : x, an integer
output : the result of adding 3 to x
x + 3
end
-
All functions require type annotations on both inputs and output.
-
Names of constants and functions should be lower case and dash separated. For configuration constants (for example the height of a character) it is acceptable to use all caps dash-separated names.
# Good Pyret Style:
flag-width = 500
width-to-height-ratio = 3/5
CHARACTER-HEIGHT = 40
# Bad Pyret Style:
flag_width = 500
widthHeightRatio = 3/5
CharacterHeight = 40
-
Keep lines under 80 characters. You will at some point see a vertical dashed blue line in Pyret.
If you see this line, your lines are too long and you need to add linebreaks (press enter
at places in your code).
The 80 character limit applies even when you have long strings and/or docstrings. Long docstrings can be written using the backtick (`) button:
fun f()
doc: ``` return 2; no inputs, always outputs 2 ```
2
end
-
Indent your code properly. You can do this by pressing ctrl-a
then tab
on Windows and Linux, or cmd-a
then tab
on Mac.
Pyret Testing Design and Clarity Guide
Testing
Example of good testing:
A handin with this work would receive full testing points.
Design
rectangle(500, 300, "solid", "green")
should be rewritten to:width = 500 rectangle(width, 3/5 * width, "solid", "green")
stairs = beside-align("bottom", rectangle(50, 50, "solid", "gray"), beside-align("bottom", rectangle(50, 100, "solid", "gray"), beside-align("bottom", rectangle(50, 150, "solid", "gray"), rectangle(50, 200, "solid", "gray"))))
could be rewritten as:
stair-width = 50 fun stair(height :: Number) -> Image: doc: "make an individual stair given its height" rectangle(stair-width, height, "solid", "gray") end stairs = beside-align("bottom", stair(50), beside-align("bottom", stair(100), beside-align("bottom", stair(150), stair(200))))
There is no point in making this function:
since you could always usefun string-lower(s :: String) -> String: string-to-lower(s) end
string-to-lower
instead.Clarity
Write docstrings for all functions, including helper and nested functions.
A good docstring gives a description of the function, including its input(s) and output. Ideally, by looking at the docstring you know what the function does and how to use it without looking at the function body itself.
fun three-stripes(bot-col :: String, mid-col :: String, top-col :: String) -> Image: doc: ``` description: make a three-striped image with the input colors inputs: - bot-col : the color of the bottom stripe - mid-col : the color of the middle stripe - top-col : the color of the top stripe output: a three-striped image with the colors of the stripes corresponding to the input colors
Bad docstring descriptions
doc: "helper function for flag making"
doc: "output the right image for this problem"
doc: "uses above to stack images"
- how your function body actually works is irrelevant to the docstring.Give constants and helper functions useful names.
n1 = 3.1415 n2 = 500 n3 = 30 fun helper(x): x + 3 end
should be rewritten as (for example)
All functions require type annotations on both inputs and output.
Names of constants and functions should be lower case and dash separated. For configuration constants (for example the height of a character) it is acceptable to use all caps dash-separated names.
Keep lines under 80 characters. You will at some point see a vertical dashed blue line in Pyret.
If you see this line, your lines are too long and you need to add linebreaks (press
enter
at places in your code).The 80 character limit applies even when you have long strings and/or docstrings. Long docstrings can be written using the backtick (`) button:
Indent your code properly. You can do this by pressing
ctrl-a
thentab
on Windows and Linux, orcmd-a
thentab
on Mac.