Skip to content

Commit

Permalink
chore: add ruff checks for python builtins, code A
Browse files Browse the repository at this point in the history
  • Loading branch information
tomjholland committed Feb 23, 2025
1 parent e9b5b91 commit f89dfd9
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 54 deletions.
2 changes: 1 addition & 1 deletion pyprobe/analysis/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def assemble_array(input_data: List[Result], name: str) -> NDArray[Any]:
Returns:
NDArray: The assembled array.
"""
return np.vstack([input.get(name) for input in input_data])
return np.vstack([input_item.get(name) for input_item in input_data])


class AnalysisValidator(BaseModel):
Expand Down
6 changes: 3 additions & 3 deletions pyprobe/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,10 +535,10 @@ def archive(self, path: str) -> None:
path (str): The path to the archive directory or zip file.
"""
if path.endswith(".zip"):
zip = True
zip_file = True
path = path[:-4]
else:
zip = False
zip_file = False
if not os.path.exists(path):
os.makedirs(path)
metadata = self.dict()
Expand All @@ -557,7 +557,7 @@ def archive(self, path: str) -> None:
with open(os.path.join(path, "metadata.json"), "w") as f:
json.dump(metadata, f)

if zip:
if zip_file:
with zipfile.ZipFile(path + ".zip", "w") as zipf:
for root, _, files in os.walk(path):
for file in files:
Expand Down
12 changes: 7 additions & 5 deletions pyprobe/cyclers/basecycler.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,15 +408,17 @@ def _get_dataframe_list(self) -> list[pl.DataFrame | pl.LazyFrame]:
"""
files = glob.glob(self.input_data_path)
files.sort()
list = [self.read_file(file, self.header_row_index) for file in files]
all_columns = set([col for df in list for col in df.collect_schema().names()])
for i in range(len(list)):
if len(list[i].collect_schema().names()) < len(all_columns):
df_list = [self.read_file(file, self.header_row_index) for file in files]
all_columns = set(
[col for df in df_list for col in df.collect_schema().names()]
)
for i in range(len(df_list)):
if len(df_list[i].collect_schema().names()) < len(all_columns):
logger.warning(
f"File {os.path.basename(files[i])} has missing columns, "
"these have been filled with null values."
)
return list
return df_list

def get_imported_dataframe(
self, dataframe_list: List[pl.DataFrame]
Expand Down
88 changes: 49 additions & 39 deletions pyprobe/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ def _filter_numerical(


def _step(
filter: "FilterToCycleType",
filtered_object: "FilterToCycleType",
*step_numbers: Union[int, range],
condition: Optional[pl.Expr] = None,
) -> "Step":
"""Return a step object. Filters to a numerical condition on the Event column.
Args:
filter (FilterToCycleType): A filter object that this method is called on.
filtered_object (FilterToCycleType): A filter object that this method is called on.
step_numbers (int | range):
Variable-length argument list of step indices or a range object.
condition (pl.Expr, optional):
Expand All @@ -82,19 +82,23 @@ def _step(
"""
if condition is not None:
base_dataframe = _filter_numerical(
filter.live_dataframe.filter(condition), "Event", step_numbers
filtered_object.live_dataframe.filter(condition), "Event", step_numbers
)
else:
base_dataframe = _filter_numerical(filter.live_dataframe, "Event", step_numbers)
base_dataframe = _filter_numerical(
filtered_object.live_dataframe, "Event", step_numbers
)
return Step(
base_dataframe=base_dataframe,
info=filter.info,
column_definitions=filter.column_definitions,
step_descriptions=filter.step_descriptions,
info=filtered_object.info,
column_definitions=filtered_object.column_definitions,
step_descriptions=filtered_object.step_descriptions,
)


def get_cycle_column(filter: "FilterToCycleType") -> pl.DataFrame | pl.LazyFrame:
def get_cycle_column(
filtered_object: "FilterToCycleType",
) -> pl.DataFrame | pl.LazyFrame:
"""Adds a cycle column to the data.
If cycle details have been provided in the README, the cycle column will be created
Expand All @@ -107,14 +111,14 @@ def get_cycle_column(filter: "FilterToCycleType") -> pl.DataFrame | pl.LazyFrame
number.
Args:
filter: The experiment or cycle object.
filtered_object: The experiment or cycle object.
Returns:
pl.DataFrame | pl.LazyFrame: The data with a cycle column.
"""
if len(filter.cycle_info) > 0:
cycle_ends = (pl.col("Step").shift() == filter.cycle_info[0][1]) & (
pl.col("Step") != filter.cycle_info[0][1]
if len(filtered_object.cycle_info) > 0:
cycle_ends = (pl.col("Step").shift() == filtered_object.cycle_info[0][1]) & (
pl.col("Step") != filtered_object.cycle_info[0][1]
).fill_null(strategy="zero").cast(pl.Int16)
cycle_column = cycle_ends.cum_sum().fill_null(strategy="zero").alias("Cycle")
else:
Expand All @@ -128,79 +132,83 @@ def get_cycle_column(filter: "FilterToCycleType") -> pl.DataFrame | pl.LazyFrame
.cum_sum()
.alias("Cycle")
)
return filter.live_dataframe.with_columns(cycle_column)
return filtered_object.live_dataframe.with_columns(cycle_column)


def _cycle(filter: "ExperimentOrCycleType", *cycle_numbers: Union[int]) -> "Cycle":
def _cycle(
filtered_object: "ExperimentOrCycleType", *cycle_numbers: Union[int]
) -> "Cycle":
"""Return a cycle object. Filters on the Cycle column.
Args:
filter (FilterToExperimentType): A filter object that this method is called on.
filtered_object (FilterToExperimentType): A filter object that this method is called on.
cycle_numbers (int | range):
Variable-length argument list of cycle indices or a range object.
Returns:
Cycle: A cycle object.
"""
df = get_cycle_column(filter)
df = get_cycle_column(filtered_object)

if len(filter.cycle_info) > 1:
next_cycle_info = filter.cycle_info[1:]
if len(filtered_object.cycle_info) > 1:
next_cycle_info = filtered_object.cycle_info[1:]
else:
next_cycle_info = []

lf_filtered = _filter_numerical(df, "Cycle", cycle_numbers)

return Cycle(
base_dataframe=lf_filtered,
info=filter.info,
column_definitions=filter.column_definitions,
step_descriptions=filter.step_descriptions,
info=filtered_object.info,
column_definitions=filtered_object.column_definitions,
step_descriptions=filtered_object.step_descriptions,
cycle_info=next_cycle_info,
)


def _charge(filter: "FilterToCycleType", *charge_numbers: Union[int, range]) -> "Step":
def _charge(
filtered_object: "FilterToCycleType", *charge_numbers: Union[int, range]
) -> "Step":
"""Return a charge step.
Args:
filter (FilterToCycleType): A filter object that this method is called on.
filtered_object (FilterToCycleType): A filter object that this method is called on.
charge_numbers (int | range):
Variable-length argument list of charge indices or a range object.
Returns:
Step: A charge step object.
"""
condition = pl.col("Current [A]") > pl.col("Current [A]").abs().max() / 10e4
return filter.step(*charge_numbers, condition=condition)
return filtered_object.step(*charge_numbers, condition=condition)


def _discharge(
filter: "FilterToCycleType",
filtered_object: "FilterToCycleType",
*discharge_numbers: Union[int, range],
) -> "Step":
"""Return a discharge step.
Args:
filter (FilterToCycleType): A filter object that this method is called on.
filtered_object (FilterToCycleType): A filter object that this method is called on.
discharge_numbers (int | range):
Variable-length argument list of discharge indices or a range object.
Returns:
Step: A discharge step object.
"""
condition = pl.col("Current [A]") < -pl.col("Current [A]").abs().max() / 10e4
return filter.step(*discharge_numbers, condition=condition)
return filtered_object.step(*discharge_numbers, condition=condition)


def _chargeordischarge(
filter: "FilterToCycleType",
filtered_object: "FilterToCycleType",
*chargeordischarge_numbers: Union[int, range],
) -> "Step":
"""Return a charge or discharge step.
Args:
filter (FilterToCycleType): A filter object that this method is called on.
filtered_object (FilterToCycleType): A filter object that this method is called on.
chargeordischarge_numbers (int | range):
Variable-length argument list of charge or discharge indices or a range
object.
Expand All @@ -213,32 +221,34 @@ def _chargeordischarge(
pl.col("Current [A]") < -pl.col("Current [A]").abs().max() / 10e4
)
condition = charge_condition | discharge_condition
return filter.step(*chargeordischarge_numbers, condition=condition)
return filtered_object.step(*chargeordischarge_numbers, condition=condition)


def _rest(filter: "FilterToCycleType", *rest_numbers: Union[int, range]) -> "Step":
def _rest(
filtered_object: "FilterToCycleType", *rest_numbers: Union[int, range]
) -> "Step":
"""Return a rest step object.
Args:
filter (FilterToCycleType): A filter object that this method is called on.
filtered_object (FilterToCycleType): A filter object that this method is called on.
rest_numbers (int | range):
Variable-length argument list of rest indices or a range object.
Returns:
Step: A rest step object.
"""
condition = pl.col("Current [A]") == 0
return filter.step(*rest_numbers, condition=condition)
return filtered_object.step(*rest_numbers, condition=condition)


def _constant_current(
filter: "FilterToCycleType",
filtered_object: "FilterToCycleType",
*constant_current_numbers: Union[int, range],
) -> "Step":
"""Return a constant current step object.
Args:
filter (FilterToCycleType): A filter object that this method is called on.
filtered_object (FilterToCycleType): A filter object that this method is called on.
constant_current_numbers (int | range):
Variable-length argument list of constant current indices or a range object.
Expand All @@ -256,17 +266,17 @@ def _constant_current(
< 1.001 * pl.col("Current [A]").abs().round_sig_figs(4).mode()
)
)
return filter.step(*constant_current_numbers, condition=condition)
return filtered_object.step(*constant_current_numbers, condition=condition)


def _constant_voltage(
filter: "FilterToCycleType",
filtered_object: "FilterToCycleType",
*constant_voltage_numbers: Union[int, range],
) -> "Step":
"""Return a constant voltage step object.
Args:
filter: A filter object that this method is called on.
filtered_object: A filter object that this method is called on.
*constant_voltage_numbers:
Variable-length argument list of constant voltage indices or a range object.
Expand All @@ -280,7 +290,7 @@ def _constant_voltage(
pl.col("Voltage [V]").abs()
< 1.001 * pl.col("Voltage [V]").abs().round_sig_figs(4).mode()
)
return filter.step(*constant_voltage_numbers, condition=condition)
return filtered_object.step(*constant_voltage_numbers, condition=condition)


class Procedure(RawData):
Expand Down
8 changes: 4 additions & 4 deletions pyprobe/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

def configure_logging(
level: str | int = logging.WARNING,
format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
str_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
log_file: Optional[str] = None,
) -> None:
"""Configure the logging level, format, and handlers for the PyProBE package.
Args:
level: The logging level.
format: The logging format.
str_format: The logging format.
log_file: The log file to write to. By default, no file is written.
"""
# Create a root logger
Expand All @@ -26,12 +26,12 @@ def configure_logging(
# Create a console handler
console_handler = logging.StreamHandler()
console_handler.setLevel(level)
console_handler.setFormatter(logging.Formatter(format))
console_handler.setFormatter(logging.Formatter(str_format))
root_logger.addHandler(console_handler)

# Optionally create a file handler
if log_file is not None:
file_handler = logging.FileHandler(log_file)
file_handler.setLevel(level)
file_handler.setFormatter(logging.Formatter(format))
file_handler.setFormatter(logging.Formatter(str_format))
root_logger.addHandler(file_handler)
8 changes: 7 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,18 @@ match = "main"
prerelease = false

[tool.ruff.lint]
select = ["D", "I001"]
select = [
"A", # flake8-builtins: Check for Python builtins being used as variables or parameters
"D", # flake8-docstrings: Check docstrings
"I", # isort: Check and enforce import ordering
]

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.per-file-ignores]
"docs/source/conf.py" = ["A"]
"tests/*" = ["SLF001"]
"docs/source/examples/*" = ["D103"]

[tool.mypy]
Expand Down
2 changes: 1 addition & 1 deletion tests/test_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def test_configure_logging_custom_level():
def test_configure_logging_custom_format():
"""Test logging configuration with a custom format."""
custom_format = "%(levelname)s - %(message)s"
configure_logging(format=custom_format)
configure_logging(str_format=custom_format)
root_logger = logging.getLogger()
assert isinstance(root_logger.handlers[0].formatter, logging.Formatter)
assert root_logger.handlers[0].formatter._fmt == custom_format
Expand Down

0 comments on commit f89dfd9

Please sign in to comment.