Skip to content

feat: add stats accessor as alternative to statistics#1448

Merged
lkstrp merged 5 commits intomasterfrom
stats-alias
Dec 4, 2025
Merged

feat: add stats accessor as alternative to statistics#1448
lkstrp merged 5 commits intomasterfrom
stats-alias

Conversation

@FabianHofmann
Copy link
Copy Markdown
Contributor

@FabianHofmann FabianHofmann commented Nov 24, 2025

Changes proposed in this Pull Request

Add n.stats as an alternative alias to access statistics.

Checklist

  • Code changes are sufficiently documented; i.e. new functions contain docstrings and further explanations may be given in docs.
  • Unit tests for new features were added (if applicable).
  • A note for the release notes docs/release-notes.md of the upcoming release is included.
  • I consent to the release of this PR's code under the MIT license.

@FabianHofmann FabianHofmann requested a review from lkstrp November 24, 2025 13:34
@coroa
Copy link
Copy Markdown
Member

coroa commented Nov 24, 2025

Not sure about this one, it is not hard to type n.statistics.

But what i would really like is a statistics accessor that by default includes nice_names=False because for soo many processing steps the nice_names are very annoying.

So, i'd be persuaded for creating: n.stats and n.exprs with this setting.

I still think, that probably is very hacky api design.

@FabianHofmann
Copy link
Copy Markdown
Contributor Author

thanks @coroa, I personally don't like writing out statistics especially in long calls like n.statistics.energy_balance.plot.bar(arg-....). I would really prefer something more snappy. the nice_name setting can be set via

pypsa.options.params.statistics.nice_names = False

but I agree that this should probably go to false per default.

@coroa
Copy link
Copy Markdown
Member

coroa commented Nov 25, 2025

thanks @coroa, I personally don't like writing out statistics especially in long calls like n.statistics.energy_balance.plot.bar(arg-....). I would really prefer something more snappy. the nice_name setting can be set via

pypsa.options.params.statistics.nice_names = False

but I agree that this should probably go to false per default.

I know that the setting works, but in library code i always feel very uncomfortable with using such global settings since you never know whose assumption you are breaking later on in the code.

But if you agree it would be good by default as nice_names = False and you want to introduce shorter versions, then i guess at least we both are in agreement to add n.stats and n.exprs with nice_names=False.

@lkstrp What do you think about this proposal?

@lkstrp
Copy link
Copy Markdown
Member

lkstrp commented Nov 25, 2025

I am fine with n.stats, doesn't do or harm a lot so let's add it.

@coroa So you mean n.exprs would just be the StatisticsAccessor with different default nice_names=False? That is indeed very hacky API design :D

I also agree that there are downsides to the global setting and that we should switch to 'nice_names=False' by default. But we can't do that right now. Rather than adding another accessor just for that purpose, I would fix it step by step:

  • With 1.1, we raise a deprecation warning that the default of nice_names will change to False. You can turn that deprecation warning off by setting the config above. This partially resolves your concern @coroa, as we then break all assumptions in the code at the same time.
  • To make this more robust, we can add another setting for param details, which enforces them. Which means once set, you can't set them on the global level anymore:
pypsa.options.params.statistics.nice_names = (False, 'strict') # or similar
# and the following would raise an error then
pypsa.options.params.statistics.nice_names  = True

I am against breaking with 1.1 and simply changing the default. Not sure if the use case is already big enough to violate semver. And also quite against n.exprs, which is very confusing for just the use case of changing a default. With the approach above, you can be opt-in breaking. Of course you need to change all code then. But using n.exprs would just lead to a mess which would need to be cleaned up at some point anyway

@coroa
Copy link
Copy Markdown
Member

coroa commented Nov 25, 2025

@coroa So you mean n.exprs would just be the StatisticsAccessor with different default nice_names=False? That is indeed very hacky API design :D

No, n.stats would be n.statistics with nice_names=False, n.exprs would be n.expressions with nice_names=False, i would not mix; or n.optimize.exprs would be n.optimize.expressions not sure what it is currently.

