-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move docs from Django to website #72
Open
JasonGrace2282
wants to merge
13
commits into
tjcsl:master
Choose a base branch
from
JasonGrace2282:move-docs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 10 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
a9251b2
Remove docs from Tin Django
JasonGrace2282 19637cd
Add new docs
JasonGrace2282 7096bc8
Fix very high tolerance
JasonGrace2282 e9a1a0e
fix typo Source -> Score
JasonGrace2282 cf1118f
Improve file-io grader to prevent race conditions
JasonGrace2282 eee6281
use absolute paths in example to match docs
JasonGrace2282 a4c92d0
Split into dev vs user docs
JasonGrace2282 c37b907
fix typo
JasonGrace2282 9f8d880
Fix feedback
JasonGrace2282 feb7a66
Add back docs link
JasonGrace2282 0d1e46a
Fix navbar
JasonGrace2282 1e856cf
Use tempfile for file io example
JasonGrace2282 de37736
remove useless icon
JasonGrace2282 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
############## | ||
Contacting Tin | ||
############## | ||
|
||
If you need to get in touch with the Tin team, you can email us at [email protected] | ||
|
||
Alternatively, you can visit the Syslab at TJ to talk to us in person. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
##### | ||
Usage | ||
##### | ||
|
||
If you're interested in writing a grader, check out | ||
the pages below: | ||
|
||
.. toctree:: | ||
:maxdepth: 1 | ||
:caption: Grader Documentation | ||
|
||
usage/graders/writing_graders | ||
usage/graders/examples |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
############### | ||
Grader Examples | ||
############### | ||
|
||
If you haven't already, check out :doc:`writing_graders` before | ||
looking at some examples. | ||
|
||
The following graders range from simple, to more sophisticated. | ||
|
||
.. toctree:: | ||
:caption: Sample Graders | ||
:maxdepth: 1 | ||
|
||
examples/file_io | ||
examples/fibonacci | ||
examples/addition | ||
|
||
To see an example of a grader that looks for a specific function name | ||
in a student script, see :doc:`addition <examples/addition>`. | ||
|
||
To see an example of a grader that gives specific permissions on files, | ||
check out :doc:`file_io <examples/file_io>`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
from __future__ import annotations | ||
|
||
import importlib.util | ||
import sys | ||
import traceback | ||
from collections.abc import Callable | ||
from pathlib import Path | ||
|
||
student_code_path: str = sys.argv[2] | ||
username: str = sys.argv[3] | ||
log_file = Path(sys.argv[4]) | ||
|
||
test_cases = ( | ||
(1, 2), | ||
(3, 4), | ||
(1000, 20345), | ||
(54, 78), | ||
) | ||
|
||
secret_test_cases = ( | ||
(127, 856.7), | ||
(789.101, 101112), | ||
) | ||
|
||
|
||
def import_module(modname: str = "student_submission", func_name="add_num") -> Callable: | ||
"""Imports the student submission and returns the function with the given name. | ||
|
||
It accomplishes this by utilizing a lot of the machinery provided by the python module | ||
``importlib``. If you don't understand how it works, feel free to just copy paste this | ||
function and pass a different value for the ``func_name`` parameter. | ||
""" | ||
|
||
spec = importlib.util.spec_from_file_location(modname, student_code_path) | ||
|
||
# these are probably grader errors and not student errors, so we raise an | ||
# exception instead of printing | ||
if spec is None: | ||
raise ImportError(f"Could not load spec for module {student_code_path!r}") | ||
if spec.loader is None: | ||
raise ImportError(f"No loader found for module {student_code_path!r} with {spec=!r}") | ||
|
||
submission = importlib.util.module_from_spec(spec) | ||
|
||
if submission is None: | ||
raise ImportError("Module spec is None") | ||
|
||
sys.modules[modname] = submission | ||
|
||
try: | ||
spec.loader.exec_module(submission) | ||
except Exception: | ||
# this traceback could provide sensitive information, so we don't provide it to students | ||
print("Could not test submission, an exception was raised while initializing.") | ||
log_file.write_text(f"Student {username} import error:\n\n" + traceback.format_exc()) | ||
# it's not our fault so we exit 0 | ||
sys.exit(0) | ||
|
||
try: | ||
func = getattr(submission, func_name) | ||
except AttributeError: | ||
print(f"Could not find function {func_name!r}") | ||
sys.exit(0) | ||
|
||
return func | ||
|
||
|
||
def run_submission(func: Callable) -> None: | ||
# grade submissions | ||
failing_cases = 0 | ||
tol = 1e-8 | ||
for x, y in test_cases: | ||
try: | ||
# take into account floating point error | ||
if func(x, y) - (x + y) > tol: | ||
print(f"Failed on test case {x=},{y=}") | ||
failing_cases += 1 | ||
except Exception: | ||
print(f"Code errored on test case {x=},{y=}") | ||
failing_cases += 1 | ||
|
||
for idx, (x, y) in enumerate(secret_test_cases): | ||
try: | ||
if func(x, y) - (x + y) > tol: | ||
print(f"Failed on secret test case {idx}") | ||
failing_cases += 1 | ||
except Exception: | ||
print(f"Code errored on secret test case {idx}") | ||
failing_cases += 1 | ||
|
||
raw = 1 - failing_cases / (len(test_cases) + len(secret_test_cases)) | ||
# print score, rounding to two decimal places | ||
print(f"Score: {raw * 100:.2f}%") | ||
|
||
|
||
def main() -> None: | ||
submission = import_module() | ||
run_submission(submission) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
########### | ||
Add Numbers | ||
########### | ||
|
||
---------- | ||
Assignment | ||
---------- | ||
Write a program that has a function called ``add_num`` that takes two parameters | ||
:math:`x` and :math:`y`, and returns their sum :math:`x+y`. | ||
|
||
|
||
---------------- | ||
Example Solution | ||
---------------- | ||
|
||
.. code-block:: python | ||
|
||
def add_num(x, y): | ||
return x + y | ||
|
||
|
||
-------------- | ||
Example Grader | ||
-------------- | ||
|
||
.. literalinclude:: addition.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from __future__ import annotations | ||
|
||
import subprocess | ||
import sys | ||
|
||
# this assignment is out of 100 points | ||
N = 100 | ||
score = 0 | ||
failing_cases = [] | ||
|
||
# set up the fibonacci sequence so that we can check student answers | ||
cur_fib = 1 | ||
next_fib = 1 | ||
|
||
# parse information from Tin | ||
submission, _submission_file, username, log_file, *_ = sys.argv[1:] | ||
|
||
for i in range(1, N + 1): | ||
try: | ||
# pass n as an argument to the student submission | ||
res = subprocess.run( | ||
[sys.executable, submission, str(i)], | ||
# it shouldn't take more than 5 seconds | ||
timeout=5, | ||
stdin=subprocess.DEVNULL, | ||
capture_output=True, | ||
check=False, | ||
) | ||
# the student submission is too slow | ||
except subprocess.TimeoutExpired: | ||
print(f"Script timeout for number {i}") | ||
else: | ||
# check if the script failed | ||
if res.stderr or res.returncode != 0: | ||
print(f"Script error for number {i}") | ||
failing_cases.append(i) | ||
continue | ||
|
||
try: | ||
stdout = res.stdout.strip().decode("utf-8") | ||
except UnicodeDecodeError: | ||
print(f"Non-UTF-8 output for number {i}") | ||
failing_cases.append(i) | ||
continue | ||
|
||
if not stdout.isdigit(): | ||
print(f"Non-integer printed for number {i}") | ||
failing_cases.append(i) | ||
continue | ||
|
||
student_ans = int(stdout) | ||
if student_ans == cur_fib: | ||
score += 1 | ||
else: | ||
print(f"Invalid result for number {i} (printed {student_ans}, answer is {cur_fib})") | ||
failing_cases.append(i) | ||
|
||
# calculate our next fibonacci number | ||
next_fib, cur_fib = cur_fib + next_fib, next_fib | ||
|
||
print(f"Score: {score / N}") | ||
|
||
with open(log_file, "a", encoding="utf-8") as logfile: | ||
logfile.write( | ||
f"User: {username}; Score: {score}/{N}; Failing test cases: {', '.join(str(case) for case in failing_cases)}\n" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
############# | ||
Nth Fibonacci | ||
############# | ||
|
||
---------- | ||
Assignment | ||
---------- | ||
Write a program that takes an integer ``n`` and returns the nth Fibonacci number. | ||
|
||
--------------- | ||
Sample Solution | ||
--------------- | ||
|
||
.. code-block:: python | ||
|
||
import sys | ||
|
||
n = int(sys.argv[1])-1 | ||
nums = [0, 1] | ||
while n >= len(nums): | ||
nums.append(nums[-1] + nums[-2]) | ||
return nums[n] | ||
|
||
|
||
|
||
|
||
-------------- | ||
Example Grader | ||
-------------- | ||
|
||
.. literalinclude:: fibonacci.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from __future__ import annotations | ||
|
||
import subprocess | ||
import sys | ||
from pathlib import Path | ||
|
||
submission = sys.argv[1] | ||
student_submission = Path(sys.argv[2]) | ||
|
||
# input file is in the same directory as our grader (this file) | ||
# make sure to use the absolute path | ||
INPUT_FILE = (Path(__file__).parent / "input.txt").resolve() | ||
|
||
# output file is in the same directory as the student submission | ||
# This way we can avoid multiple submissions trying to write to | ||
# the same file. | ||
# Again, making sure to use the absolute path | ||
OUTPUT_FILE = (student_submission.parent / "output.txt").resolve() | ||
|
||
|
||
command = [ | ||
sys.executable, | ||
submission, | ||
# give read permissions to the input | ||
# making sure to use the absolute path to the file | ||
"--read", | ||
INPUT_FILE, | ||
# and allow them to read/write to the output file | ||
"--write", | ||
OUTPUT_FILE, | ||
# and then pass the arguments to the student submission | ||
"--", | ||
INPUT_FILE, | ||
OUTPUT_FILE, | ||
] | ||
|
||
resp = subprocess.run( | ||
command, | ||
stdout=sys.stdout, | ||
stderr=subprocess.STDOUT, | ||
check=False, | ||
) | ||
|
||
if ( | ||
resp.returncode != 0 | ||
or not OUTPUT_FILE.exists() | ||
or OUTPUT_FILE.read_text() != INPUT_FILE.read_text() | ||
): | ||
print("Score: 0%") | ||
else: | ||
print("Score: 100%") |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extra comments and organization here are great!