Coverage for e2xgrader/preprocessors/permutetasks.py: 31%

29 statements  

« prev     ^ index     » next       coverage.py v7.4.2, created at 2024-03-14 13:22 +0100

1import random 

2from copy import deepcopy 

3 

4from e2xcore.utils.nbgrader_cells import get_tasks, grade_id 

5from nbformat.v4 import new_notebook 

6from nbgrader.preprocessors import NbGraderPreprocessor 

7 

8 

9class PermuteTasks(NbGraderPreprocessor): 

10 def __init__(self, **kw): 

11 self.rand = random.Random() 

12 if kw and "seed" in kw: 

13 self.rand = random.Random(kw["seed"]) 

14 

15 def permute(self, nb): 

16 permuted_nb = new_notebook() 

17 # Get indices of tasks 

18 tasks = get_tasks(nb) 

19 # Shuffle tasks 

20 shuffled_tasks = deepcopy(tasks) 

21 random.shuffle(shuffled_tasks) 

22 # Record original order 

23 original_order = [] 

24 

25 cursor = 0 

26 

27 for task in tasks: 

28 # Add all cells between cursor and current task 

29 for idx in range(cursor, task[0]): 

30 permuted_nb.cells.append(nb.cells[idx]) 

31 # Get next task 

32 next_task = shuffled_tasks.pop(0) 

33 original_order.append(grade_id(nb.cells[task[0]])) 

34 # Add cells of the next task 

35 permuted_nb.cells.extend([nb.cells[idx] for idx in next_task]) 

36 # Set the cursor to the idx after the inserted task 

37 cursor = task[-1] + 1 

38 

39 # Add remaining cells at the bottom of the notebook 

40 permuted_nb.cells.extend( 

41 [nb.cells[idx] for idx in range(cursor, len(nb.cells))] 

42 ) 

43 # Save order 

44 permuted_nb.metadata["original_order"] = original_order 

45 

46 return permuted_nb 

47 

48 def preprocess(self, nb, resources): 

49 return self.permute(nb), resources