Skip to content

Commit 97ec39c

Browse files
committed
Merge branch 'main' into change-smooth-refactor
2 parents bb88f24 + 6681a47 commit 97ec39c

File tree

30 files changed

+424
-362
lines changed

30 files changed

+424
-362
lines changed

.github/CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ git checkout -b dev-my-feature-branch
6161

6262
### Creating your indicator
6363

64-
Create a directory for your new indicator by making a copy of `_template_r` or `_template_python` depending on the programming language you intend to use. The template copies of `README.md` and `REVIEW.md` include the minimum requirements for code structure, documentation, linting, testing, and method of configuration. Beyond that, we don't have any established restrictions on implementation; you can look at other existing indicators see some examples of code layout, organization, and general approach.
64+
Create a directory for your new indicator by making a copy of `_template_r` or `_template_python` depending on the programming language you intend to use. If using Python, add the name of the directory to the list found in `jobs > build > strategy > matrix > packages` in `.github/workflows/python-ci.yml`, which will enable automated checks for your indicator when you make PRs. The template copies of `README.md` and `REVIEW.md` include the minimum requirements for code structure, documentation, linting, testing, and method of configuration. Beyond that, we don't have any established restrictions on implementation; you can look at other existing indicators see some examples of code layout, organization, and general approach.
6565

6666
- Consult your peers with questions! :handshake:
6767

.github/pull_request_template.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
### Description
2+
Type of change (bug fix, new feature, etc), brief description, and motivation for these changes.
3+
4+
### Changelog
5+
- change1
6+
- change2
7+
8+
### Fixes
9+
- Fixes #(issue)

.github/workflows/python-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
push:
88
branches: [ main ]
99
pull_request:
10-
types: [ opened, synchronized, reopened, ready_for_review ]
10+
types: [ opened, synchronize, reopened, ready_for_review ]
1111
branches: [ main ]
1212

1313
jobs:

