pyoframe 0.2.0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyoframe/__init__.py +21 -14
- pyoframe/_arithmetic.py +346 -238
- pyoframe/_constants.py +463 -0
- pyoframe/_core.py +2652 -0
- pyoframe/_model.py +598 -0
- pyoframe/_model_element.py +189 -0
- pyoframe/_monkey_patch.py +82 -0
- pyoframe/{objective.py → _objective.py} +50 -17
- pyoframe/{util.py → _utils.py} +108 -129
- pyoframe/_version.py +16 -3
- {pyoframe-0.2.0.dist-info → pyoframe-1.0.0.dist-info}/METADATA +37 -31
- pyoframe-1.0.0.dist-info/RECORD +15 -0
- pyoframe/constants.py +0 -140
- pyoframe/core.py +0 -1794
- pyoframe/model.py +0 -408
- pyoframe/model_element.py +0 -184
- pyoframe/monkey_patch.py +0 -54
- pyoframe-0.2.0.dist-info/RECORD +0 -15
- {pyoframe-0.2.0.dist-info → pyoframe-1.0.0.dist-info}/WHEEL +0 -0
- {pyoframe-0.2.0.dist-info → pyoframe-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {pyoframe-0.2.0.dist-info → pyoframe-1.0.0.dist-info}/top_level.txt +0 -0
pyoframe/{util.py → _utils.py}
RENAMED
|
@@ -1,37 +1,48 @@
|
|
|
1
|
-
"""
|
|
2
|
-
File containing utility functions and classes.
|
|
3
|
-
"""
|
|
1
|
+
"""Contains utility functions and classes."""
|
|
4
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import itertools
|
|
6
|
+
import sys
|
|
7
|
+
from collections.abc import Iterable
|
|
5
8
|
from dataclasses import dataclass, field
|
|
6
9
|
from functools import wraps
|
|
7
|
-
from typing import
|
|
8
|
-
TYPE_CHECKING,
|
|
9
|
-
Any,
|
|
10
|
-
Dict,
|
|
11
|
-
Iterable,
|
|
12
|
-
List,
|
|
13
|
-
Optional,
|
|
14
|
-
Sequence,
|
|
15
|
-
Type,
|
|
16
|
-
Union,
|
|
17
|
-
)
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Callable
|
|
18
11
|
|
|
19
12
|
import pandas as pd
|
|
20
13
|
import polars as pl
|
|
21
14
|
|
|
22
|
-
from pyoframe.
|
|
15
|
+
from pyoframe._constants import (
|
|
16
|
+
COEF_KEY,
|
|
17
|
+
CONST_TERM,
|
|
18
|
+
RESERVED_COL_KEYS,
|
|
19
|
+
VAR_KEY,
|
|
20
|
+
Config,
|
|
21
|
+
)
|
|
23
22
|
|
|
24
23
|
if TYPE_CHECKING: # pragma: no cover
|
|
25
|
-
from pyoframe.
|
|
26
|
-
from pyoframe.
|
|
24
|
+
from pyoframe._core import BaseOperableBlock
|
|
25
|
+
from pyoframe._model import Variable
|
|
27
26
|
|
|
27
|
+
if sys.version_info >= (3, 10):
|
|
28
|
+
pairwise = itertools.pairwise
|
|
29
|
+
else:
|
|
28
30
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
def pairwise(iterable):
|
|
32
|
+
iterator = iter(iterable)
|
|
33
|
+
a = next(iterator)
|
|
34
|
+
|
|
35
|
+
for b in iterator:
|
|
36
|
+
yield a, b
|
|
37
|
+
a = b
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_obj_repr(obj: object, *props: str | None, **kwargs):
|
|
41
|
+
"""Generates __repr__() strings for classes.
|
|
42
|
+
|
|
43
|
+
See usage for examples.
|
|
32
44
|
"""
|
|
33
|
-
|
|
34
|
-
props_str = " ".join(f"{k}={v}" for k, v in props.items() if v is not None)
|
|
45
|
+
props_str = " ".join(f"'{v}'" for v in props if v is not None)
|
|
35
46
|
if props_str:
|
|
36
47
|
props_str += " "
|
|
37
48
|
kwargs_str = " ".join(f"{k}={v}" for k, v in kwargs.items() if v is not None)
|
|
@@ -39,10 +50,10 @@ def get_obj_repr(obj: object, _props: Iterable[str] = (), **kwargs):
|
|
|
39
50
|
|
|
40
51
|
|
|
41
52
|
def parse_inputs_as_iterable(
|
|
42
|
-
*inputs:
|
|
53
|
+
*inputs: Any | Iterable[Any],
|
|
43
54
|
) -> Iterable[Any]:
|
|
44
|
-
"""
|
|
45
|
-
|
|
55
|
+
"""Converts a parameter *x: Any | Iterable[Any] to a single Iterable[Any] object.
|
|
56
|
+
|
|
46
57
|
This is helpful to support these two ways of passing arguments:
|
|
47
58
|
- foo([1, 2, 3])
|
|
48
59
|
- foo(1, 2, 3)
|
|
@@ -59,7 +70,7 @@ def parse_inputs_as_iterable(
|
|
|
59
70
|
return inputs
|
|
60
71
|
|
|
61
72
|
|
|
62
|
-
def _is_iterable(input:
|
|
73
|
+
def _is_iterable(input: Any | Iterable[Any]) -> bool:
|
|
63
74
|
# Inspired from the polars library, TODO: Consider using opposite check, i.e. equals list or tuple
|
|
64
75
|
return isinstance(input, Iterable) and not isinstance(
|
|
65
76
|
input,
|
|
@@ -78,15 +89,11 @@ def _is_iterable(input: Union[Any, Iterable[Any]]) -> bool:
|
|
|
78
89
|
|
|
79
90
|
|
|
80
91
|
def concat_dimensions(
|
|
81
|
-
df: pl.DataFrame,
|
|
82
|
-
prefix: Optional[str] = None,
|
|
83
|
-
keep_dims: bool = True,
|
|
84
|
-
ignore_columns: Sequence[str] = RESERVED_COL_KEYS,
|
|
85
|
-
replace_spaces: bool = True,
|
|
86
|
-
to_col: str = "concated_dim",
|
|
92
|
+
df: pl.DataFrame, prefix: str, keep_dims: bool = True, to_col: str = "concated_dim"
|
|
87
93
|
) -> pl.DataFrame:
|
|
88
|
-
"""
|
|
89
|
-
|
|
94
|
+
"""Returns a new DataFrame with the column 'concated_dim'.
|
|
95
|
+
|
|
96
|
+
Reserved columns are ignored. Spaces are replaced with underscores.
|
|
90
97
|
|
|
91
98
|
Parameters:
|
|
92
99
|
df:
|
|
@@ -94,9 +101,7 @@ def concat_dimensions(
|
|
|
94
101
|
prefix:
|
|
95
102
|
The prefix to be added to the concated dimension.
|
|
96
103
|
keep_dims:
|
|
97
|
-
If True
|
|
98
|
-
replace_spaces : bool, optional
|
|
99
|
-
If True, replaces spaces with underscores.
|
|
104
|
+
If `True`, the original dimensions are kept in the new DataFrame.
|
|
100
105
|
|
|
101
106
|
Examples:
|
|
102
107
|
>>> import polars as pl
|
|
@@ -106,20 +111,6 @@ def concat_dimensions(
|
|
|
106
111
|
... "dim2": ["Y", "Y", "Y", "N", "N", "N"],
|
|
107
112
|
... }
|
|
108
113
|
... )
|
|
109
|
-
>>> concat_dimensions(df)
|
|
110
|
-
shape: (6, 3)
|
|
111
|
-
┌──────┬──────┬──────────────┐
|
|
112
|
-
│ dim1 ┆ dim2 ┆ concated_dim │
|
|
113
|
-
│ --- ┆ --- ┆ --- │
|
|
114
|
-
│ i64 ┆ str ┆ str │
|
|
115
|
-
╞══════╪══════╪══════════════╡
|
|
116
|
-
│ 1 ┆ Y ┆ [1,Y] │
|
|
117
|
-
│ 2 ┆ Y ┆ [2,Y] │
|
|
118
|
-
│ 3 ┆ Y ┆ [3,Y] │
|
|
119
|
-
│ 1 ┆ N ┆ [1,N] │
|
|
120
|
-
│ 2 ┆ N ┆ [2,N] │
|
|
121
|
-
│ 3 ┆ N ┆ [3,N] │
|
|
122
|
-
└──────┴──────┴──────────────┘
|
|
123
114
|
>>> concat_dimensions(df, prefix="x")
|
|
124
115
|
shape: (6, 3)
|
|
125
116
|
┌──────┬──────┬──────────────┐
|
|
@@ -134,7 +125,7 @@ def concat_dimensions(
|
|
|
134
125
|
│ 2 ┆ N ┆ x[2,N] │
|
|
135
126
|
│ 3 ┆ N ┆ x[3,N] │
|
|
136
127
|
└──────┴──────┴──────────────┘
|
|
137
|
-
>>> concat_dimensions(df, keep_dims=False)
|
|
128
|
+
>>> concat_dimensions(df, prefix="", keep_dims=False)
|
|
138
129
|
shape: (6, 1)
|
|
139
130
|
┌──────────────┐
|
|
140
131
|
│ concated_dim │
|
|
@@ -148,7 +139,8 @@ def concat_dimensions(
|
|
|
148
139
|
│ [2,N] │
|
|
149
140
|
│ [3,N] │
|
|
150
141
|
└──────────────┘
|
|
151
|
-
|
|
142
|
+
|
|
143
|
+
Properly handles cases with no dimensions and ignores reserved columns
|
|
152
144
|
>>> df = pl.DataFrame({VAR_KEY: [1, 2]})
|
|
153
145
|
>>> concat_dimensions(df, prefix="x")
|
|
154
146
|
shape: (2, 2)
|
|
@@ -163,7 +155,7 @@ def concat_dimensions(
|
|
|
163
155
|
"""
|
|
164
156
|
if prefix is None:
|
|
165
157
|
prefix = ""
|
|
166
|
-
dimensions = [col for col in df.columns if col not in
|
|
158
|
+
dimensions = [col for col in df.columns if col not in RESERVED_COL_KEYS]
|
|
167
159
|
if dimensions:
|
|
168
160
|
query = pl.concat_str(
|
|
169
161
|
pl.lit(prefix + "["),
|
|
@@ -173,10 +165,7 @@ def concat_dimensions(
|
|
|
173
165
|
else:
|
|
174
166
|
query = pl.lit(prefix)
|
|
175
167
|
|
|
176
|
-
df = df.with_columns(query.alias(to_col))
|
|
177
|
-
|
|
178
|
-
if replace_spaces:
|
|
179
|
-
df = df.with_columns(pl.col(to_col).str.replace_all(" ", "_"))
|
|
168
|
+
df = df.with_columns(query.str.replace_all(" ", "_").alias(to_col))
|
|
180
169
|
|
|
181
170
|
if not keep_dims:
|
|
182
171
|
df = df.drop(*dimensions)
|
|
@@ -185,10 +174,12 @@ def concat_dimensions(
|
|
|
185
174
|
|
|
186
175
|
|
|
187
176
|
def cast_coef_to_string(
|
|
188
|
-
df: pl.DataFrame,
|
|
177
|
+
df: pl.DataFrame,
|
|
178
|
+
column_name: str = COEF_KEY,
|
|
179
|
+
drop_ones: bool = True,
|
|
180
|
+
always_show_sign: bool = True,
|
|
189
181
|
) -> pl.DataFrame:
|
|
190
|
-
"""
|
|
191
|
-
Converts column `column_name` of the dataframe `df` to a string. Rounds to `Config.print_float_precision` decimal places if not None.
|
|
182
|
+
"""Converts column `column_name` of the DataFrame `df` to a string. Round to `Config.print_float_precision` decimal places if not None.
|
|
192
183
|
|
|
193
184
|
Parameters:
|
|
194
185
|
df:
|
|
@@ -196,7 +187,9 @@ def cast_coef_to_string(
|
|
|
196
187
|
column_name:
|
|
197
188
|
The name of the column to be casted.
|
|
198
189
|
drop_ones:
|
|
199
|
-
If True
|
|
190
|
+
If `True`, 1s are replaced with an empty string for non-constant terms.
|
|
191
|
+
always_show_sign:
|
|
192
|
+
If `True`, the sign of the coefficient is always shown, i.e. 1 becomes `+1` not just `1`.
|
|
200
193
|
|
|
201
194
|
Examples:
|
|
202
195
|
>>> import polars as pl
|
|
@@ -214,22 +207,26 @@ def cast_coef_to_string(
|
|
|
214
207
|
│ +4 ┆ 4 │
|
|
215
208
|
└─────┴───────────────┘
|
|
216
209
|
"""
|
|
217
|
-
df = df.with_columns(
|
|
218
|
-
pl.col(column_name).abs(),
|
|
219
|
-
_sign=pl.when(pl.col(column_name) < 0).then(pl.lit("-")).otherwise(pl.lit("+")),
|
|
220
|
-
)
|
|
221
|
-
|
|
222
210
|
if Config.float_to_str_precision is not None:
|
|
223
211
|
df = df.with_columns(pl.col(column_name).round(Config.float_to_str_precision))
|
|
224
212
|
|
|
213
|
+
if always_show_sign:
|
|
214
|
+
df = df.with_columns(
|
|
215
|
+
pl.col(column_name).abs(),
|
|
216
|
+
_sign=pl.when(pl.col(column_name) < 0)
|
|
217
|
+
.then(pl.lit("-"))
|
|
218
|
+
.otherwise(pl.lit("+")),
|
|
219
|
+
)
|
|
220
|
+
|
|
225
221
|
df = df.with_columns(
|
|
226
|
-
pl.when(pl.col(column_name) == pl.col(column_name).
|
|
222
|
+
pl.when(pl.col(column_name) == pl.col(column_name).round())
|
|
227
223
|
.then(pl.col(column_name).cast(pl.Int64).cast(pl.String))
|
|
228
224
|
.otherwise(pl.col(column_name).cast(pl.String))
|
|
229
225
|
.alias(column_name)
|
|
230
226
|
)
|
|
231
227
|
|
|
232
228
|
if drop_ones:
|
|
229
|
+
assert always_show_sign, "drop_ones requires always_show_sign=True"
|
|
233
230
|
condition = pl.col(column_name) == str(1)
|
|
234
231
|
if VAR_KEY in df.columns:
|
|
235
232
|
condition = condition & (pl.col(VAR_KEY) != CONST_TERM)
|
|
@@ -239,15 +236,16 @@ def cast_coef_to_string(
|
|
|
239
236
|
.otherwise(pl.col(column_name))
|
|
240
237
|
.alias(column_name)
|
|
241
238
|
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
239
|
+
|
|
240
|
+
if always_show_sign:
|
|
241
|
+
df = df.with_columns(
|
|
242
|
+
pl.concat_str("_sign", column_name).alias(column_name)
|
|
243
|
+
).drop("_sign")
|
|
244
|
+
return df
|
|
247
245
|
|
|
248
246
|
|
|
249
|
-
def unwrap_single_values(func):
|
|
250
|
-
"""
|
|
247
|
+
def unwrap_single_values(func) -> pl.DataFrame | Any:
|
|
248
|
+
"""Returns the DataFrame unless it is a single value in which case return the value."""
|
|
251
249
|
|
|
252
250
|
@wraps(func)
|
|
253
251
|
def wrapper(*args, **kwargs):
|
|
@@ -259,52 +257,20 @@ def unwrap_single_values(func):
|
|
|
259
257
|
return wrapper
|
|
260
258
|
|
|
261
259
|
|
|
262
|
-
def dataframe_to_tupled_list(
|
|
263
|
-
df: pl.DataFrame, num_max_elements: Optional[int] = None
|
|
264
|
-
) -> str:
|
|
265
|
-
"""
|
|
266
|
-
Converts a dataframe into a list of tuples. Used to print a Set to the console. See examples for behaviour.
|
|
267
|
-
|
|
268
|
-
Examples:
|
|
269
|
-
>>> df = pl.DataFrame({"x": [1, 2, 3, 4, 5]})
|
|
270
|
-
>>> dataframe_to_tupled_list(df)
|
|
271
|
-
'[1, 2, 3, 4, 5]'
|
|
272
|
-
>>> dataframe_to_tupled_list(df, 3)
|
|
273
|
-
'[1, 2, 3, ...]'
|
|
274
|
-
|
|
275
|
-
>>> df = pl.DataFrame({"x": [1, 2, 3, 4, 5], "y": [2, 3, 4, 5, 6]})
|
|
276
|
-
>>> dataframe_to_tupled_list(df, 3)
|
|
277
|
-
'[(1, 2), (2, 3), (3, 4), ...]'
|
|
278
|
-
"""
|
|
279
|
-
elipse = False
|
|
280
|
-
if num_max_elements is not None:
|
|
281
|
-
if len(df) > num_max_elements:
|
|
282
|
-
elipse = True
|
|
283
|
-
df = df.head(num_max_elements)
|
|
284
|
-
|
|
285
|
-
res = (row for row in df.iter_rows())
|
|
286
|
-
if len(df.columns) == 1:
|
|
287
|
-
res = (row[0] for row in res)
|
|
288
|
-
|
|
289
|
-
res = str(list(res))
|
|
290
|
-
if elipse:
|
|
291
|
-
res = res[:-1] + ", ...]"
|
|
292
|
-
return res
|
|
293
|
-
|
|
294
|
-
|
|
295
260
|
@dataclass
|
|
296
261
|
class FuncArgs:
|
|
297
|
-
args:
|
|
298
|
-
kwargs:
|
|
262
|
+
args: list
|
|
263
|
+
kwargs: dict = field(default_factory=dict)
|
|
299
264
|
|
|
300
265
|
|
|
301
266
|
class Container:
|
|
302
|
-
"""
|
|
303
|
-
A placeholder object that makes it easy to set and get attributes. Used in Model.attr and Model.params, for example.
|
|
267
|
+
"""A placeholder object that makes it easy to set and get attributes. Used in Model.attr and Model.params, for example.
|
|
304
268
|
|
|
305
269
|
Examples:
|
|
306
270
|
>>> x = {}
|
|
307
|
-
>>> params = Container(
|
|
271
|
+
>>> params = Container(
|
|
272
|
+
... setter=lambda n, v: x.__setitem__(n, v), getter=lambda n: x[n]
|
|
273
|
+
... )
|
|
308
274
|
>>> params.a = 1
|
|
309
275
|
>>> params.b = 2
|
|
310
276
|
>>> params.a
|
|
@@ -329,35 +295,34 @@ class Container:
|
|
|
329
295
|
|
|
330
296
|
|
|
331
297
|
class NamedVariableMapper:
|
|
332
|
-
"""
|
|
333
|
-
Maps variables to a string representation using the object's name and dimensions.
|
|
298
|
+
"""Maps variables to a string representation using the object's name and dimensions.
|
|
334
299
|
|
|
335
300
|
Examples:
|
|
336
301
|
>>> import polars as pl
|
|
337
302
|
>>> m = pf.Model()
|
|
338
303
|
>>> m.foo = pf.Variable(pl.DataFrame({"t": range(4)}))
|
|
339
|
-
>>>
|
|
340
|
-
<Expression
|
|
341
|
-
foo[0] +
|
|
304
|
+
>>> m.foo.sum()
|
|
305
|
+
<Expression terms=4 type=linear>
|
|
306
|
+
foo[0] + foo[1] + foo[2] + foo[3]
|
|
342
307
|
"""
|
|
343
308
|
|
|
344
309
|
CONST_TERM_NAME = "_ONE"
|
|
345
310
|
NAME_COL = "__name"
|
|
346
311
|
|
|
347
|
-
def __init__(self
|
|
312
|
+
def __init__(self) -> None:
|
|
348
313
|
self._ID_COL = VAR_KEY
|
|
349
314
|
self.mapping_registry = pl.DataFrame(
|
|
350
315
|
{self._ID_COL: [], self.NAME_COL: []},
|
|
351
|
-
schema={self._ID_COL:
|
|
316
|
+
schema={self._ID_COL: Config.id_dtype, self.NAME_COL: pl.String},
|
|
352
317
|
)
|
|
353
318
|
self._extend_registry(
|
|
354
319
|
pl.DataFrame(
|
|
355
320
|
{self._ID_COL: [CONST_TERM], self.NAME_COL: [self.CONST_TERM_NAME]},
|
|
356
|
-
schema={self._ID_COL:
|
|
321
|
+
schema={self._ID_COL: Config.id_dtype, self.NAME_COL: pl.String},
|
|
357
322
|
)
|
|
358
323
|
)
|
|
359
324
|
|
|
360
|
-
def add(self, element:
|
|
325
|
+
def add(self, element: Variable) -> None:
|
|
361
326
|
self._extend_registry(self._element_to_map(element))
|
|
362
327
|
|
|
363
328
|
def _extend_registry(self, df: pl.DataFrame) -> None:
|
|
@@ -375,16 +340,17 @@ class NamedVariableMapper:
|
|
|
375
340
|
validate="m:1",
|
|
376
341
|
left_on=id_col,
|
|
377
342
|
right_on=self._ID_COL,
|
|
343
|
+
maintain_order="left" if Config.maintain_order else None,
|
|
378
344
|
).rename({self.NAME_COL: to_col})
|
|
379
345
|
|
|
380
|
-
def _element_to_map(self, element) -> pl.DataFrame:
|
|
346
|
+
def _element_to_map(self, element: Variable) -> pl.DataFrame:
|
|
381
347
|
element_name = element.name # type: ignore
|
|
382
348
|
assert element_name is not None, (
|
|
383
349
|
"Element must have a name to be used in a named mapping."
|
|
384
350
|
)
|
|
385
351
|
element._assert_has_ids()
|
|
386
352
|
return concat_dimensions(
|
|
387
|
-
element.data.select(element.
|
|
353
|
+
element.data.select(element._dimensions_unsafe + [VAR_KEY]),
|
|
388
354
|
keep_dims=False,
|
|
389
355
|
prefix=element_name,
|
|
390
356
|
to_col=self.NAME_COL,
|
|
@@ -392,19 +358,32 @@ class NamedVariableMapper:
|
|
|
392
358
|
|
|
393
359
|
|
|
394
360
|
def for_solvers(*solvers: str):
|
|
395
|
-
"""
|
|
396
|
-
Decorator that limits the function to only be called when the solver is in the `only` list.
|
|
397
|
-
"""
|
|
361
|
+
"""Limits the decorated function to only be available when the solver is in the `solvers` list."""
|
|
398
362
|
|
|
399
363
|
def decorator(func):
|
|
400
364
|
@wraps(func)
|
|
401
365
|
def wrapper(self, *args, **kwargs):
|
|
402
|
-
if self.
|
|
366
|
+
if self.solver.name not in solvers:
|
|
403
367
|
raise NotImplementedError(
|
|
404
|
-
f"Method '{func.__name__}' is not implemented for solver '{self.
|
|
368
|
+
f"Method '{func.__name__}' is not implemented for solver '{self.solver}'."
|
|
405
369
|
)
|
|
406
370
|
return func(self, *args, **kwargs)
|
|
407
371
|
|
|
408
372
|
return wrapper
|
|
409
373
|
|
|
410
374
|
return decorator
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
# TODO: rename and change to return_expr once Set is split away from BaseOperableBlock
|
|
378
|
+
def return_new(func: Callable[..., pl.DataFrame]) -> Callable[..., BaseOperableBlock]:
|
|
379
|
+
"""Decorator that upcasts the returned DataFrame to an Expression.
|
|
380
|
+
|
|
381
|
+
Requires the first argument (self) to support self._new().
|
|
382
|
+
"""
|
|
383
|
+
|
|
384
|
+
@wraps(func)
|
|
385
|
+
def wrapper(self: BaseOperableBlock, *args, **kwargs):
|
|
386
|
+
result = func(self, *args, **kwargs)
|
|
387
|
+
return self._new(result, name=f"{self.name}.{func.__name__}(…)")
|
|
388
|
+
|
|
389
|
+
return wrapper
|
pyoframe/_version.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '0.
|
|
21
|
-
__version_tuple__ = version_tuple = (
|
|
31
|
+
__version__ = version = '1.0.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 0, 0)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyoframe
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Blazing fast linear program interface
|
|
5
5
|
Author-email: Bravos Power <dev@bravospower.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://bravos-power.github.io/pyoframe/
|
|
8
|
-
Project-URL: documentation, https://bravos-power.github.io/pyoframe/
|
|
7
|
+
Project-URL: Homepage, https://bravos-power.github.io/pyoframe/latest
|
|
8
|
+
Project-URL: documentation, https://bravos-power.github.io/pyoframe/latest
|
|
9
9
|
Project-URL: repository, https://github.com/Bravos-Power/pyoframe/
|
|
10
10
|
Project-URL: Issues, https://github.com/Bravos-Power/pyoframe/issues
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -16,51 +16,57 @@ Requires-Python: >=3.9
|
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: polars~=1.0
|
|
19
|
-
Requires-Dist: numpy
|
|
20
19
|
Requires-Dist: pyarrow
|
|
21
20
|
Requires-Dist: pandas
|
|
22
|
-
Requires-Dist: pyoptinterface
|
|
23
|
-
Provides-Extra: dev
|
|
24
|
-
Requires-Dist: ruff; extra == "dev"
|
|
25
|
-
Requires-Dist: polars>=1.30.0; extra == "dev"
|
|
26
|
-
Requires-Dist: bumpver; extra == "dev"
|
|
27
|
-
Requires-Dist: pip-tools; extra == "dev"
|
|
28
|
-
Requires-Dist: pytest; extra == "dev"
|
|
29
|
-
Requires-Dist: pytest-cov; extra == "dev"
|
|
30
|
-
Requires-Dist: pre-commit; extra == "dev"
|
|
31
|
-
Requires-Dist: gurobipy; extra == "dev"
|
|
32
|
-
Requires-Dist: highsbox; extra == "dev"
|
|
33
|
-
Requires-Dist: coverage; extra == "dev"
|
|
34
|
-
Requires-Dist: ipykernel; extra == "dev"
|
|
35
|
-
Requires-Dist: pytest-markdown-docs; extra == "dev"
|
|
36
|
-
Requires-Dist: mkdocs-material==9.*; extra == "dev"
|
|
37
|
-
Requires-Dist: mkdocstrings[python]; extra == "dev"
|
|
38
|
-
Requires-Dist: mkdocs-git-revision-date-localized-plugin; extra == "dev"
|
|
39
|
-
Requires-Dist: mkdocs-git-committers-plugin-2; extra == "dev"
|
|
40
|
-
Requires-Dist: mkdocs-gen-files; extra == "dev"
|
|
41
|
-
Requires-Dist: mkdocs-section-index; extra == "dev"
|
|
42
|
-
Requires-Dist: mkdocs-literate-nav; extra == "dev"
|
|
43
|
-
Requires-Dist: mkdocs-table-reader-plugin; extra == "dev"
|
|
44
|
-
Requires-Dist: markdown-hide-code>=0.1.1; extra == "dev"
|
|
21
|
+
Requires-Dist: pyoptinterface==0.5.1
|
|
45
22
|
Provides-Extra: highs
|
|
46
23
|
Requires-Dist: highsbox; extra == "highs"
|
|
24
|
+
Provides-Extra: ipopt
|
|
25
|
+
Requires-Dist: pyoptinterface[nlp]; extra == "ipopt"
|
|
26
|
+
Requires-Dist: llvmlite<=0.44.0; extra == "ipopt"
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: ruff==0.12.11; extra == "dev"
|
|
29
|
+
Requires-Dist: polars>=1.32.3; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest==8.4.1; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov==6.2.1; extra == "dev"
|
|
32
|
+
Requires-Dist: sybil[pytest]==9.2.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pre-commit==4.3.0; extra == "dev"
|
|
34
|
+
Requires-Dist: gurobipy==12.0.3; extra == "dev"
|
|
35
|
+
Requires-Dist: coverage==7.10.6; extra == "dev"
|
|
36
|
+
Requires-Dist: ipykernel==6.30.1; extra == "dev"
|
|
37
|
+
Requires-Dist: highsbox; extra == "dev"
|
|
38
|
+
Requires-Dist: pyoptinterface[nlp]; extra == "dev"
|
|
39
|
+
Requires-Dist: numpy; extra == "dev"
|
|
40
|
+
Provides-Extra: docs
|
|
41
|
+
Requires-Dist: mkdocs-material~=9.6.18; extra == "docs"
|
|
42
|
+
Requires-Dist: mkdocstrings[python]~=0.30.0; extra == "docs"
|
|
43
|
+
Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.4.7; extra == "docs"
|
|
44
|
+
Requires-Dist: mkdocs-git-committers-plugin-2~=2.5.0; extra == "docs"
|
|
45
|
+
Requires-Dist: mkdocs-gen-files~=0.5.0; extra == "docs"
|
|
46
|
+
Requires-Dist: mkdocs-section-index~=0.3.10; extra == "docs"
|
|
47
|
+
Requires-Dist: mkdocs-awesome-nav~=3.1.2; extra == "docs"
|
|
48
|
+
Requires-Dist: doccmd==2025.4.8; extra == "docs"
|
|
49
|
+
Requires-Dist: mkdocs-table-reader-plugin~=3.1.0; extra == "docs"
|
|
50
|
+
Requires-Dist: markdown-katex==202406.1035; extra == "docs"
|
|
51
|
+
Requires-Dist: mike==2.1.3; extra == "docs"
|
|
52
|
+
Requires-Dist: ruff==0.12.11; extra == "docs"
|
|
47
53
|
Dynamic: license-file
|
|
48
54
|
|
|
49
55
|
# Pyoframe: Fast and low-memory linear programming models
|
|
50
56
|
|
|
51
57
|
[](https://codecov.io/gh/Bravos-Power/pyoframe)
|
|
52
58
|
[](https://github.com/Bravos-Power/pyoframe/actions/workflows/ci.yml)
|
|
53
|
-
[](https://Bravos-Power.github.io/pyoframe/reference/)
|
|
59
|
+
[](https://Bravos-Power.github.io/pyoframe/latest/reference/)
|
|
54
60
|
[](https://opensource.org/licenses/MIT)
|
|
55
61
|
[](https://github.com/Bravos-Power/pyoframe/issues?q=is%3Aopen+is%3Aissue+no%3Alabel)
|
|
56
62
|
[](https://github.com/Bravos-Power/pyoframe/issues?q=is%3Aopen+is%3Aissue+label%3Abug)
|
|
57
63
|
|
|
58
64
|
|
|
59
|
-
A library to rapidly and memory-efficiently formulate large and sparse optimization models using Pandas or Polars
|
|
65
|
+
A library to rapidly and memory-efficiently formulate large and sparse optimization models using Pandas or Polars DataFrames.
|
|
60
66
|
|
|
61
|
-
## **[Documentation](https://bravos-power.github.io/pyoframe/)**
|
|
67
|
+
## **[Documentation](https://bravos-power.github.io/pyoframe/latest/)**
|
|
62
68
|
|
|
63
|
-
[Read the documentation](https://bravos-power.github.io/pyoframe/) to get started or to learn how to [contribute](https://bravos-power.github.io/pyoframe/contribute/).
|
|
69
|
+
[Read the documentation](https://bravos-power.github.io/pyoframe/latest/) to get started or to learn how to [contribute](https://bravos-power.github.io/pyoframe/latest/contribute/index.md).
|
|
64
70
|
|
|
65
71
|
|
|
66
72
|
## Acknowledgments
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
pyoframe/__init__.py,sha256=Nlql3FYed7bXWumvUeMd3rjnoL4l8XC5orO4uxWrDAc,839
|
|
2
|
+
pyoframe/_arithmetic.py,sha256=9V3N2Yq7Ib13UfTQnINxa9oS7786f5DnRsrAPcFlYYE,20558
|
|
3
|
+
pyoframe/_constants.py,sha256=n80so80usutTJpeDlDXkHRE-_dpPD1LxF2plscXhbwQ,17925
|
|
4
|
+
pyoframe/_core.py,sha256=NXH_ze1iN61vk38Fj6Ire0uqKUJRSDUlD6PVc8mTHrQ,116975
|
|
5
|
+
pyoframe/_model.py,sha256=MtA9gleQoUAqO2dxhCFZ8GOZvyyJB_PIYBzvQ0m8enc,22466
|
|
6
|
+
pyoframe/_model_element.py,sha256=oQ7nykJ5XEzJ6Klq3lT6ZwQvDrxY_wgZYVaN7pgyZOs,6149
|
|
7
|
+
pyoframe/_monkey_patch.py,sha256=Y2zXN5MpqDeAWELddyaFQNam57fehSXHiza1PFaZ-QY,3128
|
|
8
|
+
pyoframe/_objective.py,sha256=yIHoaBLsjGCKzIB6RQErV3vzE2U5DGORlhifRStB_Mc,4335
|
|
9
|
+
pyoframe/_utils.py,sha256=5yy-5DOWCW7q3QzPv9tKquLUQJtNdpJJilEqxAq7TN8,12518
|
|
10
|
+
pyoframe/_version.py,sha256=vLA4ITz09S-S435nq6yTF6l3qiSz6w4euS1rOxXgd1M,704
|
|
11
|
+
pyoframe-1.0.0.dist-info/licenses/LICENSE,sha256=u_Spw4ynlwTMRZeCX-uacv_hBU547pBygiA6d2ONNV4,1074
|
|
12
|
+
pyoframe-1.0.0.dist-info/METADATA,sha256=pbmH3YsUkSvJtpl6NWKYw2P7zxLcwWsnt5LDCOF7jeM,4042
|
|
13
|
+
pyoframe-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
14
|
+
pyoframe-1.0.0.dist-info/top_level.txt,sha256=10z3OOJSVLriQ0IrFLMH8CH9zByugPWolqhlHlkNjV4,9
|
|
15
|
+
pyoframe-1.0.0.dist-info/RECORD,,
|