OceanDataTools / openrvdas

An open source data acquisition system designed for use on research vessels and other scientific installations
http://openrvdas.org
Other
45 stars 21 forks source link

FormatTransform that converts structured record to string #201

Closed davidpablocohn closed 4 years ago

davidpablocohn commented 4 years ago

Would be useful to have a transform that takes structured data (either a DASRecord or dict) and folds it into a formatted f-string (as in https://cito.github.io/blog/f-strings/).

E.g.

> t = FormatTransform('Heading is {S330Heading} degrees, and speed is {S330SOGkt:3.1f} kts')
> t.transform({'fields':{'S330Heading': 264.5, 'S330SOGkt': 13.5}}
Heading is 264.5 degrees, and speed is 13.5 kts

Would want a flag to say what to do if not all the format values were present. E.g. only output if all are present, output will fillers if any are present, output regardless of whether any are present...

davidpablocohn commented 4 years ago

Assuming it's a dict:

# If we're going to allow output when some/all requested fields are missing from
# the format, we need to figure out which fields are actually requested in the format
# string. Basically everything matching `{%s[:format]}`.

def __init__(self, format_str, defaults=None):
  """
  format_str    - a format string, as described https://www.w3schools.com/python/ref_string_format.asp
  default_dict - if not None, a dict of field:value pairs specifying the value that
                      should be substituted in for any missing fields. If a field:value
                      pair is missing from this dict, throw a KeyError.
  """
  self.format_str = format_str
  self.defaults = defaults

def transform(self, record):
  # Make sure record is right format - DASRecord or dict
  ????

  fields = self.default_dict.copy()
  record_fields = record.get('fields',{})
  for field, value in record_fields.items():
    fields[field] = value
  # Add the timestamp as a field, as well
  fields['timestamp'] = record.get('timestamp',0)

  result = self.format_str.format(**fields)
  if result:
    return result
  return None