Skip to content

Commit 85fd08f

Browse files
committed
formatting with ruff
1 parent 274fa59 commit 85fd08f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+698
-766
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ jobs:
3838
pip install -e .
3939
pip install -r requirements-dev.txt
4040
41-
# - name: Lint with ruff
42-
# run: |
43-
# ruff check .
44-
# ruff format --check .
41+
- name: Lint with ruff
42+
run: |
43+
ruff check .
44+
ruff format --check .
4545
4646
- name: Test with pytest
4747
run: |

iglu_python/above_percent.py

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

88

99
def above_percent(
10-
data: Union[pd.DataFrame, pd.Series, list,np.ndarray],
10+
data: Union[pd.DataFrame, pd.Series, list, np.ndarray],
1111
targets_above: List[int] = None,
12-
) -> pd.DataFrame|dict[str:float]:
12+
) -> pd.DataFrame | dict[str:float]:
1313
"""
1414
Calculate percentage of values above target thresholds.
1515
@@ -61,12 +61,11 @@ def above_percent(
6161
# Handle Series input
6262
if targets_above is None:
6363
targets_above = [140, 180, 250]
64-
if isinstance(data, (pd.Series, list,np.ndarray)):
64+
if isinstance(data, (pd.Series, list, np.ndarray)):
6565
if isinstance(data, (list, np.ndarray)):
6666
data = pd.Series(data)
6767
return above_percent_single(data, targets_above)
6868

69-
7069
# Handle DataFrame input
7170
data = check_data_columns(data)
7271
targets_above = [int(t) for t in targets_above]
@@ -83,9 +82,10 @@ def above_percent(
8382

8483
# Convert to DataFrame
8584
df = pd.DataFrame(result)
86-
df = df[['id'] + [col for col in df.columns if col != 'id']]
85+
df = df[["id"] + [col for col in df.columns if col != "id"]]
8786
return df
8887

88+
8989
def above_percent_single(data: pd.Series, targets_above: List[int] = None) -> dict[str:float]:
9090
"""
9191
Calculate percentage of values above target thresholds for a single series/subject.

