Migrate to Pyoframe v1.0
Pyoframe version 1.0 brings major improvements
- New features including support for the Ipopt solver, the COPT solver, and the ability to improve performance with
pf.Config.maintain_order=False
. - Bug fixes: notably with
Variable(equals=…)
not properly parsing DataFrames. - Improved performance after rewriting internal functions based on extensive benchmarking.
- Smoother developer experience, notably error messages explain the mathematical operations that led to an error and Pyoframe objects now print as legible tables.
- Improved documentation including a revamped API page, an examples page, new explanations of functions like
.over(…)
, and the ability to view previous versions of the documentation. - More readable syntax like our decision to rename
add_dim
toover
and the changes to.sum()
(see below).
Unfortunately, these improvements involve some breaking changes. This page will guide you in migrating your code to v1.0.
Breaking changes
Summary:
pf.Model(…)
has a new signaturepf.sum(…, obj)
was replaced byobj.sum(…)
add_dim(…)
was renamed toover(…)
keep_unmatched()
anddrop_unmatched
were renamed tokeep_extras()
anddrop_extras()
- Other less common breaking changes
Follow the steps below to upgrade to v1.0.
1. Update all calls to pf.Model(…)
The signature of pf.Model(…)
has changed from
to
Model(solver=None, solver_env=None, *, name=None, solver_uses_variable_names=False, print_uses_variable_names=True, sense=None)
Importantly, notice how,
-
name
is now a named-only parameter (you must writename=
), and -
use_var_names
was renamed tosolver_uses_variable_names
(to avoid confusion with the new optionprint_uses_variable_names
).
Please update all calls to pf.Model(…)
accordingly.
import pyoframe as pf
pf.Model("my-model") # before
pf.Model(name="my-model") # after
pf.Model(use_var_names=True) # before
pf.Model(solver_uses_variable_names=True) # after
2. Replace pf.sum(…, obj)
with obj.sum(…)
To improve readability and align with Python best practices, both pf.sum(…, obj)
and pf.sum_by(…, obj)
have been replaced by obj.sum(…)
and obj.sum_by(…)
. Here obj
represents any Pyoframe Variable or Expression.1 For example:
pf.sum(m.X) # before
m.X.sum() # after
pf.sum(["day", "hour"], m.X) # before
m.X.sum("day", "hour") # after
pf.sum_by("city", m.X) # before
m.X.sum_by("city") # after
Please update all uses of pf.sum
and pf.sum_by
accordingly.
3. Rename .add_dim(…)
to .over(…)
For clarity, .add_dim(…)
was renamed to .over(…)
. Please update your code accordingly.
4. Rename .keep_unmatched()
and .drop_unmatched()
with .keep_extras()
and .drop_extras()
For clarity, .keep_unmatched()
and .drop_unmatched()
were renamed to .keep_extras()
and .drop_extras()
, respectively.
Please update your code accordingly.
m.X.keep_unmatched() # before
m.X.keep_extras() # after
m.X.drop_unmatched() # before
m.X.drop_extras() # after
5. Review code for other breaking changes
Steps 1 to 3 should cover most breaking changes. For completeness, below are some additional breaking changes that you are less likely to encounter.
-
All submodules (e.g.
pyoframe.core
) and some attributes (obj.unmatched_strategy
,obj.allowed_new_dims
,obj.dimensions_unsafe
,Config.enable_is_duplicated_expression_safety_check
) have been renamed to begin with an underscore (e.g. nowpyoframe._core
) to indicate that these elements are no longer part of the public API. -
If you try to read
model.objective
before having defined an objective, an error will be raised. Prior to v1.0None
was returned. -
.over(…)
,.keep_extras()
, and.drop_extras()
now have a well-defined "order of operations." They must be applied after all other transforms. For example,my_obj.drop_extras().sum("time")
no longer works becausemy_obj.sum("time").drop_extras()
should be used instead. Learn more. -
pf.Config.print_max_set_elements
,pf.Config.print_max_line_length
, andpf.Config.print_max_lines
no longer exist. Usepf.Config.print_max_terms
pf.Config.print_polars_config
instead. -
pf.Config.print_uses_variable_names
no longer exists. Use the equivalent option inpf.Model(…)
-
pf.Config.default_solver
now defaults to"auto"
instead ofNone
to clarify that by default, the solver will be automatically detected. Don't setpf.Config.default_solver = None
. -
pf.Config.disable_unmatched_checks
has been renamed topf.Config.disable_extras_checks
. -
Gurobi users:
Model.write(…)
is now only available whensolver_uses_variable_names=True
. -
Previously, passing a DataFrame to the
equals=
parameter of theVariable
constructor would result in a Variable equal to 1. This bug has been fixed.
-
If you were using
pf.sum
orpf.sum_by
on a Polars or Pandas DataFrame instead of on a Pyoframe object, you should use the.sum()
function native to Pandas/Polars. ↩
Comments