Skip to content

Commit 7778c6d

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 63485af commit 7778c6d

File tree

3 files changed

+141
-44
lines changed

3 files changed

+141
-44
lines changed

linopy/io.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def print_coord(coord):
7171

7272
def get_printers(m: Model, for_polars: bool = False, with_names: bool = False):
7373
if with_names:
74+
7475
def print_variable(var):
7576
name, coord = m.variables.get_label_position(var)
7677
name = clean_name(name)
@@ -82,16 +83,21 @@ def print_constraint(cons):
8283
return f"{name}{print_coord(coord)}#{cons}"
8384

8485
def print_variable_polars(series):
85-
return pl.lit(" "), series.map_elements(print_variable, return_dtype=pl.String)
86+
return pl.lit(" "), series.map_elements(
87+
print_variable, return_dtype=pl.String
88+
)
8689

8790
def print_constraint_polars(series):
88-
return pl.lit(None), series.map_elements(print_constraint, return_dtype=pl.String)
91+
return pl.lit(None), series.map_elements(
92+
print_constraint, return_dtype=pl.String
93+
)
8994

9095
if for_polars:
9196
return print_variable_polars, print_constraint_polars
9297
else:
9398
return print_variable, print_constraint
9499
else:
100+
95101
def print_variable(var):
96102
return f"x{var}"
97103

@@ -408,7 +414,7 @@ def to_lp_file(
408414
integer_label: str,
409415
slice_size: int = 10_000_000,
410416
progress: bool = True,
411-
printers = None,
417+
printers=None,
412418
) -> None:
413419
batch_size = 5000
414420