iglu_python/active_percent.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def active_percent(
1414
range_type: str = "automatic",
1515
ndays: int = 14,
1616
consistent_end_date: Optional[Union[str, datetime]] = None,
17-
) -> pd.DataFrame|dict[str:float]:
17+
) -> pd.DataFrame | dict[str:float]:
1818
"""
1919
Calculate percentage of time CGM was active.
2020
@@ -86,21 +86,16 @@ def active_percent(
8686
# Process each subject
8787
for subject in data["id"].unique():
8888
# Filter data for current subject and remove NA values
89-
sub_data = (
90-
data[data["id"] == subject]
91-
.dropna(subset=["gl", "time"])
92-
.sort_values("time")
93-
)
89+
sub_data = data[data["id"] == subject].dropna(subset=["gl", "time"]).sort_values("time")
9490

9591
timeseries = sub_data.set_index("time")["gl"]
9692
active_percent_dict = active_percent_single(timeseries, dt0, tz, range_type, ndays, consistent_end_date)
9793
active_percent_dict["id"] = subject
9894
active_perc_data.append(active_percent_dict)
9995

100-
10196
# Convert to DataFrame
10297
df = pd.DataFrame(active_perc_data)
103-
df = df[['id'] + [col for col in df.columns if col != 'id']]
98+
df = df[["id"] + [col for col in df.columns if col != "id"]]
10499
return df
105100

106101

@@ -127,9 +122,7 @@ def active_percent_single(
127122
return {"active_percent": 0, "ndays": 0, "start_date": None, "end_date": None}
128123

129124
# Calculate time differences between consecutive measurements
130-
time_diffs = np.array(
131-
data.index.diff().total_seconds() / 60
132-
) # Convert to minutes
125+
time_diffs = np.array(data.index.diff().total_seconds() / 60) # Convert to minutes
133126

134127
# Automatically determine dt0 if not provided
135128
if dt0 is None:
@@ -154,9 +147,7 @@ def active_percent_single(
154147
ndays = (max_time - min_time).total_seconds() / (24 * 3600)
155148

156149
# Calculate active percentage
157-
active_percent = (
158-
(theoretical_gl_vals - missing_gl_vals) / theoretical_gl_vals
159-
) * 100
150+
active_percent = ((theoretical_gl_vals - missing_gl_vals) / theoretical_gl_vals) * 100
160151
elif range_type == "manual":
161152
# Handle consistent end date if provided
162153
if consistent_end_date is not None:
@@ -178,6 +169,3 @@ def active_percent_single(
178169
raise ValueError(f"Invalid range_type: {range_type}")
179170

180171
return {"active_percent": active_percent, "ndays": round(ndays, 1), "start_date": min_time, "end_date": max_time}
181-
182-
183-

iglu_python/adrr.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
21
import numpy as np
32
import pandas as pd
43

54
from .utils import check_data_columns
65

76

8-
def adrr(data: pd.DataFrame|pd.Series) -> pd.DataFrame|float:
7+
def adrr(data: pd.DataFrame | pd.Series) -> pd.DataFrame | float:
98
"""
109
Calculate average daily risk range (ADRR)
1110
@@ -52,7 +51,6 @@ def adrr(data: pd.DataFrame|pd.Series) -> pd.DataFrame|float:
5251
>>> iglu.adrr(data)
5352
"""
5453

55-
5654
# Validate input
5755
if isinstance(data, pd.Series):
5856
if not isinstance(data.index, pd.DatetimeIndex):
@@ -61,15 +59,13 @@ def adrr(data: pd.DataFrame|pd.Series) -> pd.DataFrame|float:
6159

6260
data = check_data_columns(data)
6361

64-
data.set_index("time", inplace=True,drop=True)
65-
out = data.groupby("id").agg(
66-
ADRR = ("gl", lambda x: adrr_single(x))
67-
).reset_index()
62+
data.set_index("time", inplace=True, drop=True)
63+
out = data.groupby("id").agg(ADRR=("gl", lambda x: adrr_single(x))).reset_index()
6864

6965
return out
7066

7167

72-
def adrr_single(data: pd.DataFrame|pd.Series) -> float:
68+
def adrr_single(data: pd.DataFrame | pd.Series) -> float:
7369
"""Internal function to calculate ADRR for a single subject or timeseries of glucose values"""
7470

7571
if isinstance(data, pd.Series):
@@ -85,11 +81,10 @@ def adrr_single(data: pd.DataFrame|pd.Series) -> float:
8581
return np.nan
8682

8783
# Group by date and calculate daily risk for each day
88-
daily_risks = data_filtered.groupby(data_filtered.index.date).apply(
89-
lambda x: _calculate_daily_risk(x)
90-
)
84+
daily_risks = data_filtered.groupby(data_filtered.index.date).apply(lambda x: _calculate_daily_risk(x))
9185
return daily_risks.mean()
9286

87+
9388
def _calculate_daily_risk(gl: pd.Series) -> float:
9489
"""Calculate daily risk range for a single day and subject"""
9590

iglu_python/auc.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import numpy as np
32
import pandas as pd
43

@@ -60,7 +59,7 @@ def auc(data: pd.DataFrame, tz: str = "") -> pd.DataFrame:
6059
if not isinstance(data.index, pd.DatetimeIndex):
6160
raise ValueError("Series must have a DatetimeIndex")
6261

63-
auc = auc_single(data,tz=tz)
62+
auc = auc_single(data, tz=tz)
6463
return auc
6564

6665
# Check data format and convert time to datetime
@@ -70,46 +69,41 @@ def auc(data: pd.DataFrame, tz: str = "") -> pd.DataFrame:
7069
result = []
7170
for subject in data["id"].unique():
7271
subject_data = data[data["id"] == subject]
73-
hourly_auc = auc_single(subject_data,tz=tz)
72+
hourly_auc = auc_single(subject_data, tz=tz)
7473
result.append({"id": subject, "hourly_auc": hourly_auc})
7574

7675
# Convert to DataFrame
7776
return pd.DataFrame(result)
7877

79-
def auc_single(subject_data: pd.DataFrame|pd.Series,tz:str = "") -> float:
78+
79+
def auc_single(subject_data: pd.DataFrame | pd.Series, tz: str = "") -> float:
8080
"""Calculate AUC for a single subject"""
8181
# Get interpolated data using CGMS2DayByDay
8282
gd2d, actual_dates, dt0 = CGMS2DayByDay(subject_data, tz=tz)
8383

8484
# Convert gd2d to DataFrame
8585
input_data = gd2d_to_df(gd2d, actual_dates, dt0)
8686
if is_iglu_r_compatible():
87-
input_data['day'] = input_data['time'].dt.floor('d')
88-
input_data['gl_next'] = input_data['gl'].shift(-1)
87+
input_data["day"] = input_data["time"].dt.floor("d")
88+
input_data["gl_next"] = input_data["gl"].shift(-1)
8989
each_day_area = input_data.groupby("day").apply(
90-
lambda x: np.nansum(
91-
(dt0/60)*(x["gl"].values + x["gl_next"].values) / 2
92-
),
93-
include_groups=False
90+
lambda x: np.nansum((dt0 / 60) * (x["gl"].values + x["gl_next"].values) / 2), include_groups=False
9491
)
9592
# calculate number of not nan trapezoids in total (number of not nan gl and gl_next)
9693
n_trapezoids = (~np.isnan(input_data["gl"]) & ~np.isnan(input_data["gl_next"])).sum()
97-
hours = dt0/60 * n_trapezoids
94+
hours = dt0 / 60 * n_trapezoids
9895
daily_area = each_day_area.sum()
99-
hourly_avg = daily_area/hours
96+
hourly_avg = daily_area / hours
10097
return hourly_avg
10198
else:
10299
# Add hour column by rounding time to nearest hour
103-
input_data['hour'] = input_data['time'].dt.floor('h')
100+
input_data["hour"] = input_data["time"].dt.floor("h")
104101

105-
input_data['gl_next'] = input_data['gl'].shift(-1)
102+
input_data["gl_next"] = input_data["gl"].shift(-1)
106103

107104
# Calculate AUC for each hour using trapezoidal rule (mg*min/dL)
108105
hourly_auc = input_data.groupby("hour").apply(
109-
lambda x: np.nansum(
110-
(dt0/60)*(x["gl"].values + x["gl_next"].values) / 2
111-
),
112-
include_groups=False
106+
lambda x: np.nansum((dt0 / 60) * (x["gl"].values + x["gl_next"].values) / 2), include_groups=False
113107
)
114108
# 0 mean no data in this hour, replace with nan
115109
hourly_auc = hourly_auc.replace(0, np.nan)

iglu_python/below_percent.py

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

88

99
def below_percent(
10-
data: Union[pd.DataFrame, pd.Series, list,np.ndarray], targets_below: List[int] = None
11-
) -> pd.DataFrame|dict[str:float]:
10+
data: Union[pd.DataFrame, pd.Series, list, np.ndarray], targets_below: List[int] = None
11+
) -> pd.DataFrame | dict[str:float]:
1212
"""
1313
Calculate percentage of values below target thresholds.
1414
@@ -60,12 +60,11 @@ def below_percent(
6060
# Handle Series input
6161
if targets_below is None:
6262
targets_below = [54, 70]
63-
if isinstance(data, (pd.Series, list,np.ndarray)):
63+
if isinstance(data, (pd.Series, list, np.ndarray)):
6464
if isinstance(data, (list, np.ndarray)):
6565
data = pd.Series(data)
6666
return below_percent_single(data, targets_below)
6767

68-
6968
# Handle DataFrame input
7069
data = check_data_columns(data)
7170

@@ -82,9 +81,10 @@ def below_percent(
8281

8382
# Convert to DataFrame
8483
df = pd.DataFrame(result)
85-
df = df[['id'] + [col for col in df.columns if col != 'id']]
84+
df = df[["id"] + [col for col in df.columns if col != "id"]]
8685
return df
8786

87+
8888
def below_percent_single(data: pd.Series, targets_below: List[int] = None) -> dict[str:float]:
8989
"""
9090
Calculate percentage of values below target thresholds for a single series/subject.
@@ -106,4 +106,3 @@ def below_percent_single(data: pd.Series, targets_below: List[int] = None) -> di
106106
percentages[f"below_{target}"] = (below_count / total_readings) * 100
107107

108108
return percentages
109-

iglu_python/cogi.py

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

1111

1212
def cogi(
13-
data: Union[pd.DataFrame, pd.Series, list,np.ndarray],
13+
data: Union[pd.DataFrame, pd.Series, list, np.ndarray],
1414
targets: List[int] = None,
1515
weights: List[float] = None,
16-
) -> pd.DataFrame|float:
16+
) -> pd.DataFrame | float:
1717
"""
1818
Calculate Coefficient of Glucose Irregularity (COGI).
1919
@@ -81,12 +81,11 @@ def cogi(
8181

8282
data = check_data_columns(data)
8383

84-
out = data.groupby("id").agg(
85-
COGI=('gl', lambda x: cogi_single(x, targets, weights))
86-
).reset_index()
84+
out = data.groupby("id").agg(COGI=("gl", lambda x: cogi_single(x, targets, weights))).reset_index()
8785

8886
return out
8987

88+
9089
def cogi_single(data: pd.Series, targets: List[int] = None, weights: List[float] = None) -> float:
9190
"""Calculate COGI for a single subject"""
9291
# Calculate components
@@ -110,7 +109,6 @@ def cogi_single(data: pd.Series, targets: List[int] = None, weights: List[float]
110109
return weighted_features * 100 # Convert to percentage
111110

112111

113-
114112
def weight_features(
115113
feature: Union[float, pd.Series, list],
116114
scale_range: List[float],
@@ -122,26 +120,19 @@ def weight_features(
122120
with the same number of rows (or length) as the input, with values clipped
123121
(or "inverse" clipped) so that they are between 0 and 1."""
124122
if isinstance(feature, pd.Series):
125-
scaled = (feature - min(scale_range)) / (
126-
max(scale_range) - min(scale_range)
127-
)
123+
scaled = (feature - min(scale_range)) / (max(scale_range) - min(scale_range))
128124
if increasing:
129125
out = scaled.clip(lower=0, upper=1)
130126
else:
131127
out = (1 - scaled).clip(lower=0, upper=1)
132128
elif isinstance(feature, list):
133-
scaled = [
134-
(x - min(scale_range)) / (max(scale_range) - min(scale_range))
135-
for x in feature
136-
]
129+
scaled = [(x - min(scale_range)) / (max(scale_range) - min(scale_range)) for x in feature]
137130
if increasing:
138131
out = [min(1, max(0, x)) for x in scaled]
139132
else:
140133
out = [min(1, max(0, 1 - x)) for x in scaled]
141134
else:
142-
scaled = (feature - min(scale_range)) / (
143-
max(scale_range) - min(scale_range)
144-
)
135+
scaled = (feature - min(scale_range)) / (max(scale_range) - min(scale_range))
145136
if increasing:
146137
out = min(1, max(0, scaled))
147138
else:

iglu_python/conga.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
from .utils import CGMS2DayByDay, check_data_columns
77

88

9-
def conga(
10-
data: Union[pd.DataFrame, pd.Series], n: int = 24, tz: str = ""
11-
) -> pd.DataFrame|float:
9+
def conga(data: Union[pd.DataFrame, pd.Series], n: int = 24, tz: str = "") -> pd.DataFrame | float:
1210
"""
1311
Calculate Continuous Overall Net Glycemic Action (CONGA).
1412
@@ -69,14 +67,13 @@ def conga(
6967
data = check_data_columns(data)
7068

7169
# Calculate CONGA for each subject
72-
data.set_index("time", inplace=True,drop=True)
73-
out = data.groupby('id').agg(
74-
CONGA = ("gl", lambda x: conga_single(x, hours=n, tz=tz))
75-
).reset_index()
70+
data.set_index("time", inplace=True, drop=True)
71+
out = data.groupby("id").agg(CONGA=("gl", lambda x: conga_single(x, hours=n, tz=tz))).reset_index()
7672

7773
return out
7874

79-
def conga_single(data: pd.DataFrame|pd.Series, hours: int = 1, tz: str = "") -> float:
75+
76+
def conga_single(data: pd.DataFrame | pd.Series, hours: int = 1, tz: str = "") -> float:
8077
"""Calculate CONGA for a single subject"""
8178
# Convert data to day-by-day format
8279
# Missing values will be linearly interpolated when close enough to non-missing values.

iglu_python/cv_glu.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ def cv_glu(data: Union[pd.DataFrame, pd.Series, list, np.ndarray]) -> Union[pd.D
5656

5757
data = data.dropna()
5858
# Calculate CV for each subject
59-
out = data.groupby('id').agg(
60-
CV=('gl', lambda x: 100 * x.std() / x.mean())
61-
).reset_index()
59+
out = data.groupby("id").agg(CV=("gl", lambda x: 100 * x.std() / x.mean())).reset_index()
6260

6361
return out

0 commit comments

Comments
 (0)