Skip to content

Spreadsheet (Excel) Text Response Autograding#8422

Open
adi-herwana-nus wants to merge 3 commits into
masterfrom
adi/text-response-excel-autograding
Open

Spreadsheet (Excel) Text Response Autograding#8422
adi-herwana-nus wants to merge 3 commits into
masterfrom
adi/text-response-excel-autograding

Conversation

@adi-herwana-nus
Copy link
Copy Markdown
Contributor

No description provided.


has_one_attachment

def assign_params(params)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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]

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread lib/evaluator_scripts/python/tests/test_autograde_spreadsheet.py
Comment thread lib/evaluator_scripts/python/tests/test_autograde_spreadsheet.py
Comment on lines +89 to +102
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
Comment thread config/locales/en/errors.yml Outdated
Comment thread client/app/bundles/course/assessment/submission/containers/SolutionResultView.tsx Outdated
- 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
@adi-herwana-nus adi-herwana-nus force-pushed the adi/text-response-excel-autograding branch 3 times, most recently from 8985c9f to 1636b6f Compare June 1, 2026 11:20
- 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
@adi-herwana-nus adi-herwana-nus force-pushed the adi/text-response-excel-autograding branch from 1636b6f to 65fc851 Compare June 1, 2026 11:20
end
end

def process_spreadsheet_container_evaluation_results(container, solutions)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants