Skip to content

Commit

Permalink
Teacher Tool: initial rubric, rubricCriteria classes and parsing (#9807)
Browse files Browse the repository at this point in the history
* initial rubric, rubricCriteria classes and parsing

* rename friendlyText -> displayText, criteriaID -> criteriaId

* move runEvaluate into a transform

* async await

* rename file runEvaluate -> runEvaluateAsync
  • Loading branch information
kimprice authored Jan 5, 2024
1 parent e622f92 commit 289de62
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 14 deletions.
30 changes: 30 additions & 0 deletions pxtblocks/code-validation/rubric.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace pxt.blocks {
export class Rubric {
criteria: RubricCriteria[];

constructor(criteria: RubricCriteria[]) {
this.criteria = criteria;
}
}

export function parseRubric(rubric: string): Rubric {
let rubricObj;
try {
rubricObj = JSON.parse(rubric);
} catch (e) {
console.error(`Error parsing rubric! ${e}`);
return null;
}

if (!rubricObj.criteria) {
console.error(`No criteria found in rubric`);
return null;
}

const criteria: RubricCriteria[] = rubricObj.criteria.map((c: CriteriaData) => {
return getCriteria(c);
}).filter((r: RubricCriteria) => !!r);

return new Rubric(criteria);
}
}
56 changes: 56 additions & 0 deletions pxtblocks/code-validation/rubricCriteria.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace pxt.blocks {
interface BlockSet {
blocks: string[];
count: number;
}

export interface CriteriaData {
criteriaId: string;
displayText: string;
blockRequirements?: BlockSet[];
count?: number;
}

export function getCriteria(data: CriteriaData): RubricCriteria {
switch (data.criteriaId) {
case "blockCheck":
return new BlockCheckCriteria(data.displayText, data.blockRequirements);
case "comment":
return new CommentCriteria(data.displayText, data.count);
default:
console.error(`Unrecognized criteriaId: ${data.criteriaId}`);
return null;
}
}

export abstract class RubricCriteria {
displayText: string;
abstract criteriaId: string;

constructor(displayText: string) {
this.displayText = displayText;
}
}


class BlockCheckCriteria extends RubricCriteria {
criteriaId: "blockCheck";
blockRequirements: BlockSet[];

constructor(displayText: string, blockRequirements: BlockSet[]) {
super(displayText);
this.blockRequirements = blockRequirements;
}
}

class CommentCriteria extends RubricCriteria {
criteriaId: "comment";
count: number;

constructor(displayText: string, count: number) {
super(displayText);
this.count = count;
}
}

}
2 changes: 2 additions & 0 deletions teachertool/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
<script type="text/javascript" src="/blb/target.js"></script>
<script type="text/javascript" src="/blb/pxtlib.js"></script>
<script type="text/javascript" src="/blb/pxtsim.js"></script>
<script type="text/javascript" src="/blb/pxtblockly.js"></script>
<script type="text/javascript" src="/blb/pxtblocks.js"></script>

<div id="root"></div>

Expand Down
20 changes: 6 additions & 14 deletions teachertool/src/components/DebugInput.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
/// <reference path="../../../built/pxtblocks.d.ts"/>

import { useState } from "react";
import { Button } from "react-common/components/controls/Button";
import { Input } from "react-common/components/controls/Input";
import { Textarea } from "react-common/components/controls/Textarea";
import { getProjectMetaAsync, getProjectTextAsync } from "../services/BackendRequests";
import { runEvaluateAsync } from "../transforms/runEvaluateAsync";

interface IProps {}

const DebugInput: React.FC<IProps> = ({}) => {
const [shareLink, setShareLink] = useState("https://arcade.makecode.com/S50644-45891-08403-36583");
const [rubric, setRubric] = useState("");

const runEvaluate = async () => {
console.log(`Evaluate ${shareLink} with ${rubric}!`);
const scriptId = pxt.Cloud.parseScriptId(shareLink);
if (!scriptId) {
console.log("Invalid share link!");
return;
}
const projText = await getProjectTextAsync(scriptId);
if (projText) console.log(projText["main.blocks"] || "Failed to get blocks xml!");

const projMeta = await getProjectMetaAsync(scriptId);
if (projMeta) console.log(projMeta);
const evaluate = async () => {
await runEvaluateAsync(shareLink, rubric);
}

return (
Expand All @@ -43,7 +35,7 @@ const DebugInput: React.FC<IProps> = ({}) => {
rows={20}
onChange={setRubric} />
</div>
<Button id="evaluateSingleProjectButton" className="primary" onClick={runEvaluate} title={"Evaluate"} label={lf("Evaluate")} />
<Button id="evaluateSingleProjectButton" className="primary" onClick={evaluate} title={"Evaluate"} label={lf("Evaluate")} />
</div>
)

Expand Down
17 changes: 17 additions & 0 deletions teachertool/src/transforms/runEvaluateAsync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getProjectMetaAsync, getProjectTextAsync } from "../services/BackendRequests";

export async function runEvaluateAsync(shareLink: string, rubric: string) {
console.log(`Evaluate ${shareLink} with ${rubric}!`);
const scriptId = pxt.Cloud.parseScriptId(shareLink);
if (!scriptId) {
console.log("Invalid share link!");
return;
}
const projText = await getProjectTextAsync(scriptId);
if (projText) console.log(projText["main.blocks"] || "Failed to get blocks xml!");

const projMeta = await getProjectMetaAsync(scriptId);
if (projMeta) console.log(projMeta);

console.log(pxt.blocks.parseRubric(rubric));
}

0 comments on commit 289de62

Please sign in to comment.