Conversion¶
Utilities for converting and serializing between different data formats.
from prairielearn import ...
from_json ¶
Converts a JSON serialized value (from to_json
) back to its original type.
If v has the format {'_type': ..., '_value': ...}
as would have been created
using to_json(...)
, then it is replaced according to the following table:
JSON _type field |
Python type |
---|---|
complex |
complex |
np_scalar |
numpy scalar defined by _concrete_type |
ndarray |
non-complex ndarray |
complex_ndarray |
complex ndarray |
sympy |
sympy.Expr |
sympy_matrix |
sympy.Matrix |
dataframe |
pandas.DataFrame |
dataframe_v2 |
pandas.DataFrame |
networkx_graph |
corresponding networkx graph |
missing | input value v returned |
If v encodes an ndarray and has the field '_dtype'
, this function recovers
its dtype.
If v does not have the format {'_type': ..., '_value': ...}
, then it is
returned without change.
Returns:
Type | Description |
---|---|
Any
|
The deserialized value |
Raises:
Type | Description |
---|---|
ValueError
|
If the JSON object is not in the expected format. |
is_int_json_serializable ¶
Check if an integer is less than Number.MAX_SAFE_INTEGER
and greater than Number.MIN_SAFE_INTEGER
.
Returns:
Type | Description |
---|---|
bool
|
|
latex_from_2darray ¶
latex_from_2darray(
A: _NumericScalarType | NDArray[Any],
presentation_type: str = "f",
digits: int = 2,
) -> str
Convert a NumPy array to LaTeX.
This function assumes that A is one of these things:
- a number (float or complex)
- a 2D ndarray (float or complex)
If A is a scalar, the string is a single number, not wrapped in brackets.
It A is a numpy 2D array, it returns a string with the format:
\begin{bmatrix} ... & ... \\ ... & ... \end{bmatrix}
If presentation_type is 'sigfig'
, each number is formatted using the
to_precision module to 'digits'
significant figures.
Otherwise, each number is formatted as '{:.{digits}{presentation_type}}'
.
Returns:
Type | Description |
---|---|
str
|
The input formatted in LaTeX. |
Raises:
Type | Description |
---|---|
TypeError
|
If A is not a numpy array or scalar. |
ValueError
|
If A is not a 2D numpy array. |
Examples:
>>> latex_from_2darray(np.array([[1, 2], [3, 4]]))
\begin{bmatrix} 1 & 2\\ 3 & 4\\\end{bmatrix}
numpy_to_matlab ¶
numpy_to_matlab(
np_object: _NumericScalarType | NDArray[Any],
ndigits: int = 2,
wtype: str = "f",
style: Literal["legacy", "space", "comma"] = "legacy",
) -> str
Converts np_object to a MATLAB-formatted string in which each number has "ndigits" digits after the decimal and is formatted as "wtype" (e.g., 'f', 'g', etc.).
This function assumes that np_object is one of these things:
- a number (float or complex)
- a 2D ndarray (float or complex)
The style argument must be one of three values:
- legacy: formats 1D arrays with commas and 2D arrays with spaces
- comma: formats all arrays with commas
- space: formats all arrays with spaces
Returns:
Type | Description |
---|---|
str
|
A MATLAB-formatted string |
numpy_to_matlab_sf ¶
numpy_to_matlab_sf(
A: _NumericScalarType | NDArray[Any],
ndigits: int = 2,
style: Literal["legacy", "comma", "space"] = "legacy",
) -> str
Convert A to a MATLAB-formatted string in which each number has ndigits significant digits.
This function assumes that A is one of these things:
- a number (float or complex)
- a 2D ndarray (float or complex)
The style argument must be one of three values:
- legacy: formats 1d arrays with commas and 2d arrays with spaces
- comma: formats all arrays with commas
- space: formats all arrays with spaces
Returns:
Type | Description |
---|---|
str
|
A as a MATLAB-formatted string |
Examples:
>>> numpy_to_matlab_sf(np.array([[1 + 2j, 3 + 4j], [5 + 6j, 7 + 8j]]), style="space")
[1.0+2.0j 3.0+4.0j; 5.0+6.0j 7.0+8.0j]
string_fraction_to_number ¶
string_fraction_to_number(
a_sub: str | None,
allow_fractions: bool = True,
allow_complex: bool = True,
) -> (
tuple[None, _PartialDataFormatErrors]
| tuple[
float64 | complex128, _PartialDataSubmittedAnswers
]
)
Parse a string containing a decimal number with support for answers expressing as a fraction.
On successful parsing, "data" will contain a 'submitted_answers' key that is the JSON encoded parsed answer.
If parsing failed, the first entry will be 'None' and the "data" entry will contain a 'format_errors' key.
Returns:
Type | Description |
---|---|
tuple[None, _PartialDataFormatErrors] | tuple[float64 | complex128, _PartialDataSubmittedAnswers]
|
A tuple with the parsed value in the first entry and a dictionary with the intended value of "data" in the second entry. |
Examples:
>>> string_fraction_to_number("1/2", allow_fractions=False, allow_complex=False)
(None, {"format_errors": "Fractional answers are not allowed in this input."})
>>> string_fraction_to_number("1/2", allow_fractions=True, allow_complex=False)
(0.5, {"submitted_answers": 0.5})
string_from_number_sigfig ¶
Convert a number to a string with the specified significant digits.
This function assumes that a
is of type float or complex.
Returns:
Type | Description |
---|---|
str
|
|
number, have digits significant digits.
string_from_numpy ¶
string_from_numpy(
A: _NumericScalarType | NDArray[Any],
language: _FormatLanguage = "python",
presentation_type: str = "f",
digits: int = 2,
) -> str
Return A as a string.
This function assumes that A is one of these things:
- a number (float or complex)
- a 1D ndarray (float or complex)
- a 2D ndarray (float or complex)
If language is 'python' and A is a 2D ndarray, the string looks like this:
[[ ..., ... ], [ ..., ... ]]
If A is a 1D ndarray, the string looks like this:
[ ..., ..., ... ]
If language is 'matlab'
and A is a 2D ndarray, the string looks like this:
[ ... ... ; ... ... ]
If A is a 1D ndarray, the string looks like this:
[ ..., ..., ... ]
If language is 'mathematica'
and A is a 2D ndarray, the string looks like this:
{{ ..., ... },{ ..., ... }}
If A is a 1D ndarray, the string looks like this:
{ ..., ..., ... }
If language is 'r'
and A is a 2D ndarray, the string looks like this:
matrix(c(., ., .), nrow=NUM_ROWS, ncol=NUM_COLS, byrow = TRUE)
If A is a 1D ndarray, the string looks like this:
c(., ., .)
If language is 'sympy'
and A is a 2D ndarray, the string looks like this:
Matrix([[ ..., ... ], [ ..., ... ]])
If A is a 1D ndarray, the string looks like this:
Matrix([ ..., ..., ... ])
In either case, if A is not a 1D or 2D ndarray, the string is a single number, not wrapped in brackets.
If presentation_type is 'sigfig'
, each number is formatted using the
to_precision module to 'digits'
significant figures.
Otherwise, each number is formatted as '{:.{digits}{presentation_type}}'
.
Returns:
Type | Description |
---|---|
str
|
A formatted version of the NumPy array. |
Raises:
Type | Description |
---|---|
TypeError
|
If A is not a scalar or a numpy array. |
Examples:
>>> string_from_numpy(np.zeros((2, 2)), language="mathematica")
"{{0.00, 0.00}, {0.00, 0.00}}"
>>> string_from_numpy(np.zeros((2, 2)), language="r")
"matrix(c(0.00, 0.00, 0.00, 0.00), nrow = 2, ncol = 2, byrow = TRUE)"
>>> string_from_numpy(np.zeros((2, 2)), language="sympy")
"Matrix([[0.00, 0.00], [0.00, 0.00]])"
string_partition_first_interval ¶
string_partition_first_interval(
s: str, left: str = "[", right: str = "]"
) -> tuple[str, str, str]
Split a string at the first occurrence of left and right delimiters.
string_partition_outer_interval ¶
string_partition_outer_interval(
s: str, left: str = "[", right: str = "]"
) -> tuple[str, str, str]
Split a string at the first left delimiter and last right delimiter.
string_to_2darray ¶
string_to_2darray(
s: str, *, allow_complex: bool = True
) -> tuple[NDArray[Any] | None, dict[str, str]]
Parse a string that is either a scalar or a 2D array in matlab or python format. Each number must be interpretable as type float or complex.
Returns:
Type | Description |
---|---|
tuple[NDArray[Any] | None, dict[str, str]]
|
A 2-element tuple with the value, and any errors. |
Raises:
Type | Description |
---|---|
ValueError
|
If the input isn't the right type or is infinite. |
string_to_integer ¶
Parse a string that is an integer.
Returns:
Type | Description |
---|---|
int | None
|
An integer or |
string_to_number ¶
string_to_number(
s: str, *, allow_complex: bool = True
) -> float64 | complex128 | None
Parse a string that can be interpreted either as float or (optionally) complex.
Returns:
Type | Description |
---|---|
float64 | complex128 | None
|
A number with type |
to_json ¶
to_json(
v: Any | _JSONPythonType,
*,
df_encoding_version: Literal[1, 2] = 1,
np_encoding_version: Literal[1, 2] = 1,
) -> Any | _JSONSerializedType
Convert a value to a JSON serializable format.
If v has a standard type that cannot be json serialized, it is replaced with
a {'_type': ..., '_value': ...}
pair that can be json serialized.
This is a complete table of the mappings:
Type | JSON _type field |
notes |
---|---|---|
complex scalar | complex |
including numpy |
non-complex ndarray | ndarray |
assumes each element can be json serialized |
complex ndarray | complex_ndarray |
|
sympy.Expr |
sympy |
any scalar SymPy expression |
sympy.Matrix |
sympy_matrix |
|
pandas.DataFrame |
dataframe |
df_encoding_version=1 |
pandas.DataFrame |
dataframe_v2 |
df_encoding_version=2 |
networkx graph type | networkx_graph |
|
numpy scalar | np_scalar |
np_encoding_version=2 |
any | v |
if v can be json serialized |
Note
The 'dataframe_v2'
encoding allows for missing and date time values whereas
the 'dataframe'
(default) does not. However, the 'dataframe'
encoding allows for complex
numbers while 'dataframe_v2'
does not.
If np_encoding_version
is set to 2, then numpy scalars serialize using '_type': 'np_scalar'
.
If df_encoding_version
is set to 2, then pandas DataFrames serialize using '_type': 'dataframe_v2'
.
See from_json for details about the differences between encodings.
If v is an ndarray, this function preserves its dtype (by adding '_dtype'
as
a third field in the dictionary).
If v can be JSON serialized or does not have a standard type, then it is returned without change.
Returns:
Type | Description |
---|---|
Any | _JSONSerializedType
|
The serialized value |
Raises:
Type | Description |
---|---|
ValueError
|
If |