generated from sco1/py-template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add heading parsing & column indexing
Not being able to use pandas or polars makes things complicated D:
- Loading branch information
Showing
7 changed files
with
114 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from __future__ import annotations | ||
|
||
import typing as t | ||
from dataclasses import dataclass, fields | ||
|
||
|
||
@dataclass | ||
class ColumnIndices: | ||
""" | ||
Column index in the parsed Dropmate compiled log CSV. | ||
Attribute names are assumed to correspond to the Dropmate log header name. Columns contained may | ||
vary by Dropmate app version, so if they are not present in the compiled log they will remain at | ||
a value of `-1`, indicating they were not found. | ||
""" | ||
|
||
serial_number: int = -1 | ||
uid: int = -1 | ||
battery: int = -1 | ||
device_health: int = -1 | ||
firmware_version: int = -1 | ||
start_time_utc: int = -1 | ||
end_time_utc: int = -1 | ||
start_barometric_altitude_msl_ft: int = -1 | ||
end_barometric_altitude_msl_ft: int = -1 | ||
dropmate_internal_time: int = -1 | ||
last_scanned_time: int = -1 | ||
|
||
def __iter__(self) -> t.Generator[str, None, None]: | ||
for f in fields(self): | ||
yield f.name | ||
|
||
@classmethod | ||
def from_header(cls, header: str) -> ColumnIndices: | ||
"""Attempt to match attribute names to their corresponding data columns.""" | ||
indices = ColumnIndices() | ||
|
||
# Some column names may have stray spaces in them, listify so we can iterate over repeatedly | ||
col_names = [c.strip().lower() for c in header.split(",")] | ||
for query_col in indices: | ||
for idx, col in enumerate(col_names): | ||
if col == query_col: | ||
setattr(indices, query_col, idx) | ||
|
||
return indices | ||
|
||
def __str__(self) -> str: # pragma: no cover | ||
return ", ".join(f"({f}, {getattr(self, f)})" for f in self) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from dropmate_py.parser import ColumnIndices | ||
|
||
SAMPLE_FULL_HEADER = "serial_number,uid,battery,device_health, firmware_version,log_timestamp,log_altitude,total_flights,flights_over_18kft,recorded_flights,flight_index,start_time_utc,end_time_utc,start_barometric_altitude_msl_ft,end_barometric_altitude_msl_ft,dropmate_internal_time,last_scanned_time" | ||
|
||
|
||
def test_parse_indices_full_header() -> None: | ||
TRUTH_INDICES = ColumnIndices( | ||
serial_number=0, | ||
uid=1, | ||
battery=2, | ||
device_health=3, | ||
firmware_version=4, | ||
start_time_utc=11, | ||
end_time_utc=12, | ||
start_barometric_altitude_msl_ft=13, | ||
end_barometric_altitude_msl_ft=14, | ||
dropmate_internal_time=15, | ||
last_scanned_time=16, | ||
) | ||
|
||
indices = ColumnIndices.from_header(SAMPLE_FULL_HEADER) | ||
assert indices == TRUTH_INDICES | ||
|
||
|
||
SAMPLE_OLD_HEADER = "serial_number,uid,battery,log_timestamp,log_altitude,total_flights,prior_flights,flights_over_18kft,recorded_flights,flight_index,start_time_utc,end_time_utc,start_barometric_altitude_msl_ft,end_barometric_altitude_msl_ft" | ||
|
||
|
||
def test_parse_indices_old_header() -> None: | ||
TRUTH_INDICES = ColumnIndices( | ||
serial_number=0, | ||
uid=1, | ||
battery=2, | ||
device_health=-1, | ||
firmware_version=-1, | ||
start_time_utc=10, | ||
end_time_utc=11, | ||
start_barometric_altitude_msl_ft=12, | ||
end_barometric_altitude_msl_ft=13, | ||
dropmate_internal_time=-1, | ||
last_scanned_time=-1, | ||
) | ||
|
||
indices = ColumnIndices.from_header(SAMPLE_OLD_HEADER) | ||
assert indices == TRUTH_INDICES |
This file was deleted.
Oops, something went wrong.