Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

To update the repository on coding club page. #1

Open
wants to merge 251 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
251 commits
Select commit Hold shift + click to select a range
f353049
Reorganized imports to move globals into their own namespace
Nov 25, 2019
5d8641b
Added featue based image alignment with using a reference image speci…
Dec 13, 2019
417021a
Merging commit 'c4c9896' to update changes from upstream dev
leongwaikay Dec 14, 2019
0682054
Merging commit '0f0e339' to update changes from upstream
leongwaikay Dec 14, 2019
80fd067
Merge pull request #17 from leongwaikay/clear-namespace
Udayraj123 Dec 15, 2019
0b2aaee
Fix errors for running samples
Udayraj123 Dec 15, 2019
e0f1e81
Merge pull request #18 from Udayraj123/dev
Udayraj123 Dec 15, 2019
6031f77
Fix bug with newlines in csv output
Dec 16, 2019
8ab4d33
Merge branch 'feature-based-alignment' into 'dev'
Dec 16, 2019
1181fb8
Created extension framework. Refactored image preprocessing into exte…
Dec 18, 2019
1221858
Refactored to use pathlib Paths. Added Levels module
Dec 23, 2019
82e5054
Added builtin preprocessors
leongwaikay Dec 24, 2019
ed15d12
keys in json template are case insensitive. Basically converted to lo…
Dec 25, 2019
523124f
Bug fixes from refactoring code
leongwaikay Dec 26, 2019
22f0993
Added sample for feature-based alignment
leongwaikay Dec 27, 2019
bc93101
Fixed bug in gamma formula
Dec 27, 2019
214d02b
merge theirs
Udayraj123 Dec 27, 2019
4cdc4fe
sample1 working with new configuration
Udayraj123 Mar 11, 2020
8fdb321
All samples running on new config
Udayraj123 Mar 11, 2020
52592db
Tidy up a bit
Udayraj123 Mar 11, 2020
88426dd
WIP
Udayraj123 May 9, 2020
603d8d4
add QTYPE_INT4
Udayraj123 May 15, 2020
4569f04
Merge pull request #21 from udayrajMT/master
Udayraj123 May 15, 2020
abb7640
heads up
Udayraj123 Sep 5, 2020
83c4525
Merge branch 'master' of https://github.com/udayraj123/OMRChecker
Udayraj123 Sep 5, 2020
ff1e0a1
refactor: round 1
Udayraj123 Sep 5, 2020
042c7c5
refactor round 1.5
Udayraj123 Sep 12, 2020
6d9c06b
fix: compile time issues
Udayraj123 Sep 13, 2020
86f58ad
feat: add stargazers in readme
Udayraj123 Oct 5, 2020
27604c6
fix: no.4 to no.3 now
Udayraj123 Oct 5, 2020
f12033f
fix: import errors
Udayraj123 Oct 10, 2020
46bf8e4
fix: script errors
Udayraj123 Oct 10, 2020
40910f5
fix: rename
Udayraj123 Oct 10, 2020
ff44a89
fix: rename
Udayraj123 Oct 10, 2020
18c2a6c
fix: errors begone!
Udayraj123 Oct 10, 2020
b440956
Remove unused variables and minor comments
deepakgouda Oct 10, 2020
68f95e4
Create ImageUtils class
deepakgouda Oct 17, 2020
24afb49
Create MainOperations class
deepakgouda Oct 24, 2020
f0ec190
Create static methods in notSorted.py
deepakgouda Nov 19, 2020
8c40dac
fix: pylint and black main round 1
Udayraj123 Nov 19, 2020
62e8eb2
fix: pylint and black main round 1
Udayraj123 Nov 19, 2020
0230aa3
Merge pull request #24 from deepakgouda/refactor-express
udayrajMT Nov 19, 2020
9ba554f
fix: pylint and black src round 1
Udayraj123 Nov 19, 2020
ef5ff62
Convert variable names to snake case
deepakgouda Nov 19, 2020
7c43dbe
fix: add pylintrc
Udayraj123 Nov 19, 2020
7878a6f
Merge pull request #25 from deepakgouda/refactor-express
udayrajMT Nov 19, 2020
a0947b4
fix: conflicts
Udayraj123 Nov 19, 2020
b2245a3
fix: conflicts
Udayraj123 Nov 19, 2020
3ce07e0
fix: pylint config
Udayraj123 Nov 19, 2020
56b607b
fix: pylint template
Udayraj123 Nov 19, 2020
7f013db
fix: import errors
deepakgouda Nov 19, 2020
9ecff0d
fix: resolve conflict
deepakgouda Nov 19, 2020
c1960b1
fix: pylint core
Udayraj123 Nov 19, 2020
3d35d25
fix: conflicts
Udayraj123 Nov 19, 2020
4f692de
fix: pylint not_sorted
Udayraj123 Nov 19, 2020
0bdca16
fix: make it runnable
Udayraj123 Nov 19, 2020
dd01de2
fix: commments
Udayraj123 Nov 19, 2020
9163693
fix: pylint processors
Udayraj123 Nov 20, 2020
0653e51
fix: make it runnable
Udayraj123 Nov 20, 2020
68b558e
fix: update readme and minor changes
Udayraj123 Nov 20, 2020
5981c61
fix: update readme and minor changes
Udayraj123 Nov 20, 2020
2dc31b3
fix: rename sample5
Udayraj123 Nov 20, 2020
3a3e042
fix: whitespace
Udayraj123 Nov 20, 2020
8e2d8b2
Create FUNDING.yml
Udayraj123 Nov 20, 2020
e03656d
Merge pull request #27 from Udayraj123/refactor-express
Udayraj123 Nov 20, 2020
b8da726
fix: note
Udayraj123 Nov 20, 2020
7b6ec5c
fix: update readme
Udayraj123 Nov 20, 2020
3411aa8
Merge branch 'master' of https://github.com/udayraj123/OMRChecker
Udayraj123 Nov 20, 2020
42ac9bb
fix: update readme
Udayraj123 Nov 20, 2020
df259c2
fix: update README
Udayraj123 Nov 24, 2020
c262370
fix: add sample6
Udayraj123 Nov 24, 2020
34004d0
fix: update Readme
Udayraj123 Nov 25, 2020
5487a22
fix: support jpeg as well
Udayraj123 Apr 27, 2021
407babc
fix: typo
Udayraj123 Aug 6, 2021
1828581
fix: unused
Udayraj123 Nov 6, 2021
4f11cf4
fix: draw quadlines only when needed
Udayraj123 Nov 12, 2021
afbfec7
fix: change preProcessors schema and samples
Udayraj123 Jul 3, 2022
46b2b25
Update README.md
Udayraj123 Sep 29, 2022
3e9bf31
Merge branch 'refactor-express' into dev
Udayraj123 Sep 29, 2022
fdea012
Create CONTRIBUTING.md
Udayraj123 Sep 29, 2022
0a84c62
fix: minor fixes; refactoring
Udayraj123 Sep 30, 2022
d10ca69
fix: old docs
Udayraj123 Sep 30, 2022
48e1c43
fix: sample5 correction
Udayraj123 Sep 30, 2022
e89df70
fix: conflicts
Udayraj123 Sep 30, 2022
dd398e4
fix: update readme
Udayraj123 Sep 30, 2022
15363ed
Merge pull request #46 from Udayraj123/dev
Udayraj123 Sep 30, 2022
1112358
fix: update readme
Udayraj123 Sep 30, 2022
85f0179
fix: minor changes; add contributors.md
Udayraj123 Oct 1, 2022
4f07343
fix: tidy up
Udayraj123 Oct 1, 2022
a193401
fix: tidy up
Udayraj123 Oct 1, 2022
126e1c2
fix: format files; refactoring
Udayraj123 Oct 1, 2022
726dfaa
fix: template.json typos; stack suffix; string formatting
Udayraj123 Oct 1, 2022
50ada8b
Update CONTRIBUTING.md
Udayraj123 Oct 2, 2022
d014299
fix: resolved issue #55
infinity1729 Oct 2, 2022
1c7c774
Merge pull request #51 from Udayraj123/improving-devx
Udayraj123 Oct 2, 2022
ecfc18f
Update README.md
UjjwalMahar Oct 2, 2022
ad799df
Update README.md
UjjwalMahar Oct 2, 2022
4ce8f30
made requested changes
infinity1729 Oct 2, 2022
5e4985f
Merge pull request #56 from infinity1729/master
Udayraj123 Oct 2, 2022
ecce27e
Update README.md
UjjwalMahar Oct 2, 2022
1d5c310
Update README.md
UjjwalMahar Oct 2, 2022
8b01771
Update README.md
UjjwalMahar Oct 2, 2022
c46f81b
Added dropdown for Linux Users
Rohan-G Oct 2, 2022
cbf9420
Update README.md
UjjwalMahar Oct 2, 2022
7a213fd
Update README.md
UjjwalMahar Oct 2, 2022
95738f0
Update README.md
UjjwalMahar Oct 2, 2022
1117b02
Added python3 installation using brew for OSX users
Rohan-G Oct 2, 2022
f0131c6
Update README.md
UjjwalMahar Oct 2, 2022
dad4d43
Update README.md
Udayraj123 Oct 2, 2022
1b5a4aa
Update README.md
Udayraj123 Oct 2, 2022
abf7a3c
Merge pull request #57 from UjjwalMahar/master
Udayraj123 Oct 2, 2022
27eb894
Merge branch 'Udayraj123:master' into linuxDrop
Rohan-G Oct 2, 2022
9d4a99a
Changed dropdowns
Rohan-G Oct 2, 2022
d350746
Error in formatting fixed
Rohan-G Oct 2, 2022
a903c96
Created dropdowns for each installation step
Rohan-G Oct 3, 2022
5245272
A few small fixes
Rohan-G Oct 3, 2022
94387a4
Another small fix
Rohan-G Oct 3, 2022
825f8e0
Update issue templates
Udayraj123 Oct 3, 2022
22a2419
Merge pull request #59 from Rohan-G/linuxDrop
Udayraj123 Oct 3, 2022
ddc1065
fix: resolved issue#62
infinity1729 Oct 3, 2022
f8f120f
Good news
Udayraj123 Oct 4, 2022
7b1f942
Added a new sample image and its template
Antibodyy Oct 4, 2022
1e4ee27
Added new sample and its template.json
Antibodyy Oct 4, 2022
f849d8d
Merge pull request #63 from infinity1729/master
Udayraj123 Oct 4, 2022
2d0d35f
update template.json for sample 1
05Alston Oct 4, 2022
08f92b7
Align labels to top right
05Alston Oct 4, 2022
0dd566e
Merge branch 'Udayraj123:master' into master
05Alston Oct 4, 2022
6b77ac0
fixed show_image_level and removed hardcoded value
05Alston Oct 4, 2022
39e6675
fixed extra rectangles bug
05Alston Oct 5, 2022
905b2cc
' Pip module not found' issue added to readme
asc249 Oct 5, 2022
f1a8eaa
Updated template.py
05Alston Oct 5, 2022
527ad9b
Merge pull request #66 from 05Alston/master
Udayraj123 Oct 5, 2022
aca1929
pip install issue linked in readme
asc249 Oct 5, 2022
e644102
Merge branch 'Udayraj123:master' into master
asc249 Oct 5, 2022
ee86758
New sample and template added
Antibodyy Oct 5, 2022
4de7399
Merge branch 'Udayraj123:master' into master
Antibodyy Oct 5, 2022
e0c94cb
Added pip installation guidelines, check for python and pip installat…
asc249 Oct 5, 2022
4ab4915
Added pip install instructions
asc249 Oct 5, 2022
c57b38a
Merge pull request #69 from asc249/master
Udayraj123 Oct 5, 2022
86353de
Renamed and created folders/files as required
Antibodyy Oct 5, 2022
c1f978a
Merge branch 'Udayraj123:master' into master
Antibodyy Oct 5, 2022
16cbc86
Merge branch 'master' of https://github.com/Antibodyy/OMRChecker
Antibodyy Oct 5, 2022
77700c4
Undone changes here
Antibodyy Oct 5, 2022
e94ba96
Merge pull request #64 from Antibodyy/master
Udayraj123 Oct 5, 2022
79c1f81
Added a new sample and its template.json
sandptel Oct 5, 2022
ad2bff3
Renamed the files and added it to community folder.
sandptel Oct 5, 2022
d4a839d
Merge pull request #75 from Sandeep-1507/master
Udayraj123 Oct 5, 2022
98366ff
reduced the size of omr-1.png
sandptel Oct 5, 2022
6210783
added basic logging with rich handler
pixalquarks Oct 5, 2022
f60e1bb
Merge pull request #76 from Sandeep-1507/master
Udayraj123 Oct 5, 2022
783ab9c
Added jsonschema requirement
SpyzzVVarun Oct 3, 2022
deb7e72
adding validation scheme for template
SpyzzVVarun Oct 5, 2022
ce59476
Merge pull request #60 from SpyzzVVarun/master
Udayraj123 Oct 5, 2022
604cdce
Update template.py
SpyzzVVarun Oct 5, 2022
6c9a63c
Merge branch 'Udayraj123:master' into master
SpyzzVVarun Oct 5, 2022
40dee1c
Merge pull request #78 from SpyzzVVarun/master
Udayraj123 Oct 5, 2022
ac3ffbe
Adding name
Harsh-Kapoorr Oct 5, 2022
3324c37
fix: reformat readme
Udayraj123 Oct 5, 2022
e2ca6ce
fix: reformat readme
Udayraj123 Oct 5, 2022
ca12dd2
Update Contributors.md
Udayraj123 Oct 5, 2022
e4782ea
Merge branch 'master' into changess
Udayraj123 Oct 5, 2022
842b63a
Merge pull request #81 from Harsh-Kapoorr/changess
Udayraj123 Oct 5, 2022
e533dd9
fix: resolved issue #83
infinity1729 Oct 6, 2022
e1e63ce
Update README.md
Udayraj123 Oct 7, 2022
a10c162
Update issue templates
Udayraj123 Oct 7, 2022
2715193
Merge branch 'Udayraj123:master' into master
infinity1729 Oct 7, 2022
a895a0f
fix: fixes merged templates using deepcopy function
Kurtsley Oct 7, 2022
80cc32c
Merge pull request #84 from infinity1729/master
Udayraj123 Oct 7, 2022
b09bfd4
removed redundant error and warning prefixes
pixalquarks Oct 8, 2022
5689717
added option for disabling rich tracebacks
pixalquarks Oct 8, 2022
c49fe18
added config options to Logger class
pixalquarks Oct 8, 2022
8674152
Merge pull request #87 from Kurtsley/fix-template-merge
Udayraj123 Oct 9, 2022
8b9496b
moved logging function to logutil function to follow dry principle
pixalquarks Oct 9, 2022
ac9e2dc
Update Contributors.md
Udayraj123 Oct 9, 2022
cbbe57c
Convert part of readme to issue
Udayraj123 Oct 9, 2022
09a1c07
added returns to the functions
pixalquarks Oct 10, 2022
27d9111
fix: string corrections
Udayraj123 Oct 11, 2022
9b06ac2
Fixed errors
theranjitraut Oct 11, 2022
743c113
Corrected mistakes
theranjitraut Oct 11, 2022
b206728
feat: support for emptyVal in template.json
Udayraj123 Oct 11, 2022
ad3403b
Merge pull request #90 from theranjitraut/master
Udayraj123 Oct 11, 2022
292aa91
fix: review changes
Udayraj123 Oct 12, 2022
c1e792a
Merge pull request #91 from Udayraj123/feature/61
Udayraj123 Oct 12, 2022
050cad6
fix: remove bad_rolls_dir
Udayraj123 Oct 12, 2022
931d4f3
Merge branch 'master' into logging
Udayraj123 Oct 13, 2022
d2fb0bf
refactored to follow PEP8 formatting
pixalquarks Oct 14, 2022
c1fc63b
fix: comment out Present checks
Udayraj123 Oct 15, 2022
f5c03ca
Merge branch 'master' of https://github.com/pixalquarks/OMRChecker in…
pixalquarks Oct 15, 2022
92d4ded
fix: add comment for later changes
Udayraj123 Oct 15, 2022
2e4b527
Merge pull request #95 from Udayraj123/47-logging-reduce-noise-in-log…
Udayraj123 Oct 15, 2022
4d6b72f
merged master into logging
pixalquarks Oct 16, 2022
0aaa11a
changed print functions to log
pixalquarks Oct 16, 2022
8b07b71
merged remote logging branch to local
pixalquarks Oct 16, 2022
5fcbb5b
Merge branch 'master' into logging
Udayraj123 Oct 16, 2022
b9a9b8a
Merge pull request #77 from pixalquarks/logging
Udayraj123 Oct 16, 2022
41e9f64
Adding pre-commit hook for auto code formatting
Oct 20, 2022
26ef26c
Merge pull request #96 from gaursagar21/feature/pre-commit
Udayraj123 Oct 21, 2022
99ff626
feat: run pre-commit config on all files
Udayraj123 Oct 21, 2022
6b10b4c
added display question labels flag
Oct 22, 2022
77ad538
Merge branch 'master' of https://github.com/aayushibansal2001/OMRChecker
Oct 22, 2022
2fe7306
trying red colour text on output images
Oct 24, 2022
45f9bf6
fix: check for non uint8 types or multiple channels
Udayraj123 Oct 24, 2022
079375d
Revert "added display question labels flag"
Udayraj123 Oct 24, 2022
64ad04a
Update README.md
Udayraj123 Nov 1, 2022
d20a326
Update issue templates
Udayraj123 Nov 8, 2022
3309716
Create CODE_OF_CONDUCT.md
Udayraj123 Dec 3, 2022
e005f76
fix: update readme with links
Udayraj123 Dec 2, 2022
8e85266
new OMR_template created (#108)
ShamanthVallem Dec 19, 2022
a04a60b
created a preprocessor Median blur (#109)
rudrapsc Dec 19, 2022
418dbd4
Updated src/defaults/schema.json
rudrapsc Dec 23, 2022
848a771
Update schema.json
rudrapsc Dec 25, 2022
ce25cd2
updated schema.json
rudrapsc Dec 27, 2022
f023f6b
Update schema.json
rudrapsc Dec 27, 2022
65a6e7c
Update schema.json
rudrapsc Dec 28, 2022
4db4162
Update schema.json
rudrapsc Dec 29, 2022
d4f0bd9
Update file.py
rudrapsc Dec 29, 2022
a54147e
fix: parse int for cases like 1.0; minor changes in schema
Udayraj123 Dec 29, 2022
ee57677
fix: better error messages; minor changes in schema parsing
Udayraj123 Dec 29, 2022
9370975
Update Contributors.md
Udayraj123 Jan 1, 2023
ac6fb56
updated .pre-commit-config.yaml (#120)
rudrapsc Jan 6, 2023
13acd4d
Update README.md
Udayraj123 Jan 26, 2023
0bc3df9
Update README.md
Udayraj123 Jan 26, 2023
37ca3d5
Update README.md
Udayraj123 Jan 26, 2023
26003be
Update CONTRIBUTING.md
Udayraj123 Jan 26, 2023
080b360
Evaluation Schema + a necessary revamp (#118)
Udayraj123 Feb 12, 2023
09ce78a
fix: minor fix
Udayraj123 Feb 21, 2023
5db8f24
refactor: follow the-step-down-rule (#129)
Udayraj123 Feb 25, 2023
f51097e
Fixed issue where OMR input images are processed twice in Windows env…
aqoshi Apr 19, 2023
d777136
Release/combined bugfixes (#143)
Udayraj123 Jun 25, 2023
9147316
Feature/devx upgrade packages (#144)
Udayraj123 Jun 25, 2023
47f028a
fix: improve pytest output
Udayraj123 Jun 28, 2023
62f6aa3
License clarifications (#146)
Udayraj123 Jul 4, 2023
f9f6dc3
fix: typos and coherence (#164)
benfrstr Feb 16, 2024
c448e0c
feat: support for multiple-correct-weighted answer key (#166)
Udayraj123 Feb 24, 2024
7e6e4b8
Update README.md (#181)
Udayraj123 Apr 13, 2024
80634b3
fix: demo
Udayraj123 May 24, 2024
4469a1c
added docs
palash018 Jul 18, 2024
a244965
edited readme
palash018 Jul 19, 2024
fb74a7d
Merge branch 'master' of github.com:palash018/OMRChecker
Udayraj123 Jul 19, 2024
9b0e9c5
fix: link colored outputs
Udayraj123 Jul 19, 2024
9c75256
Update License to MIT
Udayraj123 Jul 25, 2024
2a44f2e
Update License to MIT (#200)
Udayraj123 Jul 25, 2024
54fc8ca
Update License in readme
Udayraj123 Jul 25, 2024
4fed356
Merge branch 'master' of https://github.com/Udayraj123/OMRChecker
Udayraj123 Jul 25, 2024
6e46922
Merge branch 'feature/update-license'
Udayraj123 Jul 25, 2024
bf19841
fix: update code of conduct to v2.1
Udayraj123 Aug 7, 2024
7189c2e
added new sample (#227)
Dxuian Oct 6, 2024
646a080
Fixed [Environment] OpenCV NULL guiReceiver error during pre-commit t…
Princekumarofficial Oct 26, 2024
fcdb49c
Added feature to export the evaluation summary table in csv format (…
Drita-ai Oct 26, 2024
7b37b0e
waec sample (#232)
samuelIkoli Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: support for multiple-correct-weighted answer key (Udayraj123#166)
* feat: support for multiple-correct-weighted answer key; minor refactor evaluation schema

* fix: update validation
Udayraj123 authored Feb 24, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit c448e0cc28c1ea21f0fb1f34a0f4ecf20272c146
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ repos:
hooks:
- id: pytest-on-commit
name: Running single sample test
entry: pytest -rfpsxEX --disable-warnings --verbose -k sample1
entry: python3 -m pytest -rfpsxEX --disable-warnings --verbose -k sample1
language: system
pass_filenames: false
always_run: true
@@ -51,7 +51,7 @@ repos:
hooks:
- id: pytest-on-push
name: Running all tests before push...
entry: pytest -rfpsxEX --disable-warnings --verbose --durations=3
entry: python3 -m pytest -rfpsxEX --disable-warnings --verbose --durations=3
language: system
pass_filenames: false
always_run: true
Binary file added samples/answer-key/using-csv/adrian_omr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
q1,B
q1,C
q2,E
q3,A
q4,C
q4,B
q5,B
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
"answer_key_csv_path": "answer_key.csv",
"should_explain_scoring": true
},
"marking_scheme": {
"marking_schemes": {
"DEFAULT": {
"correct": "1",
"incorrect": "0",
35 changes: 35 additions & 0 deletions samples/answer-key/using-csv/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"pageDimensions": [
300,
400
],
"bubbleDimensions": [
25,
25
],
"preProcessors": [
{
"name": "CropPage",
"options": {
"morphKernel": [
10,
10
]
}
}
],
"fieldBlocks": {
"MCQ_Block_1": {
"fieldType": "QTYPE_MCQ5",
"origin": [
65,
60
],
"fieldLabels": [
"q1..5"
],
"labelsGap": 52,
"bubblesGap": 41
}
}
}
35 changes: 35 additions & 0 deletions samples/answer-key/weighted-answers/evaluation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"source_type": "custom",
"options": {
"questions_in_order": [
"q1..5"
],
"answers_in_order": [
"C",
"E",
[
"A",
"C"
],
[
[
"B",
2
],
[
"C",
"3/2"
]
],
"C"
],
"should_explain_scoring": true
},
"marking_schemes": {
"DEFAULT": {
"correct": "3",
"incorrect": "-1",
"unmarked": "0"
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions samples/answer-key/weighted-answers/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"pageDimensions": [
300,
400
],
"bubbleDimensions": [
25,
25
],
"preProcessors": [
{
"name": "CropPage",
"options": {
"morphKernel": [
10,
10
]
}
}
],
"fieldBlocks": {
"MCQ_Block_1": {
"fieldType": "QTYPE_MCQ5",
"origin": [
65,
60
],
"fieldLabels": [
"q1..5"
],
"labelsGap": 52,
"bubblesGap": 41
}
}
}
2 changes: 1 addition & 1 deletion samples/community/UPSC-mock/evaluation.json
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
],
"should_explain_scoring": true
},
"marking_scheme": {
"marking_schemes": {
"DEFAULT": {
"correct": "2",
"incorrect": "-2/3",
4 changes: 2 additions & 2 deletions samples/community/UmarFarootAPS/answer_key.csv
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@ q1,C
q2,C
q3,"D,E"
q4,"A,AB"
q5,"['A', ['1', '-2/3', '0']]"
q6,"['A', ['2']]"
q5,"[['A', '1'], ['B', '2']]"
q6,"['A', 'B']"
q7,C
q8,D
q9,B
2 changes: 1 addition & 1 deletion samples/community/UmarFarootAPS/evaluation.json
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
"answer_key_csv_path": "answer_key.csv",
"should_explain_scoring": true
},
"marking_scheme": {
"marking_schemes": {
"DEFAULT": {
"correct": "1",
"incorrect": "0",
8 changes: 6 additions & 2 deletions samples/sample4/evaluation.json
Original file line number Diff line number Diff line change
@@ -11,15 +11,19 @@
"B",
"D",
"C",
"BC",
[
"B",
"C",
"BC"
],
"A",
"C",
"D",
"C"
],
"should_explain_scoring": true
},
"marking_scheme": {
"marking_schemes": {
"DEFAULT": {
"correct": "3",
"incorrect": "-1",
2 changes: 1 addition & 1 deletion samples/sample5/evaluation.json
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@
],
"should_explain_scoring": true
},
"marking_scheme": {
"marking_schemes": {
"DEFAULT": {
"correct": "1",
"incorrect": "0",
191 changes: 104 additions & 87 deletions src/evaluation.py
Original file line number Diff line number Diff line change
@@ -22,123 +22,127 @@


class AnswerMatcher:
def __init__(self, answer_item, marking_scheme):
self.answer_type = self.get_answer_type(answer_item)
self.parsed_answer = self.parse_answer_item(answer_item)
self.set_defaults_from_scheme(marking_scheme)
self.marking_scheme = marking_scheme

def get_answer_type(self, answer_item):
item_type = type(answer_item)
if item_type == str:
def __init__(self, answer_item, section_marking_scheme):
self.section_marking_scheme = section_marking_scheme
self.answer_item = answer_item
self.answer_type = self.validate_and_get_answer_type(answer_item)
self.set_defaults_from_scheme(section_marking_scheme)

@staticmethod
def is_a_marking_score(answer_element):
# Note: strict type checking is already done at schema validation level,
# Here we focus on overall struct type
return type(answer_element) == str or type(answer_element) == int

@staticmethod
def is_standard_answer(answer_element):
return type(answer_element) == str and len(answer_element) >= 1

def validate_and_get_answer_type(self, answer_item):
if self.is_standard_answer(answer_item):
return "standard"
elif item_type == list:
elif type(answer_item) == list:
if (
# Array of answer elements: ['A', 'B', 'AB']
len(answer_item) >= 2
and type(answer_item[0]) == str
and type(answer_item[1]) == str
and all(
self.is_standard_answer(answers_or_score)
for answers_or_score in answer_item
)
):
return "multiple-correct"
elif (
len(answer_item) == 2
and type(answer_item[0]) == str
and type(answer_item[1]) == list
# Array of two-tuples: [['A', 1], ['B', 1], ['C', 3], ['AB', 2]]
len(answer_item) >= 1
and all(
type(answer_and_score) == list and len(answer_and_score) == 2
for answer_and_score in answer_item
)
and all(
self.is_standard_answer(allowed_answer)
and self.is_a_marking_score(answer_score)
for allowed_answer, answer_score in answer_item
)
):
return "multiple-correct-weighted"
elif (
len(answer_item) == 2
and type(answer_item[0]) in list
and type(answer_item[1]) == list
):
return "answer-weights"
else:
logger.critical(
f"Unable to determine answer type for answer item: {answer_item}"
)
raise Exception("Unable to determine answer type")

def parse_answer_item(self, answer_item):
return answer_item
logger.critical(
f"Unable to determine answer type for answer item: {answer_item}"
)
raise Exception("Unable to determine answer type")

def set_defaults_from_scheme(self, marking_scheme):
def set_defaults_from_scheme(self, section_marking_scheme):
answer_type = self.answer_type
self.empty_val = marking_scheme.empty_val
parsed_answer = self.parsed_answer
self.marking = deepcopy(marking_scheme.marking)
self.empty_val = section_marking_scheme.empty_val
answer_item = self.answer_item
self.marking = deepcopy(section_marking_scheme.marking)
# TODO: reuse part of parse_scheme_marking here -
if answer_type == "standard":
# no local overrides
pass
elif answer_type == "multiple-correct":
# no local overrides
for allowed_answer in parsed_answer:
# override marking scheme scores for each allowed answer
for allowed_answer in answer_item:
self.marking[f"correct-{allowed_answer}"] = self.marking["correct"]
elif answer_type == "multiple-correct-weighted":
custom_marking = list(map(parse_float_or_fraction, parsed_answer[1]))
verdict_types_length = min(len(MARKING_VERDICT_TYPES), len(custom_marking))
# override the given marking
for i in range(verdict_types_length):
verdict_type = MARKING_VERDICT_TYPES[i]
self.marking[verdict_type] = custom_marking[i]

if type(parsed_answer[0] == str):
allowed_answer = parsed_answer[0]
self.marking[f"correct-{allowed_answer}"] = self.marking["correct"]
else:
for allowed_answer in parsed_answer[0]:
self.marking[f"correct-{allowed_answer}"] = self.marking["correct"]
# Note: No override using marking scheme as answer scores are provided in answer_item
for allowed_answer, answer_score in answer_item:
self.marking[f"correct-{allowed_answer}"] = parse_float_or_fraction(
answer_score
)

def get_marking_scheme(self):
return self.marking_scheme
return self.section_marking_scheme

def get_section_explanation(self):
answer_type = self.answer_type
if answer_type in ["standard", "multiple-correct"]:
return self.marking_scheme.section_key
return self.section_marking_scheme.section_key
elif answer_type == "multiple-correct-weighted":
return f"Custom: {self.marking}"

def get_verdict_marking(self, marked_answer):
answer_type = self.answer_type
question_verdict = "incorrect"
if answer_type == "standard":
question_verdict = self.get_standard_verdict(marked_answer)
return question_verdict, self.marking[question_verdict]
elif answer_type == "multiple-correct":
question_verdict = self.get_multiple_correct_verdict(marked_answer)
return question_verdict, self.marking[question_verdict]
elif answer_type == "multiple-correct-weighted":
question_verdict = self.get_multi_weighted_verdict(marked_answer)
return question_verdict, self.marking[question_verdict]
question_verdict = self.get_multiple_correct_weighted_verdict(marked_answer)
return question_verdict, self.marking[question_verdict]

def get_standard_verdict(self, marked_answer):
parsed_answer = self.parsed_answer
allowed_answer = self.answer_item
if marked_answer == self.empty_val:
return "unmarked"
elif marked_answer == parsed_answer:
elif marked_answer == allowed_answer:
return "correct"
else:
return "incorrect"

def get_multi_weighted_verdict(self, marked_answer):
return self.get_multiple_correct_verdict(marked_answer)

def get_multiple_correct_verdict(self, marked_answer):
parsed_answer = self.parsed_answer
allowed_answers = self.answer_item
if marked_answer == self.empty_val:
return "unmarked"
elif marked_answer in parsed_answer:
elif marked_answer in allowed_answers:
return f"correct-{marked_answer}"
else:
return "incorrect"

def get_multiple_correct_weighted_verdict(self, marked_answer):
allowed_answers = [
allowed_answer for allowed_answer, _answer_score in self.answer_item
]
if marked_answer == self.empty_val:
return "unmarked"
elif marked_answer in allowed_answers:
return f"correct-{marked_answer}"
else:
return "incorrect"

def __str__(self):
answer_type, parsed_answer = self.answer_type, self.parsed_answer
if answer_type == "multiple-correct":
return str(parsed_answer)
elif answer_type == "multiple-correct-weighted":
return f"{parsed_answer[0]}"
# TODO: multi-lines in multi-weights
return parsed_answer
return f"{self.answer_item}"


class SectionMarkingScheme:
@@ -154,6 +158,9 @@ def __init__(self, section_key, section_scheme, empty_val):
self.questions = parse_fields(section_key, section_scheme["questions"])
self.marking = self.parse_scheme_marking(section_scheme["marking"])

def __str__(self):
return self.section_key

def parse_scheme_marking(self, marking):
parsed_marking = {}
for verdict_type in MARKING_VERDICT_TYPES:
@@ -184,15 +191,13 @@ class EvaluationConfig:
def __init__(self, curr_dir, evaluation_path, template, tuning_config):
self.path = evaluation_path
evaluation_json = open_evaluation_with_validation(evaluation_path)
options, marking_scheme, source_type = map(
evaluation_json.get, ["options", "marking_scheme", "source_type"]
options, marking_schemes, source_type = map(
evaluation_json.get, ["options", "marking_schemes", "source_type"]
)
self.should_explain_scoring = options.get("should_explain_scoring", False)
self.has_non_default_section = False
self.exclude_files = []

marking_scheme = marking_scheme

if source_type == "csv":
csv_path = curr_dir.joinpath(options["answer_key_csv_path"])
if not os.path.exists(csv_path):
@@ -286,21 +291,21 @@ def __init__(self, curr_dir, evaluation_path, template, tuning_config):

self.validate_questions(answers_in_order)

self.marking_scheme, self.question_to_scheme = {}, {}
for section_key, section_scheme in marking_scheme.items():
self.section_marking_schemes, self.question_to_scheme = {}, {}
for section_key, section_scheme in marking_schemes.items():
section_marking_scheme = SectionMarkingScheme(
section_key, section_scheme, template.global_empty_val
)
if section_key != DEFAULT_SECTION_KEY:
self.marking_scheme[section_key] = section_marking_scheme
self.section_marking_schemes[section_key] = section_marking_scheme
for q in section_marking_scheme.questions:
# TODO: check the answer key for custom scheme here?
self.question_to_scheme[q] = section_marking_scheme
self.has_non_default_section = True
else:
self.default_marking_scheme = section_marking_scheme

self.validate_marking_scheme()
self.validate_marking_schemes()

self.question_to_answer_matcher = self.parse_answers_and_map_questions(
answers_in_order
@@ -360,10 +365,13 @@ def get_exclude_files(self):
@staticmethod
def parse_answer_column(answer_column):
if answer_column[0] == "[":
# multiple-correct-weighted or multiple-correct
parsed_answer = ast.literal_eval(answer_column)
elif "," in answer_column:
# multiple-correct
parsed_answer = answer_column.split(",")
else:
# single-correct
parsed_answer = answer_column
return parsed_answer

@@ -385,12 +393,13 @@ def validate_answers(self, answers_in_order, tuning_config):
multi_marked_answer = True
break
if answer_type == "multiple-correct-weighted":
if len(answer_item[0]) > 1:
multi_marked_answer = True
for single_answer, _answer_score in answer_item:
if len(single_answer) > 1:
multi_marked_answer = True

if multi_marked_answer:
raise Exception(
f"Answer key contains multiple correct answer(s), but filter_out_multimarked_files is True. Scoring will get skipped."
f"Provided answer key contains multiple correct answer(s), but config.filter_out_multimarked_files is True. Scoring will get skipped."
)

def validate_questions(self, answers_in_order):
@@ -406,10 +415,10 @@ def validate_questions(self, answers_in_order):
f"Unequal lengths for questions_in_order and answers_in_order ({len_questions_in_order} != {len_answers_in_order})"
)

def validate_marking_scheme(self):
marking_scheme = self.marking_scheme
def validate_marking_schemes(self):
section_marking_schemes = self.section_marking_schemes
section_questions = set()
for section_key, section_scheme in marking_scheme.items():
for section_key, section_scheme in section_marking_schemes.items():
if section_key == DEFAULT_SECTION_KEY:
continue
current_set = set(section_scheme.questions)
@@ -431,9 +440,15 @@ def parse_answers_and_map_questions(self, answers_in_order):
question_to_answer_matcher = {}
for question, answer_item in zip(self.questions_in_order, answers_in_order):
section_marking_scheme = self.get_marking_scheme_for_question(question)
question_to_answer_matcher[question] = AnswerMatcher(
answer_item, section_marking_scheme
)
answer_matcher = AnswerMatcher(answer_item, section_marking_scheme)
question_to_answer_matcher[question] = answer_matcher
if (
answer_matcher.answer_type == "multiple-correct-weighted"
and section_marking_scheme.section_key != DEFAULT_SECTION_KEY
):
logger.warning(
f"The custom scheme '{section_marking_scheme}' will not apply to question '{question}' as it will use the given answer weights f{answer_item}"
)
return question_to_answer_matcher

# Then unfolding lower abstraction levels
@@ -481,9 +496,11 @@ def conditionally_add_explanation(
str.title(question_verdict),
str(round(delta, 2)),
str(round(next_score, 2)),
answer_matcher.get_section_explanation()
if self.has_non_default_section
else None,
(
answer_matcher.get_section_explanation()
if self.has_non_default_section
else None
),
]
if item is not None
]
62 changes: 22 additions & 40 deletions src/schemas/evaluation_schema.py
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
"required": ["correct", "incorrect", "unmarked"],
"type": "object",
"properties": {
# TODO: can support streak marking if we allow array of marking_scores here
"correct": marking_score,
"incorrect": marking_score,
"unmarked": marking_score,
@@ -31,12 +32,12 @@
"description": "OMRChecker evaluation schema i.e. the marking scheme",
"type": "object",
"additionalProperties": True,
"required": ["source_type", "options", "marking_scheme"],
"required": ["source_type", "options", "marking_schemes"],
"properties": {
"additionalProperties": False,
"source_type": {"type": "string", "enum": ["csv", "custom"]},
"options": {"type": "object"},
"marking_scheme": {
"marking_schemes": {
"type": "object",
"required": [DEFAULT_SECTION_KEY],
"patternProperties": {
@@ -102,57 +103,38 @@
"type": "array",
"items": {
"oneOf": [
# "standard": single correct, multimarked single-correct
# Example: "q1" --> 'AB'
# "standard": single correct, multi-marked single-correct
# Example: "q1" --> '67'
{"type": "string"},
# "multiple-correct": multiple correct answers (for ambiguos/bonus questions)
# "multiple-correct": multiple-correct (for ambiguous/bonus questions)
# Example: "q1" --> [ 'A', 'B' ]
{
"type": "array",
"items": {"type": "string"},
"minItems": 2,
},
# "multiple-correct-weighted": array of answer-wise weights
# Example: "q1" --> [['A', 1], ['B', 2], ['C', 3]]
# "multiple-correct-weighted": array of answer-wise weights (marking scheme not applicable)
# Example 1: "q1" --> [['A', 1], ['B', 2], ['C', 3]] or
# Example 2: "q2" --> [['A', 1], ['B', 1], ['AB', 2]]
{
"type": "array",
"items": False,
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{"type": "string"},
{
"type": "array",
"items": marking_score,
"minItems": 1,
"maxItems": 3,
},
],
"items": {
"type": "array",
"items": False,
"minItems": 2,
"maxItems": 2,
"prefixItems": [
{"type": "string"},
marking_score,
],
},
},
# Multiple-correct with custom marking scheme
# ["A", ["1", "2", "3"]],
# [["A", "B", "AB"], ["1", "2", "3"]]
],
},
},
{
# TODO: answer_weight format
"type": "array", # two column array for weights
"items": False,
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{
"type": "array",
"items": {"type": "string"},
"minItems": 2,
"maxItems": 2,
},
{
"type": "array",
"items": marking_score,
"minItems": 1,
"maxItems": 3,
},
],
},
]
},
"questions_in_order": ARRAY_OF_STRINGS,
41 changes: 38 additions & 3 deletions src/tests/__snapshots__/test_all_samples.ambr
Original file line number Diff line number Diff line change
@@ -1,4 +1,39 @@
# serializer version: 1
# name: test_run_answer_key_using_csv
dict({
'Manual/ErrorFiles.csv': '''
"file_id","input_path","output_path","score","q1","q2","q3","q4","q5"

''',
'Manual/MultiMarkedFiles.csv': '''
"file_id","input_path","output_path","score","q1","q2","q3","q4","q5"

''',
'Results/Results_05AM.csv': '''
"file_id","input_path","output_path","score","q1","q2","q3","q4","q5"
"adrian_omr.png","samples/answer-key/using-csv/adrian_omr.png","outputs/answer-key/using-csv/CheckedOMRs/adrian_omr.png","5.0","C","E","A","B","B"

''',
})
# ---
# name: test_run_answer_key_weighted_answers
dict({
'images/Manual/ErrorFiles.csv': '''
"file_id","input_path","output_path","score","q1","q2","q3","q4","q5"

''',
'images/Manual/MultiMarkedFiles.csv': '''
"file_id","input_path","output_path","score","q1","q2","q3","q4","q5"

''',
'images/Results/Results_05AM.csv': '''
"file_id","input_path","output_path","score","q1","q2","q3","q4","q5"
"adrian_omr.png","samples/answer-key/weighted-answers/images/adrian_omr.png","outputs/answer-key/weighted-answers/images/CheckedOMRs/adrian_omr.png","5.5","B","E","A","C","B"
"adrian_omr_2.png","samples/answer-key/weighted-answers/images/adrian_omr_2.png","outputs/answer-key/weighted-answers/images/CheckedOMRs/adrian_omr_2.png","10.0","C","E","A","B","B"

''',
})
# ---
# name: test_run_community_Antibodyy
dict({
'Manual/ErrorFiles.csv': '''
@@ -97,7 +132,7 @@
'scans/Results/Results_05AM.csv': '''
"file_id","input_path","output_path","score","Roll_no","q1","q2","q3","q4","q5","q6","q7","q8","q9","q10","q11","q12","q13","q14","q15","q16","q17","q18","q19","q20","q21","q22","q23","q24","q25","q26","q27","q28","q29","q30","q31","q32","q33","q34","q35","q36","q37","q38","q39","q40","q41","q42","q43","q44","q45","q46","q47","q48","q49","q50","q51","q52","q53","q54","q55","q56","q57","q58","q59","q60","q61","q62","q63","q64","q65","q66","q67","q68","q69","q70","q71","q72","q73","q74","q75","q76","q77","q78","q79","q80","q81","q82","q83","q84","q85","q86","q87","q88","q89","q90","q91","q92","q93","q94","q95","q96","q97","q98","q99","q100","q101","q102","q103","q104","q105","q106","q107","q108","q109","q110","q111","q112","q113","q114","q115","q116","q117","q118","q119","q120","q121","q122","q123","q124","q125","q126","q127","q128","q129","q130","q131","q132","q133","q134","q135","q136","q137","q138","q139","q140","q141","q142","q143","q144","q145","q146","q147","q148","q149","q150","q151","q152","q153","q154","q155","q156","q157","q158","q159","q160","q161","q162","q163","q164","q165","q166","q167","q168","q169","q170","q171","q172","q173","q174","q175","q176","q177","q178","q179","q180","q181","q182","q183","q184","q185","q186","q187","q188","q189","q190","q191","q192","q193","q194","q195","q196","q197","q198","q199","q200"
"scan-type-1.jpg","samples/community/UmarFarootAPS/scans/scan-type-1.jpg","outputs/community/UmarFarootAPS/scans/CheckedOMRs/scan-type-1.jpg","49.0","2468","A","C","B","C","A","D","B","C","B","D","C","A","C","D","B","C","A","B","C","A","C","B","D","C","A","B","D","C","A","C","B","D","B","A","C","D","B","C","A","C","D","A","C","D","A","B","D","C","A","C","D","B","C","A","C","D","B","C","D","A","B","C","B","C","D","B","D","A","C","B","D","A","B","C","B","A","C","D","B","A","C","B","C","B","A","D","B","A","C","D","B","D","B","C","B","D","A","C","B","C","B","C","D","B","C","A","B","C","A","D","C","B","D","B","A","B","C","D","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","B","A","C","B","A","C","A","B","C","B","C","B","A","C","A","C","B","B","C","B","A","C","A","B","A","B","A","B","C","D","B","C","A","C","D","C","A","C","B","A","C","A","B","C","B","D","A","B","C","D","C","B","B","C","A","B","C","B"
"scan-type-2.jpg","samples/community/UmarFarootAPS/scans/scan-type-2.jpg","outputs/community/UmarFarootAPS/scans/CheckedOMRs/scan-type-2.jpg","18.333333333333336","0234","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","A","D","","","AD","","","","A","D","","","","","","","D","A","","D","","A","","D","","","","A","","","C","","","D","","","A","","","","D","","C","","A","","C","","D","B","B","","","A","","D","","","","D","","","","","A","D","","","B","","","D","","","A","","","D","","","","","","D","","","","A","D","","","A","","B","","D","","","","C","C","D","D","A","","D","","A","D","","","D","","B","D","","","D","","D","B","","","","D","","A","","","","D","","B","","","","","","D","","","A","","","A","","D","","","D"
"scan-type-2.jpg","samples/community/UmarFarootAPS/scans/scan-type-2.jpg","outputs/community/UmarFarootAPS/scans/CheckedOMRs/scan-type-2.jpg","20.0","0234","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","C","D","C","B","A","B","A","D","","","AD","","","","A","D","","","","","","","D","A","","D","","A","","D","","","","A","","","C","","","D","","","A","","","","D","","C","","A","","C","","D","B","B","","","A","","D","","","","D","","","","","A","D","","","B","","","D","","","A","","","D","","","","","","D","","","","A","D","","","A","","B","","D","","","","C","C","D","D","A","","D","","A","D","","","D","","B","D","","","D","","D","B","","","","D","","A","","","","D","","B","","","","","","D","","","A","","","A","","D","","","D"

''',
})
@@ -148,8 +183,8 @@
''',
'AdrianSample/Results/Results_05AM.csv': '''
"file_id","input_path","output_path","score","q1","q2","q3","q4","q5"
"adrian_omr.png","samples/sample2/AdrianSample/adrian_omr.png","outputs/sample2/AdrianSample/CheckedOMRs/adrian_omr.png","5.0","B","E","A","C","B"
"adrian_omr_2.png","samples/sample2/AdrianSample/adrian_omr_2.png","outputs/sample2/AdrianSample/CheckedOMRs/adrian_omr_2.png","3.0","C","E","A","B","B"
"adrian_omr.png","samples/sample2/AdrianSample/adrian_omr.png","outputs/sample2/AdrianSample/CheckedOMRs/adrian_omr.png","0","B","E","A","C","B"
"adrian_omr_2.png","samples/sample2/AdrianSample/adrian_omr_2.png","outputs/sample2/AdrianSample/CheckedOMRs/adrian_omr_2.png","0","C","E","A","B","B"

''',
})
10 changes: 10 additions & 0 deletions src/tests/test_all_samples.py
Original file line number Diff line number Diff line change
@@ -42,6 +42,16 @@ def extract_sample_outputs(output_dir):
return sample_outputs


def test_run_answer_key_using_csv(mocker, snapshot):
sample_outputs = run_sample(mocker, "answer-key/using-csv")
assert snapshot == sample_outputs


def test_run_answer_key_weighted_answers(mocker, snapshot):
sample_outputs = run_sample(mocker, "answer-key/weighted-answers")
assert snapshot == sample_outputs


def test_run_sample1(mocker, snapshot):
sample_outputs = run_sample(mocker, "sample1")
assert snapshot == sample_outputs