88import six
99from voluptuous import Schema , Required , Any , All , Invalid , Length
1010from mitxgraders .comparers import equality_comparer
11- from mitxgraders .sampling import schema_user_functions_no_random
11+ from mitxgraders .sampling import schema_user_functions_no_random , DependentSampler
1212from mitxgraders .exceptions import MissingInput
1313from mitxgraders .baseclasses import ItemGrader
1414from mitxgraders .helpers .calc import evaluator , DEFAULT_VARIABLES
@@ -131,7 +131,7 @@ def reset_default_comparer(cls):
131131 cls .set_default_comparer (equality_comparer )
132132
133133 @staticmethod
134- def eval_and_validate_comparer_params (scoped_eval , comparer_params , siblings_eval ):
134+ def eval_and_validate_comparer_params (scoped_eval , comparer_params ):
135135 """
136136 Evaluate the comparer_params, and make sure they contain no references
137137 to empty siblings.
@@ -149,11 +149,6 @@ def eval_and_validate_comparer_params(scoped_eval, comparer_params, siblings_eva
149149 for param in comparer_params ]
150150 # results is a list of (value, EvalMetaData) pairs
151151 comparer_params_eval = [value for value , _ in results ]
152- used_variables = set ().union (* [used .variables_used for _ , used in results ])
153-
154- for variable in used_variables :
155- if variable in siblings_eval and np .isnan (siblings_eval [variable ]):
156- raise MissingInput ('Cannot grade answer, a required input is missing.' )
157152
158153 return comparer_params_eval
159154
@@ -290,11 +285,13 @@ def gen_evaluations(self, comparer_params, student_input, sibling_formulas,
290285 comparer_params_evals = []
291286 student_evals = []
292287
293- # Create a list of instructor variables to remove from student evaluation
288+ # Create a list of instructor and sibling variables to remove from student evaluation
289+ sibling_vars = [key for key in sibling_formulas ]
294290 var_blacklist = []
295291 for var in self .config ['instructor_vars' ]:
296292 if var in var_samples [0 ]:
297293 var_blacklist .append (var )
294+ var_blacklist += sibling_vars
298295
299296 for i in range (self .config ['samples' ]):
300297 # Update the functions and variables listings with this sample
@@ -309,33 +306,21 @@ def scoped_eval(expression,
309306 return evaluator (expression , variables , functions , suffixes , max_array_dim ,
310307 allow_inf = self .config ['allow_inf' ])
311308
312- # Compute the sibling values, and add them to varlist
313- siblings_eval = {
314- key : scoped_eval (sibling_formulas [key ])[0 ]
315- for key in sibling_formulas
316- }
317- varlist .update (siblings_eval )
318-
319309 # Compute expressions
320- comparer_params_eval = self .eval_and_validate_comparer_params (
321- scoped_eval , comparer_params , siblings_eval )
310+ comparer_params_eval = self .eval_and_validate_comparer_params (scoped_eval , comparer_params )
322311 comparer_params_evals .append (comparer_params_eval )
323312
324313 # Before performing student evaluation, scrub the sibling and instructor
325314 # variables so that students can't use them
326- for key in siblings_eval :
327- del varlist [key ]
328315 for key in var_blacklist :
329316 del varlist [key ]
330317
331318 student_eval , meta = scoped_eval (student_input )
332319 student_evals .append (student_eval )
333320
334- # TODO: Remove this if statement
335321 if self .config ['debug' ]:
336322 # Put the siblings and instructor variables back in for the debug output
337323 varlist .update (var_samples [i ])
338- varlist .update (siblings_eval )
339324 self .log_eval_info (i , varlist , funclist ,
340325 comparer_params_eval = comparer_params_eval ,
341326 student_eval = student_eval )
@@ -347,8 +332,15 @@ def raw_check(self, answer, student_input, **kwargs):
347332
348333 # Extract sibling formulas to allow for sampling
349334 siblings = kwargs .get ('siblings' , None )
335+ # Find sibling variables used in comparer parameters
350336 comparer_params = answer ['expect' ]['comparer_params' ]
351337 required_siblings = self .get_used_vars (comparer_params )
338+ # Add in any sibling variables used in DependentSamplers
339+ samplers = [self .config ['sample_from' ][x ]
340+ for x in self .config ['sample_from' ]
341+ if isinstance (self .config ['sample_from' ][x ], DependentSampler )]
342+ sampler_vars = sum ((x .config ['depends' ] for x in samplers ), [])
343+ required_siblings = list (set (required_siblings ).union (set (sampler_vars )))
352344 # required_siblings might include some extra variable names, but no matter
353345 sibling_formulas = self .get_sibling_formulas (siblings , required_siblings )
354346
0 commit comments