def test_no_var(self): for text in [ "1+e", "0*int", "float**2", "nan*45.", "inf/1000", "none(no)" ]: with self.subTest("Reference to undefined variables", text=text): with self.assertRaises(maexpa.exception.NoVarException): maexpa.Expression(text)()
def test_float(self): for text in [ "0.", ".0", "1.1", "1e10", "-1e100", "1e+10", "+2e+20", "-3e-30", "-4e+40", "-00007e-70", "00008e+80", "0009e-90", "-.1e200", "-.1e-200", "1.8765e-111", "-8.4097e+300", "+3.1415926358979" ]: with self.subTest("Float conversion", text=text): self.assertEqual(maexpa.Expression(text)(), float(text))
def test_ops_int(self): tests = [("max(a,b)", numpy.asarray([5, 3, 4])), ("min(a,b)", numpy.asarray([2, 1, 2])), ("pow(tot,2)", numpy.asarray([100, 100, 100]))] for expr, comp in tests: with self.subTest("NumPy comparison on integers", expr=expr): res = maexpa.Expression(expr)(var=self.var_cb_int) self.comp_array(res, comp)
def test_func_cbrt_float(self): tests = [ ("cbrt(a)", numpy.cbrt(numpy.asarray([0.2, 0.3, 0.4]))), ("cbrt(b*c)", numpy.cbrt(numpy.asarray([0.15, 0.06, 0.08]))), ] for expr, comp in tests: with self.subTest("Cube root on floats", expr=expr): res = maexpa.Expression(expr)(var=self.var_cb_float) self.comp_array(res, comp)
def test_func_cbrt_int(self): tests = [ ("cbrt(a)", numpy.cbrt(numpy.asarray([2., 3., 4.]))), ("cbrt(b*c)", numpy.cbrt(numpy.asarray([15., 6., 8.]))), ] for expr, comp in tests: with self.subTest("Cube root on integer", expr=expr): res = maexpa.Expression(expr)(var=self.var_cb_int) self.comp_array(res, comp)
def test_func_mod_float(self): tests = [ ("abs(-a)", numpy.asarray([0.2, 0.3, 0.4])), ("floor(b)", numpy.asarray([0., 0., 0.])), ("ceil(c)", numpy.asarray([1., 1., 1.])), ] for expr, comp in tests: with self.subTest("Modifiers on floats", expr=expr): res = maexpa.Expression(expr)(var=self.var_cb_float) self.comp_array(res, comp)
def test_ops_float(self): tests = [ ("max(a,b)", numpy.asarray([0.5, 0.3, 0.4])), ("min(a,b)", numpy.asarray([0.2, 0.1, 0.2])), ("pow(tot,2)", numpy.asarray([1., 1., 1.])), ] for expr, comp in tests: with self.subTest("NumPy comparison on floats", expr=expr): res = maexpa.Expression(expr)(var=self.var_cb_float) self.comp_array(res, comp)
def test_func_abs_float( self ): tests = [ ( "abs(1.7648)", 1.7648 ), ( "abs(-1.7648)", 1.7648 ), ] for expr, comp in tests: with self.subTest( "Absoltue value on float", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), float ) self.assertAlmostEqual( res, comp )
def test_func_builtin_float( self ): tests = [ ( "min(0.9,1.1)", 0.9 ), ( "max(0.9,1.1)", 1.1 ), ( "pow(2.0,4)", 16. ), ] for expr, comp in tests: with self.subTest( "Builting functions on floats", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), float ) self.assertAlmostEqual( res, comp )
def test_func_sqrt( self ): tests = [ ( "sqrt(2)", math.sqrt( 2. ) ), ( "sqrt(2.)", math.sqrt( 2. ) ), ( "sqrt(45**2)", 45. ), ] for expr, comp in tests: with self.subTest( "Square root", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), float ) self.assertAlmostEqual( res, comp )
def test_func_cbrt( self ): tests = [ ( "cbrt(8.)", 2. ), ( "cbrt(-7)", -7**( 1. / 3. ) ), ( "cbrt(45**3)", 45. ), ] for expr, comp in tests: with self.subTest( "Cube root", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), float ) self.assertAlmostEqual( res, comp )
def test_var( self ): tests = [ ( "e", math.e ), ( "pi", math.pi ), ( "tau", math.tau ), ] for expr, comp in tests: with self.subTest( "Constants", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), float ) self.assertAlmostEqual( res, comp )
def test_exp_float(self): tests = [ ("2.5**2", 2.5**2), ("2.3**4.5", 2.3**4.5), ("-1.1**3", -1.1**3), ] for expr, comp in tests: with self.subTest("Floating-point exponentiation", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def test_func_explog_float( self ): tests = [ ( "exp(1)", math.e ), ( "log(e)", 1. ), ( "log2(2)", 1. ), ( "log10(10)", 1. ), ] for expr, comp in tests: with self.subTest( "Exponential and logarithms on float", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), float ) self.assertAlmostEqual( res, comp )
def test_func_type_float( self ): tests = [ ( "floor(1.7648)", 1 ), ( "ceil(1.7648)", 2 ), ( "floor(-1.7648)", -2 ), ( "ceil(-1.7648)", -1 ), ] for expr, comp in tests: with self.subTest( "Conversion from float to integer", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), int ) self.assertEqual( res, comp )
def test_div_float(self): tests = [ ("-1.5/1", -1.5), ("1/0.5", 2.), ("10.//20", 0.), ("3/4*5", 3.75), ("6.7*10//10", 6.), ] for expr, comp in tests: with self.subTest("Floating-point division", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def test_mult_int(self): tests = [ ("-1*1", -1), ("1*0", 0), ("0*1", 0), ("10*20", 200), ("3*4*5", 60), ("-9*9*10", -810), ] for expr, comp in tests: with self.subTest("Integer multiplication", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), int) self.assertEqual(res, comp)
def test_terms_int(self): tests = [ ("-1-1", -2), ("1-1", 0), ("-1+1", 0), ("1+1", 2), ("1+1+1", 3), ("1-1-1-1", -2), ] for expr, comp in tests: with self.subTest("Integer addition and substractions", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), int) self.assertEqual(res, comp)
def test_par_float(self): tests = [ ("3*(5+3.5)", 25.5), ("6*(7.2-7)", 1.2), ("5.*(10-15)", -25.), ("(2.5*2.5)**2", 39.0625), ("(-4*1.5)**2", 36.), ] for expr, comp in tests: with self.subTest("Floating-point expressions with parentheses", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def test_par_int(self): tests = [ ("3*(5+1)", 18), ("6*(7-7)", 0), ("5*(10-15)", -25), ("(3*3)**2", 81), ("(-4*4)**2", 256), ] for expr, comp in tests: with self.subTest("Integer expressions with parentheses", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), int) self.assertEqual(res, comp)
def test_mult_float(self): tests = [ ("-1.*2.5", -2.5), ("110*0.01", 1.1), ("1e10*1e10", 1.e20), ("-0.4*20", -8.), ("3.3*4.4*5.5", 79.86), ("-9.*9.*.1", -8.1), ] for expr, comp in tests: with self.subTest("Floating-point multiplication", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def test_func_builtin_int( self ): tests = [ ( "min(1,2)", 1 ), ( "max(1,2)", 2 ), ( "min(-1,1)", -1 ), ( "max(-1,1)", 1 ), ( "pow(1,2)", 1 ), ( "pow(2,3)", 8 ), ] for expr, comp in tests: with self.subTest( "Builting functions on integers", expr = expr ): res = maexpa.Expression( expr )() self.assertIs( type( res ), int ) self.assertEqual( res, comp )
def test_div_int(self): tests = [ ("-1//1", -1), ("1//1", 1), ("0//1", 0), ("10//20", 0), ("3*4//5", 2), ("-9*9//10", -8), ] for expr, comp in tests: with self.subTest("Integer division", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), int) self.assertEqual(res, comp)
def test_prec_int(self): tests = [ ("3*5+1", 16), ("-2+3//3", -1), ("1+3*2**2", 13), ("3*3**2", 27), ("-4+4**2", 12), ("4-4**2", -12), ] for expr, comp in tests: with self.subTest("Operator precendence with integer expressions", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), int) self.assertEqual(res, comp)
def test_div_int_float(self): tests = [ ("-1/1", -1.), ("1/1", 1.), ("0/1", 0.), ("10/20", 0.5), ("3*4/5", 2.4), ("-9*9/10", -8.1), ] for expr, comp in tests: with self.subTest("Integer division resulting in float", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def test_prec_float(self): tests = [ ("1.5+6*3", 19.5), ("-7-5*1.2", -13.), ("1.5+3.5*2.0**2", 15.5), ("3+9/3", 6.), ("1.5+6//3", 3.5), ("-9+8*0.75", -3.), ] for expr, comp in tests: with self.subTest( "Operator precendence with floating-point expressions", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def test_exp_int(self): tests = [ ("0**10", 0), ("1**20", 1), ("2**2", 4), ("2**4", 16), ("2**2**2**2", 65536), ("4**3**2", 65536 * 4), ("2**3**3", 65536 * 2048), ("-10**3", -1000), ] for expr, comp in tests: with self.subTest("Integer exponentiation", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), int) self.assertAlmostEqual(res, comp)
def test_terms_float(self): tests = [ ("-1.-1", -2.), ("1.-1", 0.), ("-1.+1", 0.), ("1+1.", 2.), ("1+1+1.", 3.), ("1-1.-1-1", -2.), ("1.5+1.5", 3.), ("1.5+1.5-3.", 0.), ] for expr, comp in tests: with self.subTest("Mixed integer/float addition and substractions", expr=expr): res = maexpa.Expression(expr)() self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def test_vars(self): def consts(name): if name == "ten": return 10. else: raise maexpa.exception.NoVarException(name) tests = [ ("ten", 10.), ("ten*ten", 100.), ("ten**2", 100.), ("2**ten", 1024.), ] for expr, comp in tests: with self.subTest("Constants as variables", expr=expr): res = maexpa.Expression(expr)(var=consts) self.assertIs(type(res), float) self.assertAlmostEqual(res, comp)
def compute_item( self, config, sub ): # Disallow subpages if not ( sub is None or sub == "" ): raise hcds_exception.NotFound defs = config[ "fields" ] h5file = tables.open_file( config[ "file" ] ) data = [] labels = [] try: for n in range( 1000 ): try: group = h5file.root.__getattr__( "file_{:03d}".format( n ) ) except: continue get_data = lambda name: numpy.asarray( getattr( group, name )[ ... ] ) sets = [ maexpa.Expression( item[ "data" ], var = get_data )() for item in defs ] items = [] for i in range( len( sets[ 0 ] ) ): items.append( [ self.num( dset[ i ] ) for dset in sets ] ) data.append( items ) labels.append( group._v_attrs[ "desc" ] ) finally: h5file.close() response = { "value": [ item[ "value" ] for item in defs ], "unit": [ item[ "unit" ] for item in defs ], "short": [ ( item[ "short" ] if "short" in item else item[ "value" ] ) for item in defs ], "series": data, "label": labels, } self.start( "200 OK", [ ( "Content-Type", "application/json" ) ] ) self.add_output( bytes( json.dumps( response ), "utf-8" ) )