"ignore", message='Using `tqdm.autonotebook.tqdm` in notebook mode') warnings.filterwarnings(
Input file
In order to avoid tqdm
’s experimental warning
= '_input_.yaml' test_file
Finding the appropriate settings in the file
A convenience function to extract the settings of a given class within a certain category. If there are duplicated categories and/or classes, the one that is found first is returned.
extract_class_settings
extract_class_settings (category_name:Union[str,list], class_name:str, settings:dict)
file: third_midterm.yaml
output /midterm3
pictures base directory: tc-wrapper: '~/gift-wrapper/wrap.py'
path to gift
categories:
- name: Entropy of the input given the output
classes:
- name: EntropyOfInputGivenOutput
input given the output
question base name: Entropy of
init parameters:
/entropy_at_input_given_output.tex
picture_file: DMCs
|
statement:
Consider...
|
feedback: is...
One way of tackling the problem
2 number of instances:
Overwriting _input_.yaml
with open(test_file) as yaml_data:
= yaml.load(yaml_data, Loader=yaml.FullLoader)
settings
'Entropy of the input given the output', 'EntropyOfInputGivenOutput', settings) extract_class_settings(
{'name': 'EntropyOfInputGivenOutput',
'question base name': 'Entropy of input given the output',
'init parameters': {'picture_file': 'DMCs/entropy_at_input_given_output.tex'},
'statement': 'Consider...\n',
'feedback': 'One way of tackling the problem is...\n',
'number of instances': 2}
Managing the settings with an ad-hoc object
A class to manage (in memory) all the settings required to build the questions.
Settings
Settings (output_file:str='quiz.yaml', pictures_directory:str='quiz/pics', test_mode:bool=False)
Initialize self. See help(type(self)) for accurate signature.
The object right after initialization:
= Settings()
settings settings
{'categories': None,
'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics'}
A scalar category is added (it doesn’t have any class yet)
'My category')
settings.add_category( settings
{'categories': [{'classes': None, 'name': 'My category'}],
'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics'}
If test_mode
is set to True
when instantiating the class,
= Settings(test_mode=True) settings
then the passed category name is ignored and test is used
= settings.add_category('My category')
category_name settings
{'categories': [{'classes': None, 'name': 'test'}],
'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics'}
In such case, it is important to retrieve the value returned by add_category
, since that is the actual category name added.
settings.add_or_update_class(=category_name, class_name='MeanLinearCombinationCosineAndUniform', question_base_name='Mean of a random process',
category_name=dict(
init_parameters=[2, 8], uniform_high_range=[12, 30], mean_range=[-5, 5],
uniform_low_range=[1, 10], cosine_frequency_over_pi=[1, 2, 3], t_range=[0, 30]
variance_range
),=2, time=4
n_instances
) settings
{'categories': [{'classes': [{'init parameters': {'cosine_frequency_over_pi': [1,
2,
3],
'mean_range': [-5, 5],
't_range': [0, 30],
'uniform_high_range': [12,
30],
'uniform_low_range': [2, 8],
'variance_range': [1, 10]},
'name': 'MeanLinearCombinationCosineAndUniform',
'number of instances': 2,
'question base name': 'Mean of a random process',
'time': 4}],
'name': 'test'}],
'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics'}
= Settings()
settings 'My category')
settings.add_category(='My category',class_name='A', question_base_name='question for class #1', n_instances=2, time=4)
settings.add_or_update_class(category_name='My category',class_name='B', question_base_name='question for class #2', n_instances=2, time=10)
settings.add_or_update_class(category_name='My category #1',base_category='Parent')
settings.add_category(category_name
settings.add_or_update_class(=['Parent', 'Parent/My category #1'],class_name='C', question_base_name='question for class #2', n_instances=2, time=10) category_name
settings
{'categories': [{'classes': [{'name': 'A',
'number of instances': 2,
'question base name': 'question for class #1',
'time': 4},
{'name': 'B',
'number of instances': 2,
'question base name': 'question for class #2',
'time': 10}],
'name': 'My category'},
{'classes': [{'name': 'C',
'number of instances': 2,
'question base name': 'question for class #2',
'time': 10}],
'name': ['Parent', 'Parent/My category #1']}],
'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics'}
'My category', 'B') settings.locate(
{'name': 'B',
'question base name': 'question for class #2',
'number of instances': 2,
'time': 10}
=['Parent', 'Parent/My category #1']) settings.locate(category_name
{'name': ['Parent', 'Parent/My category #1'],
'classes': [{'name': 'C',
'question base name': 'question for class #2',
'number of instances': 2,
'time': 10}]}
If the classes do exist
class A:
= 'A'
name
class B:
= 'B'
name
class C:
= 'C' name
= settings.fake_module
classes_container print(classes_container.A.name)
print(classes_container.B.name)
A
B
Composing a dictionary with the YAML settings
initialize
initialize (output_file:str, pictures_directory:str)
= initialize(output_file='quiz.yaml', pictures_directory='quiz/pics') settings_dict
set_class_preamble
set_class_preamble (settings:dict, category_name:str, base_category:Optional[str]=None, test_mode:bool=False)
'Test category')
set_class_preamble(settings_dict, settings_dict
{'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics',
'categories': [{'name': 'Test category', 'classes': None}]}
set_class_closing
set_class_closing (settings:dict, n_instances:int, time:Optional[int]=None)
2, 15)
set_class_closing(settings_dict, settings_dict
{'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics',
'categories': [{'name': 'Test category',
'classes': [{'number of instances': 2, 'time': 15}]}]}
set_class
set_class (settings:dict, class_name:str, question_base_name:str, init_parameters:Optional[dict]=None, parameters:Optional[List[dict]]=None, n_instances:Optional[int]=None, time:Optional[int]=None)
set_class(='MeanLinearCombinationCosineAndUniform', question_base_name='Mean of a random process',
settings_dict, class_name=dict(
init_parameters=[2, 8], uniform_high_range=[12, 30], mean_range=[-5, 5],
uniform_low_range=[1, 10], cosine_frequency_over_pi=[1, 2, 3], t_range=[0, 30]
variance_range=2, time=4) ), n_instances
settings_dict
{'output file': 'quiz.yaml',
'pictures base directory': 'quiz/pics',
'categories': [{'name': 'Test category',
'classes': [{'name': 'MeanLinearCombinationCosineAndUniform',
'question base name': 'Mean of a random process',
'init parameters': {'uniform_low_range': [2, 8],
'uniform_high_range': [12, 30],
'mean_range': [-5, 5],
'variance_range': [1, 10],
'cosine_frequency_over_pi': [1, 2, 3],
't_range': [0, 30]},
'number of instances': 2,
'time': 4}]}]}
Writing
Code to write input files.
Header
A function to write the header of the file. * file
: name of the input file to be created
write_header
write_header (file:Union[str,pathlib.Path], output_file:str, pictures_directory:str)
='quiz.yaml', pictures_directory='quiz/pics') write_header(test_file, output_file
output file: quiz.yaml pictures base directory: quiz/pics categories:
Class
Writing the preamble
A function to write the preamble for a class which includes the name of the category. Strictly speaking, it’s not necessary to create a new category every time a class is added, but this is more general and a category can show up many times in the input file. * file
: name of the input file to be appended to * category_name
: name of the category in which the class will be encompassed * base_category
: a parent category for category_name
(optional) * test_mode
: if True
, the last two parameters are overriden and the category is simply called test
For convenience, the final category_name
(notice that it might get tweaked because of the other parameters) is returned.
write_class_preamble
write_class_preamble (file:Union[str,pathlib.Path], category_name:str, base_category:Optional[str]=None, test_mode:bool=False)
Writes the preamble for a class which includes the name of the category. Strictly speaking, it’s not necessary to create a new category every time a class is added, but this is more general and a category can show up many times in the input file.
Parameters
file
: str, PathlibInput file to be appended to.
category_name
: strName of the category in which the class will be encompassed.
base_category
: str, optionalThe parent category for
category_name
.test_mode
: boolIf
True
the last two parameters are overriden and the category is simply calledtest
.
Returns
category_name
: str or listThe final name for the category (notice that it might get tweaked due to
test_mode
).
'Test category') write_class_preamble(test_file,
'Test category'
output file: quiz.yaml pictures base directory: quiz/pics categories: - name: Test category classes:
Parameter base_category
allows to create hierarchical categories
='quiz.yaml', pictures_directory='quiz/pics')
write_header(test_file, output_file'Test category', base_category='base') write_class_preamble(test_file,
['base', 'base/Test category']
output file: quiz.yaml
pictures base directory: quiz/pics
categories:
- name:
- base
- base/Test category
classes:
In test_mode
='quiz.yaml', pictures_directory='quiz/pics')
write_header(test_file, output_file'Test category', base_category='base', test_mode=True) write_class_preamble(test_file,
'test'
output file: quiz.yaml pictures base directory: quiz/pics categories: - name: test classes:
Writing the closing
A function to write the closing settings of a class. * file
: name of the input file to be appended to * n_instances
: number of questions of this class that will be created (the setup
method of the class should be non-deterministic) * time
: time in minutes (an integer) estimated necessary to solve the question
write_class_closing
write_class_closing (file:Union[str,pathlib.Path], n_instances:int, time:Optional[int]=None)
2, 15) write_class_closing(test_file,
output file: quiz.yaml pictures base directory: quiz/pics categories: - name: test classes: - number of instances: 2 time: 15
!rm {test_file}
Categories
function_to_make_hierarchical_category_name
function_to_make_hierarchical_category_name (base_category:str)
= function_to_make_hierarchical_category_name('2020 exam')
f 'Random') f(
['2020 exam', '2020 exam/Random']