refactor: extract filter_by_anzsic_prefixes() shared helper#200
refactor: extract filter_by_anzsic_prefixes() shared helper#200martinguthrie93 wants to merge 5 commits into
Conversation
Replace identical ANZSIC prefix filtering in NPI, Safeguard, and oil and gas site sources with a single function in safeguard/anzsic.py. No change to emission calculations or filtering behaviour. Co-authored-by: Cursor <cursoragent@cursor.com>
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
aethr
left a comment
There was a problem hiding this comment.
Change seems reasonable, but if we're going to make an abstraction/helper it has a higher burden of testing and documentation than something in a function body that isn't meant to be re-used.
Happy to accept this PR if we add a bit more diverse testing and documentation around the new function.
| df = pd.DataFrame({"anzsic_code": ["0600", "1212", "0700", "9999"]}) | ||
| filtered = filter_by_anzsic_prefixes(df, ["06", "07"], column="anzsic_code") | ||
| assert list(filtered["anzsic_code"]) == ["0600", "0700"] |
There was a problem hiding this comment.
I would suggest broadening this test to cover more complex matching. ANZSIC code "0600" and "06" are equivalent so that's a clear match. "0700" and "07" are similar, so adding them doesn't really broaden the coverage of the test.
For example, filtering by "06" should match:
- 06
- 060
- 0600
- 061
- 0612
Filtering by "202" might be more nuanced:
- match "202"
- match "2021"
- match "2029"
- doesn't match "20"
- doesn't match "201"
- doesn't match "22"
- etc
There was a problem hiding this comment.
Do any of the new tests actually test the prefix shortening? Might be good to explicitly have something for anzsic_codes: ["2000"] matching "2021", etc?
| *, | ||
| column: str, | ||
| ) -> pd.DataFrame: | ||
| """Return rows whose ``column`` value starts with any simplified ANZSIC prefix.""" |
There was a problem hiding this comment.
The ANZSIC classification scheme doesn't use the word "prefix", so if the aim is to make a helper that's more approachable we should try to use the right terminology. Since the anzsic_codes argument supports subdivision, group or class-level codes, I would probably call this something like filter_by_anzsic_code_family.
Providing at least one example for anzsic_codes and what resulting codes would match might be a good addition.
|
The failure in the Build docker image step is expected, since this is an external PR we don't want it to push images to our hosted packages. |
Use ANZSIC code family terminology, expand unit tests, and document matching examples in the helper docstring. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Thanks for the review @aethr — addressed in ffc08a8:
All ANZSIC unit tests pass locally. Ready for re-review. |
|
Hi @aethr — thank you for the thoughtful review. I have pushed
All ANZSIC tests pass locally. I also read your note that the Docker build failure is expected for external PRs. That makes sense. If possible, could the workflow be adjusted so fork PRs skip the Ready for re-review — thanks again! |
Raised in issue #201. This is possibly the first external PR to this repo, so not something we've run into before! |
aethr
left a comment
There was a problem hiding this comment.
One small nitpick but otherwise looks good.
| Each entry in ``anzsic_codes`` may be a division, subdivision, group, or class | ||
| code. Codes are simplified (trailing zeros removed) before matching, so filtering | ||
| by ``"06"`` matches ``"06"``, ``"060"``, ``"0600"``, ``"061"``, and ``"0612"``. | ||
| Filtering by ``"202"`` matches ``"202"``, ``"2021"``, and ``"2029"`` but not | ||
| ``"20"``, ``"201"``, or ``"22"``. |
There was a problem hiding this comment.
Nitpick, but technically "division" is not supported here (and it's rarely used in datasets I've seen). Division is like "C Manufacturing", a subdivision of which might be "11 Food Product Manufacturing". These helpers are only concerned with the numeric codes from subdivision onwards.
More detail available here: https://www.abs.gov.au/statistics/classifications/australian-and-new-zealand-standard-industrial-classification-anzsic/2006-revision-2-0/numbering-system-and-titles
| Each entry in ``anzsic_codes`` may be a division, subdivision, group, or class | |
| code. Codes are simplified (trailing zeros removed) before matching, so filtering | |
| by ``"06"`` matches ``"06"``, ``"060"``, ``"0600"``, ``"061"``, and ``"0612"``. | |
| Filtering by ``"202"`` matches ``"202"``, ``"2021"``, and ``"2029"`` but not | |
| ``"20"``, ``"201"``, or ``"22"``. | |
| Each entry in ``anzsic_codes`` may be a subdivision, group, or class code | |
| Codes are simplified, so specifying a subdivision like "0600" will match | |
| any group or class within it. For example: | |
| - ``"0600"`` or ``"06"`` matches ``"06"``, ``"060"``, ``"0600"``, ``"061"``, and ``"0612"`` | |
| - ``"202"`` matches ``"202"``, ``"2021"``, and ``"2029"`` but not | |
| ``"20"``, ``"201"``, or ``"22"``. |
|
Thanks again @aethr, and glad the fork-PR check issue was useful — happy to have surfaced it. The rename to If #201 turns into something a contributor can pick up (e.g. gating the ghcr.io push step on non-fork PRs), I'd be glad to take a look and open a follow-up PR. Either way, thanks for the thorough and welcoming review on what turned out to be the first external PR here. |
aethr
left a comment
There was a problem hiding this comment.
Reading my own comment re: the tests made me realise the pre-existing code has a bug in it.
In the classification, "Subdivision: 30 - Building Construction" is completely separate from "Subdivision: 31 - Heavy and Civil Engineering Construction", but if someone specified anzsic_codes: ["30"], the simplify_anzsic_code method would shorten it to "3", which would match all the subdivisions in "E Construction".
The simplify_anzsic_code method shouldn't remove any zeroes that occur in the first two characters. Would you mind updating the method and expanding the tests for both simplify_anzsic_code and filter_by_anzsic_code_family so this is covered?
Preserve the first two subdivision characters when removing trailing zeros, expand ANZSIC helper tests, and apply the requested docstring. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Thanks @aethr — addressed in the latest push:
All |
I appreciate the offer, but infrastructure changes are probably best left to team members for now. |
|
Makes sense — that's a reasonable place to draw the line, and I'd rather infra stay with the team. Thanks for clarifying. |
Distinguish subdivision-level (2000/20) from group-level (2020/202) matching behaviour in filter_by_anzsic_code_family tests. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Clarified padded-code tests to distinguish hierarchy levels:
|
|
Hi @martinguthrie93 , sorry I've been quiet on this PR. I've been working on resolving the issue with checks failing for external PRs in #202 and I was hoping we could test those improvements in this PR before merging. I'll comment again here when that's ready. |
Summary
Following maintainer feedback on the GIS preprocessing discussion, this PR addresses one duplication (Rule of Three): identical ANZSIC prefix filtering in three modules.
Extracted
filter_by_anzsic_prefixes()indata_sources/safeguard/anzsic.py.Behaviour
No change to emission calculations or filtering results.
Test plan
uv run python -m pytest tests/unit/test_data/test_anzsic.py -v- 2 passedChecklist
Made with Cursor