Example #1
0
def test_create_Chemplate_from_sources_multisource_with_overrides1():
    overrides = CP.Chemplate(DoD={
        "rand2a": {
            'random_value': {
                'type': 'exact',
                'exact': '126.456'
            }
        }
    })
    source = CP.Chemplate(
        DoD={
            "rand2a": {
                'random_value': {
                    'range': {
                        'low': 11.0,
                        'high': 12.0
                    }
                }
            },
            'rand2b': {
                'random_value': {
                    'type': 'exact',
                    'exact': '123.567'
                }
            }
        })

    var = CPU.create_Chemplate_from_sources(source, overrides)
    assert str(var.getIDattr('rand2a',
                             'value')) == str(DV.DataValue("126.456"))
    assert str(var.getIDattr('rand2b',
                             'value')) == str(DV.DataValue("123.567"))
Example #2
0
def test_create_Chemplate_from_sources_sources_only():
    source = CP.Chemplate(
        DoD={"rand1": {
            'random_value': {
                'type': 'exact',
                'exact': '123.456'
            }
        }})
    var = CPU.create_Chemplate_from_sources(source)
    assert str(var.getIDattr('rand1', 'value')) == str(DV.DataValue("123.456"))
Example #3
0
def test_create_Chemplate_from_sources_with_chemplate():
    source = CP.Chemplate(
        DoD={
            "text4": {
                "fill_template": {
                    "template": "vol = {{data.mass/data.density}}",
                    "use_values": "true"
                }
            },
        })
    overrides = None
    values = CP.Chemplate(DoD={"data": {"mass": 5.0, "density": 10.0}})
    var = CPU.create_Chemplate_from_sources(source, overrides, values)
    assert str(var.getIDattr('text4', 'value')) == "vol = 0.5"
Example #4
0
def test_create_Chemplate_from_sources_with_valsdict():
    source = CP.Chemplate(
        DoD={
            "expr": {
                "parse_expression": {
                    "expression": "mass/density",
                    "use_values": "true"
                }
            }
        })
    overrides = None
    valsdict = {"mass": 5.0, "density": 10.0}
    var = CPU.create_Chemplate_from_sources(source, overrides, valsdict)
    assert str(var.getIDattr('expr', 'value')) == str(DV.DataValue("0.5"))
Example #5
0
def check_chemplatefile(filename):
    with open(filename, 'r') as handle:
        try:
            chemplateDict = commentjson.load(handle)
        except:
            print(f"malformed JSON in {filename}")
            handle.close()
            return

    chemplateNameList = [k for k in chemplateDict.keys() if "_answer" not in k]

    for name in chemplateNameList:
        print(f"file:{filename} chemplate:{name}")
        chemplate = chemplateDict[name]
        answer = chemplateDict[name + "_answer"]
        res = CPU.validatefullChemplate(chemplate)
        print("res::\n", str("\n".join(res)))
        assert str("\n".join(res)) == answer
Example #6
0
def test_create_Chemplate_from_sources_with_overrides2():
    overrides = CP.Chemplate(
        DoD={
            "rand3": {
                'random_value': {
                    'type': 'exact',
                    'exact': '127.456',
                    'units': 'gram / milliliter'
                }
            }
        })
    source = CP.Chemplate(DoD={
        'rand3': {
            'random_value': {
                'range': {
                    'low': 11.0,
                    'high': 12.0
                }
            }
        }
    })
    var = CPU.create_Chemplate_from_sources(source, overrides)
    assert str(var.getIDattr('rand3', 'value')) == str(
        DV.DataValue("127.456 gram / milliliter"))
Example #7
0
def test_create_Chemplate_from_sources_bad_generator():
    source = CP.Chemplate(DoD={'rand1a': {'randomdalue': 123}})
    with pytest.raises(AssertionError):
        var = CPU.create_Chemplate_from_sources(source)
