Spreadsheet (Excel) Text Response Autograding#8422
Conversation
|
|
||
| has_one_attachment | ||
|
|
||
| def assign_params(params) |
There was a problem hiding this comment.
Metrics/AbcSize: Assignment Branch Condition size for assign_params is too high. [<8, 25, 8> 27.44/20]
Metrics/CyclomaticComplexity: Cyclomatic complexity for assign_params is too high. [9/7]
Metrics/PerceivedComplexity: Perceived complexity for assign_params is too high. [9/8]
There was a problem hiding this comment.
Pull request overview
Adds a new autograding mode for Text Response questions based on evaluating student-entered spreadsheet formulas against an instructor-provided test spreadsheet, including optional randomization controls and richer per-solution grading results surfaced in the submission UI.
Changes:
- Introduces a Python-based spreadsheet formula evaluator (run inside the evaluator Docker container) and wires it into Text Response autograding.
- Adds DB/model support for attaching a “test spreadsheet” + randomization/timestamp/seed configuration to Text Response solutions.
- Extends the authoring and submission UIs to manage spreadsheet uploads/randomization settings and to display per-solution evaluation results.
Reviewed changes
Copilot reviewed 44 out of 49 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/evaluator_scripts/python/tests/test_autograde_spreadsheet.py | Adds unit tests for the spreadsheet evaluator script. |
| lib/evaluator_scripts/python/autograde_spreadsheet.py | Implements formula evaluation, randomization, and result serialization for container execution. |
| lib/evaluator_scripts/python/.gitignore | Ignores Python venv/cache artifacts for evaluator scripts. |
| lib/autoload/coursemology_docker_container.rb | Adds support for specifying Docker container entrypoint. |
| db/schema.rb | Updates schema with the new solution spreadsheet table + FK. |
| db/migrate/20260423065615_add_test_spreadsheets_to_text_response_solutions.rb | Creates course_assessment_question_text_response_solution_spreadsheets. |
| config/locales/en/errors.yml | Adds error strings for Text Response autograding failures/timeouts. |
| client/yarn.lock | Locks the newly-added SheetJS xlsx dependency. |
| client/package.json | Adds SheetJS xlsx for client-side spreadsheet preview. |
| client/locales/en.json | Adds UI strings for regex/spreadsheet solution types and randomization options. |
| client/locales/ko.json | Adds Korean UI strings for the new Text Response solution types/options. |
| client/locales/zh.json | Adds Chinese UI strings for the new Text Response solution types/options. |
| client/app/types/course/assessment/submission/question/types.ts | Extends Text Response solution type union to include regex/spreadsheet. |
| client/app/types/course/assessment/submission/answer/textResponse.ts | Adds solutionResults typing for richer autograding results display. |
| client/app/types/course/assessment/question/text-responses.ts | Adds spreadsheet/randomization configuration types and POST payload typings. |
| client/app/lib/translations/form.ts | Adds generic “Minimum/Maximum” form translations used by randomization UI. |
| client/app/lib/components/icons/RandomizeIcon.tsx | Adds a custom shuffle/randomize icon component. |
| client/app/lib/components/icons/OneNineIcon.tsx | Adds numeric randomization icon component. |
| client/app/lib/components/icons/AZIcon.tsx | Adds string randomization icon component. |
| client/app/lib/components/form/fields/SingleFileInput/SpreadsheetPreview.tsx | Implements client-side spreadsheet preview/grid rendering. |
| client/app/lib/components/form/fields/SingleFileInput/index.tsx | Adds className passthrough for styling the file input. |
| client/app/bundles/course/assessment/translations.ts | Adds translation keys for new solution types and spreadsheet randomization UI. |
| client/app/bundles/course/assessment/submission/reducers/index.js | Registers the new gradingResults reducer. |
| client/app/bundles/course/assessment/submission/reducers/gradingResults.ts | Stores/updates per-question solution evaluation results in Redux. |
| client/app/bundles/course/assessment/submission/pages/SubmissionEditIndex/components/QuestionContent.tsx | Shows solution evaluation results for text responses when present. |
| client/app/bundles/course/assessment/submission/containers/SolutionResultView.tsx | Renders per-solution results (including spreadsheet test runs). |
| client/app/bundles/course/assessment/question/text-responses/operations.ts | Switches create/update to multipart FormData and includes spreadsheet attributes. |
| client/app/bundles/course/assessment/question/text-responses/components/StringRandomizationManager.tsx | UI controls for string randomization config. |
| client/app/bundles/course/assessment/question/text-responses/components/SpreadsheetRandomizationManager.tsx | UI for selecting spreadsheet cells and setting per-cell randomization modes. |
| client/app/bundles/course/assessment/question/text-responses/components/SpreadsheetManagerPrompt.tsx | “Advanced options” dialog for fixed seed/timestamp and variable config. |
| client/app/bundles/course/assessment/question/text-responses/components/Solution.tsx | Extends solution authoring UI for regex/spreadsheet solution types + spreadsheet upload. |
| client/app/bundles/course/assessment/question/text-responses/components/ShuffleRandomizationManager.tsx | UI helper panel for shuffle mode. |
| client/app/bundles/course/assessment/question/text-responses/components/OverrideRandomizationManager.tsx | UI for override-value mode. |
| client/app/bundles/course/assessment/question/text-responses/components/NumericRandomizationManager.tsx | UI for numeric range mode. |
| client/app/bundles/course/assessment/question/text-responses/commons/validations.ts | Adds regex validation and spreadsheet file-required validation. |
| client/app/assets/icons/randomize.svg | Adds SVG asset for RandomizeIcon. |
| client/app/assets/icons/one-nine.svg | Adds SVG asset for OneNineIcon. |
| client/app/assets/icons/a-z.svg | Adds SVG asset for AZIcon. |
| client/app/api/course/Assessment/Question/TextResponse.ts | Updates API methods to accept FormData payloads. |
| app/views/course/assessment/question/text_responses/_solution_details.json.jbuilder | Exposes test spreadsheet metadata/config in the edit payload. |
| app/views/course/assessment/answer/text_responses/_text_response.json.jbuilder | Adds solutionResults to answer payloads and job/autograding status wiring. |
| app/services/course/assessment/answer/text_response_auto_grading_service.rb | Adds regex + spreadsheet-formula evaluation pathways and returns structured evaluation results. |
| app/models/course/assessment/question/text_response_solution.rb | Extends solution types and adds nested test spreadsheet association handling. |
| app/models/course/assessment/question/text_response_solution_spreadsheet.rb | New model for test spreadsheet attachment + randomization config. |
| app/models/course/assessment/answer/text_response.rb | Makes inline grading conditional on absence of spreadsheet solutions. |
| app/controllers/course/assessment/submission/submissions_controller.rb | Adjusts reevaluation response when no job is created. |
| app/controllers/course/assessment/question/text_responses_controller.rb | Permits nested spreadsheet attributes in solution params. |
| app/controllers/course/assessment/question/controller.rb | Hardens skill-id updates against nil params. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def evaluate_correct_regex_solutions(answer_text, solutions) | ||
| solutions.map do |s| | ||
| match = answer_text.match?(Regexp.new(s.solution, Regexp::IGNORECASE, timeout: 15.0)) | ||
| if match | ||
| SolutionEvaluationResult.new(s, s.grade, s.explanation) | ||
| else | ||
| nil | ||
| end | ||
| rescue Regexp::TimeoutError | ||
| SolutionEvaluationResult.new( | ||
| s, 0, I18n.t('errors.course.assessment.answer.text_response_auto_grading.grade.regex_timeout') | ||
| ) | ||
| end.compact | ||
| end |
- created spreadsheets table to capture spreadsheet-specific fields - added spreadsheet-formula-specific configuration section to solutions form
- install SheetJS (xlsx) library for FE spreadsheet parsing - configure popover and dialog to tweak per-cell randomization settings
8985c9f to
1636b6f
Compare
- use python evaluator to parse and evaluate formulas and make variable substitutions - save solution results in auto grading result column - implement FE view and reducer for solution results
1636b6f to
65fc851
Compare
| end | ||
| end | ||
|
|
||
| def process_spreadsheet_container_evaluation_results(container, solutions) |
There was a problem hiding this comment.
Metrics/AbcSize: Assignment Branch Condition size for process_spreadsheet_container_evaluation_results is too high. [<6, 19, 9> 21.86/20]
Metrics/CyclomaticComplexity: Cyclomatic complexity for process_spreadsheet_container_evaluation_results is too high. [8/7]
Metrics/PerceivedComplexity: Perceived complexity for process_spreadsheet_container_evaluation_results is too high. [9/8]
No description provided.