@lkstrp
Copy link
Copy Markdown
Member

lkstrp commented Nov 25, 2025

That makes more sense, but it doesn't change anything. We don't just want to change functionality for an alias. If there would be more stuff different, we could package it as the "new statistics accessor". But there is not. We should just properly deprecate and change the defaults if we wanna change them.

Also we not even have n.expressions currently, just n.optimize.expressions.

@coroa
Copy link
Copy Markdown
Member

coroa commented Nov 25, 2025

With 1.1, we raise a deprecation warning that the default of nice_names will change to False. You can turn that deprecation warning off by setting the config above. This partially resolves your concern @coroa, as we then break all assumptions in the code at the same time.

Yes, please.

To make this more robust, we can add another setting for param details, which enforces them. Which means once set, you can't set them on the global level anymore:

pypsa.options.params.statistics.nice_names = (False, 'strict') # or similar
# and the following would raise an error then
pypsa.options.params.statistics.nice_names  = True

Hmm .., i don't understand that. Aren't settings always global? Why would you have a setting then?

@coroa
Copy link
Copy Markdown
Member

coroa commented Nov 25, 2025

Also we not even have n.expressions currently, just n.optimize.expressions.

Yes, i'm always confused by that. ie. i always start of with n.expressions and then have to add in the .optimize. Then we could introduce n.optimize.exprs equally, and skip out on n.exprs.

Well, my main concern is that it very seldom makes sense for me to have the nice_names. I agree that this is fixed by changing the default, but of course we cannot do this immediately. Therefore i would have used the chance of introducing the aliases to give them already saner defaults and then transition the main calling points to those defaults over time. ie. i'd have my cake and eat it at the same time.

But, well, i can live without that.

@lkstrp
Copy link
Copy Markdown
Member

lkstrp commented Nov 25, 2025

Hmm .., i don't understand that. Aren't settings always global? Why would you have a setting then?

They are global, but you could change them again after a couple of lines. A strict option isn't necessarily needed, but it would give you the option to ensure that the configuration isn't changed again. It might be too complicated, but we could make it very optional.

My proposal above would give you the cake, isn't it? Either eat it all at once which is most robust, and go with the strict option. Or eat it over time, and change the defaults over time. And live with the deprecation warnings until then.

@coroa
Copy link
Copy Markdown
Member

coroa commented Nov 25, 2025

Hmm .., i don't understand that. Aren't settings always global? Why would you have a setting then?

They are global, but you could change them again after a couple of lines. A strict option isn't necessarily needed, but it would give you the option to ensure that the configuration isn't changed again. It might be too complicated, but we could make it very optional.

I don't think that is very relevant.

My proposal above would give you the cake, isn't it? Either eat it all at once which is most robust, and go with the strict option. Or eat it over time, and change the defaults over time. And live with the deprecation warnings until then.

And the cake would be: I make sure that my scripts have pypsa.options.params.statistics.nice_names = False for the time being, and in two versions time i'll slowly stop caring about adding these?

Yes, why not. Can do.

@FabianHofmann
Copy link
Copy Markdown
Contributor Author

alright, means we leave it like this? would say it makes the api a bit more consistent, and gives us an incentive to push v1.1 soon

@lkstrp lkstrp added this to the v1.1 milestone Nov 25, 2025
@lkstrp
Copy link
Copy Markdown
Member

lkstrp commented Nov 25, 2025

alright, means we leave it like this? would say it makes the api a bit more consistent, and gives us an incentive to push v1.1 soon

Let me release another patch with #1450 and then we merge all the v1.1 prs?

@lkstrp lkstrp enabled auto-merge (squash) December 4, 2025 10:14
@lkstrp lkstrp merged commit 7906e78 into master Dec 4, 2025
19 of 20 checks passed
@lkstrp lkstrp deleted the stats-alias branch December 4, 2025 11:19
a-buntjer pushed a commit to a-buntjer/PyPSA that referenced this pull request Dec 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants