From 36d9c479c874580105ea7ef00df9afce42d19026 Mon Sep 17 00:00:00 2001 From: lilyxmeng Date: Mon, 2 Mar 2026 19:02:33 -0500 Subject: [PATCH 01/10] fixed editor modules stil appearing after question close + unable to create function names in practice mode w no question selected --- frontend/src/features/canvas/Canvas.tsx | 23 +++++++++++++++++++ .../features/editors/boxEditor/BoxEditor.tsx | 4 ++++ .../src/features/editors/boxEditor/Header.tsx | 6 +++++ .../boxEditor/classBoxes/ClassDisplay.tsx | 3 +++ .../editors/classEditor/ClassEditorPanel.tsx | 8 ++++--- .../editors/classEditor/classEditor.tsx | 3 +++ .../functionEditor/FunctionNameSelector.tsx | 3 +++ .../FunctionNameSelectorPanel.tsx | 6 +++-- .../memoryModelEditor/MemoryModelEditor.tsx | 2 ++ frontend/src/features/shared/types.ts | 2 ++ 10 files changed, 55 insertions(+), 5 deletions(-) diff --git a/frontend/src/features/canvas/Canvas.tsx b/frontend/src/features/canvas/Canvas.tsx index 1f6f57c..85d28f4 100644 --- a/frontend/src/features/canvas/Canvas.tsx +++ b/frontend/src/features/canvas/Canvas.tsx @@ -41,6 +41,8 @@ interface FloatingEditorProps { addClasses?: (className: string) => void; removeClasses?: (className: string) => void; sandbox: boolean; + canManageClasses?: boolean; + canManageFunctions?: boolean; elements: CanvasElement[]; editorScale: number; questionFunctionNames?: string[]; @@ -61,6 +63,8 @@ function FloatingEditor({ addClasses, removeClasses, sandbox, + canManageClasses, + canManageFunctions, elements, editorScale, questionFunctionNames, @@ -107,6 +111,8 @@ function FloatingEditor({ addClasses={addClasses} removeClasses={removeClasses} sandbox={sandbox} + canManageClasses={canManageClasses ?? sandbox} + canManageFunctions={canManageFunctions ?? sandbox} elements={elements} questionFunctionNames={questionFunctionNames} /> @@ -126,6 +132,8 @@ interface CanvasProps { addClasses?: (className: string) => void; removeClasses?: (className: string) => void; sandbox?: boolean; + canManageClasses?: boolean; + canManageFunctions?: boolean; onClear: () => void; onEditorOpenerReady?: (openEditor: (element: CanvasElement) => void) => void; scale?: number; @@ -144,6 +152,8 @@ function Canvas({ addClasses, removeClasses, sandbox = true, + canManageClasses, + canManageFunctions, onEditorOpenerReady, scale: externalScale, editorScale = 1, @@ -256,6 +266,17 @@ function Canvas({ .forEach((id) => addId(id)); }, [elements, ids, sandbox, addId]); + // Close any floating editors whose element no longer exists + // (e.g. when exiting a question clears the canvas, or an element is deleted) + useEffect(() => { + setOpenEditors((prev) => { + const filtered = prev.filter((editor) => + elements.some((el) => el.boxId === editor.boxId) + ); + return filtered.length === prev.length ? prev : filtered; + }); + }, [elements]); + // Validate elements whenever they change // Create a stable signature of elements for comparison const elementsSignature = useMemo(() => { @@ -501,6 +522,8 @@ function Canvas({ addClasses={addClasses} removeClasses={removeClasses} sandbox={sandbox} + canManageClasses={canManageClasses ?? sandbox} + canManageFunctions={canManageFunctions ?? sandbox} elements={elements} editorScale={editorScale} questionFunctionNames={questionFunctionNames} diff --git a/frontend/src/features/editors/boxEditor/BoxEditor.tsx b/frontend/src/features/editors/boxEditor/BoxEditor.tsx index f04c427..30c19ff 100644 --- a/frontend/src/features/editors/boxEditor/BoxEditor.tsx +++ b/frontend/src/features/editors/boxEditor/BoxEditor.tsx @@ -39,6 +39,8 @@ const BoxEditorModule = ({ addClasses, removeClasses, sandbox = true, + canManageClasses = sandbox, + canManageFunctions = sandbox, elements = [], questionFunctionNames, }: BoxEditorType) => { @@ -123,6 +125,8 @@ const BoxEditorModule = ({ setElementId={setOwnId} removeId={removeId} sandbox={sandbox} + canManageClasses={canManageClasses} + canManageFunctions={canManageFunctions} elements={elements} onClose={onClose} /> diff --git a/frontend/src/features/editors/boxEditor/Header.tsx b/frontend/src/features/editors/boxEditor/Header.tsx index eeab6f0..b22c2f6 100644 --- a/frontend/src/features/editors/boxEditor/Header.tsx +++ b/frontend/src/features/editors/boxEditor/Header.tsx @@ -20,6 +20,8 @@ interface Props { setElementId: (id: ID) => void; removeId: (id: ID) => void; sandbox: boolean; + canManageClasses?: boolean; + canManageFunctions?: boolean; classes?: string[]; addClasses?: (className: string) => void; ownClasses?: string; @@ -56,6 +58,8 @@ const Header = ({ setElementId, removeId, sandbox, + canManageClasses = sandbox, + canManageFunctions = sandbox, classes = [], addClasses = () => {}, ownClasses = "", @@ -117,6 +121,7 @@ const Header = ({ setElementClassName={setOwnClassName} removeClassName={removeClasses} sandbox={sandbox} + canManageClasses={canManageClasses} /> ) : kind === "function" ? ( ) : ( {typeLabel} diff --git a/frontend/src/features/editors/boxEditor/classBoxes/ClassDisplay.tsx b/frontend/src/features/editors/boxEditor/classBoxes/ClassDisplay.tsx index fc87041..585de64 100644 --- a/frontend/src/features/editors/boxEditor/classBoxes/ClassDisplay.tsx +++ b/frontend/src/features/editors/boxEditor/classBoxes/ClassDisplay.tsx @@ -11,6 +11,7 @@ interface Props { setElementClassName: (className: string) => void; removeClassName: (className: string) => void; sandbox: boolean; + canManageClasses?: boolean; } /** @@ -25,6 +26,7 @@ const ClassDisplay = ({ setElementClassName, removeClassName, sandbox, + canManageClasses = sandbox, }: Props) => ( ); diff --git a/frontend/src/features/editors/classEditor/ClassEditorPanel.tsx b/frontend/src/features/editors/classEditor/ClassEditorPanel.tsx index 0dc1fd4..0f344dd 100644 --- a/frontend/src/features/editors/classEditor/ClassEditorPanel.tsx +++ b/frontend/src/features/editors/classEditor/ClassEditorPanel.tsx @@ -9,6 +9,7 @@ interface Props { onRemove: (className: string) => void; onClose: () => void; sandbox: boolean; + canManageClasses?: boolean; } const ClassSelectorPanel: React.FC = ({ @@ -18,6 +19,7 @@ const ClassSelectorPanel: React.FC = ({ onRemove, onClose, sandbox, + canManageClasses = sandbox, }) => { const [customClass, setCustomClass] = useState(""); const [showWarn, setShowWarn] = useState(false); @@ -63,7 +65,7 @@ const ClassSelectorPanel: React.FC = ({ > {className} - {sandbox && ( + {canManageClasses && ( - {sandbox && ( + {canManageFunctions && ( diff --git a/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css b/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css index 1cb45b3..24642cf 100644 --- a/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css +++ b/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css @@ -254,6 +254,54 @@ background: #047857; } +.checkAtLineButton { + padding: 0.5rem 1rem; + border: 1.5px solid #7dd3fc; + border-radius: 8px; + cursor: pointer; + font-weight: 600; + font-size: 0.85rem; + flex: 1; + transition: all 160ms ease; + background: rgba(125, 211, 252, 0.1); + color: #7dd3fc; +} + +.checkAtLineButton:hover { + background: rgba(125, 211, 252, 0.2); + border-color: #38bdf8; + color: #38bdf8; +} + +.checkAtLineButton:active { + background: rgba(125, 211, 252, 0.3); +} + +.lineHint { + margin: 0.5rem 0 0 0; + font-size: 0.75rem; + color: var(--text-muted); + font-style: italic; + transition: color 200ms ease; +} + +/* Light mode overrides */ +:root:not([data-theme="dark"]) .checkAtLineButton { + background: rgba(14, 116, 144, 0.1); + border-color: #0e7490; + color: #0e7490; +} + +:root:not([data-theme="dark"]) .checkAtLineButton:hover { + background: rgba(14, 116, 144, 0.18); + border-color: #0369a1; + color: #0369a1; +} + +:root:not([data-theme="dark"]) .checkAtLineButton:active { + background: rgba(14, 116, 144, 0.28); +} + /* Dark mode overrides */ :root[data-theme="dark"] .questionText code { color: #fb7185; diff --git a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx index d8f9d0f..ce48641 100644 --- a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx +++ b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx @@ -44,6 +44,7 @@ interface QuestionData { question: string; code: string[]; answer: unknown; + steps?: Array<{ lineNumber: number; answer: unknown }> | null; description?: string | null; topics?: string[] | null; canvasConfig?: CanvasData | null; @@ -67,6 +68,7 @@ interface QuestionTabProps { questionView: QuestionView; setQuestionView: (view: QuestionView) => void; onSubmit: () => Promise; + onSubmitAtLine: (lineNumber: number) => Promise; setSubmissionResults: (results: SubmissionResult | null) => void; onClearCanvas: () => void; onRestoreCanvas: (elements: any[], ids: number[], classes: string[]) => void; @@ -105,6 +107,7 @@ export default function QuestionTab({ questionView: questionViewProp, setQuestionView, onSubmit, + onSubmitAtLine, setSubmissionResults, onClearCanvas, onRestoreCanvas, @@ -126,6 +129,7 @@ export default function QuestionTab({ index: number; } | null>(null); const [showResetModal, setShowResetModal] = useState(false); + const [selectedLine, setSelectedLine] = useState(null); const hydratedList = useRef(false); const hydratedQuestion = useRef(false); @@ -202,6 +206,17 @@ export default function QuestionTab({ return questionStatus[key] || "unattempted"; }; + const handleSubmitAtLine = async (lineNumber: number) => { + if (questionType && questionIndex !== null) { + try { + await onSubmitAtLine(lineNumber); + // line-check results don't change question completion status + } catch (error) { + console.error("Error during line submission:", error); + } + } + }; + const handleSubmit = async () => { if (questionType && questionIndex !== null) { try { @@ -270,6 +285,7 @@ export default function QuestionTab({ hydratedQuestion.current = false; setQuestionData(null); setSubmissionResults(null); + setSelectedLine(null); setView("loading"); @@ -321,6 +337,7 @@ export default function QuestionTab({ setQuestionIndex(null); setQuestionData(null); + setSelectedLine(null); hydratedQuestion.current = false; onRestoreCanvas([], [], []); setView("list"); @@ -332,6 +349,7 @@ export default function QuestionTab({ if (pendingNavigation.index === -1) { setQuestionIndex(null); setQuestionData(null); + setSelectedLine(null); hydratedQuestion.current = false; onRestoreCanvas([], [], []); setView("list"); @@ -513,63 +531,90 @@ export default function QuestionTab({ )} - {view === "question" && questionData && ( - <> -
-
- Topics -
- {(questionData.topics ?? []).length > 0 ? ( -
- {(questionData.topics ?? []).map((topic, index) => ( - - {topic} - - ))} -
- ) : ( -

- No topics listed yet. -

- )} + {view === "question" && questionData && (() => { + const checkableLines = new Set( + questionData.steps?.map((s) => s.lineNumber) ?? [] + ); + return ( + <> +
+
+ Topics +
+ {(questionData.topics ?? []).length > 0 ? ( +
+ {(questionData.topics ?? []).map((topic, index) => ( + + {topic} + + ))} +
+ ) : ( +

+ No topics listed yet. +

+ )} +
+
+ +
+ {questionData.question}
-
- -
- {questionData.question} -
- - -
- - + + setSelectedLine((prev) => (prev === n ? null : n)) + } + /> + + {checkableLines.size > 0 && ( +

+ Click a highlighted line number to check your answer at that point. +

+ )} + +
+ + {selectedLine !== null && checkableLines.has(selectedLine) && ( + + )} + +
-
- - )} + + ); + })()} {showCanvasClearModal && ( diff --git a/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css b/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css index a2c401c..41bc059 100644 --- a/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css +++ b/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css @@ -29,3 +29,29 @@ white-space: pre; padding-right: 1.25rem; } + +/* Interactive line selection */ +.checkableLine { + cursor: pointer; +} + +.checkableLine:hover { + background: rgba(255, 255, 255, 0.05); +} + +.checkableGutter { + opacity: 0.75; + color: #7dd3fc; /* light blue tint to hint interactivity */ +} + +.selectedLine { + background: rgba(125, 211, 252, 0.12); + border-left: 3px solid #7dd3fc; + padding-left: 0; +} + +.selectedLine .gutter { + padding-left: 0; + color: #7dd3fc; + opacity: 1; +} diff --git a/frontend/src/features/informationTabs/questionTab/components/CodeBlock.tsx b/frontend/src/features/informationTabs/questionTab/components/CodeBlock.tsx index df2a07d..76d4035 100644 --- a/frontend/src/features/informationTabs/questionTab/components/CodeBlock.tsx +++ b/frontend/src/features/informationTabs/questionTab/components/CodeBlock.tsx @@ -6,6 +6,9 @@ interface CodeBlockProps { language: "python" | "javascript" | "typescript" | "java" | string; showLineNumbers?: boolean; startLineNumber?: number; + checkableLines?: Set; + selectedLine?: number | null; + onLineClick?: (lineNumber: number) => void; } export default function CodeBlock({ @@ -13,6 +16,9 @@ export default function CodeBlock({ language, showLineNumbers = true, startLineNumber = 1, + checkableLines, + selectedLine, + onLineClick, }: CodeBlockProps) { return ( @@ -26,11 +32,28 @@ export default function CodeBlock({ {tokens.map((line, index) => { const lineNumber = startLineNumber + index; const lineProps = getLineProps({ line, key: index }); + const isCheckable = checkableLines?.has(lineNumber) ?? false; + const isSelected = selectedLine === lineNumber; + + const lineClassName = [ + styles.line, + lineProps.className ?? "", + isCheckable ? styles.checkableLine : "", + isSelected ? styles.selectedLine : "", + ] + .filter(Boolean) + .join(" "); return (
onLineClick(lineNumber) + : undefined + } + title={isCheckable ? `Check answer at line ${lineNumber}` : undefined} {...Object.fromEntries( Object.entries(lineProps).filter( ([key]) => key !== "className" @@ -38,7 +61,10 @@ export default function CodeBlock({ )} > {showLineNumbers && ( -
diff --git a/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css b/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css index 24642cf..bcb8352 100644 --- a/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css +++ b/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css @@ -285,6 +285,59 @@ transition: color 200ms ease; } +.iterationPicker { + display: flex; + align-items: center; + gap: 0.4rem; + margin-top: 0.5rem; + flex-wrap: wrap; +} + +.iterationLabel { + font-size: 0.75rem; + color: var(--text-muted); + font-style: italic; + transition: color 200ms ease; +} + +.iterationBtn { + padding: 0.2rem 0.6rem; + border: 1.5px solid #7dd3fc; + border-radius: 6px; + cursor: pointer; + font-weight: 600; + font-size: 0.78rem; + background: transparent; + color: #7dd3fc; + transition: all 140ms ease; +} + +.iterationBtn:hover { + background: rgba(125, 211, 252, 0.15); +} + +.iterationBtnActive { + background: rgba(125, 211, 252, 0.25); + border-color: #38bdf8; + color: #38bdf8; +} + +/* Light mode iteration buttons */ +:root:not([data-theme="dark"]) .iterationBtn { + border-color: #0e7490; + color: #0e7490; +} + +:root:not([data-theme="dark"]) .iterationBtn:hover { + background: rgba(14, 116, 144, 0.1); +} + +:root:not([data-theme="dark"]) .iterationBtnActive { + background: rgba(14, 116, 144, 0.18); + border-color: #0369a1; + color: #0369a1; +} + /* Light mode overrides */ :root:not([data-theme="dark"]) .checkAtLineButton { background: rgba(14, 116, 144, 0.1); diff --git a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx index ce48641..84f15b1 100644 --- a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx +++ b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx @@ -44,7 +44,7 @@ interface QuestionData { question: string; code: string[]; answer: unknown; - steps?: Array<{ lineNumber: number; answer: unknown }> | null; + steps?: Array<{ lineNumber: number; iterationNumber?: number; answer: unknown }> | null; description?: string | null; topics?: string[] | null; canvasConfig?: CanvasData | null; @@ -68,7 +68,7 @@ interface QuestionTabProps { questionView: QuestionView; setQuestionView: (view: QuestionView) => void; onSubmit: () => Promise; - onSubmitAtLine: (lineNumber: number) => Promise; + onSubmitAtLine: (lineNumber: number, iterationNumber?: number) => Promise; setSubmissionResults: (results: SubmissionResult | null) => void; onClearCanvas: () => void; onRestoreCanvas: (elements: any[], ids: number[], classes: string[]) => void; @@ -130,6 +130,7 @@ export default function QuestionTab({ } | null>(null); const [showResetModal, setShowResetModal] = useState(false); const [selectedLine, setSelectedLine] = useState(null); + const [selectedIteration, setSelectedIteration] = useState(undefined); const hydratedList = useRef(false); const hydratedQuestion = useRef(false); @@ -206,10 +207,10 @@ export default function QuestionTab({ return questionStatus[key] || "unattempted"; }; - const handleSubmitAtLine = async (lineNumber: number) => { + const handleSubmitAtLine = async (lineNumber: number, iterationNumber?: number) => { if (questionType && questionIndex !== null) { try { - await onSubmitAtLine(lineNumber); + await onSubmitAtLine(lineNumber, iterationNumber); // line-check results don't change question completion status } catch (error) { console.error("Error during line submission:", error); @@ -286,6 +287,7 @@ export default function QuestionTab({ setQuestionData(null); setSubmissionResults(null); setSelectedLine(null); + setSelectedIteration(undefined); setView("loading"); @@ -338,6 +340,7 @@ export default function QuestionTab({ setQuestionIndex(null); setQuestionData(null); setSelectedLine(null); + setSelectedIteration(undefined); hydratedQuestion.current = false; onRestoreCanvas([], [], []); setView("list"); @@ -350,6 +353,7 @@ export default function QuestionTab({ setQuestionIndex(null); setQuestionData(null); setSelectedLine(null); + setSelectedIteration(undefined); hydratedQuestion.current = false; onRestoreCanvas([], [], []); setView("list"); @@ -535,6 +539,21 @@ export default function QuestionTab({ const checkableLines = new Set( questionData.steps?.map((s) => s.lineNumber) ?? [] ); + // Map from lineNumber → sorted iteration numbers (empty array = no iterations) + const lineIterations = new Map(); + for (const s of questionData.steps ?? []) { + if (s.iterationNumber !== undefined) { + const arr = lineIterations.get(s.lineNumber) ?? []; + arr.push(s.iterationNumber); + lineIterations.set(s.lineNumber, arr); + } + } + const selectedLineHasIterations = + selectedLine !== null && (lineIterations.get(selectedLine)?.length ?? 0) > 0; + const canCheckAtLine = + selectedLine !== null && + checkableLines.has(selectedLine) && + (!selectedLineHasIterations || selectedIteration !== undefined); return ( <>
@@ -569,9 +588,10 @@ export default function QuestionTab({ language="python" checkableLines={checkableLines} selectedLine={selectedLine} - onLineClick={(n) => - setSelectedLine((prev) => (prev === n ? null : n)) - } + onLineClick={(n) => { + setSelectedLine((prev) => (prev === n ? null : n)); + setSelectedIteration(undefined); + }} /> {checkableLines.size > 0 && ( @@ -580,6 +600,24 @@ export default function QuestionTab({

)} + {selectedLine !== null && selectedLineHasIterations && ( +
+ After iteration: + {(lineIterations.get(selectedLine) ?? []).map((iter) => ( + + ))} +
+ )} +
- {selectedLine !== null && checkableLines.has(selectedLine) && ( + {canCheckAtLine && ( )} From e6bfefc534aa4ba920d7001bd8ce2e84a92a89ac Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Mar 2026 20:44:21 -0500 Subject: [PATCH 07/10] added question zoom feature --- .../canvasControls/CanvasControls.module.css | 50 +++++++++++++++++++ .../canvasControls/CanvasControls.tsx | 37 ++++++++++++++ .../InformationTabs.module.css | 42 ++++++++++++++++ .../informationTabs/InformationTabs.tsx | 4 ++ .../components/ErrorListDisplay.module.css | 14 +++--- .../feedbackTab/FeedbackTab.module.css | 2 +- .../feedbackTab/FeedbackTab.tsx | 48 ++++++++++-------- .../questionTab/QuestionTab.module.css | 20 ++++---- .../questionTab/QuestionTab.tsx | 4 +- .../components/CodeBlock.module.css | 2 +- .../memoryModelEditor/MemoryModelEditor.tsx | 14 ++++++ frontend/src/features/palette/Palette.tsx | 6 +++ 12 files changed, 202 insertions(+), 41 deletions(-) diff --git a/frontend/src/features/canvasControls/CanvasControls.module.css b/frontend/src/features/canvasControls/CanvasControls.module.css index 03bb9eb..9c11656 100644 --- a/frontend/src/features/canvasControls/CanvasControls.module.css +++ b/frontend/src/features/canvasControls/CanvasControls.module.css @@ -217,3 +217,53 @@ .toggleActive .toggleThumb { transform: translateX(20px); } + +/* ======================================= + === Font Zoom Controls ================ +======================================= */ + +.fontZoomControls { + display: flex; + flex-direction: row; + gap: 4px; + width: 100%; +} + +.fontZoomBtn { + all: unset; + flex: 1; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + font-weight: 600; + line-height: 1; + background-color: var(--button-bg); + color: var(--text-secondary); + border: 1px solid var(--border-primary); + border-radius: 8px; + box-shadow: var(--shadow-sm); + cursor: pointer; + transition: all 160ms ease; +} + +.fontZoomBtn:hover:not(:disabled) { + background-color: var(--button-hover); + border-color: var(--border-secondary); + color: var(--text-primary); +} + +.fontZoomBtn:active:not(:disabled) { + background-color: var(--button-active); +} + +.fontZoomBtn:disabled { + opacity: 0.35; + cursor: not-allowed; +} + +.fontZoomBtn:focus-visible { + outline: 2px solid var(--border-focus); + outline-offset: 2px; +} diff --git a/frontend/src/features/canvasControls/CanvasControls.tsx b/frontend/src/features/canvasControls/CanvasControls.tsx index 305ea51..1e9e317 100644 --- a/frontend/src/features/canvasControls/CanvasControls.tsx +++ b/frontend/src/features/canvasControls/CanvasControls.tsx @@ -22,6 +22,8 @@ interface CanvasControlsProps { onScaleChange?: (scale: number) => void; editorScale?: number; onEditorScaleChange?: (scale: number) => void; + fontScale?: number; + onFontScaleChange?: (delta: number) => void; } type ControlTab = "actions" | "view" | "settings"; @@ -61,6 +63,8 @@ export default function CanvasControls({ onScaleChange, editorScale = 1, onEditorScaleChange, + fontScale = 1, + onFontScaleChange, }: CanvasControlsProps) { const { theme, toggleTheme } = useTheme(); const isDarkMode = theme === 'dark'; @@ -131,6 +135,39 @@ export default function CanvasControls({
)} + + {onFontScaleChange && ( + <> +
+ + {Math.round(fontScale * 100)}% +
+
+
+ + +
+
+ + )}
)} diff --git a/frontend/src/features/informationTabs/InformationTabs.module.css b/frontend/src/features/informationTabs/InformationTabs.module.css index dcc8a7b..4db864e 100644 --- a/frontend/src/features/informationTabs/InformationTabs.module.css +++ b/frontend/src/features/informationTabs/InformationTabs.module.css @@ -84,3 +84,45 @@ .hidden { display: none; } + +.zoomControls { + display: flex; + align-items: center; + gap: 2px; + margin-left: auto; + padding-left: 6px; +} + +.zoomBtn { + all: unset; + cursor: pointer; + width: 22px; + height: 22px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 5px; + font-size: 0.95rem; + font-weight: 600; + color: var(--text-tertiary); + transition: color 160ms ease, background 160ms ease; +} + +.zoomBtn:hover:not(:disabled) { + color: var(--text-primary); + background: var(--bg-hover); +} + +.zoomBtn:disabled { + opacity: 0.3; + cursor: default; +} + +.zoomLabel { + font-size: 0.7rem; + font-weight: 600; + color: var(--text-muted); + min-width: 2.8ch; + text-align: center; + user-select: none; +} diff --git a/frontend/src/features/informationTabs/InformationTabs.tsx b/frontend/src/features/informationTabs/InformationTabs.tsx index 3d44b0c..115f9b1 100644 --- a/frontend/src/features/informationTabs/InformationTabs.tsx +++ b/frontend/src/features/informationTabs/InformationTabs.tsx @@ -30,6 +30,7 @@ interface InformationTabsProps { onQuestionDataChange?: (data: any) => void; tabScrollPositions: Record; setTabScrollPositions: React.Dispatch>>; + fontScale?: number; } export default function InformationTabs({ @@ -57,6 +58,7 @@ export default function InformationTabs({ onQuestionDataChange, tabScrollPositions, setTabScrollPositions, + fontScale = 1, }: InformationTabsProps) { const tabBodyRef = useRef(null); // Track the last submission context so Resubmit repeats the same check @@ -165,6 +167,7 @@ export default function InformationTabs({ currentCanvasState={currentCanvasState} onQuestionDataChange={onQuestionDataChange} isSandboxMode={isSandboxMode} + fontScale={fontScale} /> @@ -185,6 +188,7 @@ export default function InformationTabs({ isSandboxMode={!isSandboxMode} onResubmit={handleResubmit} resubmitLine={lastSubmitLine} + fontScale={fontScale} /> diff --git a/frontend/src/features/informationTabs/components/ErrorListDisplay.module.css b/frontend/src/features/informationTabs/components/ErrorListDisplay.module.css index e0104c2..420d648 100644 --- a/frontend/src/features/informationTabs/components/ErrorListDisplay.module.css +++ b/frontend/src/features/informationTabs/components/ErrorListDisplay.module.css @@ -34,13 +34,13 @@ } .errorCount { - font-size: 1.35rem; + font-size: calc(1.35rem * var(--font-scale, 1)); font-weight: 700; color: #dc2626; } .errorLabel { - font-size: 0.875rem; + font-size: calc(0.875rem * var(--font-scale, 1)); color: #991b1b; font-weight: 500; } @@ -89,7 +89,7 @@ display: flex; align-items: center; gap: 6px; - font-size: 0.9rem; + font-size: calc(0.9rem * var(--font-scale, 1)); color: var(--text-secondary); } @@ -98,13 +98,13 @@ } .elementType { - font-size: 0.78rem; + font-size: calc(0.78rem * var(--font-scale, 1)); color: var(--text-muted); font-weight: 400; } .errorMessage { - font-size: 0.825rem; + font-size: calc(0.825rem * var(--font-scale, 1)); color: #991b1b; line-height: 1.5; margin-bottom: 6px; @@ -112,7 +112,7 @@ } .errorField { - font-size: 0.78rem; + font-size: calc(0.78rem * var(--font-scale, 1)); color: #7f1d1d; padding-left: 24px; margin-top: 4px; @@ -122,7 +122,7 @@ background-color: #fee2e2; padding: 2px 6px; border-radius: 4px; - font-size: 0.78rem; + font-size: calc(0.78rem * var(--font-scale, 1)); color: #991b1b; border: 1px solid #fca5a5; } diff --git a/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.module.css b/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.module.css index 4c00a57..27a8fd9 100644 --- a/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.module.css +++ b/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.module.css @@ -87,7 +87,7 @@ gap: 10px; padding: 10px 14px; border-radius: 10px; - font-size: 0.85rem; + font-size: calc(0.85rem * var(--font-scale, 1)); font-weight: 500; margin-bottom: 16px; } diff --git a/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.tsx b/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.tsx index 54e90b5..16bd344 100644 --- a/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.tsx +++ b/frontend/src/features/informationTabs/feedbackTab/FeedbackTab.tsx @@ -22,6 +22,7 @@ interface FeedbackTabProps { isSandboxMode: boolean; onResubmit: () => Promise; resubmitLine?: { line: number; iteration?: number } | null; + fontScale?: number; } export default function FeedbackTab({ @@ -36,6 +37,7 @@ export default function FeedbackTab({ isSandboxMode, onResubmit, resubmitLine, + fontScale = 1, }: FeedbackTabProps) { const renderTitle = () => { let questionName = ""; @@ -89,11 +91,13 @@ export default function FeedbackTab({ ); } + const scaleStyle = { '--font-scale': fontScale } as React.CSSProperties; + if (submissionResults.correct) { return ( <> {renderTitle()} -
+
{renderTitle()} - -
- +
+ +
+ +
); diff --git a/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css b/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css index bcb8352..2469ad8 100644 --- a/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css +++ b/frontend/src/features/informationTabs/questionTab/QuestionTab.module.css @@ -119,7 +119,7 @@ } .questionText { - font-size: 0.95rem; + font-size: calc(0.95rem * var(--font-scale, 1)); line-height: 1.55; margin-bottom: 0.875rem; color: var(--text-secondary); @@ -149,7 +149,7 @@ cursor: pointer; padding: 0.6rem 0.85rem; font-weight: 600; - font-size: 0.85rem; + font-size: calc(0.85rem * var(--font-scale, 1)); color: var(--text-secondary); background: var(--bg-tertiary); list-style: none; @@ -192,7 +192,7 @@ border: 1px solid #bfdbfe; border-radius: 6px; padding: 0.2rem 0.6rem; - font-size: 0.73rem; + font-size: calc(0.73rem * var(--font-scale, 1)); font-weight: 600; letter-spacing: 0.01em; } @@ -200,7 +200,7 @@ .topicsEmpty { margin: 0; color: var(--text-muted); - font-size: 0.85rem; + font-size: calc(0.85rem * var(--font-scale, 1)); transition: color 200ms ease; } @@ -216,7 +216,7 @@ border-radius: 8px; cursor: pointer; font-weight: 500; - font-size: 0.85rem; + font-size: calc(0.85rem * var(--font-scale, 1)); flex: 1; transition: all 160ms ease; background: var(--bg-primary); @@ -239,7 +239,7 @@ border-radius: 8px; cursor: pointer; font-weight: 600; - font-size: 0.85rem; + font-size: calc(0.85rem * var(--font-scale, 1)); flex: 1; transition: all 160ms ease; background: #10b981; @@ -260,7 +260,7 @@ border-radius: 8px; cursor: pointer; font-weight: 600; - font-size: 0.85rem; + font-size: calc(0.85rem * var(--font-scale, 1)); flex: 1; transition: all 160ms ease; background: rgba(125, 211, 252, 0.1); @@ -279,7 +279,7 @@ .lineHint { margin: 0.5rem 0 0 0; - font-size: 0.75rem; + font-size: calc(0.75rem * var(--font-scale, 1)); color: var(--text-muted); font-style: italic; transition: color 200ms ease; @@ -294,7 +294,7 @@ } .iterationLabel { - font-size: 0.75rem; + font-size: calc(0.75rem * var(--font-scale, 1)); color: var(--text-muted); font-style: italic; transition: color 200ms ease; @@ -306,7 +306,7 @@ border-radius: 6px; cursor: pointer; font-weight: 600; - font-size: 0.78rem; + font-size: calc(0.78rem * var(--font-scale, 1)); background: transparent; color: #7dd3fc; transition: all 140ms ease; diff --git a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx index 84f15b1..102b958 100644 --- a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx +++ b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx @@ -75,6 +75,7 @@ interface QuestionTabProps { currentCanvasState: { elements: any[]; ids: number[]; classes: string[] }; onQuestionDataChange?: (data: any) => void; isSandboxMode: boolean; + fontScale?: number; } function loadQuestionStatus(): QuestionStatusMap { @@ -114,6 +115,7 @@ export default function QuestionTab({ currentCanvasState, onQuestionDataChange, isSandboxMode, + fontScale = 1, }: QuestionTabProps) { const [view, setView] = useState( () => (VALID_VIEWS.includes(questionViewProp as View) && questionViewProp !== "loading" ? (questionViewProp as View) : "root") @@ -556,7 +558,7 @@ export default function QuestionTab({ (!selectedLineHasIterations || selectedIteration !== undefined); return ( <> -
+
Topics
diff --git a/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css b/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css index e465794..8f91681 100644 --- a/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css +++ b/frontend/src/features/informationTabs/questionTab/components/CodeBlock.module.css @@ -3,7 +3,7 @@ padding: 1rem 1.25rem; border-radius: 10px; overflow-x: auto; - font-size: 0.85rem; + font-size: calc(0.85rem * var(--font-scale, 1)); line-height: 1.5; background: #1e1e2e; } diff --git a/frontend/src/features/memoryModelEditor/MemoryModelEditor.tsx b/frontend/src/features/memoryModelEditor/MemoryModelEditor.tsx index a108635..be3b29c 100644 --- a/frontend/src/features/memoryModelEditor/MemoryModelEditor.tsx +++ b/frontend/src/features/memoryModelEditor/MemoryModelEditor.tsx @@ -59,6 +59,17 @@ export default function MemoryModelEditor({ const _initialUI = loadInitialUIData(); const [canvasScale, setCanvasScale] = useState(_initialUI.canvasScale ?? 1); const [editorScale, setEditorScale] = useState(_initialUI.editorScale ?? 1); + const [fontScale, setFontScale] = useState(() => { + const saved = localStorage.getItem("questionFontScale"); + return saved ? parseFloat(saved) : 1; + }); + const adjustFontScale = (delta: number) => { + setFontScale((prev) => { + const next = Math.max(0.75, Math.min(1.5, Math.round((prev + delta) * 10) / 10)); + localStorage.setItem("questionFontScale", String(next)); + return next; + }); + }; // Initialize undo history const { canUndo, canRedo, undo, redo, recordState, clearHistory } = useUndoHistory( @@ -484,6 +495,8 @@ export default function MemoryModelEditor({ onScaleChange={setCanvasScale} editorScale={editorScale} onEditorScaleChange={setEditorScale} + fontScale={fontScale} + onFontScaleChange={adjustFontScale} />
@@ -570,6 +583,7 @@ export default function MemoryModelEditor({ onQuestionDataChange={setCurrentQuestionData} tabScrollPositions={state.tabScrollPositions} setTabScrollPositions={state.setTabScrollPositions} + fontScale={fontScale} />
diff --git a/frontend/src/features/palette/Palette.tsx b/frontend/src/features/palette/Palette.tsx index 34273f3..d8d770d 100644 --- a/frontend/src/features/palette/Palette.tsx +++ b/frontend/src/features/palette/Palette.tsx @@ -67,6 +67,8 @@ interface PaletteProps { onScaleChange?: (scale: number) => void; editorScale?: number; onEditorScaleChange?: (scale: number) => void; + fontScale?: number; + onFontScaleChange?: (delta: number) => void; } // Extract TabButton component inline @@ -114,6 +116,8 @@ export default function Palette({ onScaleChange, editorScale, onEditorScaleChange, + fontScale, + onFontScaleChange, }: PaletteProps) { const allBoxes = TAB_BOX_MAPPING[activeTab]; @@ -218,6 +222,8 @@ export default function Palette({ onScaleChange={onScaleChange} editorScale={editorScale} onEditorScaleChange={onEditorScaleChange} + fontScale={fontScale} + onFontScaleChange={onFontScaleChange} />
From f27002276339b5d58dfb20c5652f379aa939e258 Mon Sep 17 00:00:00 2001 From: lilyxmeng Date: Sat, 7 Mar 2026 13:50:44 -0500 Subject: [PATCH 08/10] added prep questions --- backend/src/database/prepQuestions.json | 929 ++++++++++++++++++ .../questionTab/QuestionTab.tsx | 2 +- 2 files changed, 930 insertions(+), 1 deletion(-) diff --git a/backend/src/database/prepQuestions.json b/backend/src/database/prepQuestions.json index 18e7704..6a2bb7f 100644 --- a/backend/src/database/prepQuestions.json +++ b/backend/src/database/prepQuestions.json @@ -1033,5 +1033,934 @@ ] } ] + }, + { + "id": 2, + "question": "Draw the memory model for the code below **immediately after** `bst = BST(None)` executes.\n\n**Notes:**\n- You are allowed to use either Practice or Test mode to complete this question.", + "code": [ + "class BST:", + " \"\"\"Binary Search Tree class from the course notes.", + "", + " Representation Invariants:", + " - If self._root is None, then so are self._left and self._right;", + " this represents an empty BST.", + " - If self._root is not None, then self._left and self._right", + " are BSTs; in particular, self is a leaf in this case", + " if self._left and self._right are both empty BSTs", + " - (BST Property) If self is not empty, then all items in", + " self._left are <= self._root, and all items in", + " self._right are >= self._root.", + " \"\"\"", + " _root: Any | None", + " _left: BST | None", + " _right: BST | None", + "", + " def __init__(self, root: Any | None) -> None:", + " \"\"\"", + " Initialize a new BST containing only the given root value.", + " If is None, initialize an empty tree.", + " \"\"\"", + " if root is None:", + " self._root = None", + " self._left = None", + " self._right = None", + " else:", + " self._root = root", + " self._left = BST(None)", + " self._right = BST(None)", + "", + "", + "if __name__ == '__main__':", + " bst = BST(None) # draw the memory model here" + ], + "answer": [ + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ], + "description": null, + "topics": [ + "BST", + "Classes", + "CSC148" + ], + "canvasConfig": null, + "steps": [ + { + "lineNumber": 18, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": {} }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 23, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": {} }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 24, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 25, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 26, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 34, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 18, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 3, "value": 148 } + ] + }, + { + "lineNumber": 23, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 3, "value": 148 } + ] + }, + { + "lineNumber": 27, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 3, "value": 148 } + ] + }, + { + "lineNumber": 28, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 3, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 3, "value": 148 } + ] + }, + { + "lineNumber": 29, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 3, "_left": 4, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 3, "value": 148 }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } + ] + }, + { + "lineNumber": 30, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 3, "_left": 4, "_right": 5 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 3, "value": 148 }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 5, "value": { "_root": 2, "_left": 2, "_right": 2 } } + ] + } + ] + }, + { + "id": 3, + "question": "You are given an initially empty BST (the memory model is preloaded on the canvas). Update the memory model to show what it will look like **after** `bst.insert(148)` executes.\n\n**Notes:**\n- The `insert` method is not shown — use the BST representation invariants to reason about the result.\n- You are allowed to use either Practice or Test mode to complete this question.", + "code": [ + "class BST:", + " \"\"\"Binary Search Tree class from the course notes.", + "", + " Representation Invariants:", + " - If self._root is None, then so are self._left and self._right;", + " this represents an empty BST.", + " - If self._root is not None, then self._left and self._right", + " are BSTs; in particular, self is a leaf in this case", + " if self._left and self._right are both empty BSTs", + " - (BST Property) If self is not empty, then all items in", + " self._left are <= self._root, and all items in", + " self._right are >= self._root.", + " \"\"\"", + " _root: Any | None", + " _left: BST | None", + " _right: BST | None", + "", + " def __init__(self, root: Any | None) -> None:", + " \"\"\"", + " Initialize a new BST containing only the given root value.", + " If is None, initialize an empty tree.", + " \"\"\"", + " if root is None:", + " self._root = None", + " self._left = None", + " self._right = None", + " else:", + " self._root = root", + " self._left = BST(None)", + " self._right = BST(None)", + "", + " # (insert and other methods not shown)", + "", + "", + "if __name__ == '__main__':", + " bst = BST(None)", + " # initial memory model (empty BST) is preloaded on the canvas", + " bst.insert(148) # update the memory model to show the result" + ], + "answer": [ + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + } + ], + "description": null, + "topics": [ + "BST", + "Classes", + "CSC148" + ], + "canvasConfig": { + "elements": [ + { + "boxId": 0, + "id": "_", + "x": 0, + "y": 0, + "kind": { + "name": "function", + "type": "function", + "value": null, + "functionName": "__main__", + "params": [{ "name": "bst", "targetId": 1 }], + "order": 1 + } + }, + { + "boxId": 1, + "id": 1, + "x": 735, + "y": 186, + "kind": { + "name": "class", + "type": "class", + "value": null, + "className": "BST", + "classVariables": [ + { "key": "_root", "value": 2 }, + { "key": "_left", "value": 2 }, + { "key": "_right", "value": 2 } + ] + } + }, + { + "boxId": 2, + "id": 2, + "x": 738, + "y": 396, + "kind": { + "name": "primitive", + "type": "NoneType", + "value": "None" + } + } + ], + "ids": [1, 2], + "classes": ["BST"] + }, + "steps": [ + { + "lineNumber": 18, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": {} }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 23, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": {} }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 24, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 25, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 26, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 36, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 18, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 23, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 27, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 28, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 29, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } } + ] + }, + { + "lineNumber": 30, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } + ] + }, + { + "lineNumber": 38, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } + ] + } + ] + }, + { + "id": 4, + "question": "You are given a BST that is initially only a leaf containing the value 148 (the memory model is preloaded on the canvas). Update the memory model to show what it will look like **after** `bst.insert(108)` executes.\n\n**Hint**: Which of `bst`'s subtrees will be mutated?\n\n**Notes:**\n- The `insert` method is not shown — use the BST representation invariants to reason about the result.\n- You are allowed to use either Practice or Test mode to complete this question.", + "code": [ + "class BST:", + " \"\"\"Binary Search Tree class from the course notes.", + "", + " Representation Invariants:", + " - If self._root is None, then so are self._left and self._right;", + " this represents an empty BST.", + " - If self._root is not None, then self._left and self._right", + " are BSTs; in particular, self is a leaf in this case", + " if self._left and self._right are both empty BSTs", + " - (BST Property) If self is not empty, then all items in", + " self._left are <= self._root, and all items in", + " self._right are >= self._root.", + " \"\"\"", + " _root: Any | None", + " _left: BST | None", + " _right: BST | None", + "", + " def __init__(self, root: Any | None) -> None:", + " \"\"\"", + " Initialize a new BST containing only the given root value.", + " If is None, initialize an empty tree.", + " \"\"\"", + " if root is None:", + " self._root = None", + " self._left = None", + " self._right = None", + " else:", + " self._root = root", + " self._left = BST(None)", + " self._right = BST(None)", + "", + " # (insert and other methods not shown)", + "", + "", + "if __name__ == '__main__':", + " bst = BST(None)", + " bst.insert(148)", + " # initial memory model (BST with root 148) is preloaded on the canvas", + " bst.insert(108) # update the memory model to show the result" + ], + "answer": [ + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 8, + "_left": 6, + "_right": 7 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 6, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 7, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 8, + "value": 108 + } + ], + "description": null, + "topics": [ + "BST", + "Classes", + "CSC148" + ], + "canvasConfig": { + "elements": [ + { + "boxId": 0, + "id": "_", + "x": 0, + "y": 0, + "kind": { + "name": "function", + "type": "function", + "value": null, + "functionName": "__main__", + "params": [{ "name": "bst", "targetId": 1 }], + "order": 1 + } + }, + { + "boxId": 1, + "id": 1, + "x": 735, + "y": 186, + "kind": { + "name": "class", + "type": "class", + "value": null, + "className": "BST", + "classVariables": [ + { "key": "_root", "value": 5 }, + { "key": "_left", "value": 3 }, + { "key": "_right", "value": 4 } + ] + } + }, + { + "boxId": 2, + "id": 2, + "x": 744, + "y": 492, + "kind": { + "name": "primitive", + "type": "NoneType", + "value": "None" + } + }, + { + "boxId": 3, + "id": 3, + "x": 497, + "y": 424, + "kind": { + "name": "class", + "type": "class", + "value": null, + "className": "BST", + "classVariables": [ + { "key": "_root", "value": 2 }, + { "key": "_left", "value": 2 }, + { "key": "_right", "value": 2 } + ] + } + }, + { + "boxId": 4, + "id": 4, + "x": 998, + "y": 420, + "kind": { + "name": "class", + "type": "class", + "value": null, + "className": "BST", + "classVariables": [ + { "key": "_root", "value": 2 }, + { "key": "_left", "value": 2 }, + { "key": "_right", "value": 2 } + ] + } + }, + { + "boxId": 5, + "id": 5, + "x": 963, + "y": 140, + "kind": { + "name": "primitive", + "type": "int", + "value": "148" + } + } + ], + "ids": [1, 2, 3, 4, 5], + "classes": ["BST"] + }, + "steps": [ + { + "lineNumber": 18, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": {} }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 23, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": {} }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 24, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 25, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 26, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 36, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" } + ] + }, + { + "lineNumber": 18, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 23, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 27, + "iterationNumber": 1, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 28, + "iterationNumber": 1, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 2, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 29, + "iterationNumber": 1, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 2 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } } + ] + }, + { + "lineNumber": 30, + "iterationNumber": 1, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } + ] + }, + { + "lineNumber": 37, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 } + ] + }, + { + "lineNumber": 18, + "iterationNumber": 3, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "int", "id": 8, "value": 108 } + ] + }, + { + "lineNumber": 23, + "iterationNumber": 3, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "int", "id": 8, "value": 108 } + ] + }, + { + "lineNumber": 27, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "int", "id": 8, "value": 108 } + ] + }, + { + "lineNumber": 28, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "int", "id": 8, "value": 108 } + ] + }, + { + "lineNumber": 29, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 6, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 6, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 8, "value": 108 } + ] + }, + { + "lineNumber": 30, + "iterationNumber": 2, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 6, "_right": 7 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 6, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 7, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 8, "value": 108 } + ] + }, + { + "lineNumber": 39, + "answer": [ + { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, + { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, + { "type": "NoneType", "id": 2, "value": "None" }, + { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 6, "_right": 7 } }, + { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 5, "value": 148 }, + { "type": "object", "name": "BST", "id": 6, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "object", "name": "BST", "id": 7, "value": { "_root": 2, "_left": 2, "_right": 2 } }, + { "type": "int", "id": 8, "value": 108 } + ] + } + ] } ] \ No newline at end of file diff --git a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx index 84f15b1..4b00cf0 100644 --- a/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx +++ b/frontend/src/features/informationTabs/questionTab/QuestionTab.tsx @@ -502,7 +502,7 @@ export default function QuestionTab({ variant="category" text="CSC148 Prep Questions" subtitle="" - icon="🔗" + icon="🎓" categoryType="prep" onClick={() => loadQuestions("prep")} /> From de41bf177a41d39a64cc76f0c4a752e22b148d9c Mon Sep 17 00:00:00 2001 From: lilyxmeng Date: Sat, 7 Mar 2026 21:37:31 -0500 Subject: [PATCH 09/10] fix steps --- backend/src/database/prepQuestions.json | 2348 ++++++++++++++++++++--- backend/src/database/testQuestions.json | 2 - 2 files changed, 2040 insertions(+), 310 deletions(-) diff --git a/backend/src/database/prepQuestions.json b/backend/src/database/prepQuestions.json index 68eaa5e..a22671a 100644 --- a/backend/src/database/prepQuestions.json +++ b/backend/src/database/prepQuestions.json @@ -219,8 +219,18 @@ } } ], - "ids": [1, 2, 3, 4, 5, 6], - "classes": ["_Node", "LinkedList"] + "ids": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "classes": [ + "_Node", + "LinkedList" + ] }, "steps": [ { @@ -1100,136 +1110,519 @@ { "lineNumber": 18, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": {} }, - { "type": "NoneType", "id": 2, "value": "None" } - ] + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": {} + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ], + "iterationNumber": 1 }, { "lineNumber": 23, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": {} }, - { "type": "NoneType", "id": 2, "value": "None" } - ] + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": {} + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ], + "iterationNumber": 1 }, { "lineNumber": 24, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 25, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 26, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 34, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 18, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 3, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 3 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 3, + "value": 148 + } ] }, { "lineNumber": 23, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 3, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 3 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 3, + "value": 148 + } ] }, { "lineNumber": 27, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 3, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 3 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 3, + "value": 148 + } ] }, { "lineNumber": 28, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 3, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 3, "value": 148 } - ] - }, - { - "lineNumber": 29, - "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 3, "_left": 4, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 3, "value": 148 }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } - ] - }, - { - "lineNumber": 30, - "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 3 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 3, "_left": 4, "_right": 5 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 3, "value": 148 }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 5, "value": { "_root": 2, "_left": 2, "_right": 2 } } - ] - } - ] - }, - { - "id": 3, - "question": "You are given an initially empty BST (the memory model is preloaded on the canvas). Update the memory model to show what it will look like **after** `bst.insert(148)` executes.\n\n**Notes:**\n- The `insert` method is not shown — use the BST representation invariants to reason about the result.\n- You are allowed to use either Practice or Test mode to complete this question.", - "code": [ - "class BST:", - " \"\"\"Binary Search Tree class from the course notes.", - "", - " Representation Invariants:", - " - If self._root is None, then so are self._left and self._right;", - " this represents an empty BST.", - " - If self._root is not None, then self._left and self._right", - " are BSTs; in particular, self is a leaf in this case", - " if self._left and self._right are both empty BSTs", + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 3 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 3, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 3, + "value": 148 + } + ] + }, + { + "lineNumber": 29, + "answer": [ + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 3 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 3, + "_left": 4, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 3, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + } + ] + }, + { + "lineNumber": 30, + "answer": [ + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 3 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 3, + "_left": 4, + "_right": 5 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 3, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 5, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + } + ] + } + ] + }, + { + "id": 3, + "question": "You are given an initially empty BST (the memory model is preloaded on the canvas). Update the memory model to show what it will look like **after** `bst.insert(148)` executes.\n\n**Notes:**\n- The `insert` method is not shown \u00e2\u20ac\u201d use the BST representation invariants to reason about the result.\n- You are allowed to use either Practice or Test mode to complete this question.", + "code": [ + "class BST:", + " \"\"\"Binary Search Tree class from the course notes.", + "", + " Representation Invariants:", + " - If self._root is None, then so are self._left and self._right;", + " this represents an empty BST.", + " - If self._root is not None, then self._left and self._right", + " are BSTs; in particular, self is a leaf in this case", + " if self._left and self._right are both empty BSTs", " - (BST Property) If self is not empty, then all items in", " self._left are <= self._root, and all items in", " self._right are >= self._root.", @@ -1329,7 +1722,12 @@ "type": "function", "value": null, "functionName": "__main__", - "params": [{ "name": "bst", "targetId": 1 }], + "params": [ + { + "name": "bst", + "targetId": 1 + } + ], "order": 1 } }, @@ -1344,9 +1742,18 @@ "value": null, "className": "BST", "classVariables": [ - { "key": "_root", "value": 2 }, - { "key": "_left", "value": 2 }, - { "key": "_right", "value": 2 } + { + "key": "_root", + "value": 2 + }, + { + "key": "_left", + "value": 2 + }, + { + "key": "_right", + "value": 2 + } ] } }, @@ -1362,144 +1769,575 @@ } } ], - "ids": [1, 2], - "classes": ["BST"] + "ids": [ + 1, + 2 + ], + "classes": [ + "BST" + ] }, "steps": [ { "lineNumber": 18, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": {} }, - { "type": "NoneType", "id": 2, "value": "None" } - ] + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": {} + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ], + "iterationNumber": 1 }, { "lineNumber": 23, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": {} }, - { "type": "NoneType", "id": 2, "value": "None" } - ] + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": {} + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ], + "iterationNumber": 1 }, { "lineNumber": 24, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 25, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 26, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } - ] - }, - { - "lineNumber": 36, - "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } - ] - }, - { - "lineNumber": 18, - "iterationNumber": 2, - "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } - ] - }, + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ] + }, + { + "lineNumber": 36, + "answer": [ + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ] + }, + { + "lineNumber": 18, + "iterationNumber": 2, + "answer": [ + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } + ] + }, { "lineNumber": 23, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 27, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 28, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 29, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + } ] }, { "lineNumber": 30, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + } ] }, { "lineNumber": 38, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + } ] } ] }, { "id": 4, - "question": "You are given a BST that is initially only a leaf containing the value 148 (the memory model is preloaded on the canvas). Update the memory model to show what it will look like **after** `bst.insert(108)` executes.\n\n**Hint**: Which of `bst`'s subtrees will be mutated?\n\n**Notes:**\n- The `insert` method is not shown — use the BST representation invariants to reason about the result.\n- You are allowed to use either Practice or Test mode to complete this question.", + "question": "You are given a BST that is initially only a leaf containing the value 148 (the memory model is preloaded on the canvas). Update the memory model to show what it will look like **after** `bst.insert(108)` executes.\n\n**Hint**: Which of `bst`'s subtrees will be mutated?\n\n**Notes:**\n- The `insert` method is not shown \u00e2\u20ac\u201d use the BST representation invariants to reason about the result.\n- You are allowed to use either Practice or Test mode to complete this question.", "code": [ "class BST:", " \"\"\"Binary Search Tree class from the course notes.", @@ -1635,7 +2473,12 @@ "type": "function", "value": null, "functionName": "__main__", - "params": [{ "name": "bst", "targetId": 1 }], + "params": [ + { + "name": "bst", + "targetId": 1 + } + ], "order": 1 } }, @@ -1650,9 +2493,18 @@ "value": null, "className": "BST", "classVariables": [ - { "key": "_root", "value": 5 }, - { "key": "_left", "value": 3 }, - { "key": "_right", "value": 4 } + { + "key": "_root", + "value": 5 + }, + { + "key": "_left", + "value": 3 + }, + { + "key": "_right", + "value": 4 + } ] } }, @@ -1678,9 +2530,18 @@ "value": null, "className": "BST", "classVariables": [ - { "key": "_root", "value": 2 }, - { "key": "_left", "value": 2 }, - { "key": "_right", "value": 2 } + { + "key": "_root", + "value": 2 + }, + { + "key": "_left", + "value": 2 + }, + { + "key": "_right", + "value": 2 + } ] } }, @@ -1695,9 +2556,18 @@ "value": null, "className": "BST", "classVariables": [ - { "key": "_root", "value": 2 }, - { "key": "_left", "value": 2 }, - { "key": "_right", "value": 2 } + { + "key": "_root", + "value": 2 + }, + { + "key": "_left", + "value": 2 + }, + { + "key": "_right", + "value": 2 + } ] } }, @@ -1713,244 +2583,1106 @@ } } ], - "ids": [1, 2, 3, 4, 5], - "classes": ["BST"] + "ids": [ + 1, + 2, + 3, + 4, + 5 + ], + "classes": [ + "BST" + ] }, "steps": [ { "lineNumber": 18, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": {} }, - { "type": "NoneType", "id": 2, "value": "None" } - ] + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": {} + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ], + "iterationNumber": 1 }, { "lineNumber": 23, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": {} }, - { "type": "NoneType", "id": 2, "value": "None" } - ] + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": {} + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } + ], + "iterationNumber": 1 }, { "lineNumber": 24, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 25, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 26, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": {} }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 2 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": {} + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 36, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + } ] }, { "lineNumber": 18, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 23, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 27, "iterationNumber": 1, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 28, "iterationNumber": 1, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 2, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 2, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 29, "iterationNumber": 1, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 2 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 2 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + } ] }, { "lineNumber": 30, "iterationNumber": 1, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 1, "root": 5 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 1, + "root": 5 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + } ] }, { "lineNumber": 37, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + } ] }, { "lineNumber": 18, "iterationNumber": 3, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "int", "id": 8, "value": 108 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 3, + "root": 8 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "int", + "id": 8, + "value": 108 + } ] }, { "lineNumber": 23, "iterationNumber": 3, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "int", "id": 8, "value": 108 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 3, + "root": 8 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "int", + "id": 8, + "value": 108 + } ] }, { "lineNumber": 27, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "int", "id": 8, "value": 108 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 3, + "root": 8 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "int", + "id": 8, + "value": 108 + } ] }, { "lineNumber": 28, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "int", "id": 8, "value": 108 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 3, + "root": 8 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 8, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "int", + "id": 8, + "value": 108 + } ] }, { "lineNumber": 29, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 6, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 6, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 8, "value": 108 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 3, + "root": 8 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 8, + "_left": 6, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 6, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 8, + "value": 108 + } ] }, { "lineNumber": 30, "iterationNumber": 2, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": ".frame", "name": "BST.__init__", "id": null, "order": 2, "value": { "self": 3, "root": 8 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 6, "_right": 7 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 6, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 7, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 8, "value": 108 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": ".frame", + "name": "BST.__init__", + "id": null, + "order": 2, + "value": { + "self": 3, + "root": 8 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 8, + "_left": 6, + "_right": 7 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 6, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 7, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 8, + "value": 108 + } ] }, { "lineNumber": 39, "answer": [ - { "type": ".frame", "name": "__main__", "id": null, "order": 1, "value": { "bst": 1 } }, - { "type": "object", "name": "BST", "id": 1, "value": { "_root": 5, "_left": 3, "_right": 4 } }, - { "type": "NoneType", "id": 2, "value": "None" }, - { "type": "object", "name": "BST", "id": 3, "value": { "_root": 8, "_left": 6, "_right": 7 } }, - { "type": "object", "name": "BST", "id": 4, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 5, "value": 148 }, - { "type": "object", "name": "BST", "id": 6, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "object", "name": "BST", "id": 7, "value": { "_root": 2, "_left": 2, "_right": 2 } }, - { "type": "int", "id": 8, "value": 108 } + { + "type": ".frame", + "name": "__main__", + "id": null, + "order": 1, + "value": { + "bst": 1 + } + }, + { + "type": "object", + "name": "BST", + "id": 1, + "value": { + "_root": 5, + "_left": 3, + "_right": 4 + } + }, + { + "type": "NoneType", + "id": 2, + "value": "None" + }, + { + "type": "object", + "name": "BST", + "id": 3, + "value": { + "_root": 8, + "_left": 6, + "_right": 7 + } + }, + { + "type": "object", + "name": "BST", + "id": 4, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 5, + "value": 148 + }, + { + "type": "object", + "name": "BST", + "id": 6, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "object", + "name": "BST", + "id": 7, + "value": { + "_root": 2, + "_left": 2, + "_right": 2 + } + }, + { + "type": "int", + "id": 8, + "value": 108 + } ] } ] } -] +] \ No newline at end of file diff --git a/backend/src/database/testQuestions.json b/backend/src/database/testQuestions.json index 2d04749..f006270 100644 --- a/backend/src/database/testQuestions.json +++ b/backend/src/database/testQuestions.json @@ -1061,7 +1061,6 @@ }, { "lineNumber": 4, - "iterationNumber": 3, "answer": [ { "id": null, @@ -3771,7 +3770,6 @@ }, { "lineNumber": 7, - "iterationNumber": 2, "answer": [ { "id": null, From 766a63435c80ef1c30a95d8ce390e58a545ff7cd Mon Sep 17 00:00:00 2001 From: Kevin Chen <109507575+kcccr123@users.noreply.github.com> Date: Sat, 7 Mar 2026 21:52:29 -0500 Subject: [PATCH 10/10] flip iteration --- backend/src/database/testQuestions.json | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/backend/src/database/testQuestions.json b/backend/src/database/testQuestions.json index f006270..701b2fc 100644 --- a/backend/src/database/testQuestions.json +++ b/backend/src/database/testQuestions.json @@ -1265,18 +1265,8 @@ }, { "lineNumber": 7, - "iterationNumber": 2, + "iterationNumber": 1, "answer": [ - { - "id": null, - "name": "RecursiveList.__init__", - "type": ".frame", - "order": 3, - "value": { - "self": 5, - "items": 8 - } - }, { "id": null, "name": "RecursiveList.__init__", @@ -1334,7 +1324,8 @@ "name": "RecursiveList", "type": "object", "value": { - "_first": 2 + "_first": 2, + "_rest": 5 } }, { @@ -1359,8 +1350,18 @@ }, { "lineNumber": 7, - "iterationNumber": 1, + "iterationNumber": 2, "answer": [ + { + "id": null, + "name": "RecursiveList.__init__", + "type": ".frame", + "order": 3, + "value": { + "self": 5, + "items": 8 + } + }, { "id": null, "name": "RecursiveList.__init__", @@ -1418,8 +1419,7 @@ "name": "RecursiveList", "type": "object", "value": { - "_first": 2, - "_rest": 5 + "_first": 2 } }, { @@ -8428,4 +8428,4 @@ } ] } -] \ No newline at end of file +]