- # To accept other software's CSV format
- DUPLEX_MAP = {
"Minus": "-",
"Plus": "+",
"Simplex": "",
"Split": "split",
- }
- SKIP_MAP = {
"Off": "",
"On": "S",
"P Scan": "P",
"Skip": "S",
}
- TMODE_MAP = {
"None": "",
"T Sql": "TSQL",
- }
- ATTR_MAP = { "Location" : (int, "number"), "Name" : (str, "name"),
@@ -59,11 +79,21 @@ "DtcsPolarity" : (str, "dtcs_polarity"), "Mode" : (str, "mode"), "TStep" : (float, "tuning_step"),
"Skip" : (str, "skip"),
"Skip" : (lambda v: CSVRadio.SKIP_MAP.get(v, v),
So, this isn't too bad as it is, but I think we might want to make it a little more explicit. This would let us more easily add additional dialects without just polluting this file with further hacks that would make it harder and harder to understand.
Right now, we traverse the list of headers specified in ATTR_MAP each time through the list. Instead, I think we should traverse those in the actual header row that we read on the first line. Then we can delegate to per-column handlers if need be, to do the actual work. This is overly complicated, but might be syntactically nice:
fname = "process_%s" % header.replace(" ", "_") if hasattr(self, fname): handled = getattr(self, fname)(mem, attr, datum, typ) if not handled: setattr(mem, attr, typ(datum)
Then, you could define methods like this in the CSV driver:
def process_Tone_Mode(self, mem, attr, datum, typ): tmode_map = { "None": "", "T Sql": "TSQL, } setattr(mem, attr, tmode_map[datum]_ return True
Another alternative might be to do what a lot of spreadsheets do, which is take a run through the first ten lines or so (or just the header, if that is enough) and try to detect the dialect. If it is know, then we delegate to a subclass of the CSV driver, with less magic and more explicit behavior. What do you think? It would probably result in less code re-use, but might be a little easier to understand.