@@ -625,7 +631,9 @@ def integers_to_file_polars(
625631
formatted.write_csv(f, **kwargs)
626632

627633

628-
def constraints_to_file_polars(m, f, progress=False, lazy=False, slice_size=2_000_000, printers=None):
634+
def constraints_to_file_polars(
635+
m, f, progress=False, lazy=False, slice_size=2_000_000, printers=None
636+
):
629637
if not len(m.constraints):
630638
return
631639

@@ -695,16 +703,22 @@ def to_lp_file_polars(
695703
start = time.time()
696704

697705
objective_to_file_polars(m, f, progress=progress, printers=printers)
698-
constraints_to_file_polars(m, f=f, progress=progress, slice_size=slice_size, printers=printers)
699-
bounds_to_file_polars(m, f=f, progress=progress, slice_size=slice_size, printers=printers)
700-
binaries_to_file_polars(m, f=f, progress=progress, slice_size=slice_size, printers=printers)
706+
constraints_to_file_polars(
707+
m, f=f, progress=progress, slice_size=slice_size, printers=printers
708+
)
709+
bounds_to_file_polars(
710+
m, f=f, progress=progress, slice_size=slice_size, printers=printers
711+
)
712+
binaries_to_file_polars(
713+
m, f=f, progress=progress, slice_size=slice_size, printers=printers
714+
)
701715
integers_to_file_polars(
702716
m,
703717
integer_label=integer_label,
704718
f=f,
705719
progress=progress,
706720
slice_size=slice_size,
707-
printers = printers,
721+
printers=printers,
708722
)
709723
f.write(b"end\n")
710724

@@ -736,13 +750,25 @@ def to_file(
736750
if progress is None:
737751
progress = m._xCounter > 10_000
738752

739-
printers = get_printers(m, for_polars=io_api=="lp-polars", with_names=with_names)
753+
printers = get_printers(m, for_polars=io_api == "lp-polars", with_names=with_names)
740754

741755
if io_api == "lp":
742-
to_lp_file(m, fn, integer_label, slice_size=slice_size, progress=progress, printers=printers)
756+
to_lp_file(
757+
m,
758+
fn,
759+
integer_label,
760+
slice_size=slice_size,
761+
progress=progress,
762+
printers=printers,
763+
)
743764
elif io_api == "lp-polars":
744765
to_lp_file_polars(
745-
m, fn, integer_label, slice_size=slice_size, progress=progress, printers=printers
766+
m,
767+
fn,
768+
integer_label,
769+
slice_size=slice_size,
770+
progress=progress,
771+
printers=printers,
746772
)
747773

748774
elif io_api == "mps":

linopy/model.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,9 @@ def solve(
11371137
)
11381138
else:
11391139
if solver_name in ["glpk", "cbc"] and with_names:
1140-
logger.warning(f"{solver_name} does not support writing names to lp files, disabling it.")
1140+
logger.warning(
1141+
f"{solver_name} does not support writing names to lp files, disabling it."
1142+
)
11411143
with_names = False
11421144
problem_fn = self.to_file(
11431145
to_path(problem_fn),

test/test_optimization.py

Lines changed: 101 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
@author: fabian
66
"""
7+
78
import itertools
89
import logging
910
import platform
@@ -30,9 +31,11 @@
3031

3132
params = [
3233
(name, io_api, with_names)
33-
for (name, io_api, with_names) in list(itertools.product(available_solvers, io_apis, with_names))
34-
if "lp" in io_api or with_names == False
35-
]
34+
for (name, io_api, with_names) in list(
35+
itertools.product(available_solvers, io_apis, with_names)
36+
)
37+
if "lp" in io_api or with_names == False
38+
]
3639

3740
direct_solvers = ["gurobi", "highs", "mosek"]
3841
for solver in direct_solvers:
@@ -376,8 +379,12 @@ def test_default_setting_expression_sol_accessor(model, solver, io_api, with_nam
376379

377380

378381
@pytest.mark.parametrize("solver,io_api,with_names", params)
379-
def test_anonymous_constraint(model, model_anonymous_constraint, solver, io_api, with_names):
380-
status, condition = model_anonymous_constraint.solve(solver, io_api=io_api, with_names=with_names)
382+
def test_anonymous_constraint(
383+
model, model_anonymous_constraint, solver, io_api, with_names
384+
):
385+
status, condition = model_anonymous_constraint.solve(
386+
solver, io_api=io_api, with_names=with_names
387+
)
381388
assert status == "ok"
382389
assert np.isclose(model_anonymous_constraint.objective.value, 3.3)
383390

@@ -402,15 +409,19 @@ def test_model_maximization(model_maximization, solver, io_api, with_names):
402409

403410
@pytest.mark.parametrize("solver,io_api,with_names", params)
404411
def test_default_settings_chunked(model_chunked, solver, io_api, with_names):
405-
status, condition = model_chunked.solve(solver, io_api=io_api, with_names=with_names)
412+
status, condition = model_chunked.solve(
413+
solver, io_api=io_api, with_names=with_names
414+
)
406415
assert status == "ok"
407416
assert np.isclose(model_chunked.objective.value, 3.3)
408417

409418

410419
@pytest.mark.parametrize("solver,io_api,with_names", params)
411420
def test_default_settings_small_slices(model, solver, io_api, with_names):
412421
assert model.objective.sense == "min"
413-
status, condition = model.solve(solver, io_api=io_api, with_names=with_names, slice_size=2)
422+
status, condition = model.solve(
423+
solver, io_api=io_api, with_names=with_names, slice_size=2
424+
)
414425
assert status == "ok"
415426
assert np.isclose(model.objective.value, 3.3)
416427
assert model.solver_name == solver
@@ -430,20 +441,30 @@ def test_solver_options(model, solver, io_api, with_names):
430441
"mindopt": {"MaxTime": 1},
431442
"copt": {"TimeLimit": 1},
432443
}
433-
status, condition = model.solve(solver, io_api=io_api, with_names=with_names, **time_limit_option[solver])
444+
status, condition = model.solve(
445+
solver, io_api=io_api, with_names=with_names, **time_limit_option[solver]
446+
)
434447
assert status == "ok"
435448

436449

437450
@pytest.mark.parametrize("solver,io_api,with_names", params)
438-
def test_duplicated_variables(model_with_duplicated_variables, solver, io_api, with_names):
439-
status, condition = model_with_duplicated_variables.solve(solver, io_api=io_api, with_names=with_names)
451+
def test_duplicated_variables(
452+
model_with_duplicated_variables, solver, io_api, with_names
453+
):
454+
status, condition = model_with_duplicated_variables.solve(
455+
solver, io_api=io_api, with_names=with_names
456+
)
440457
assert status == "ok"
441458
assert all(model_with_duplicated_variables.solution["x"] == 5)
442459

443460

444461
@pytest.mark.parametrize("solver,io_api,with_names", params)
445-
def test_non_aligned_variables(model_with_non_aligned_variables, solver, io_api, with_names):
446-
status, condition = model_with_non_aligned_variables.solve(solver, io_api=io_api, with_names=with_names)
462+
def test_non_aligned_variables(
463+
model_with_non_aligned_variables, solver, io_api, with_names
464+
):
465+
status, condition = model_with_non_aligned_variables.solve(
466+
solver, io_api=io_api, with_names=with_names
467+
)
447468
assert status == "ok"
448469
with pytest.warns(UserWarning):
449470
assert model_with_non_aligned_variables.solution["x"][0] == 0
@@ -509,7 +530,9 @@ def test_infeasible_model(model, solver, io_api, with_names):
509530

510531
@pytest.mark.parametrize("solver,io_api,with_names", params)
511532
def test_model_with_inf(model_with_inf, solver, io_api, with_names):
512-
status, condition = model_with_inf.solve(solver, io_api=io_api, with_names=with_names)
533+
status, condition = model_with_inf.solve(
534+
solver, io_api=io_api, with_names=with_names
535+
)
513536
assert condition == "optimal"
514537
assert (model_with_inf.solution.x == 0).all()
515538
assert (model_with_inf.solution.y == 10).all()
@@ -519,7 +542,9 @@ def test_model_with_inf(model_with_inf, solver, io_api, with_names):
519542
"solver,io_api,with_names", [p for p in params if p[0] not in ["mindopt"]]
520543
)
521544
def test_milp_binary_model(milp_binary_model, solver, io_api, with_names):
522-
status, condition = milp_binary_model.solve(solver, io_api=io_api, with_names=with_names)
545+
status, condition = milp_binary_model.solve(
546+
solver, io_api=io_api, with_names=with_names
547+
)
523548
assert condition == "optimal"
524549
assert (
525550
(milp_binary_model.solution.y == 1) | (milp_binary_model.solution.y == 0)
@@ -530,7 +555,9 @@ def test_milp_binary_model(milp_binary_model, solver, io_api, with_names):
530555
"solver,io_api,with_names", [p for p in params if p[0] not in ["mindopt"]]
531556
)
532557
def test_milp_binary_model_r(milp_binary_model_r, solver, io_api, with_names):
533-
status, condition = milp_binary_model_r.solve(solver, io_api=io_api, with_names=with_names)
558+
status, condition = milp_binary_model_r.solve(
559+
solver, io_api=io_api, with_names=with_names
560+
)
534561
assert condition == "optimal"
535562
assert (
536563
(milp_binary_model_r.solution.x == 1) | (milp_binary_model_r.solution.x == 0)
@@ -553,18 +580,26 @@ def test_milp_model_r(milp_model_r, solver, io_api, with_names):
553580
# MPS format by Highs wrong, see https://github.com/ERGO-Code/HiGHS/issues/1325
554581
# skip it
555582
if io_api != "mps":
556-
status, condition = milp_model_r.solve(solver, io_api=io_api, with_names=with_names)
583+
status, condition = milp_model_r.solve(
584+
solver, io_api=io_api, with_names=with_names
585+
)
557586
assert condition == "optimal"
558587
assert ((milp_model_r.solution.x == 11) | (milp_model_r.solution.y == 0)).all()
559588

560589

561590
@pytest.mark.parametrize(
562591
"solver,io_api,with_names",
563-
[p for p in params if (p[0],p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]],
592+
[
593+
p
594+
for p in params
595+
if (p[0], p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]
596+
],
564597
)
565598
def test_quadratic_model(quadratic_model, solver, io_api, with_names):
566599
if solver in feasible_quadratic_solvers:
567-
status, condition = quadratic_model.solve(solver, io_api=io_api, with_names=with_names)
600+
status, condition = quadratic_model.solve(
601+
solver, io_api=io_api, with_names=with_names
602+
)
568603
assert condition == "optimal"
569604
assert (quadratic_model.solution.x.round(3) == 0).all()
570605
assert (quadratic_model.solution.y.round(3) >= 10).all()
@@ -576,28 +611,44 @@ def test_quadratic_model(quadratic_model, solver, io_api, with_names):
576611

577612
@pytest.mark.parametrize(
578613
"solver,io_api,with_names",
579-
[p for p in params if (p[0],p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]],
614+
[
615+
p
616+
for p in params
617+
if (p[0], p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]
618+
],
580619
)
581-
def test_quadratic_model_cross_terms(quadratic_model_cross_terms, solver, io_api, with_names):
620+
def test_quadratic_model_cross_terms(
621+
quadratic_model_cross_terms, solver, io_api, with_names
622+
):
582623
if solver in feasible_quadratic_solvers:
583-
status, condition = quadratic_model_cross_terms.solve(solver, io_api=io_api, with_names=with_names)
624+
status, condition = quadratic_model_cross_terms.solve(
625+
solver, io_api=io_api, with_names=with_names
626+
)
584627
assert condition == "optimal"
585628
assert (quadratic_model_cross_terms.solution.x.round(3) == 1.5).all()
586629
assert (quadratic_model_cross_terms.solution.y.round(3) == 8.5).all()
587630
assert round(quadratic_model_cross_terms.objective.value, 3) == 77.5
588631
else:
589632
with pytest.raises(ValueError):
590-
quadratic_model_cross_terms.solve(solver, io_api=io_api, with_names=with_names)
633+
quadratic_model_cross_terms.solve(
634+
solver, io_api=io_api, with_names=with_names
635+
)
591636

592637

593638
@pytest.mark.parametrize(
594639
"solver,io_api,with_names",
595-
[p for p in params if (p[0],p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]],
640+
[
641+
p
642+
for p in params
643+
if (p[0], p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]
644+
],
596645
)
597646
def test_quadratic_model_wo_constraint(quadratic_model, solver, io_api, with_names):
598647
quadratic_model.constraints.remove("con0")
599648
if solver in feasible_quadratic_solvers:
600-
status, condition = quadratic_model.solve(solver, io_api=io_api, with_names=with_names)
649+
status, condition = quadratic_model.solve(
650+
solver, io_api=io_api, with_names=with_names
651+
)
601652
assert condition == "optimal"
602653
assert (quadratic_model.solution.x.round(3) == 0).all()
603654
assert round(quadratic_model.objective.value, 3) == 0
@@ -608,22 +659,34 @@ def test_quadratic_model_wo_constraint(quadratic_model, solver, io_api, with_nam
608659

609660
@pytest.mark.parametrize(
610661
"solver,io_api,with_names",
611-
[p for p in params if (p[0],p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]],
662+
[
663+
p
664+
for p in params
665+
if (p[0], p[1]) not in [("mindopt", "lp"), ("mindopt", "lp-polars")]
666+
],
612667
)
613-
def test_quadratic_model_unbounded(quadratic_model_unbounded, solver, io_api, with_names):
668+
def test_quadratic_model_unbounded(
669+
quadratic_model_unbounded, solver, io_api, with_names
670+
):
614671
if solver in feasible_quadratic_solvers:
615-
status, condition = quadratic_model_unbounded.solve(solver, io_api=io_api, with_names=with_names)
672+
status, condition = quadratic_model_unbounded.solve(
673+
solver, io_api=io_api, with_names=with_names
674+
)
616675
assert condition in ["unbounded", "unknown", "infeasible_or_unbounded"]
617676
else:
618677
with pytest.raises(ValueError):
619-
quadratic_model_unbounded.solve(solver, io_api=io_api, with_names=with_names)
678+
quadratic_model_unbounded.solve(
679+
solver, io_api=io_api, with_names=with_names
680+
)
620681

621682

622683
@pytest.mark.parametrize(
623684
"solver,io_api,with_names", [p for p in params if p[0] not in ["mindopt"]]
624685
)
625686
def test_modified_model(modified_model, solver, io_api, with_names):
626-
status, condition = modified_model.solve(solver, io_api=io_api, with_names=with_names)
687+
status, condition = modified_model.solve(
688+
solver, io_api=io_api, with_names=with_names
689+
)
627690
assert condition == "optimal"
628691
assert (modified_model.solution.x == 0).all()
629692
assert (modified_model.solution.y == 10).all()
@@ -657,9 +720,13 @@ def test_basis_and_warmstart(tmp_path, model, solver, io_api, with_names):
657720

658721

659722
@pytest.mark.parametrize("solver,io_api,with_names", params)
660-
def test_solution_fn_parent_dir_doesnt_exist(model, solver, io_api, with_names, tmp_path):
723+
def test_solution_fn_parent_dir_doesnt_exist(
724+
model, solver, io_api, with_names, tmp_path
725+
):
661726
solution_fn = tmp_path / "non_existent_dir" / "non_existent_file"
662-
status, condition = model.solve(solver, io_api=io_api, with_names=with_names, solution_fn=solution_fn)
727+
status, condition = model.solve(
728+
solver, io_api=io_api, with_names=with_names, solution_fn=solution_fn
729+
)
663730
assert status == "ok"
664731

665732

@@ -697,7 +764,9 @@ def test_model_resolve(model, solver, io_api, with_names):
697764
assert np.isclose(model.objective.value, 5.25)
698765

699766

700-
@pytest.mark.parametrize("solver,io_api,with_names", [p for p in params if "direct" not in p])
767+
@pytest.mark.parametrize(
768+
"solver,io_api,with_names", [p for p in params if "direct" not in p]
769+
)
701770
def test_solver_classes_from_problem_file(model, solver, io_api, with_names):
702771
# first test initialization of super class. Should not be possible to initialize
703772
with pytest.raises(TypeError):

0 commit comments

Comments
 (0)