Skip to content

Commit b25b29a

Browse files
committed
use match/case in __format__
1 parent 276bfd7 commit b25b29a

14 files changed

Lines changed: 180 additions & 153 deletions

File tree

src/pms/sensors/base.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import warnings
44
from abc import abstractmethod
55
from dataclasses import asdict, dataclass
6-
from typing import ClassVar
6+
from typing import ClassVar, Literal
77

88
from loguru import logger
99

@@ -65,7 +65,7 @@ def checksum(self) -> int:
6565

6666
@classmethod
6767
@abstractmethod
68-
def _validate(self, message: bytes, header: bytes, length: int) -> Message:
68+
def _validate(cls, message: bytes, header: bytes, length: int) -> Message:
6969
pass
7070

7171
@staticmethod
@@ -101,11 +101,12 @@ def subset(self, spec: str | None = None) -> dict[str, float]: # pragma: no cov
101101
)
102102

103103
@abstractmethod
104-
def __format__(self, spec: str) -> str:
105-
if spec == "header": # header for csv file
106-
return ", ".join(asdict(self).keys())
107-
if spec == "":
108-
return str(self)
104+
def __format__(self, spec: Literal["header"] | str) -> str:
105+
match spec:
106+
case "header": # header for csv file
107+
return ", ".join(asdict(self).keys())
108+
case "":
109+
return str(self)
109110

