def test_do_convert(inputDVstr,finalunitsstr,answerDVstr): inputDV=DV.DataValue(inputDVstr) answerDV=DV.DataValue(answerDVstr) finalunits=finalunitsstr convertedDV = do_convert(inputDV,finalunits) assert str(answerDV)==str(convertedDV) assert isinstance(convertedDV,DV.DataValue)
def test_datavalue_sub_fail_units(): x = DV.DataValue("2.414", "g") y = DV.DataValue("2.0", "mL") with pytest.raises(AssertionError): z = x - y ##print("repr z:",repr(z)) assert str(z) == "4.4 gram"
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"))
def test_datavalue_mul(): x = DV.DataValue("2.314", "g/mL") y = DV.DataValue("2.0", "mL") z = x * y #print("repr x:",repr(x)) #print("repr y:",repr(y)) #print("repr z:",repr(z)) assert str(z) == "4.6 gram"
def render_item_to_string(target_item, print_list=None): """ render_item_to_string(target_item, print_list) renders and returns a string representation of a Chemplate answer. If the answer is incorrect, it forcres the units to be those given in the Chemplate print_list - a list of modifiers, which can alter the output txt: Implemented so far: 'text' - append on the value of the 'text' ID in the Chemplate """ assert isinstance(target_item,CP.Chemplate) verbose = False if verbose: print("PRINT_LIST:",pformat(print_list)) if print_list is None: print_list = [] if is_correct(target_item): if (verbose): print("answer item is correct") answer_str = str(target_item.getIDvalue("value")) else: value = target_item.getIDvalue("value") if (verbose): print("answer item is incorrect",value) if isinstance(value, DV.DataValue): magnitude = value.magnitude units = target_item.getIDvalue("units") value = DV.DataValue(magnitude = str(magnitude), units = units) answer_str = str(value) if "text" in print_list: answer_str += " " + target_item.getIDvalue("text") return answer_str
def parse_expression(args): """generate data from a parsed expression Parameters ---------- expression = an expression to parse vars : Each key is a the variable name and the value is a DataValue to use in the expression Returns ------- a DataValue which is the result of the expression Raises ------ AttributeError if no attribute, value pair or dict is specified. """ verbose = False #make this more robust and test it XXX expression = args["expression"] vars = args["vars"] if verbose: print("expression:", pformat(expression), "\nvars:", pformat(vars)) parser = Parser() result = parser.parse(expression).evaluate(vars) return {'value': DV.DataValue(result)}
def test_datavalue_add_float_int(): x = DV.DataValue("2.414", "") y = 2 z = x + y #print("repr z:",repr(z)) assert str(z) == "4" y = 2.001 z = x + y #print("repr z:",repr(z)) assert str(z) == "4.415"
def test_datavalue_div_float_int(): x = DV.DataValue("2.424") y = 2 z = x / y #print("repr z:",repr(z)) assert str(z) == "1" y = 2.0000000000001 z = x / y #print("repr z:",repr(z)) assert str(z) == "1.212"
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"))
def test_datavalue_mul_float_int(): x = DV.DataValue("2.314") y = 2 z = x * y #print("repr z:",repr(z)) #print("str z:",str(z),"<<") assert str(z) == "5" y = 2.0000001 z = x * y #print("repr z:",repr(z)) assert str(z) == "4.628"
def random_value(repl=None): """generate a random DataValue Parameters ---------- type (str): context for generating random number 'range'|'approx'|'exact' default: range, range (dict): numerical range for range context default: {'low': 0.01, 'high': 10.0}, approx (dict): target and variance for approximate random number default: {'target' : 9.99999, 'pct': 10.0}, exact (str): magnitude to use for an exact number no default, nsf_range (list): number of sig figs to create result with, default:[3,5], units (str) :string to use for units, default: '' units_format (str): how to format the units, 'abbrev' and/or 'HTML', default: '', Returns ------- a DataValue with the units specified, if any Raises ------ AttributeError if no attribute, value pair or dict is specified. """ verbose = False config = deepcopy(random_value.valid_args) if verbose: print("repl:", pformat(repl)) if repl is not None: config.update(repl) if verbose: print("updating:") if verbose: print("randomValue config:", pformat(config)) if config['type'] == 'range': mag = SF.SciSigFig.in_range(config['range']['low'], config['range']['high'], config['nsf_range']) elif config['type'] == 'approx': mag = SF.SciSigFig.approximate_magnitude(config['approx']['target'], config['approx']['pct']) elif (config['type'] == 'exact'): numberstr = config['exact'] assert float( numberstr), f"value for exact ({numberstr}) is not a number" mag = SF.SciSigFig(str(numberstr)) else: assert False, f"config.type \"{config['type']}\" is not 'range'|'approx'" if config['units'] == '': use_units = None else: use_units = config['units'] use_format = config['units_format'] datavalue = DV.DataValue(magnitude=str(mag), units=use_units, units_format=use_format) if verbose: print("randomValue return:", pformat(datavalue)) return {'value': datavalue}
def test_datavalue_sub_ok_int_float(): x = DV.DataValue("22.414", "") y = 22 z = x - y #print("repr z:",repr(z)) assert str(z) == "0" # rounded to nearest unit y = 22.000 z = x - y #print("repr z:",repr(z)) assert str(z) == "0.4" y = 22.001 z = x - y #print("repr z:",repr(z)) assert str(z) == "0.413"
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"))
def get_conversion_factor(input_units, output_units): """get_conversion_factor determine the conversion factor between units Parameters ---------- input_units : a string representing the units to convert from output_units: a string representing the units to convert to Returns ------- a DataValue with the units conversion factor (1 in_unit = xx out_units) Raises ------ """ inputDV = DV.DataValue(" ".join(("1", input_units)), exact=True) resultDV = do_convert(inputDV, output_units) #print("get_conversion_factor::",pformat(resultDV)) return resultDV
def do_convert(inputDV, finalunits): """do_convert calculate a units conversion Parameters ---------- inputDV : a DataValue to be converted to different units finalunits: a string representing the units to convert to Returns ------- a DataValue with the units specified in final units Raises ------ pint.errors.DimensionalityError if there's no way to convert the units """ verbose = False result = inputDV.quantity.to(finalunits) resultDV = DV.DataValue(result.magnitude, result.units) return resultDV
def __init__(self, chemicalProperty=None, chemicalName=None): Prop = Query() assert chemicalProperty != None, "No ChemicalProperty specified" results = {} if chemicalName != None: searchResultsList = CV_db.search( (Prop.property == chemicalProperty) & (Prop.chemicalName == chemicalName)) Nresults = len(searchResultsList) #print("cmpd + prop results:",searchResultsList) assert Nresults > 0, f"No results from search {chemicalProperty},{chemicalName}" assert Nresults == 1, f"too many ({Nresults}) results from search of {chemicalProperty}+{chemicalName}" results = searchResultsList[0] else: searchResultsList = CV_db.search(Prop.property == chemicalProperty) Nresults = len(searchResultsList) assert Nresults > 0, f"No results from search of {chemicalProperty}" results = searchResultsList[randint(0, Nresults - 1)] #print("DB Results:",results) self.value = DV.DataValue(results["value"], results["units"]) self.chemicalName = results["chemicalName"] self.property = results["property"] self.data_source = results["source"]
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"))
def test_DataValue_object_default(): x = DV.DataValue() #print("DV:",repr(x)) assert str(x) == "0.0"
def test_do_convert_broken_calls(inputDVstr,finalunitsstr,answerDVstr): inputDV=DV.DataValue(inputDVstr) finalunits=finalunitsstr with pytest.raises(pint.errors.DimensionalityError) as excinfo: convertedDV = do_convert(inputDV,finalunits) assert "DimensionalityError" in str(excinfo.value)
def test_datavalue_div(): x = DV.DataValue("2.414", "g") y = DV.DataValue("2.0", "mL") z = x / y #print("repr z:",repr(z)) assert str(z) == "1.2 gram / milliliter"
def test_datavalue_div2(): x = DV.DataValue("10.00", "g") y = DV.DataValue("2.00", "mL") z = x / y #print("repr z:",repr(z)) assert str(z) == "5.00 gram / milliliter"
def test_datavalue_add_ok(): x = DV.DataValue("2.414", "g") y = DV.DataValue("2.0", "g") z = x + y #print("repr z:",repr(z)) assert str(z) == "4.4 gram"
def test_datavalue_sub_ok(): x = DV.DataValue("22.414", "g") y = DV.DataValue("22.0", "g") z = x - y #print("repr z:",repr(z)) assert str(z) == "0.4 gram"
def test_DataValue_object_exact(mag, mag_exact, units, answer): x = DV.DataValue(mag, units, exact=True) #print("DV repr:"+repr(x)) assert str(x) == answer assert str(x.magnitude) == mag_exact assert str(x.units) == units
("200.", "2.00e+2"), ("4.003e-10", "4.003e-10"), ]) def test_exactnumbers(number, answerstr): repl = {'type': 'exact', 'exact': number} x = DG.random_value(repl) assert str(x['value'].magnitude) == answerstr @pytest.mark.parametrize( "expression, vars, answer", [ #I use str because I don't want rounding errors in comparison ("1+2", {}, "3"), ("one + two", { 'one': DV.DataValue("1"), 'two': DV.DataValue("2") }, DV.DataValue("3")), ("one + two", { 'one': DV.DataValue("1 g"), 'two': DV.DataValue("2 g") }, DV.DataValue("3 gram")), ]) def test_parser(expression, vars, answer): x = DG.parse_expression({"expression": expression, "vars": vars}) #print("test_parser x:",pformat(x)) assert str(x["value"]) == str(answer) @pytest.mark.parametrize("template, vars, answer", [ ("1+2", {
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)
def test_DataValue_object_format(mag, units, answer, spec_in): x = DV.DataValue(mag, units, units_format=spec_in) #print("DV repr:"+repr(x)) assert str(x) == answer assert str(x.magnitude) == mag assert str(x.units) == units
DoD={ 'correct': { 'value': 'true' }, 'reason': { 'value': 'To be implemented' }, 'text': { 'value': 'mass/volume = (10.00 gram)/2.00 milliliter = 5.0000 gram / milliliter' }, 'units': { 'value': 'gram / milliliter' }, 'value': { 'value': DV.DataValue(magnitude="2.00", units="milliliter") } }), CP.Chemplate( DoD={ 'correct': { 'value': 'false' }, 'reason': { 'value': 'To be implemented' }, 'text': { 'value': 'mass/volume = (10.00 gram)/2.00 milliliter = 5.0000 gram / milliliter' }, 'units': {