_delphi_utils_python/delphi_utils/archive.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ def run_module(archive_type: str,
104104
Parameters
105105
----------
106106
archive_type: str
107-
Type of ArchiveDiffer to run. Must be one of ["git", "s3"] which correspond to `GitArchiveDiffer` and `S3ArchiveDiffer`, respectively.
107+
Type of ArchiveDiffer to run. Must be one of ["git", "s3"] which correspond to
108+
`GitArchiveDiffer` and `S3ArchiveDiffer`, respectively.
108109
cache_dir: str
109110
The directory for storing most recent archived/uploaded CSVs to start diffing from.
110111
export_dir: str
@@ -351,7 +352,7 @@ def update_cache(self):
351352

352353
self._cache_updated = True
353354

354-
def archive_exports(self,
355+
def archive_exports(self, # pylint: disable=arguments-differ
355356
exported_files: Files,
356357
update_cache: bool = True,
357358
update_s3: bool = True

_delphi_utils_python/delphi_utils/export.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Export data in the format expected by the Delphi API."""
12
# -*- coding: utf-8 -*-
23
from datetime import datetime
34
from os.path import join

_delphi_utils_python/delphi_utils/geomap.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- remove deprecated functions once integration into JHU and Quidel is refactored
1010
see: https://github.com/cmu-delphi/covidcast-indicators/issues/283
1111
"""
12-
12+
# pylint: disable=too-many-lines
1313
from os.path import join
1414
import warnings
1515
import pkg_resources
@@ -41,7 +41,7 @@
4141
}
4242

4343

44-
class GeoMapper:
44+
class GeoMapper: # pylint: disable=too-many-public-methods
4545
"""Geo mapping tools commonly used in Delphi.
4646
4747
The GeoMapper class provides utility functions for translating between different
@@ -301,7 +301,7 @@ def add_geocode(
301301
df[from_col] = df[from_col].astype(str)
302302

303303
# Assuming that the passed-in records are all United States data, at the moment
304-
if (from_code, new_code) in [("fips", "nation"), ("zip", "nation")]:
304+
if (from_code, new_code) in [("fips", "nation"), ("zip", "nation")]: # pylint: disable=no-else-return
305305
df[new_col] = df[from_col].apply(lambda x: "us")
306306
return df
307307
elif new_code == "nation":
@@ -724,7 +724,7 @@ def convert_state_code_to_state_id(
724724
)
725725

726726
state_table = self._load_crosswalk(from_code="state", to_code="state")
727-
state_table = state_table[["state_code", "state_id"]].rename(
727+
state_table = state_table[["state_code", "state_id"]].rename( # pylint: disable=unsubscriptable-object
728728
columns={"state_id": state_id_col}
729729
)
730730
data = data.copy()
@@ -796,7 +796,7 @@ def convert_zip_to_hrr(self, data, zip_col="zip", hrr_col="hrr"):
796796
return data
797797

798798
def convert_zip_to_msa(
799-
self, data, zip_col="zip", msa_col="msa", date_col="date", count_cols=None
799+
self, data, zip_col="zip", date_col="date", count_cols=None
800800
):
801801
"""DEPRECATED."""
802802
warnings.warn(
@@ -828,7 +828,6 @@ def zip_to_msa(
828828
data = self.convert_zip_to_msa(
829829
data,
830830
zip_col=zip_col,
831-
msa_col=msa_col,
832831
date_col=date_col,
833832
count_cols=count_cols,
834833
)

_delphi_utils_python/delphi_utils/smooth.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import pandas as pd
1919

2020

21-
class Smoother:
21+
class Smoother: # pylint: disable=too-many-instance-attributes
2222
"""Smoother class.
2323
2424
This is the smoothing utility class. This class holds the parameter settings for its smoother
@@ -78,8 +78,8 @@ class Smoother:
7878
Methods
7979
----------
8080
smooth: np.ndarray or pd.Series
81-
Takes a 1D signal and returns a smoothed version. The input and the output have the same
82-
length and type.
81+
Takes a 1D signal and returns a smoothed version.
82+
The input and the output have the same length and type.
8383
8484
Example Usage
8585
-------------
@@ -260,20 +260,21 @@ def left_gauss_linear_smoother(self, signal):
260260
)
261261
n = len(signal)
262262
signal_smoothed = np.zeros_like(signal)
263-
A = np.vstack([np.ones(n), np.arange(n)]).T # the regression design matrix
263+
# A is the regression design matrix
264+
A = np.vstack([np.ones(n), np.arange(n)]).T # pylint: disable=invalid-name
264265
for idx in range(n):
265266
weights = np.exp(
266267
-((np.arange(idx + 1) - idx) ** 2) / self.gaussian_bandwidth
267268
)
268-
AwA = np.dot(A[: (idx + 1), :].T * weights, A[: (idx + 1), :])
269-
Awy = np.dot(
269+
AwA = np.dot(A[: (idx + 1), :].T * weights, A[: (idx + 1), :]) # pylint: disable=invalid-name
270+
Awy = np.dot( # pylint: disable=invalid-name
270271
A[: (idx + 1), :].T * weights, signal[: (idx + 1)].reshape(-1, 1)
271272
)
272273
try:
273274
beta = np.linalg.solve(AwA, Awy)
274275
signal_smoothed[idx] = np.dot(A[: (idx + 1), :], beta)[-1]
275276
except np.linalg.LinAlgError:
276-
signal_smoothed[idx] = signal[idx] if self.impute else np.nan
277+
signal_smoothed[idx] = signal[idx] if self.impute else np.nan # pylint: disable=using-constant-test
277278
if self.minval is not None:
278279
signal_smoothed[signal_smoothed <= self.minval] = self.minval
279280
return signal_smoothed
@@ -336,7 +337,7 @@ def savgol_coeffs(self, nl, nr):
336337
if nr > 0:
337338
raise warnings.warn("The filter is no longer causal.")
338339

339-
A = np.vstack(
340+
A = np.vstack( # pylint: disable=invalid-name
340341
[np.arange(nl, nr + 1) ** j for j in range(self.poly_fit_degree + 1)]
341342
).T
342343

@@ -380,7 +381,7 @@ def savgol_smoother(self, signal):
380381
# - shortened_window (default) applies savgol with a smaller window to do the fit
381382
# - identity keeps the original signal (doesn't smooth)
382383
# - nan writes nans
383-
if self.boundary_method == "shortened_window":
384+
if self.boundary_method == "shortened_window": # pylint: disable=no-else-return
384385
for ix in range(len(self.coeffs)):
385386
if ix == 0:
386387
signal_smoothed[ix] = signal[ix]

_delphi_utils_python/delphi_utils/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Read parameter files containing configuration information."""
12
# -*- coding: utf-8 -*-
23
from json import load
34
from os.path import exists

_delphi_utils_python/tests/test_signal.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Tests for delphi_utils.signal."""
22
from unittest.mock import patch
3-
import pandas as pd
43

4+
import pandas as pd
5+
import pytest
56
from delphi_utils.signal import add_prefix, public_signal
67

78
# Constants for mocking out the call to `covidcast.metadata` within `public_signal()`.
@@ -14,12 +15,17 @@ class TestSignal:
1415
def test_add_prefix_to_all(self):
1516
"""Tests that `add_prefix()` derives work-in-progress names for all input signals."""
1617
assert add_prefix(["sig1", "sig3"], True, prefix="wip_") == ["wip_sig1", "wip_sig3"]
17-
18+
1819
def test_add_prefix_to_specified(self):
1920
"""Tests that `add_prefix()` derives work-in-progress names for specified signals."""
2021
assert add_prefix(["sig1", "sig2", "sig3"], ["sig2"], prefix="wip_") ==\
2122
["sig1", "wip_sig2", "sig3"]
22-
23+
24+
def test_invalid_prefix_input(self):
25+
"""Tests that `add_prefix()` raises a ValueError when invalid input is given."""
26+
with pytest.raises(ValueError):
27+
add_prefix(None, None)
28+
2329
@patch("covidcast.metadata")
2430
def test_add_prefix_to_non_public(self, metadata):
2531
"""Tests that `add_prefix()` derives work-in-progress names for non-public signals."""

_template_python/README.md

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
The indicator is run by directly executing the Python module contained in this
88
directory. The safest way to do this is to create a virtual environment,
99
installed the common DELPHI tools, and then install the module and its
10-
dependencies. To do this, run the following code from this directory:
10+
dependencies. To do this, run the following command from this directory:
1111

1212
```
13-
python -m venv env
14-
source env/bin/activate
15-
pip install ../_delphi_utils_python/.
16-
pip install .
13+
make install
1714
```
1815

16+
This command will install the package in editable mode, so you can make changes that
17+
will automatically propagate to the installed package.
18+
1919
All of the user-changable parameters are stored in `params.json`. To execute
2020
the module and produce the output datasets (by default, in `receiving`), run
2121
the following:
@@ -24,34 +24,39 @@ the following:
2424
env/bin/python -m delphi_NAME
2525
```
2626

27-
Once you are finished with the code, you can deactivate the virtual environment
28-
and (optionally) remove the environment itself.
27+
If you want to enter the virtual environment in your shell,
28+
you can run `source env/bin/activate`. Run `deactivate` to leave the virtual environment.
29+
30+
Once you are finished, you can remove the virtual environment and
31+
params file with the following:
2932

3033
```
31-
deactivate
32-
rm -r env
34+
make clean
3335
```
3436

3537
## Testing the code
3638

37-
To do a static test of the code style, it is recommended to run **pylint** on
38-
the module. To do this, run the following from the main module directory:
39+
To run static tests of the code style, run the following command:
3940

4041
```
41-
env/bin/pylint delphi_NAME
42+
make lint
4243
```
4344

44-
The most aggressive checks are turned off; only relatively important issues
45-
should be raised and they should be manually checked (or better, fixed).
46-
4745
Unit tests are also included in the module. To execute these, run the following
4846
command from this directory:
4947

5048
```
51-
(cd tests && ../env/bin/pytest --cov=delphi_NAME --cov-report=term-missing)
49+
make test
50+
```
51+
52+
To run individual tests, run the following:
53+
54+
```
55+
(cd tests && ../env/bin/pytest <your_test>.py --cov=delphi_NAME --cov-report=term-missing)
5256
```
5357

5458
The output will show the number of unit tests that passed and failed, along
55-
with the percentage of code covered by the tests. None of the tests should
56-
fail and the code lines that are not covered by unit tests should be small and
57-
should not include critical sub-routines.
59+
with the percentage of code covered by the tests.
60+
61+
None of the linting or unit tests should fail, and the code lines that are not covered by unit tests should be small and
62+
should not include critical sub-routines.

cdc_covidnet/README.md

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ installed the common DELPHI tools, and then install the module and its
1010
dependencies. To do this, run the following code from this directory:
1111

1212
```
13-
python -m venv env
14-
source env/bin/activate
15-
pip install ../_delphi_utils_python/.
16-
pip install .
13+
make install
1714
```
1815

16+
This command will install the package in editable mode, so you can make changes that
17+
will automatically propagate to the installed package.
18+
1919
All of the user-changable parameters are stored in `params.json`.
2020

2121
The module has to request for each participating state's hospitalization data
@@ -32,35 +32,39 @@ the following:
3232
env/bin/python -m delphi_cdc_covidnet
3333
```
3434

35-
Once you are finished with the code, you can deactivate the virtual environment
36-
and (optionally) remove the environment itself.
35+
If you want to enter the virtual environment in your shell,
36+
you can run `source env/bin/activate`. Run `deactivate` to leave the virtual environment.
37+
38+
Once you are finished, you can remove the virtual environment and
39+
params file with the following:
3740

3841
```
39-
deactivate
40-
rm -r env
42+
make clean
4143
```
4244

4345
## Testing the code
4446

45-
To do a static test of the code style, it is recommended to run **pylint** on
46-
the module. To do this, run the following from the main module directory:
47+
To run static tests of the code style, run the following command:
4748

4849
```
49-
env/bin/pylint delphi_cdc_covidnet
50+
make lint
5051
```
5152

52-
The most aggressive checks are turned off; only relatively important issues
53-
should be raised and they should be manually checked (or better, fixed).
54-
5553
Unit tests are also included in the module. To execute these, run the following
5654
command from this directory:
57-
(Note: the following command requires python 3.8, having any version less than 3.8 might
58-
fail some test cases. Please install it before running.)
55+
5956
```
60-
(cd tests && ../env/bin/pytest --cov=delphi_cdc_covidnet --cov-report=term-missing)
57+
make test
58+
```
59+
60+
To run individual tests, run the following:
61+
62+
```
63+
(cd tests && ../env/bin/pytest <your_test>.py --cov=delphi_cdc_covidnet --cov-report=term-missing)
6164
```
6265

6366
The output will show the number of unit tests that passed and failed, along
64-
with the percentage of code covered by the tests. None of the tests should
65-
fail and the code lines that are not covered by unit tests should be small and
66-
should not include critical sub-routines.
67+
with the percentage of code covered by the tests.
68+
69+
None of the linting or unit tests should fail, and the code lines that are not covered by unit tests should be small and
70+
should not include critical sub-routines.

0 commit comments

Comments
 (0)