110111
raise ValueError(
111112
f"Unknown format code '{spec}' for object of type '{self.__class__.__qualname__}'"

src/pms/sensors/bosch_sensortec/mcu680.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import struct
77
from dataclasses import dataclass, field
8+
from typing import Literal
89

910
from pms import SensorWarmingUp, WrongMessageChecksum, WrongMessageFormat
1011

@@ -108,27 +109,28 @@ def __post_init__(self):
108109
self.IAQ &= 0x0FFF
109110
self.gas /= 1000
110111

111-
def __format__(self, spec: str) -> str:
112-
if spec == "atm":
113-
return (
114-
f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %, "
115-
f"Press {self.pres:.2f} hPa"
116-
)
117-
if spec == "bme":
118-
return (
119-
f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %, "
120-
f"Press {self.pres:.2f} hPa, {self.gas:.1f} kΩ"
121-
)
122-
if spec == "bsec":
123-
return (
124-
f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %, "
125-
f"Press {self.pres:.2f} hPa, {self.IAQ} IAQ"
126-
)
127-
if spec == "csv":
128-
return (
129-
f"{self.time}, {self.temp:.1f}, {self.rhum:.1f}, {self.pres:.2f}, "
130-
f"{self.IAQ_acc}, {self.IAQ}, {self.gas:.1f}, {self.alt}"
131-
)
112+
def __format__(self, spec: Literal["atm", "bme", "bsec", "csv", "header"] | str) -> str:
113+
match spec:
114+
case "atm":
115+
return (
116+
f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %, "
117+
f"Press {self.pres:.2f} hPa"
118+
)
119+
case "bme":
120+
return (
121+
f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %, "
122+
f"Press {self.pres:.2f} hPa, {self.gas:.1f} kΩ"
123+
)
124+
case "bsec":
125+
return (
126+
f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %, "
127+
f"Press {self.pres:.2f} hPa, {self.IAQ} IAQ"
128+
)
129+
case "csv":
130+
return (
131+
f"{self.time}, {self.temp:.1f}, {self.rhum:.1f}, {self.pres:.2f}, "
132+
f"{self.IAQ_acc}, {self.IAQ}, {self.gas:.1f}, {self.alt}"
133+
)
132134

133135
return super().__format__(spec)
134136

src/pms/sensors/honeywell/hpma115c0.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
from dataclasses import dataclass, field
8+
from typing import Literal
89

910
from .. import base
1011
from . import hpma115s0
@@ -50,15 +51,17 @@ def pm2_5(self) -> int:
5051
def pm4(self) -> int:
5152
return self.pm04
5253

53-
def __format__(self, spec: str) -> str:
54-
if spec == "pm":
55-
return (
56-
f"{self.date:%F %T}: PM1 {self.pm01:.1f}, PM2.5 {self.pm25:.1f}, "
57-
f"PM4 {self.pm04:.1f}, PM10 {self.pm10:.1f} μg/m3"
58-
)
59-
if spec == "csv":
60-
return (
61-
f"{self.time}, {self.pm01:.1f}, {self.pm25:.1f}, {self.pm04:.1f}, {self.pm10:.1f}"
62-
)
54+
def __format__(self, spec: Literal["pm", "csv", "header"] | str) -> str:
55+
match spec:
56+
case "pm":
57+
return (
58+
f"{self.date:%F %T}: PM1 {self.pm01:.1f}, PM2.5 {self.pm25:.1f}, "
59+
f"PM4 {self.pm04:.1f}, PM10 {self.pm10:.1f} μg/m3"
60+
)
61+
case "csv":
62+
return (
63+
f"{self.time}, {self.pm01:.1f}, {self.pm25:.1f}, "
64+
f"{self.pm04:.1f}, {self.pm10:.1f}"
65+
)
6366

6467
return super().__format__(spec)

src/pms/sensors/honeywell/hpma115s0.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import struct
88
from dataclasses import dataclass, field
9+
from typing import Literal
910

1011
from pms import SensorWarmingUp, WrongMessageChecksum, WrongMessageFormat
1112

@@ -91,12 +92,11 @@ class ObsData(base.ObsData):
9192
def pm2_5(self) -> int:
9293
return self.pm25
9394

94-
def __format__(self, spec: str) -> str:
95-
if spec == "pm":
96-
return f"{self.date:%F %T}: PM2.5 {self.pm25:.1f}, PM10 {self.pm10:.1f} μg/m3"
97-
if spec == "csv":
98-
return f"{self.time}, {self.pm25:.1f}, {self.pm10:.1f}"
99-
if spec == "":
100-
return str(self)
95+
def __format__(self, spec: Literal["pm", "csv", "header"] | str) -> str:
96+
match spec:
97+
case "pm":
98+
return f"{self.date:%F %T}: PM2.5 {self.pm25:.1f}, PM10 {self.pm10:.1f} μg/m3"
99+
case "csv":
100+
return f"{self.time}, {self.pm25:.1f}, {self.pm10:.1f}"
101101

102102
return super().__format__(spec)

src/pms/sensors/novafitness/sds01x.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import struct
77
from dataclasses import dataclass, field
8+
from typing import Literal
89

910
from pms import SensorWarmingUp, WrongMessageChecksum, WrongMessageFormat
1011

@@ -113,12 +114,11 @@ def __post_init__(self):
113114
self.pm25 /= 10
114115
self.pm10 /= 10
115116

116-
def __format__(self, spec: str) -> str:
117-
if spec == "pm":
118-
return f"{self.date:%F %T}: PM2.5 {self.pm25:.1f}, PM10 {self.pm10:.1f} μg/m3"
119-
if spec == "csv":
120-
return f"{self.time}, {self.pm25:.1f}, {self.pm10:.1f}"
121-
if spec == "":
122-
return str(self)
117+
def __format__(self, spec: Literal["pm", "csv", "header"] | str) -> str:
118+
match spec:
119+
case "pm":
120+
return f"{self.date:%F %T}: PM2.5 {self.pm25:.1f}, PM10 {self.pm10:.1f} μg/m3"
121+
case "csv":
122+
return f"{self.time}, {self.pm25:.1f}, {self.pm10:.1f}"
123123

124124
return super().__format__(spec)

src/pms/sensors/novafitness/sds198.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
from dataclasses import dataclass, field
8+
from typing import Literal
89

910
from .. import base
1011
from . import sds01x
@@ -37,12 +38,11 @@ class ObsData(base.ObsData):
3738

3839
pm100: int = field(metadata=base.metadata("PM100", "μg/m3", "concentration"))
3940

40-
def __format__(self, spec: str) -> str:
41-
if spec == "pm":
42-
return f"{self.date:%F %T}: PM100 {self.pm100:.1f} μg/m3"
43-
if spec == "csv":
44-
return f"{self.time}, {self.pm100:.1f}"
45-
if spec == "":
46-
return str(self)
41+
def __format__(self, spec: Literal["pm", "csv", "header"] | str) -> str:
42+
match spec:
43+
case "pm":
44+
return f"{self.date:%F %T}: PM100 {self.pm100:.1f} μg/m3"
45+
case "csv":
46+
return f"{self.time}, {self.pm100:.1f}"
4747

4848
return super().__format__(spec)

src/pms/sensors/plantower/pms3003.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import struct
88
from dataclasses import dataclass, field
9+
from typing import Literal
910

1011
from pms import SensorWarmingUp, WrongMessageChecksum, WrongMessageFormat
1112

@@ -130,25 +131,27 @@ def _safe_div(x: int, y: int) -> float: # pragma: no cover
130131
return 1
131132
return 0
132133

133-
def __format__(self, spec: str) -> str:
134-
if spec == "pm":
135-
return (
136-
f"{self.date:%F %T}: PM1 {self.pm01:.1f}, PM2.5 {self.pm25:.1f}, "
137-
f"PM10 {self.pm10:.1f} μg/m3"
138-
)
139-
if spec == "csv":
140-
return (
141-
f"{self.time}, {self.raw01}, {self.raw25}, {self.raw10}, "
142-
f"{self.pm01:.1f}, {self.pm25:.1f}, {self.pm10:.1f}"
143-
)
144-
if spec == "cf":
145-
return (
146-
f"{self.date:%F %T}: CF1 {self.cf01:.0%}, CF2.5 {self.cf25:.0%}, "
147-
f"CF10 {self.cf10:.0%}"
148-
)
149-
if spec == "raw":
150-
return (
151-
f"{self.date:%F %T}: PM1 {self.raw01}, PM2.5 {self.raw25}, PM10 {self.raw10} μg/m3"
152-
)
134+
def __format__(self, spec: Literal["pm", "csv", "header"] | str) -> str:
135+
match spec:
136+
case "pm":
137+
return (
138+
f"{self.date:%F %T}: PM1 {self.pm01:.1f}, PM2.5 {self.pm25:.1f}, "
139+
f"PM10 {self.pm10:.1f} μg/m3"
140+
)
141+
case "csv":
142+
return (
143+
f"{self.time}, {self.raw01}, {self.raw25}, {self.raw10}, "
144+
f"{self.pm01:.1f}, {self.pm25:.1f}, {self.pm10:.1f}"
145+
)
146+
case "cf":
147+
return (
148+
f"{self.date:%F %T}: CF1 {self.cf01:.0%}, CF2.5 {self.cf25:.0%}, "
149+
f"CF10 {self.cf10:.0%}"
150+
)
151+
case "raw":
152+
return (
153+
f"{self.date:%F %T}: PM1 {self.raw01}, PM2.5 {self.raw25}, "
154+
f"PM10 {self.raw10} μg/m3"
155+
)
153156

154157
return super().__format__(spec)

src/pms/sensors/plantower/pms5003s.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
from dataclasses import dataclass, field
8+
from typing import Literal
89

910
from .. import base
1011
from . import pms3003, pmsx003
@@ -43,11 +44,14 @@ def __post_init__(self):
4344
super().__post_init__()
4445
self.HCHO /= 1000
4546

46-
def __format__(self, spec: str) -> str:
47-
if spec == "csv":
48-
csv = super().__format__(spec)
49-
return f"{csv}, {self.HCHO:.3f}"
50-
if spec == "hcho":
51-
return f"{self.date:%F %T}: HCHO {self.HCHO:.3f} mg/m3"
47+
def __format__(
48+
self, spec: Literal["pm", "raw", "cf", "num", "hcho", "csv", "header"] | str
49+
) -> str:
50+
match spec:
51+
case "csv":
52+
csv = super().__format__(spec)
53+
return f"{csv}, {self.HCHO:.3f}"
54+
case "hcho":
55+
return f"{self.date:%F %T}: HCHO {self.HCHO:.3f} mg/m3"
5256

5357
return super().__format__(spec)

src/pms/sensors/plantower/pms5003st.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import struct
88
from dataclasses import dataclass, field
9+
from typing import Literal
910

1011
from .. import base
1112
from . import pms3003, pms5003s, pmsx003
@@ -64,11 +65,14 @@ def __post_init__(self):
6465
self.temp /= 10
6566
self.rhum /= 10
6667

67-
def __format__(self, spec: str) -> str:
68-
if spec == "csv":
69-
csv = super().__format__(spec)
70-
return f"{csv}, {self.temp:.1f}, {self.rhum:.1f}"
71-
if spec == "atm":
72-
return f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %"
68+
def __format__(
69+
self, spec: Literal["pm", "raw", "cf", "num", "hcho", "atm", "csv", "header"] | str
70+
) -> str:
71+
match spec:
72+
case "csv":
73+
csv = super().__format__(spec)
74+
return f"{csv}, {self.temp:.1f}, {self.rhum:.1f}"
75+
case "atm":
76+
return f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %"
7377

7478
return super().__format__(spec)

src/pms/sensors/plantower/pms5003t.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import struct
88
from dataclasses import dataclass, field
9+
from typing import Literal
910

1011
from pms import InconsistentObservation
1112

@@ -71,19 +72,22 @@ def __post_init__(self):
7172
f"inconsistent obs: PM10={self.pm10} and N0.3={self.n0_3}"
7273
)
7374