Example #8
0
def test_validateFullChemplate():
    full = {
        "description":
        "Description of the problem type",
        "keywords": ["keywords for looking up problems"],
        "sources": {
            # "source_name" : {"function": {"param":value, ... } },
            "mass": {
                "random_value": {
                    "range": {
                        "low": 11.0,
                        "high": 12.0
                    },
                    "units": "g"
                }
            },
            "volume": {
                "random_value": {
                    "range": {
                        "low": 5.5,
                        "high": 6.0
                    },
                    "units": "milliliter"
                }
            }
        },
        "questionlist": [
            # template with vars, callables(chemformula, chemreaction)
            # uses template_variables (see below)
            # {"function": {"param":value, ... } },
            {
                "fill_template": {
                    "template":
                    "What is the density of a sample with mass {{mass}} and volume {{volume}}?",
                    "vars": {
                        "var1": "true"
                    }
                }
            }
        ],
        "answerlist": [
            # uses values from sources
            #answer_template: an answer_template is a dictionary with the following
            #             keys (those currently used have asterisks. The others
            #             are currently ignored):
            #    'value' : the equation to get the answer, which is parsed and evaluated
            #    'units' : units desired for the answer
            #    'text' : text to be rendered as a jinja2 template. It could explain
            #              the answer with variable values filled in
            #    'correct' : a boolean flag tell in this answer is correct.
            #  {"dictkey" : {"function": {"param":value, ... } },
            #  },
            {
                "value": {
                    "parse_expression": {
                        "expression": "volume/mass",
                        "vars": {}
                    }
                },
                "units": {
                    "copy_text": {
                        "text": "gram / milliliter"
                    }
                },
                "text": {
                    "fill_template": {
                        "template": "mass/volume = ({{mass}})/{{volume}}",
                        "vars": {}
                    }
                },
                "correct": {
                    "copy_text": {
                        "text": "false"
                    }
                }
            },
        ]
    }
    res = CPU.validatefullChemplate(full)
Example #9
0
def test_answer_template():
    source = CP.Chemplate(
        DoD={
            "rand1": {
                'random_value': {
                    'type': 'exact',
                    'exact': '12.02'
                }
            },
            "rand2": {
                'random_value': {
                    'type': 'exact',
                    'exact': '6.01'
                }
            }
        })

    var = CPU.create_Chemplate_from_sources(source)
    answer_template_1 = CP.Chemplate(
        DoD={
            "value": {
                "parse_expression": {
                    "expression": "mass/density",
                    "use_values": "true"
                }
            },
            "units": {
                "copy_text": {
                    "text": "gram / milliliter"
                }
            },
            "text": {
                "fill_template": {
                    "template":
                    "mass/volume = ({{mass}})/{{volume}} = {{density}}",
                    "use_values": "true"
                }
            },
            "text2": {
                "fill_template": {
                    "template":
                    "mag units = {{property.magnitude}} {{property['units']}}",
                    "use_values": "true"
                }
            },
            "text3": {
                "fill_template": {
                    "template": "density = {{mass/volume}}",
                    "use_values": "true"
                }
            },
            "text4": {
                "fill_template": {
                    "template": "two = {{rand1.value/rand2.value}}",
                    "use_values": "true"
                }
            },
            "correct": {
                "copy_text": {
                    "text": "true"
                }
            },
            "reason": {
                "copy_text": {
                    "text": "To be implemented"
                }
            },  #"partials" : [{"parse_expression":{ "expression":"2.00*mass", "vars":true}},
            #              {"parse_expression":{ "expression":"0.0500*mass", "vars":true}},
            #             ]
        })
    correct_answers = {
        'correct': {
            'value': 'true'
        },
        'reason': {
            'value': 'To be implemented'
        },
        'text': {
            'value':
            'mass/volume = (10.00 gram)/2.00 milliliter = 5.0000 gram / milliliter'
        },
        'text2': {
            'value': 'mag units = 7.777 km/hr'
        },
        'text3': {
            'value': 'density = 5.00 gram / milliliter'
        },
        'text4': {
            'value': 'two = 2.00'
        },
        'units': {
            'value': 'gram / milliliter'
        },
        'value': {
            'value': str(DV.DataValue("2.000 milliliter"))
        }
    }
    #print("SOURCE:",pformat(var))
    overrides = CP.Chemplate(DoD={})
    correct_CP = CP.Chemplate(DoD=correct_answers)
    ten = DV.DataValue('10.00 g')
    #This should be a DOD with "values"
    vars = {
        'mass': ten,
        'volume': DV.DataValue('2.00 milliliter'),
        'density': DV.DataValue('5.0000 gram / milliliter'),
        'property': {
            "magnitude": 7.777,
            "units": "km/hr"
        }
    }
    vars.update([("rand1", var.getID("rand1")), ("rand2", var.getID("rand2"))])

    filled = CPU.create_Chemplate_from_sources(answer_template_1,
                                               overrides,
                                               values=vars)
    #print("ANSWERS:",pformat(filled))
    assert filled.assertEqualTo(correct_CP)
