python-search-space


Namepython-search-space JSON
Version 1.0.1 PyPI version JSON
download
home_page
SummaryPython's DSL to describe the search space of search problems
upload_time2022-12-29 02:57:09
maintainer
docs_urlNone
author
requires_python>=3.9
licenseMIT License Copyright (c) 2022 Daniel Orlando Ortiz Pacheco Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords describe problems space search
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 🔭 Python Search Space

[![wakatime](https://wakatime.com/badge/github/danielorlando97/search-space.svg)](https://wakatime.com/badge/github/danielorlando97/search-space)
[![unit and statistic testing](https://github.com/danielorlando97/search-space/actions/workflows/test.yml/badge.svg)](https://github.com/danielorlando97/search-space/actions/workflows/test.yml)

## 🤔 What's it?

A Python library that defines a DSL to describe search spaces. The DSL defines
design patterns with which the user can decorate their Python classes to describe
their space of interest. The resulting descriptions are declarative, expressive,
context sensitive, extensible and scalable. In addition, the system has a sample
generator system that is consistent and coherent with the selected description.\
**Principal Skills**: `Python` `Metaprogramming` `DSL` `AST` `Visitor Pattern`

## 🤓 Motivation

After a study of the different systems that try to solve search problems,
parametric optimization or AutoML, it was detected that there were limitations
to describe in detail the search spaces. As well as the lack of a tool whose
main objective is the description and generation of samples of such spaces.
Except for the tools with imperative syntax, none of the tools studied can
express constraints with contextual or conditional dependencies or dynamic
dimension spaces. The list of tools studied include a:
[`@autogoal`](https://github.com/autogoal/autogoal/),
[`@optuna`](https://github.com/optuna/optuna),
[`@hyperopt`](http://hyperopt.github.io/hyperopt),
[`@auto-sklearn`](https://github.com/automl/auto-sklearn),
[`@autogluon`](https://github.com/awslabs/autogluon)

## ⭐ Quickstart

### Factory of Search Space

The `Domain` space factory is the main public interface to the Python Search Space.
This factory is generic to the type of space you want to generate. In addition,
its constructor can use the following parameters to modify the characteristics of the generated space:

- `min` and `max`: with which the limits of a number space can be defined.
- `options`: list of options to choose from, this parameter transforms any space to a categorical space.
- `distribute_like`: string that refers to the random distribution with which the samples of the resulting space will be generated.
  Its default value is uniform distribution.

```python
# binary space
B = Domain[bool]()
# space of real numbers, (-oo, +oo)
R = Domain[float]()
# space of natural numbers, [0, +oo)
N = Domain[int](min=0)
# space of negative integers plus zero, [-oo, 0]
_N = Domain[int](max=0)
# categorical space of the first 100 powers of 10
ten_powers = [pow(10, i) for i in range(100)]
P = Domain[int](options = ten_powers)
# space of colors
C = Domain[str](options = ['Red', 'Blue', 'Black', 'White'])
```

Any space generated by the Domain factory define the `get_sample`
method generates random samples according to the respective distribution.

```python
space = Domain[int](min=0, max=1)
value, sample_context = sample.get_sample()
# value is 1 or 0
```

The `get_sample` method, in addition to the generated sample,
returns the sampling context relative to that sample.
This context can be used as a parameter to the `get_sample`
function and ensures that whenever an attempt is made to
generate a sample from the same space with the same context,
the same sample will be generated.

```python
space = Domain[int](min=0, max=1)
value, sample_context = sample.get_sample()
# Let value = 1, so
value1, _ = sample.get_sample(context = sample_context)
# value1 = 1
```

### Tensorial Spaces

With the `Domain` factory we can also create tensor spaces.
To describe each of the dimensions of the tensors that belong
to the resulting space, the DSL allows to use ints or random spaces
previously defined.

```python
# space of integer lists with size 10
L10 = Domain[int][10]()
# space of all integer lists
random_len = Domain[int]()
Ln = Domain[int][random_len]()
# Space of all square matrices
Mnxn = Domain[float][random_len][random_len]()
# Space of all lists of tuple with size 2
Mnx2 = Domain[float][random_len][2]()
```

In the case of tensor spaces, the parameters of the constructor of the Domain
factory are applied to each of the internal spaces of the domain.

### Constraint Function

The DSL defines a syntax to be able to describe the details of the search
spaces we are defining. This syntax is inspired by the definition of
mathematical domains, where a set is described from the particular
characteristics of any element of the set. To describe these characteristics we use
the lambda function syntax of Python. And to use these restriction functions we must
know the following characteristics.

- The constraint functions can define as many parameters as we need,
  but the first one always refers to any element of the space we are
  describing. The rest of the variables, if they do not have a default
  value declared, will represent dimensions of the space we are describing.

  ```python
  # x is any element of A space,
  # So A = {x in Z, x != 10}
  A = Domain[int] | (lambda x: x != 10)
  # B is the space of all strictly increasing lists with size 10
  B = Domain[int][10] | (lambda x, i: x[i] > x[i+1])
  # C is the space of all symmetric square matrices with size 10
  C = Domain[int][10][10] | (lambda x, i, j: x[i][j] == x[j][i])
  ```

- The constraint functions support all Python arithmetic and
  comparison operations but some settings are not valid.
  Check these tests for some of the [valid](https://github.com/danielorlando97/search-space/blob/main/tests/constraint/test_syntaxes_valid.py) and [invalid](https://github.com/danielorlando97/search-space/blob/main/tests/constraint/test_syntaxes_invalid.py) combinations

  ```python
  valid_space = Domain[int] | (lambda x : x / 10 < 0) # OK
  invalid_space = Domain[int] | (lambda x : 10 / x < 0) # raise UnSupportOpError
  ```

- If we want to describe more than one constraint within the same function
  we must write them all between parentheses and separated by commas.

  ```python
  # So A = {x in Z, x, in (0, 20) x != 10}
  A = Domain[int] | (lambda x: (x != 10, x > 0, x < 20)),
  ```

- The `&`(AND) and `|`(OR) operators have a cutting behavior that allows
  you to define conditional constraints. If either of these operators
  can know its result only by evaluating the most left expression then
  the expression on the right will never be evaluated. In cases where
  the operands would be constraints then the `&` operator works like
  commas and the `|` operator defines a segmented domain.

  ```python
  A = Domain[int] | (lambda x: False & (x == 0)) # A = Z (integer domain)
  A = Domain[int] | (lambda x: True & (x == 0)) # A = { 10 }
  B = Domain[int] | (lambda x: True | (x == 0)) # B = Z (integer domain)
  # C is a segmented domain, C = [(-oo, -1), (101, +oo)]
  # This means that in order to generate samples,
  # you must first choose between the following segments
  C = Domain[int] | (lambda x: (x < 0) | (x > 100))
  ```

### Custom Spaces

Among the main objectives of the DSL is to define a design pattern
for writing a search space using Python's classes. To define a custom
space we only have to assign to each of the parameters of the functions
of the classes a search space as a default value.

```python
class Line:
  """
    We want to find the line that best interpolates our data.
    And for some reason, we know that the slope is an integer
    between 50 and 100, but it is not 65. We also know that
    the intercept of the line is less than 50
  """

  def __init__(
      self,
      m: int = Domain[int](min=50, max=100) | (lambda x: x != 65),
      n: float = Domain[float]() | (lambda x: x < 50)
  ) -> None:
      self.m, self.n = m, n

  def get_point(self, x: float = Domain[float](min=0, max=10))
    return x, self.m * x + self.n

  def contains(self, x, y):
    return y == self.m * x + self.n
```

If we use these decorated classes as a generic type of the Domain
factory we can create random spaces where the samples are instances of
these classes.

```python
space = Domain[Line]()
line_instance, _ = space.get_sample()
type(line_instance) # Line

#If a class method was decorated with the DSL design pattern
#then its parameters become optional.
#If no values are specified for those parameters
#then random ones are generated.
random_point = line_instance.get_point()
specific_point = line_instance.get_point(1)

line_instance.contains(0, 0) # OK
line_instance.contains() # Error
```

### Contextual Dependencies

To describe contextual dependencies, a reference to a previously
defined search space is needed. This reference will be used as the
default value of one of the parameters of the restriction function
of the dependent space. In the same way that we describe the
characteristics of a set by means of the particular characteristics
of any element of it, we will describe the relation between two
sets by means of the particular relation of any two elements of them.

```python
class CenterPoint:
  """
  We want to find the pointer more centered and with more
  density around it. For some reason, we know that our data
  looks like a heavy diagonal 20u thick.
  All points in the dataset lie between the lines
  y = x + 10 and y = x - 10.
  """

  Y_Domain = Domain[int]() # previous definition

  def __init__(
      self,
      x: float = Domain[float]() | (
          #Let y be any element of the domain Y_Domain
          lambda x, y=Y_Domain: (x - 10 < y, y < x + 10)
      ),
      y: int = Y_Domain # use the previous definition
  ) -> None:
      self.x, self.y = x, y
```

### Examples of Use Cases

- [Simple Cases, Lines, CenterPoint and LogisticRegression](https://github.com/danielorlando97/search-space/blob/main/tests/examples/basic_class_example_test.py)
- [Graph Description, Adjacency Matrix and Object Oriented](https://github.com/danielorlando97/search-space/blob/main/tests/examples/graph_examples_test.py) (integration with typing, `Optional` and `Self` spaces)
- [Transformation of classical problems to search problems, The Bag](https://github.com/danielorlando97/search-space/blob/main/tests/examples/greedy_or_dp_example.py) (hierarchical descriptions, inheritance and reference between classes)
- [Detailed description of combinatorial spaces, Color Map](https://github.com/danielorlando97/search-space/blob/main/tests/examples/ia_examples_test.py) (Imperative constrains)
- [AutoML, model selection and parametric description, Semi-supervised Model](https://github.com/danielorlando97/search-space/blob/main/tests/examples/auto_ml_example_test.py)

<!--
#### Valid Syntaxes

```python
Domain[int] | (lambda x: x | True)
Domain[int] | (lambda x: True | x)
Domain[int] | (lambda x: x & True)
Domain[int] | (lambda x: True & x)
Domain[str] | (lambda x: x == 'a') # (lambda x: 'a' == x)
Domain[int] | (lambda x: x != [1, 2]) # (lambda x: [1, 2] != x)
Domain[int] | (lambda x: x < 10) # (lambda x: 10 < x)
Domain[int] | (lambda x: x > 10) # (lambda x: 10 > x)
Domain[int] | (lambda x: x <= 10) # (lambda x: 10 <= x)
Domain[int] | (lambda x: x >= 10) # (lambda x: 10 >= x)
Domain[int] | (lambda x: x + 10) # (lambda x: 10 + x)
Domain[int] | (lambda x: x - 10) # (lambda x: 10 - x)
Domain[int] | (lambda x: x * 10) # (lambda x: 10 * x)
Domain[int] | (lambda x: x / 10) # (lambda x: 10 / x)
Domain[int] | (lambda x: x % 10)
Domain[int] | (lambda x: x % 10 % 10)
Domain[int] | (lambda x: x % 10 + 10)
Domain[int] | (lambda x: x % 10 - 10)
Domain[int] | (lambda x: x % 10 * 10)
Domain[int] | (lambda x: x % 10 / 10)
Domain[int] | (lambda x: x % 10 == 10)
Domain[int] | (lambda x: x % 10 != 10)
Domain[int] | (lambda x: x % 10 < 10)
Domain[int] | (lambda x: x % 10 <= 10)
Domain[int] | (lambda x: x % 10 > 10)
Domain[int] | (lambda x: x % 10 >= 10)
```

#### Invalid Syntaxes

```python
Domain[int] | (lambda x: 10 % x)
Domain[int] | (lambda x: False | x < 3)
Domain[int] | (lambda x: x > 5 | x < 3)
Domain[int] | (lambda x: True & x < 3)
Domain[int] | (lambda x: x > 5 & x < 3)
Domain[int] | (lambda x: (x == x) < 3)
Domain[int] | (lambda x: (x == x) + 3)
Domain[int] | (lambda x: (x != x) > 3)
Domain[int] | (lambda x: (x != x) - 3)
Domain[int] | (lambda x: (x < x) == 3)
Domain[int] | (lambda x: (x < x) * 3)
Domain[int] | (lambda x: (x > x) <= 3)
Domain[int] | (lambda x: (x > x) % 3)
Domain[int] | (lambda x: (x + 3)[3])
Domain[int] | (lambda x: (x + 3).member)
Domain[int] | (lambda x: (x % 3 == 1) + 5)
Domain[int] | (lambda x: (x % 3 == 1) < 5)
Domain[int][6][6][6]() | (lambda x, i, j: x[i][j] == x[j][i])

```
-->
<!--
#### Imperative Restrictions

## ⚙️ Installation

## 📚 Documentation
-->

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "python-search-space",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": "",
    "keywords": "describe,problems,space,search",
    "author": "",
    "author_email": "Daniel Orlando Ortiz Pacheco <danielorlandoortizpacheco@gmial.com>",
    "download_url": "https://files.pythonhosted.org/packages/d6/3c/5c786d5962bdc13d7ee681a38aa7ad147df4e71cdd0929a8212be3e2a5a0/python-search-space-1.0.1.tar.gz",
    "platform": null,
    "description": "# \ud83d\udd2d Python Search Space\n\n[![wakatime](https://wakatime.com/badge/github/danielorlando97/search-space.svg)](https://wakatime.com/badge/github/danielorlando97/search-space)\n[![unit and statistic testing](https://github.com/danielorlando97/search-space/actions/workflows/test.yml/badge.svg)](https://github.com/danielorlando97/search-space/actions/workflows/test.yml)\n\n## \ud83e\udd14 What's it?\n\nA Python library that defines a DSL to describe search spaces. The DSL defines\ndesign patterns with which the user can decorate their Python classes to describe\ntheir space of interest. The resulting descriptions are declarative, expressive,\ncontext sensitive, extensible and scalable. In addition, the system has a sample\ngenerator system that is consistent and coherent with the selected description.\\\n**Principal Skills**: `Python` `Metaprogramming` `DSL` `AST` `Visitor Pattern`\n\n## \ud83e\udd13 Motivation\n\nAfter a study of the different systems that try to solve search problems,\nparametric optimization or AutoML, it was detected that there were limitations\nto describe in detail the search spaces. As well as the lack of a tool whose\nmain objective is the description and generation of samples of such spaces.\nExcept for the tools with imperative syntax, none of the tools studied can\nexpress constraints with contextual or conditional dependencies or dynamic\ndimension spaces. The list of tools studied include a:\n[`@autogoal`](https://github.com/autogoal/autogoal/),\n[`@optuna`](https://github.com/optuna/optuna),\n[`@hyperopt`](http://hyperopt.github.io/hyperopt),\n[`@auto-sklearn`](https://github.com/automl/auto-sklearn),\n[`@autogluon`](https://github.com/awslabs/autogluon)\n\n## \u2b50 Quickstart\n\n### Factory of Search Space\n\nThe `Domain` space factory is the main public interface to the Python Search Space.\nThis factory is generic to the type of space you want to generate. In addition,\nits constructor can use the following parameters to modify the characteristics of the generated space:\n\n- `min` and `max`: with which the limits of a number space can be defined.\n- `options`: list of options to choose from, this parameter transforms any space to a categorical space.\n- `distribute_like`: string that refers to the random distribution with which the samples of the resulting space will be generated.\n  Its default value is uniform distribution.\n\n```python\n# binary space\nB = Domain[bool]()\n# space of real numbers, (-oo, +oo)\nR = Domain[float]()\n# space of natural numbers, [0, +oo)\nN = Domain[int](min=0)\n# space of negative integers plus zero, [-oo, 0]\n_N = Domain[int](max=0)\n# categorical space of the first 100 powers of 10\nten_powers = [pow(10, i) for i in range(100)]\nP = Domain[int](options = ten_powers)\n# space of colors\nC = Domain[str](options = ['Red', 'Blue', 'Black', 'White'])\n```\n\nAny space generated by the Domain factory define the `get_sample`\nmethod generates random samples according to the respective distribution.\n\n```python\nspace = Domain[int](min=0, max=1)\nvalue, sample_context = sample.get_sample()\n# value is 1 or 0\n```\n\nThe `get_sample` method, in addition to the generated sample,\nreturns the sampling context relative to that sample.\nThis context can be used as a parameter to the `get_sample`\nfunction and ensures that whenever an attempt is made to\ngenerate a sample from the same space with the same context,\nthe same sample will be generated.\n\n```python\nspace = Domain[int](min=0, max=1)\nvalue, sample_context = sample.get_sample()\n# Let value = 1, so\nvalue1, _ = sample.get_sample(context = sample_context)\n# value1 = 1\n```\n\n### Tensorial Spaces\n\nWith the `Domain` factory we can also create tensor spaces.\nTo describe each of the dimensions of the tensors that belong\nto the resulting space, the DSL allows to use ints or random spaces\npreviously defined.\n\n```python\n# space of integer lists with size 10\nL10 = Domain[int][10]()\n# space of all integer lists\nrandom_len = Domain[int]()\nLn = Domain[int][random_len]()\n# Space of all square matrices\nMnxn = Domain[float][random_len][random_len]()\n# Space of all lists of tuple with size 2\nMnx2 = Domain[float][random_len][2]()\n```\n\nIn the case of tensor spaces, the parameters of the constructor of the Domain\nfactory are applied to each of the internal spaces of the domain.\n\n### Constraint Function\n\nThe DSL defines a syntax to be able to describe the details of the search\nspaces we are defining. This syntax is inspired by the definition of\nmathematical domains, where a set is described from the particular\ncharacteristics of any element of the set. To describe these characteristics we use\nthe lambda function syntax of Python. And to use these restriction functions we must\nknow the following characteristics.\n\n- The constraint functions can define as many parameters as we need,\n  but the first one always refers to any element of the space we are\n  describing. The rest of the variables, if they do not have a default\n  value declared, will represent dimensions of the space we are describing.\n\n  ```python\n  # x is any element of A space,\n  # So A = {x in Z, x != 10}\n  A = Domain[int] | (lambda x: x != 10)\n  # B is the space of all strictly increasing lists with size 10\n  B = Domain[int][10] | (lambda x, i: x[i] > x[i+1])\n  # C is the space of all symmetric square matrices with size 10\n  C = Domain[int][10][10] | (lambda x, i, j: x[i][j] == x[j][i])\n  ```\n\n- The constraint functions support all Python arithmetic and\n  comparison operations but some settings are not valid.\n  Check these tests for some of the [valid](https://github.com/danielorlando97/search-space/blob/main/tests/constraint/test_syntaxes_valid.py) and [invalid](https://github.com/danielorlando97/search-space/blob/main/tests/constraint/test_syntaxes_invalid.py) combinations\n\n  ```python\n  valid_space = Domain[int] | (lambda x : x / 10 < 0) # OK\n  invalid_space = Domain[int] | (lambda x : 10 / x < 0) # raise UnSupportOpError\n  ```\n\n- If we want to describe more than one constraint within the same function\n  we must write them all between parentheses and separated by commas.\n\n  ```python\n  # So A = {x in Z, x, in (0, 20) x != 10}\n  A = Domain[int] | (lambda x: (x != 10, x > 0, x < 20)),\n  ```\n\n- The `&`(AND) and `|`(OR) operators have a cutting behavior that allows\n  you to define conditional constraints. If either of these operators\n  can know its result only by evaluating the most left expression then\n  the expression on the right will never be evaluated. In cases where\n  the operands would be constraints then the `&` operator works like\n  commas and the `|` operator defines a segmented domain.\n\n  ```python\n  A = Domain[int] | (lambda x: False & (x == 0)) # A = Z (integer domain)\n  A = Domain[int] | (lambda x: True & (x == 0)) # A = { 10 }\n  B = Domain[int] | (lambda x: True | (x == 0)) # B = Z (integer domain)\n  # C is a segmented domain, C = [(-oo, -1), (101, +oo)]\n  # This means that in order to generate samples,\n  # you must first choose between the following segments\n  C = Domain[int] | (lambda x: (x < 0) | (x > 100))\n  ```\n\n### Custom Spaces\n\nAmong the main objectives of the DSL is to define a design pattern\nfor writing a search space using Python's classes. To define a custom\nspace we only have to assign to each of the parameters of the functions\nof the classes a search space as a default value.\n\n```python\nclass Line:\n  \"\"\"\n    We want to find the line that best interpolates our data.\n    And for some reason, we know that the slope is an integer\n    between 50 and 100, but it is not 65. We also know that\n    the intercept of the line is less than 50\n  \"\"\"\n\n  def __init__(\n      self,\n      m: int = Domain[int](min=50, max=100) | (lambda x: x != 65),\n      n: float = Domain[float]() | (lambda x: x < 50)\n  ) -> None:\n      self.m, self.n = m, n\n\n  def get_point(self, x: float = Domain[float](min=0, max=10))\n    return x, self.m * x + self.n\n\n  def contains(self, x, y):\n    return y == self.m * x + self.n\n```\n\nIf we use these decorated classes as a generic type of the Domain\nfactory we can create random spaces where the samples are instances of\nthese classes.\n\n```python\nspace = Domain[Line]()\nline_instance, _ = space.get_sample()\ntype(line_instance) # Line\n\n#If a class method was decorated with the DSL design pattern\n#then its parameters become optional.\n#If no values are specified for those parameters\n#then random ones are generated.\nrandom_point = line_instance.get_point()\nspecific_point = line_instance.get_point(1)\n\nline_instance.contains(0, 0) # OK\nline_instance.contains() # Error\n```\n\n### Contextual Dependencies\n\nTo describe contextual dependencies, a reference to a previously\ndefined search space is needed. This reference will be used as the\ndefault value of one of the parameters of the restriction function\nof the dependent space. In the same way that we describe the\ncharacteristics of a set by means of the particular characteristics\nof any element of it, we will describe the relation between two\nsets by means of the particular relation of any two elements of them.\n\n```python\nclass CenterPoint:\n  \"\"\"\n  We want to find the pointer more centered and with more\n  density around it. For some reason, we know that our data\n  looks like a heavy diagonal 20u thick.\n  All points in the dataset lie between the lines\n  y = x + 10 and y = x - 10.\n  \"\"\"\n\n  Y_Domain = Domain[int]() # previous definition\n\n  def __init__(\n      self,\n      x: float = Domain[float]() | (\n          #Let y be any element of the domain Y_Domain\n          lambda x, y=Y_Domain: (x - 10 < y, y < x + 10)\n      ),\n      y: int = Y_Domain # use the previous definition\n  ) -> None:\n      self.x, self.y = x, y\n```\n\n### Examples of Use Cases\n\n- [Simple Cases, Lines, CenterPoint and LogisticRegression](https://github.com/danielorlando97/search-space/blob/main/tests/examples/basic_class_example_test.py)\n- [Graph Description, Adjacency Matrix and Object Oriented](https://github.com/danielorlando97/search-space/blob/main/tests/examples/graph_examples_test.py) (integration with typing, `Optional` and `Self` spaces)\n- [Transformation of classical problems to search problems, The Bag](https://github.com/danielorlando97/search-space/blob/main/tests/examples/greedy_or_dp_example.py) (hierarchical descriptions, inheritance and reference between classes)\n- [Detailed description of combinatorial spaces, Color Map](https://github.com/danielorlando97/search-space/blob/main/tests/examples/ia_examples_test.py) (Imperative constrains)\n- [AutoML, model selection and parametric description, Semi-supervised Model](https://github.com/danielorlando97/search-space/blob/main/tests/examples/auto_ml_example_test.py)\n\n<!--\n#### Valid Syntaxes\n\n```python\nDomain[int] | (lambda x: x | True)\nDomain[int] | (lambda x: True | x)\nDomain[int] | (lambda x: x & True)\nDomain[int] | (lambda x: True & x)\nDomain[str] | (lambda x: x == 'a') # (lambda x: 'a' == x)\nDomain[int] | (lambda x: x != [1, 2]) # (lambda x: [1, 2] != x)\nDomain[int] | (lambda x: x < 10) # (lambda x: 10 < x)\nDomain[int] | (lambda x: x > 10) # (lambda x: 10 > x)\nDomain[int] | (lambda x: x <= 10) # (lambda x: 10 <= x)\nDomain[int] | (lambda x: x >= 10) # (lambda x: 10 >= x)\nDomain[int] | (lambda x: x + 10) # (lambda x: 10 + x)\nDomain[int] | (lambda x: x - 10) # (lambda x: 10 - x)\nDomain[int] | (lambda x: x * 10) # (lambda x: 10 * x)\nDomain[int] | (lambda x: x / 10) # (lambda x: 10 / x)\nDomain[int] | (lambda x: x % 10)\nDomain[int] | (lambda x: x % 10 % 10)\nDomain[int] | (lambda x: x % 10 + 10)\nDomain[int] | (lambda x: x % 10 - 10)\nDomain[int] | (lambda x: x % 10 * 10)\nDomain[int] | (lambda x: x % 10 / 10)\nDomain[int] | (lambda x: x % 10 == 10)\nDomain[int] | (lambda x: x % 10 != 10)\nDomain[int] | (lambda x: x % 10 < 10)\nDomain[int] | (lambda x: x % 10 <= 10)\nDomain[int] | (lambda x: x % 10 > 10)\nDomain[int] | (lambda x: x % 10 >= 10)\n```\n\n#### Invalid Syntaxes\n\n```python\nDomain[int] | (lambda x: 10 % x)\nDomain[int] | (lambda x: False | x < 3)\nDomain[int] | (lambda x: x > 5 | x < 3)\nDomain[int] | (lambda x: True & x < 3)\nDomain[int] | (lambda x: x > 5 & x < 3)\nDomain[int] | (lambda x: (x == x) < 3)\nDomain[int] | (lambda x: (x == x) + 3)\nDomain[int] | (lambda x: (x != x) > 3)\nDomain[int] | (lambda x: (x != x) - 3)\nDomain[int] | (lambda x: (x < x) == 3)\nDomain[int] | (lambda x: (x < x) * 3)\nDomain[int] | (lambda x: (x > x) <= 3)\nDomain[int] | (lambda x: (x > x) % 3)\nDomain[int] | (lambda x: (x + 3)[3])\nDomain[int] | (lambda x: (x + 3).member)\nDomain[int] | (lambda x: (x % 3 == 1) + 5)\nDomain[int] | (lambda x: (x % 3 == 1) < 5)\nDomain[int][6][6][6]() | (lambda x, i, j: x[i][j] == x[j][i])\n\n```\n-->\n<!--\n#### Imperative Restrictions\n\n## \u2699\ufe0f Installation\n\n## \ud83d\udcda Documentation\n-->\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2022 Daniel Orlando Ortiz Pacheco  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "Python's DSL to describe the search space of search problems",
    "version": "1.0.1",
    "split_keywords": [
        "describe",
        "problems",
        "space",
        "search"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "b47643e5721be27c9124c16ae3b43a72",
                "sha256": "67e84ecf2ea5f7aa2147a813a7a31c66feddba4b98a068e5be17f364548ae229"
            },
            "downloads": -1,
            "filename": "python_search_space-1.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b47643e5721be27c9124c16ae3b43a72",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 7344,
            "upload_time": "2022-12-29T02:57:02",
            "upload_time_iso_8601": "2022-12-29T02:57:02.988267Z",
            "url": "https://files.pythonhosted.org/packages/0d/de/7d72adb6479083cb17d93081b40b730aa3db61d93694dc70beb628583b83/python_search_space-1.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "b689f98aa49f36fe78194a2f0d90035a",
                "sha256": "afc76f542790063a808899258b19887ecba5ab61f64b3893abf1e7e7f017066e"
            },
            "downloads": -1,
            "filename": "python-search-space-1.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "b689f98aa49f36fe78194a2f0d90035a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 7754,
            "upload_time": "2022-12-29T02:57:09",
            "upload_time_iso_8601": "2022-12-29T02:57:09.081552Z",
            "url": "https://files.pythonhosted.org/packages/d6/3c/5c786d5962bdc13d7ee681a38aa7ad147df4e71cdd0929a8212be3e2a5a0/python-search-space-1.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-29 02:57:09",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "python-search-space"
}
        
Elapsed time: 0.05198s