1
1
2
2
=head1 NAME
3
3
4
- PGProblemCritic - Parse a PG program and analyze the contents for good and bad features.
4
+ PGProblemCritic - Parse a PG program and analyze the contents for positive and negative features.
5
5
6
6
=head1 DESCRIPTION
7
7
@@ -80,17 +80,27 @@ sub analyzePGcode ($code) {
80
80
# default flags for presence of features in a PG problem
81
81
my $features = {
82
82
metadata => { DBsubject => 0, DBchapter => 0, DBsection => 0, KEYWORDS => 0 },
83
- good => {
83
+ positive => {
84
84
PGML => 0,
85
85
solution => 0,
86
86
hint => 0,
87
- scaffold => 0,
88
87
custom_checker => 0,
89
88
multianswer => 0,
90
- answer_hints => 0,
91
- nicetable => 0,
89
+ nicetables => 0,
90
+ contexts => { BaseN => 0, Units => 0, Boolean => 0, Reaction => 0 },
91
+ parsers =>
92
+ { dropdown => 0, RadioButtons => 0, CheckboxList => 0, RadioMultianswer => 0, GraphTool => 0 },
93
+ macros => {
94
+ randomPerson => 0,
95
+ Plots => 0,
96
+ PGtikz => 0,
97
+ Plotly3D => 0,
98
+ PGlateximage => 0,
99
+ Scaffold => 0,
100
+ AnswerHints => 0,
101
+ }
92
102
},
93
- bad => {
103
+ negative => {
94
104
BEGIN_TEXT => 0,
95
105
beginproblem => 0,
96
106
oldtable => 0,
@@ -100,8 +110,8 @@ sub analyzePGcode ($code) {
100
110
context_texstrings => 0,
101
111
multiple_loadmacros => 0,
102
112
showPartialCorrect => 0,
103
- old_multiple_choice => 0,
104
113
lines_below_enddocument => 0,
114
+ macros => { PGgraphmacros => 0, PGchoicemacros => 0 }
105
115
},
106
116
deprecated_macros => [],
107
117
macros => []
@@ -129,12 +139,12 @@ sub analyzePGcode ($code) {
129
139
# Skip any full-line comments.
130
140
next if $line =~ / ^\s *#/ ;
131
141
132
- $features -> {good }{solution } = 1 if $line =~ / BEGIN_(PGML_)?SOLUTION/ ;
133
- $features -> {good }{hint } = 1 if $line =~ / BEGIN_(PGML_)?HINT/ ;
142
+ $features -> {positive }{solution } = 1 if $line =~ / BEGIN_(PGML_)?SOLUTION/ ;
143
+ $features -> {positive }{hint } = 1 if $line =~ / BEGIN_(PGML_)?HINT/ ;
134
144
135
145
# Analyze the loadMacros info.
136
146
if ($line =~ / loadMacros\( / ) {
137
- $features -> {bad }{multiple_loadmacros } = 1 if $loadmacros_parsed == 1;
147
+ $features -> {negative }{multiple_loadmacros } = 1 if $loadmacros_parsed == 1;
138
148
$loadmacros_parsed = 1;
139
149
# Parse the macros, which may be on multiple rows.
140
150
my $macros = $line ;
@@ -161,7 +171,7 @@ sub analyzePGcode ($code) {
161
171
push (@{ $features -> {deprecated_macros } }, $macro ) if (grep { $macro eq $_ } @$all_deprecated_macros );
162
172
}
163
173
} elsif ($line =~ / BEGIN_PGML(_SOLUTION|_HINT)?/ ) {
164
- $features -> {good }{PGML } = 1;
174
+ $features -> {positive }{PGML } = 1;
165
175
my @pgml_lines ;
166
176
while (1) {
167
177
$line = shift @pglines ;
@@ -170,40 +180,62 @@ sub analyzePGcode ($code) {
170
180
}
171
181
172
182
my $pgml_features = analyzePGMLBlock(@pgml_lines );
173
- $features -> {bad }{missing_alt_tag } = 1 if $pgml_features -> {missing_alt_tag };
183
+ $features -> {negative }{missing_alt_tag } = 1 if $pgml_features -> {missing_alt_tag };
174
184
}
175
185
176
186
if ($line =~ / ENDDOCUMENT/ ) { # scan if there are any lines below the ENDDOCUMENT
177
187
178
188
do {
179
189
$line = shift @pglines ;
180
190
last unless defined ($line );
181
- $features -> {bad }{lines_below_enddocument } = 1 if $line !~ / ^\s *$ / ;
191
+ $features -> {negative }{lines_below_enddocument } = 1 if $line !~ / ^\s *$ / ;
182
192
} while (defined ($line ));
183
193
}
184
194
185
- # Check for bad features.
186
- $features -> {bad }{beginproblem } = 1 if $line =~ / beginproblem\(\) / ;
187
- $features -> {bad }{BEGIN_TEXT } = 1 if $line =~ / (BEGIN_(TEXT|HINT|SOLUTION))|EV[23]/ ;
188
- $features -> {bad }{context_texstrings } = 1 if $line =~ / ->(texStrings|normalStrings)/ ;
195
+ # Check for negative features.
196
+ $features -> {negative }{beginproblem } = 1 if $line =~ / beginproblem\(\) / ;
197
+ $features -> {negative }{BEGIN_TEXT } = 1 if $line =~ / (BEGIN_(TEXT|HINT|SOLUTION))|EV[23]/ ;
198
+ $features -> {negative }{context_texstrings } = 1 if $line =~ / ->(texStrings|normalStrings)/ ;
189
199
for (qw( num str fun) ) {
190
- $features -> {bad }{ $_ . ' _cmp' } = 1 if $line =~ / ${_}_cmp\( / ;
200
+ $features -> {negative }{ $_ . ' _cmp' } = 1 if $line =~ / ${_}_cmp\( / ;
191
201
}
192
- $features -> {bad }{oldtable } = 1 if $line =~ / BeginTable/i ;
193
- $features -> {bad }{showPartialCorrect } = 1 if $line =~ / \$ showPartialCorrectAnswers\s =\s 1/ ;
194
- $features -> {bad }{old_multiple_choice } = 1
202
+ $features -> {negative }{oldtable } = 1 if $line =~ / BeginTable/i ;
203
+ $features -> {negative }{showPartialCorrect } = 1 if $line =~ / \$ showPartialCorrectAnswers\s =\s 1/ ;
204
+ $features -> {negative }{macros }{PGgraphmacros } = 1 if $line =~ / init_graph\( / ;
205
+ $features -> {negative }{macros }{PGchoicemacros } = 1
195
206
if $line =~ / new_checkbox_multiple_choice/
196
207
|| $line =~ / new_match_list/
197
208
|| $line =~ / new_select_list/
198
209
|| $line =~ / new_multiple_choice/
199
210
|| $line =~ / qa\s\( / ;
200
211
201
- # check for good features
202
- $features -> {good }{scaffold } = 1 if $line =~ / Scaffold::Begin/ ;
203
- $features -> {good }{answer_hints } = 1 if $line =~ / AnswerHints/ ;
204
- $features -> {good }{multianswer } = 1 if $line =~ / MultiAnswer/ ;
205
- $features -> {good }{custom_checker } = 1 if $line =~ / checker =>/ ;
206
- $features -> {good }{nicetables } = 1 if $line =~ / DataTable|LayoutTable/ ;
212
+ # check for positive features
213
+ # macros:
214
+ $features -> {positive }{macros }{Scaffold } = 1 if $line =~ / Scaffold::Begin/ ;
215
+ $features -> {positive }{macros }{Plots } = 1 if $line =~ / Plot\( / ;
216
+ $features -> {positive }{macros }{Plotly3D } = 1 if $line =~ / Graph3D\( / ;
217
+ $features -> {positive }{macros }{PGtikz } = 1 if $line =~ / createTikZImage\( / ;
218
+ $features -> {positive }{macros }{AnswerHints } = 1 if $line =~ / AnswerHints/ ;
219
+ $features -> {positive }{macros }{randomPerson } = 1 if $line =~ / randomPerson\( / || $line =~ / randomLastName\( / ;
220
+ $features -> {positive }{macros }{PGlateximage } = 1 if $line =~ / createLaTeXImage\( / ;
221
+
222
+ # contexts:
223
+
224
+ $features -> {positive }{contexts }{Units } = 1 if $line =~ / Context\( ['"]Units['"]\) / ;
225
+ $features -> {positive }{contexts }{BaseN } = 1 if $line =~ / Context\( ['"](Limited)?BaseN['"]\) / ;
226
+ $features -> {positive }{contexts }{Boolean } = 1 if $line =~ / Context\( ['"]Boolean['"]\) / ;
227
+ $features -> {positive }{contexts }{Reaction } = 1 if $line =~ / Context\( ['"]Reaction['"]\) / ;
228
+
229
+ # parsers:
230
+ $features -> {positive }{parsers }{PopUp } = 1 if $line =~ / DropDown\( / ;
231
+ $features -> {positive }{parsers }{RadioButtons } = 1 if $line =~ / RadioButtons\( / ;
232
+ $features -> {positive }{parsers }{CheckboxList } = 1 if $line =~ / CheckboxList\( / ;
233
+ $features -> {positive }{parsers }{GraphTool } = 1 if $line =~ / GraphTool\( / ;
234
+
235
+ # other:
236
+ $features -> {positive }{multianswer } = 1 if $line =~ / MultiAnswer/ ;
237
+ $features -> {positive }{custom_checker } = 1 if $line =~ / checker\s *=>/ ;
238
+ $features -> {positive }{nicetables } = 1 if $line =~ / DataTable|LayoutTable/ ;
207
239
208
240
}
209
241
return $features ;
0 commit comments