Skip to content

Commit

Permalink
PyGrader v2 (hmontero1205#4)
Browse files Browse the repository at this point in the history
* removed sys.path before import in grade.py

* PARINTING MOD: now has color variables

* added more printing functions

* rewrote prIntro

* moved points and description into a list of tupples (p,d)

* moved rubric_item.py under common, and fixed white space in E2,3

* hw1.py add self.part# and store selection in part1

* allow grader to slecet file for all parts

* cleaned up some code

* option to run in tmux

* add hw_setup.py and moved grading to ~/grade/hw1/student

* setup hw1 dir and extracting .tgz for all hws

* rename run_and_prompt to grade_section and reagranged code

* can now run grade.py with all, A...n, A1..An

* grade.py not works with -c, -g, -t flags

* updated readme

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Change hw1 tarball setup

* HW1 refactoring and logic improvements (hmontero1205#3)

* Update README.md

* Add pylint.yml

* Add pylintrc

* Update pylint.yml

* Fix a lot of the linting errors

* Update .pylintrc

* Update pylint.yml

* Fix string concatenation

* Fix the rest of the linting errors

* Change run_commend to run_command

* Update README.md

* Clean up sed usage between patterns

* Count instances of test_tree.py and print OK/OOPS in utils

* removed sys.path before import in grade.py

* PARINTING MOD: now has color variables

* added more printing functions

* rewrote prIntro

* moved points and description into a list of tupples (p,d)

* moved rubric_item.py under common, and fixed white space in E2,3

* hw1.py add self.part# and store selection in part1

* allow grader to slecet file for all parts

* cleaned up some code

* option to run in tmux

* add hw_setup.py and moved grading to ~/grade/hw1/student

* setup hw1 dir and extracting .tgz for all hws

* rename run_and_prompt to grade_section and reagranged code

* can now run grade.py with all, A...n, A1..An

* grade.py not works with -c, -g, -t flags

* updated readme

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Change hw1 tarball setup

* Simply hw_setup as per Dave's suggestions

* Fix old references

* Get mod_name manually just in case in E2-3

* Add support for extracting between a line and EOF

Co-authored-by: dd2912 <[email protected]>
Co-authored-by: Debbie Debian <debbie@vm20>
Co-authored-by: Dave <[email protected]>

* Detect if hw was set up already

* Refactor logic for detecting mispelled file names

* Store deadline in ~/.grade/hwN and use it to check for late submissions

* Add SIGINT handler and ^D logic for input

* Store grades in a dict

* Persist grades through sessions

* Dump grades with indentation for human-readability

* Show previous grade if already graded

* Change single letter args to longer form, save them in an env dict

* Update README

* FIX: linter errors

* continue to fix error

* fixing linter

* remove require docstring

* remove require docstring

* remove require docstring: fingers crossed

* ignore bad-continuation

* movever tumux_grade logic into main

* fixed most of liter

* fixed almost all issues, they are a few errors im not sure

* fixed typo in printing.py

* Fix the remaining linting errors

* Clean up some indentation and comments

* Stupid indentation wtf

Co-authored-by: Debbie Debian <debbie@vm20>
Co-authored-by: Dave <[email protected]>
Co-authored-by: dd2912 <[email protected]>
  • Loading branch information
4 people authored and PalashSharma20 committed Feb 13, 2025
1 parent fa5b8a7 commit 32a4fa2
Show file tree
Hide file tree
Showing 10 changed files with 528 additions and 145 deletions.
12 changes: 6 additions & 6 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,17 @@ disable=print-statement,
deprecated-sys-function,
exception-escape,
comprehension-escape,
inconsistent-return-statements,
inconsistent-return-statements,
no-else-continue,
no-name-in-module,
too-few-public-methods,
subprocess-run-check,
subprocess-run-check,
import-error,
no-self-use,
missing-function-docstring,
bad-continuation,
W0311,
no-else-return
missing-function-docstring,
bad-continuation,
W0311,
no-else-return

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
54 changes: 48 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,52 @@
[![pylint](https://github.com/cs4118/new_grading_scripts/workflows/pylint/badge.svg)](https://github.com/cs4118/new_grading_scripts/actions?query=workflow%3Apylint)
# Guide

to test:
## Setting up the env

- unzip hw1 solutions.tgz into hw1 folder
- you should now have multiple dir with student uni's
- choose one {uni}/ to extact their tgz submition
- run ./grade.py hw1 {table} {uni}
- {table} is one of A,B,C,D,E (don't use A, it is not handled yet)
- Obtain `hw1.tgz` as follows: Download the zipped submissions file from
Courseworks, unzip, and place all tarballs in a directory called `hw1`.
Then, make a tarball out of that. TODO: make this process better.

- Run `./hw_setup.py hw1 -f {path to hw1.tgz}`

This will create a dir called `.grade/` in your `HOME` dir. In addition to
serving as the workspace for grading submissions, grades and the hw deadline
will also be stored here. The directory will look like this:
```
~
\_ .grade/
\_ hw1/
\_ .grades.json
\_ .deadline
\_ uni1/
\_ uni2/
|
|
\_ uni3/
```

## Running the grading script
```
Usage: grade.py [-h]
[--amend | --continue | --grade-only | --regrade | --test-only]
hw student table
Entry point to grade OS HWs
positional arguments:
hw homework # to grade
student the name of student/group to grade
table table to grade
optional arguments:
-h, --help show this help message and exit
--amend Amend comment without rerunning test for that item
--continue Continue from last graded item
--grade-only Grade without running any tests
--regrade Regrade an item
--test-only Run tests without grading
```

NOTES
- amend hasn't been implemented
- regrade might be redundant
83 changes: 65 additions & 18 deletions common/printing.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,90 @@
"""printing.py: Colored output helpers"""

CEND = '\33[0m'
CBOLD = '\33[1m'
CITALIC = '\33[3m'
CURL = '\33[4m'
CBLINK = '\33[5m'
CBLINK2 = '\33[6m'
CSELECTED = '\33[7m'

CBLACK = '\33[30m'
CRED = '\33[31m'
CGREEN = '\33[32m'
CYELLOW = '\33[33m'
CBLUE = '\33[34m'
CVIOLET = '\33[35m'
CBEIGE = '\33[36m'
CWHITE = '\33[37m'

CBLACKBG = '\33[40m'
CREDBG = '\33[41m'
CGREENBG = '\33[42m'
CYELLOWBG = '\33[43m'
CBLUEBG = '\33[44m'
CVIOLETBG = '\33[45m'
CBEIGEBG = '\33[46m'
CWHITEBG = '\33[47m'

CGREY = '\33[90m'
CRED2 = '\33[91m'
CGREEN2 = '\33[92m'
CYELLOW2 = '\33[93m'
CBLUE2 = '\33[94m'
CVIOLET2 = '\33[95m'
CCYAN = '\33[96m'
CGRAYL = '\33[97m'

CGREYBG = '\33[100m'
CREDBG2 = '\33[101m'
CGREENBG2 = '\33[102m'
CYELLOWBG2 = '\33[103m'
CBLUEBG2 = '\33[104m'
CVIOLETBG2 = '\33[105m'
CBEIGEBG2 = '\33[106m'
CWHITEBG2 = '\33[107m'

def print_red(s):
"""Prints s in red"""
print("\033[91m{}\033[00m" .format(s))
print("{}{}{}".format(CRED2, s, CEND))

def print_green(s):
"""Prints s in green"""
print("\033[92m{}\033[00m" .format(s))
print("{}{}{}".format(CGREEN2, s, CEND))

def print_yellow(s):
"""Prints s in yellow"""
print("\033[93m{}\033[00m" .format(s))
print("{}{}{}".format(CYELLOW2, s, CEND))

def print_light_purple(s):
"""Prints s in light purple"""
print("\033[95m{}\033[00m" .format(s))
print("{}{}{}".format(CVIOLET2, s, CEND))

def print_purple(s):
"""Prints s in purple"""
print("\033[35m{}\033[00m" .format(s))
print("{}{}{}".format(CVIOLET, s, CEND))

def print_cyan(s):
"""Prints s in cyan"""
print("\033[96m{}\033[00m" .format(s))
print("{}{}{}" .format(CCYAN, s, CEND))

def print_light_gray(s):
"""Prints s in light gray"""
print("\033[97m{}\033[00m" .format(s))
print("{}{}{}".format(CGRAYL, s, CEND))

def print_line():
print_cyan('-'*85)

def print_black(s):
"""Prints s in black"""
print("\033[98m{}\033[00m" .format(s))
def print_double():
print_cyan('='*85)

def print_intro(team, hw, part):
"""Prints the intro banner for the grading script"""
print_cyan("="*85)
print("\033[96m{}\033[00m \033[95m{}\033[00m \033[96m {}\033[00m \033[95m{}"
"\033[96m {}\033[00m \033[95m{}\033[00m".format("Team:", team,
"HW:", hw,
"Rubric Table:",
part))
print_cyan("="*85)
print_double()
print(f"{CCYAN}Team:{CEND} {CVIOLET2}{team}{CEND} {CCYAN}HW:{CEND} "\
f"{CVIOLET2}{hw}{CEND} {CCYAN}Rubric Table:{CEND} {CVIOLET2}{part}{CEND}")
print_double()

def print_outro(table_item):
print_line()
print_green("End test of {}".format(table_item))
print_double()
7 changes: 2 additions & 5 deletions table/rubric_item.py → common/rubric_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ class RubricItem():
"""Representation of a rubric item
Attributes:
table: the table letter (e.g. A, B, etc)
table_item: the number of the item (e.g. A1, C3, etc)
desc: the desciption of this item
points: value of this item
desc: tuple containing point value and desc of item
tester: callback function to grade this item
"""

def __init__(self, table_item, desc, points, funct):
def __init__(self, table_item, desc, funct):
self.table_item = table_item
self.desc = desc
self.points = points
self.tester = funct
36 changes: 36 additions & 0 deletions common/submissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""submissions.py: Utils that help dealing with submissions"""

import pickle
from datetime import datetime, timedelta
import common.printing as printing

def check_late(deadline_path, iso_timestamp):
"""Checks if iso_timestamp is past the deadline
Arguments:
deadline_path: Location of the serialized datetime object
representing the deadline (e.g. ~/.grade/hw1/.deadline)
iso_timestamp: The ISO timestamp to compare against deadline
(e.g. git log -n 1 --format='%aI')
"""
submission = datetime.fromisoformat(iso_timestamp)
with open(deadline_path, "rb") as d:
deadline = pickle.load(d)

if submission <= deadline:
printing.print_green("[ SUBMISSION ON TIME ]")
return False

# Let's calculaute the difference
diff = submission - deadline

# Wow this is like a page table walk xD
days, hrs_r = divmod(diff, timedelta(days=1))
hrs, mins_r = divmod(hrs_r, timedelta(hours=1))
mins, secs_r = divmod(mins_r, timedelta(minutes=1))
secs, _ = divmod(secs_r, timedelta(seconds=1))

printing.print_red(f"[SUBMISSION LATE]: Submitted {days} days, "
f"{hrs} hrs, {mins} mins, "
f"and {secs} secs late")
return True
Loading

0 comments on commit 32a4fa2

Please sign in to comment.