From 40140668dee9a9852ef4cf8f46f6a6226f86178d Mon Sep 17 00:00:00 2001 From: BoYanZh <32470225+BoYanZh@users.noreply.github.com> Date: Sun, 4 Oct 2020 05:08:15 +0800 Subject: update: rubric in comment --- VG101GradeHelper.py | 5 +-- worker/CanvasWorker.py | 30 +++++++++------- worker/GiteaWorker.py | 98 +++++++++++++++++++++++++++++++++++--------------- worker/JOJWorker.py | 10 +++++- 4 files changed, 100 insertions(+), 43 deletions(-) diff --git a/VG101GradeHelper.py b/VG101GradeHelper.py index 6918d6f..4073d94 100644 --- a/VG101GradeHelper.py +++ b/VG101GradeHelper.py @@ -58,9 +58,10 @@ def parse(): if __name__ == "__main__": hgroups = json.load(open("hgroups.json")) + names = [item[1] for value in hgroups.values() for item in value] pwd = os.getcwd() args = parse() - indvScores, groupScores, jojScores = None, None, None + indvScores, groupScores, jojScores = {}, {}, {} giteaWorker = GiteaWorker(args, hgroups, [item[0] for item in JOJ_INFO["problemInfo"]]) if args.indv: @@ -72,7 +73,7 @@ if __name__ == "__main__": jojScores = jojWorker.checkGroupJOJ(JOJ_INFO) if args.score: canvasWorker = CanvasWorker(args, RUBRIC, CANVAS_TOKEN, COURSE_ID, - indvScores, groupScores, jojScores) + names, indvScores, groupScores, jojScores) canvasWorker.exportScores("scores.json") if args.upload: canvasWorker.grade2Canvas() diff --git a/worker/CanvasWorker.py b/worker/CanvasWorker.py index 1d86189..99ad61c 100644 --- a/worker/CanvasWorker.py +++ b/worker/CanvasWorker.py @@ -9,6 +9,7 @@ class CanvasWorker(): rubric, canvasToken, courseID, + names, indvScores, groupScores, jojScores, @@ -20,23 +21,26 @@ class CanvasWorker(): self.users = self.course.get_users() self.assignments = self.course.get_assignments() self.logger = logger - if not indvScores or not groupScores or not jojScores: - raise Exception("Not enough scores") - self.scores = indvScores - for key, value in self.scores.items(): + self.scores = {} + self.names = names + for key in names: self.scores[key] = { - **value, - **groupScores[key], - **jojScores[key] + **indvScores.get(key, {}), + **groupScores.get(key, {}), + **jojScores.get(key, {}) } def generateHomeworkData(self, scoreInfo): score = 0 comment = [] - for key, value in self.rubric: - for _ in range(scoreInfo[key]): - score -= value[0] - comment.append(value[1]) + for key, value in self.rubric.items(): + for _ in range(scoreInfo.get(key, 0)): + score += value[0] + comment.append(f"{value[1]}, {value[0]}") + comment.extend( + scoreInfo.get("indvComment", []) + + scoreInfo.get("groupComment", []) + + scoreInfo.get("jojComment", [])) if not comment: comment = ['good job'] return { 'submission': { @@ -56,8 +60,10 @@ class CanvasWorker(): lambda user: user.id == submission.user_id) if currentUser is None: continue name = currentUser.name.strip() + if name not in self.names: continue data = self.generateHomeworkData(self.scores[name]) - submission.edit(**data) + self.logger.debug(data.__repr__()) + # submission.edit(**data) def exportScores(self, fileName): json.dump(self.scores, diff --git a/worker/GiteaWorker.py b/worker/GiteaWorker.py index 8c4c775..8bbbe60 100644 --- a/worker/GiteaWorker.py +++ b/worker/GiteaWorker.py @@ -43,6 +43,7 @@ class GiteaWorker(): stuName: { "indvFailSubmit": 0, "indvUntidy": 0, + "indvComment": [], } for _, stuName in self.hgroups[repoName] } @@ -52,9 +53,12 @@ class GiteaWorker(): self.logger.warning( f"{repoName} {stuID} {stuName} branch missing") scores[stuName]['indvFailSubmit'] = 1 + scores[stuName]['indvComment'].append( + "individual branch missing") continue repo.git.checkout(f"{stuID}", "-f") - repo.git.pull("origin", f"{stuID}", "--rebase", "-f") + repo.git.reset('--hard') + repo.git.pull("origin", f"{stuID}", "-f") repo.git.reset(f"origin/{stuID}", "--hard") repo.git.clean("-d", "-f", "-x") if self.args.dir: @@ -67,15 +71,20 @@ class GiteaWorker(): self.logger.warning( f"{repoName} {stuID} {stuName} h{hwNum} dir missing") scores[stuName]['indvFailSubmit'] = 1 - for path in [ - os.path.join('hwrepos', repoName, f"h{hwNum}", fn) - for fn in self.mandatoryFiles - ]: - if not os.path.exists(path): - self.logger.warning( - f"{repoName} {stuID} {stuName} h{hwNum} file missing" - ) - scores[stuName]['indvFailSubmit'] = 1 + scores[stuName]['indvComment'].append( + f"h{hwNum} dir missing") + else: + for fn, path in [(fn, + os.path.join('hwrepos', repoName, + f"h{hwNum}", fn)) + for fn in self.mandatoryFiles]: + if not os.path.exists(path): + self.logger.warning( + f"{repoName} {stuID} {stuName} h{hwNum}/{fn} file missing" + ) + scores[stuName]['indvFailSubmit'] = 1 + scores[stuName]['indvComment'].append( + f"h{hwNum}/{fn} file missing") self.logger.debug(f"{repoName} {stuID} {stuName} succeed") if tidy: dirList = os.listdir(os.path.join('hwrepos', repoName)) @@ -87,8 +96,12 @@ class GiteaWorker(): ], dirList)) if dirList: self.logger.warning( - f"{repoName} {stuID} {stuName} untidy {dirList.__repr__()}") + f"{repoName} {stuID} {stuName} untidy {dirList.__repr__()}" + ) scores[stuName]['indvUntidy'] = 1 + scores[stuName]['indvComment'].append( + f"individual branch redundant files: {dirList.__repr__()}" + ) if os.path.exists(hwDir): dirList = os.listdir(hwDir) dirList = list( @@ -97,9 +110,12 @@ class GiteaWorker(): startswith("README."), dirList)) if dirList: self.logger.warning( - f"{repoName} {stuID} {stuName} h{hwNum} untidy {dirList.__repr__()}" + f"{repoName} {stuID} {stuName} h{hwNum}/ untidy {dirList.__repr__()}" ) scores[stuName]['indvUntidy'] = 1 + scores[stuName]['indvComment'].append( + f"individual branch redundant files: {dirList.__repr__()}" + ) except Exception: self.logger.error(f"{repoName} {stuID} {stuName} error") self.logger.error(traceback.format_exc()) @@ -108,13 +124,15 @@ class GiteaWorker(): def checkGroupProcess(self, groupNum, hwNum): tidy = self.args.tidy repoName = f"hgroup-{groupNum:02}" - if not os.path.exists(os.path.join('hwrepos', repoName)): + repoDir = os.path.join('hwrepos', repoName) + hwDir = os.path.join(repoDir, f"h{hwNum}") + if not os.path.exists(repoDir): repo = git.Repo.clone_from( f"https://focs.ji.sjtu.edu.cn/git/vg101/{repoName}", - os.path.join('hwrepos', repoName), + repoDir, branch='master') else: - repo = git.Repo(os.path.join('hwrepos', repoName)) + repo = git.Repo(repoDir) repo.git.checkout("master", "-f") repo.git.fetch("--tags", "-f") tagNames = [tag.name for tag in repo.tags] @@ -122,6 +140,7 @@ class GiteaWorker(): stuName: { "groupFailSubmit": 0, "groupUntidy": 0, + "groupComment": [], } for _, stuName in self.hgroups[repoName] } @@ -129,23 +148,27 @@ class GiteaWorker(): self.logger.warning(f"{repoName} tags/h{hwNum} missing") for _, stuName in self.hgroups[repoName]: scores[stuName]['groupFailSubmit'] = 1 + scores[stuName]['groupComment'].append( + f"tags/h{hwNum} missing") return repo.git.checkout(f"tags/h{hwNum}", "-f") - if not os.path.exists(os.path.join('hwrepos', repoName, f"h{hwNum}")): + if not os.path.exists(hwDir): self.logger.warning(f"{repoName} h{hwNum} dir missing") for _, stuName in self.hgroups[repoName]: scores[stuName]['groupFailSubmit'] = 1 - for path in [ - os.path.join('hwrepos', repoName, f"h{hwNum}", fn) - for fn in self.mandatoryFiles - ]: - if not os.path.exists(path): - self.logger.warning(f"{repoName} h{hwNum} file missing") - for _, stuName in self.hgroups[repoName]: - scores[stuName]['groupFailSubmit'] = 1 + scores[stuName]['groupComment'].append(f"h{hwNum} dir missing") + else: + for fn, path in [(fn, os.path.join(hwDir, fn)) + for fn in self.mandatoryFiles]: + if not os.path.exists(path): + self.logger.warning(f"{repoName} h{hwNum}/{fn} file missing") + for _, stuName in self.hgroups[repoName]: + scores[stuName]['groupFailSubmit'] = 1 + scores[stuName]['groupComment'].append( + f"h{hwNum}/{fn} missing") self.logger.debug(f"{repoName} checkout to tags/h{hwNum} succeed") if tidy: - dirList = os.listdir(os.path.join('hwrepos', repoName)) + dirList = os.listdir(repoDir) dirList = list( filter( lambda x: x not in @@ -155,6 +178,22 @@ class GiteaWorker(): self.logger.warning(f"{repoName} untidy {dirList.__repr__()}") for _, stuName in self.hgroups[repoName]: scores[stuName]['groupUntidy'] = 1 + scores[stuName]['groupComment'].append( + f"master branch redundant files: {dirList.__repr__()}") + if os.path.exists(hwDir): + dirList = os.listdir(hwDir) + dirList = list( + filter( + lambda x: not x.startswith("ex") and not x.startswith( + "README."), dirList)) + if dirList: + self.logger.warning( + f"{repoName} h{hwNum} untidy {dirList.__repr__()}") + for _, stuName in self.hgroups[repoName]: + scores[stuName]['groupUntidy'] = 1 + scores[stuName]['groupComment'].append( + f"master branch redundant files: {dirList.__repr__()}" + ) return scores def checkProjProcess(self, id_, name, projNum, milestoneNum): @@ -171,7 +210,8 @@ class GiteaWorker(): self.logger.warning(f"{repoName} branch master missing") return repo.git.checkout(f"master", "-f") - repo.git.pull("origin", "master", "--rebase", "-f") + repo.git.reset('--hard') + repo.git.pull("origin", "master", "-f") repo.git.reset('--hard') repo.git.clean("-d", "-f", "-x") if not list( @@ -196,14 +236,16 @@ class GiteaWorker(): hwNum = self.args.hw with multiprocessing.Pool(self.processCount) as p: res = p.starmap(self.checkIndvProcess, - [(i, hwNum) for i in range(26)]) + [(i, hwNum) + for i in range(len(self.hgroups.keys()))]) return {k: v for d in res for k, v in d.items()} def checkGroup(self): hwNum, tidy = self.args.hw, self.args.tidy with multiprocessing.Pool(self.processCount) as p: res = p.starmap(self.checkGroupProcess, - [(i, hwNum, tidy) for i in range(26)]) + [(i, hwNum) + for i in range(len(self.hgroups.keys()))]) return {k: v for d in res for k, v in d.items()} def checkProj(self, projNum, milestoneNum): diff --git a/worker/JOJWorker.py b/worker/JOJWorker.py index 48ea1d2..aed12da 100644 --- a/worker/JOJWorker.py +++ b/worker/JOJWorker.py @@ -113,21 +113,29 @@ class JOJWorker(): for fn, problemID, _ in jojInfo["problemInfo"]]) scores = [(scores[i], jojInfo["problemInfo"][i][2]) for i in range(len(scores))] + self.logger.info(f"{key} h{hwNum} score {scores.__repr__()}") jojFailExercise = min( sum([ int(acCount < 0.25 * totalCount) for acCount, totalCount in scores ]), 2) - self.logger.info(f"{key} h{hwNum} score {scores.__repr__()}") jojFailHomework = int( sum([item[0] for item in scores]) < 0.5 * sum([item[1] for item in scores])) jojFailCompile = int(True in [item[0] == -1 for item in scores]) + comments = [] + if jojFailHomework + jojFailExercise + jojFailCompile != 0: + scoreComments = [ + f"{fn}: {scores[i][0]}/{scores[i][1]}" + for i, (fn, _, _) in enumerate(jojInfo["problemInfo"]) + ] + comments = [f"JOJ score: {','.join(scoreComments)}"] for _, stuName in value: res[stuName] = { "jojFailHomework": jojFailHomework, "jojFailExercise": jojFailExercise, "jojFailCompile": jojFailCompile, + "jojComment": comments, } return res -- cgit v1.2.3