Changeset 1927


Ignore:
Timestamp:
Oct 14, 2005, 4:14:19 PM (19 years ago)
Author:
ole
Message:

Improved expression parser for apply_expression_to_dictionary()

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • inundation/pyvolution/data_manager.py

    r1919 r1927  
    13221322    quantity_dict = {}
    13231323    for name in fid.variables.keys():
    1324 
    1325         if name not in ['x', 'y', 'volumes', 'time']:
    1326             quantity_dict[name] = fid.variables[name][:]
     1324        quantity_dict[name] = fid.variables[name][:]
    13271325
    13281326    #print quantity_dict     
  • inundation/pyvolution/test_util.py

    r1919 r1927  
    10121012       
    10131013
     1014    def test_multiple_replace(self):
     1015        """Hard test that checks a true word-by-word simultaneous replace
     1016        """
     1017       
     1018        D = {'x': 'xi', 'y': 'eta', 'xi':'lam'}
     1019        exp = '3*x+y + xi'
     1020       
     1021        new = multiple_replace(exp, D)
     1022       
     1023        assert new == '3*xi+eta + lam'
     1024                         
    10141025
    10151026
  • inundation/pyvolution/util.py

    r1924 r1927  
    460460
    461461
    462 
    463 
    464 
    465 def apply_expression_to_dictionary(expression, _):
    466     """Apply arbitrary expression to values of dictionary _
    467 
    468     expression: Arbitrary, e.g. arithmetric, expression relating keys
    469                 from dictionary _. A key must not be the single character '_'
    470 
    471     _: Dictionary of variable names used in expression and their
    472        corresponding values. The dictinary name is chosen as the
    473        inconspicuous symbol _ in order to avoid single letter variable
    474        to inabvertently substitute parts of the dictionary name
    475    
     462def multiple_replace(text, dictionary):
     463    """Multiple replace of words in text
     464
     465    text:       String to be modified
     466    dictionary: Mapping of words that are to be substituted
     467
     468    Python Cookbook 3.14 page 88 and page 90
     469    """
     470
     471    import re
     472   
     473    #Create a regular expression from all of the dictionary keys
     474    #matching only entire words
     475    regex = re.compile(r'\b'+ \
     476                       r'\b|\b'.join(map(re.escape, dictionary.keys()))+ \
     477                       r'\b' )
     478
     479    #For each match, lookup the corresponding value in the dictionary
     480    return regex.sub(lambda match: dictionary[match.group(0)], text)
     481
     482
     483
     484
     485def apply_expression_to_dictionary(expression, dictionary):#dictionary):
     486    """Apply arbitrary expression to values of dictionary
    476487
    477488    Given an expression in terms of the keys, replace key by the
    478489    corresponding values and evaluate.
    479 
    480     Values in dictionary must support operators given in expression
    481     e.g. by overloading
    482     """
    483 
    484    
     490   
     491
     492    expression: Arbitrary, e.g. arithmetric, expression relating keys
     493                from dictionary.
     494
     495    dictionary: Mapping between symbols in expression and objects that
     496                will be evaluated by expression.
     497                Values in dictionary must support operators given in
     498                expression e.g. by overloading               
     499    """
     500
    485501    import types
    486502    import re
    487503
    488504    assert isinstance(expression, basestring)
    489     assert type(_) == types.DictType
    490 
    491 
    492     #FIXME: Varibles may substitute into other variables e.g. x into xmomentum.
    493 
    494     #words = re.compile("^.*?\\b([A-Za-z'-]+)\\b(.*)$")
    495     #words = re.compile("[A-Za-z]")
    496     #print expression
    497     #res = words.search(expression)
    498     #for
    499     #print 'Res ', res.group(0)
    500     #print 'Res ', res.group(1)
    501     #tokens =
    502 
    503     #Replace key names with values
    504     for key in _.keys():
    505         msg = 'Key must not be the single character "_"'
    506         assert key != '_', msg
    507         expression = expression.replace(key,
    508                                         '_["%s"]' %key)
    509 
     505    assert type(dictionary) == types.DictType
     506
     507    #Convert dictionary values to textual representations suitable for eval
     508    D = {}
     509    for key in dictionary:
     510        D[key] = 'dictionary["%s"]' %key
     511
     512    #Perform substitution of variables   
     513    expression = multiple_replace(expression, D)
    510514
    511515    #Evaluate and return
  • tools/pytools/misc.py

    r18 r1927  
    11     
     2def multiple_replace(dictionary, text):
     3    """Multiple replace
     4
     5    Python Cookbook 3.14 page 88 and page 90
     6    """
     7
     8    import re
     9   
     10    #Create a regular expression from all of the dictionary keys
     11    #matching only entire words
     12    #regex = re.compile("|".join(map(re.escape, dictionary.keys())))
     13    regex = re.compile(r'\b'+ \
     14                       r'\b|\b'.join(map(re.escape, dictionary.keys()))+ \
     15                       r'\b' )
     16
     17    #For each match, lookup the corresponding value in the dictionary
     18    return regex.sub(lambda match: dictionary[match.group(0)], text)
     19
     20
    221def merge_dictionaries(D1,D2):
    322    """merge_dictionaries(D1,D2)
     
    1938    return D1
    2039
     40
     41
Note: See TracChangeset for help on using the changeset viewer.