def __init__(self, dev_path, port=9600): ''' Input: - dev_path: Path to the device - port: Port to listen on The parameters range_low and range_high are used for faking data if the device connection fails. ''' self.dev_path = dev_path self.port = port self.reader = ArduinoReader(dev_path, port)
class ArduinoDevice(object): ''' A base class for representing an Arduino device. Actual devices inherit from this base class and need to implement the following methods: - parse_line: parsing a single line read from the device - score: score a pandas DataFrame representing the set of observations ''' def __init__(self, dev_path, port=9600): ''' Input: - dev_path: Path to the device - port: Port to listen on The parameters range_low and range_high are used for faking data if the device connection fails. ''' self.dev_path = dev_path self.port = port self.reader = ArduinoReader(dev_path, port) def parse_line(self, line): ''' Method for parsing a single line, to be implemented by inheriting classes. Input: -line: A character string representing a line read from an Arduino device Output: A dict of the form {'variable_name1': value1, 'variable_name2: value2}. Throws an exception for lines that do not parse. ''' pass def parse_lines(self, lines): ''' Method for parsing a list of lines and generating a pandas DataFrame object from them. Lines that cannot be parsed by parse_line() are silently omitted. Input: - lines: List of lines, as generated by ArduinoReader.read() Output: A pandas dataframe with one column for each variable output by the device and the time stamp of each record as the index; each row represents one observation. ''' values = [] keep = [] for line in lines: try: row = self.parse_line(line) values.append(row) keep.append(True) except: keep.append(False) df = DataFrame(values, index=lines.index[keep]) return(df) def score(self, df): ''' Method for scoring a dataframe of records, to be implemented by inheriting classes. Input: - df: A pandas DataFrame with one column for each output produced by the Arduino device and the time stamp of each record as the index; each row represents one observation. Output: A single numeric score. ''' pass def measure(self, secs): ''' Read from the device for a specified number of seconds, process the device output, and score it. Input: - secs: Number of seconds to read from the device for. Output: A numeric scalar ''' if self.reader.ready: lines = self.reader.read(secs=secs) df = self.parse_lines(lines) score = self.score(df) else: time.sleep(secs) score = self.random_score() return score def random_score(self): ''' Generate a random score ''' score = 1 while score > 0.3: score = random.lognormvariate(mu=-3, sigma=0.7) if score < 0.02: score = 0 return score def test(self, secs): ''' Read from the device for a specified number of seconds, process the device output, and score it. Input: - secs: Number of seconds to read from the device for. Output: A dict containing two keys: - score: A single numeric score summarizing the output by the device. - data: A pandas DataFrame representing the data output by the device, with one column per variable and one row per observations. Time stamps of the observations form the index of the DataFrame. ''' if self.reader.ready: lines = self.reader.read(secs=secs) df = self.parse_lines(lines) score = self.score(df) else: score = self.random_score() return {'score': score, 'data': df}
class ArduinoDevice(object): ''' A base class for representing an Arduino device. Actual devices inherit from this base class and need to implement the following methods: - parse_line: parsing a single line read from the device - score: score a pandas DataFrame representing the set of observations ''' def __init__(self, dev_path, port=9600): ''' Input: - dev_path: Path to the device - port: Port to listen on The parameters range_low and range_high are used for faking data if the device connection fails. ''' self.dev_path = dev_path self.port = port self.reader = ArduinoReader(dev_path, port) def parse_line(self, line): ''' Method for parsing a single line, to be implemented by inheriting classes. Input: -line: A character string representing a line read from an Arduino device Output: A dict of the form {'variable_name1': value1, 'variable_name2: value2}. Throws an exception for lines that do not parse. ''' pass def parse_lines(self, lines): ''' Method for parsing a list of lines and generating a pandas DataFrame object from them. Lines that cannot be parsed by parse_line() are silently omitted. Input: - lines: List of lines, as generated by ArduinoReader.read() Output: A pandas dataframe with one column for each variable output by the device and the time stamp of each record as the index; each row represents one observation. ''' values = [] keep = [] for line in lines: try: row = self.parse_line(line) values.append(row) keep.append(True) except: keep.append(False) df = DataFrame(values, index=lines.index[keep]) return (df) def score(self, df): ''' Method for scoring a dataframe of records, to be implemented by inheriting classes. Input: - df: A pandas DataFrame with one column for each output produced by the Arduino device and the time stamp of each record as the index; each row represents one observation. Output: A single numeric score. ''' pass def measure(self, secs): ''' Read from the device for a specified number of seconds, process the device output, and score it. Input: - secs: Number of seconds to read from the device for. Output: A numeric scalar ''' if self.reader.ready: lines = self.reader.read(secs=secs) df = self.parse_lines(lines) score = self.score(df) else: time.sleep(secs) score = self.random_score() return score def random_score(self): ''' Generate a random score ''' score = 1 while score > 0.3: score = random.lognormvariate(mu=-3, sigma=0.7) if score < 0.02: score = 0 return score def test(self, secs): ''' Read from the device for a specified number of seconds, process the device output, and score it. Input: - secs: Number of seconds to read from the device for. Output: A dict containing two keys: - score: A single numeric score summarizing the output by the device. - data: A pandas DataFrame representing the data output by the device, with one column per variable and one row per observations. Time stamps of the observations form the index of the DataFrame. ''' if self.reader.ready: lines = self.reader.read(secs=secs) df = self.parse_lines(lines) score = self.score(df) else: score = self.random_score() return {'score': score, 'data': df}