Example #10
0
def process_chemplate(template):
    """
    process_chemplate(chemplate) - process the sources, questionlist, and
        answerlist in a full chemplate, in that order.
    Parameters
    --------
        chemplate: dict of CP.Chemplates (required)
               the dict must have sources, questionlist, and
                   answerlist as IDs, each value is a CP.ChemPlate
    Returns
    _______
        a dictionary of strings:
            'question' : the text of the question used with templates filled in
            'answers' : a list of answer strings, the first one is the correct one


    Raises
    ------
        AttributeError
            if any of the required IDs are missing

    """
    verbose = False
    correcttag = "***"

    sourceCP = CP.Chemplate(DoD=template["sources"])
    sources = CPU.create_Chemplate_from_sources(sourceCP)
    src_vals = {id: sources.getIDvalue(id) for id in sources.getIDs()}

    intermediate_vals = src_vals
    search_key = "intermediate_"
    intermediate_keys = [
        key for key, val in template.items() if search_key in key
    ]
    if verbose: print("PROCESS CHEMPLATE\n", pformat(intermediate_keys))
    for intermediate_key in sorted(intermediate_keys):
        if verbose: print("PROCESSING: ", intermediate_key, "\n")
        if verbose: print("CURRENT vals:\n", pformat(intermediate_vals), "\n")
        intermediateCP = CP.Chemplate(DoD=template[intermediate_key])
        sources = CPU.create_Chemplate_from_sources(intermediateCP, None,
                                                    intermediate_vals)
        new_vals = {id: sources.getIDvalue(id) for id in sources.getIDs()}
        if verbose:
            print("\n=======\nintermediateCP:", pformat(intermediateCP))
        intermediate_vals.update(new_vals)
        if verbose:
            print("PROCESSED: ", intermediate_key, "\n",
                  pformat(intermediate_vals), "\n")

    if verbose: print("Intermediate PROCESSING DONE\n")

    # This has its own label because the question list in the template has none
    # and it would be harder to code if it did - it'd just be thrown away.
    qCP = CP.Chemplate(DoD={"q": template["questionlist"][0]})
    if verbose: print("qCP:", pformat(qCP))
    if verbose: print("type sources", type(sources))
    question = CPU.create_Chemplate_from_sources(qCP, None, intermediate_vals)

    if verbose: print("\nQuestion:", pformat(question))

    answerlist = template["answerlist"]
    if verbose: print("intermediate_vals:", pformat(intermediate_vals))
    if verbose: print("answer_list:", pformat(answerlist))
    answer_results = []
    for answer in answerlist:
        if verbose: print("answer list n:", pformat(answer))

        answerCP = CP.Chemplate(DoD=answer)
        answerval = CPU.create_Chemplate_from_sources(answerCP, None,
                                                      intermediate_vals)
        if verbose: print("answerval:", pformat(answerval))
        answertext = Render.render_item_to_string(answerval)
        if verbose: print("answer text:", answertext)
        if Render.is_correct(answerval):
            answer_results.insert(0, correcttag + answertext)
        else:
            answer_results.append(answertext)
    shuffle(answer_results)
    if verbose: print("answer_results:", pformat(answer_results))
    return ({'question': question.getIDvalue('q'), 'answers': answer_results})