74-
def __format__(self, spec: str) -> str:
75-
if spec == "csv":
76-
pm = super().__format__(spec)
77-
return (
78-
f"{pm}, {self.n0_3:.2f}, {self.n0_5:.2f}, {self.n1_0:.2f}, "
79-
f"{self.n2_5:.2f}, {self.temp:.1f}, {self.rhum:.1f}"
80-
)
81-
if spec == "num":
82-
return (
83-
f"{self.date:%F %T}: N0.3 {self.n0_3:.2f}, N0.5 {self.n0_5:.2f}, "
84-
f"N1.0 {self.n1_0:.2f}, N2.5 {self.n2_5:.2f} #/cm3"
85-
)
86-
if spec == "atm":
87-
return f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %"
75+
def __format__(
76+
self, spec: Literal["pm", "raw", "cf", "num", "atm", "csv", "header"] | str
77+
) -> str:
78+
match spec:
79+
case "csv":
80+
pm = super().__format__(spec)
81+
return (
82+
f"{pm}, {self.n0_3:.2f}, {self.n0_5:.2f}, {self.n1_0:.2f}, "
83+
f"{self.n2_5:.2f}, {self.temp:.1f}, {self.rhum:.1f}"
84+
)
85+
case "num":
86+
return (
87+
f"{self.date:%F %T}: N0.3 {self.n0_3:.2f}, N0.5 {self.n0_5:.2f}, "
88+
f"N1.0 {self.n1_0:.2f}, N2.5 {self.n2_5:.2f} #/cm3"
89+
)
90+
case "atm":
91+
return f"{self.date:%F %T}: Temp. {self.temp:.1f} °C, Rel.Hum. {self.rhum:.1f} %"
8892

8993
return super().__format__(spec)

0 commit comments

Comments
 (0)