Skip to content

Releases: pyparsing/plusminus

Plusminus 0.7.0

19 Dec 12:22
Compare
Choose a tag to compare
  • Added type annotations on public methods, to aid in type checking and autocomplete.

  • Added sin², sin³, sin⁻¹, etc. methods for common mathematical notation such as sin²(x) for sin(x)**2, and sin⁻¹(x) for asin(x).

  • Dropped BasicArithmeticParser synonym for ArithmeticParser (too easily confused with BaseArithmeticParser).

  • Added symmetric difference set operations, supported by '∆' and '^' operators.

  • Added radical expressions for roots > 2, up to 9, to the ArithmeticParser class:

    ³√2 -> 2**(1/3) (1.259921049894873)
    ⁹√2 -> 2**(1/9) (1.080059738892306)

  • Added Unicode variable assignment operator '←'.

  • Added option to allow/disallow user-defined variables in expressions.

  • Added better docstring to enumerate all supported parser options.

  • Added scan_string method, to replace deprecated scanString method.

(Many features added by @theonemusic, thanks!)

plusminus 0.6.0

06 May 17:22
Compare
Choose a tag to compare
- Auto-promote operators that are alphabetic to pyparsing Keywords,
  to help differentiate operators that are similar.

- Added "less" and "off" operators to BusinessArithmeticParser for parsing
  discounting expressions like "20% off of 30" or "30 less 20%".

plusminus 0.5.0

05 May 15:15
Compare
Choose a tag to compare
plusminus 0.5.0 Pre-release
Pre-release
- Python 3.5 is no longer supported, plusminus now only works with Python 3.6 and later.

- Refactored classes and parser interface to support better definition of precedence of operations for custom operators, and to better align the BaseArithmeticParser class to standard Python `eval()`, with some enhancements/distinctions:
    - `|x|` absolute value notation included
    - Unicode operators included (`≠ ≤ ≥ ∈ ∉ ∩ ∪ ∧ ∨` for
      `!= <= >= in not-in intersection union and or`)
    - C-style `condition ? true_value : false_value` ternary operator included
    - support for set union, intersection, and element
    - dict and list containers not supported

  The new ArithmeticParser class (renamed from BasicArithmeticParser) adds:
    - trig, algebra, and random functions
    - algebra constants `π τ e φ ϕ`
    - `√` square root operator (unary and binary)
    - exponent operators `⁻¹ ⁰ ¹ ² ³`
    - `!` factorial operator
    - `°` degrees-to-radians conversion operator

  The former `BasicArithmeticParser` is deprecated, as too easily confused with the `BaseArithmeticParser`. A compatibility synonym is defined for now, but this will be removed in a future release (probably 1.0).

- Dropped support for "in" range notation, with ranges specified using (), (], [) or [] notation ("in" with sets is still supported).

- Deleted the example_parsers.py module in the examples directory, and split the parsers out into separate modules in that directory.

- Added __version_info__ structure, following pattern of sys.version_info field names.

- Added `user_defined_formulas_supported` attribute for parsers, to enable/disable support for `@=` formula assignment operator
  (default=`True`)

- Added documentation to functions in the ArithmeticParser class for better understanding and readability.

- Unary "+" operator can now be used. For example:
    
    parser = ArithmeticParser()
    parser.evaluate("+5")

- "&" and "|" added as set operations, respectively intersection and
  union (same as "∩" and "∪" characters).

plusminus_0.4.0

30 Aug 20:23
Compare
Choose a tag to compare
plusminus_0.4.0 Pre-release
Pre-release

plusminus 0.4.0

- Update default sys.setrecursionlimit to 3000 if it has not
  already been modified, to allow for deep call stacks generated
  from infixNotation parsers.

- Custom functions can now take different numbers of arguments,
  using a tuple of integers for the arity. For example, here is the
  log function, that can take only one or two arguments:

      self.add_function("log", (1, 2), math.log)

- Updated operators and functions in ArithmeticParser:

    - "−" can now be used as a unary minus operator, like "-".

    - "//" operator for floor division added.

    - round function now accepts one or two arguments, instead of two only.

- Updated operators, functions and variables in BasicArithmeticParser:

    - Added the log function above in the BasicArithmeticParser. If called
      with one argument, base e is used. If called with two, the second
      argument is used as the base.

    - Removed the nhypot function. The hypot function now takes any number
      of arguments.

    - gamma function now takes one parameter, instead of two.

    - Added variable "tau" (same as "τ"), which is equal to 2×π.

    - Added variables "ϕ" and "phi" (same as "φ", the golden number).

- Updated documentation and examples in the BasicArithmeticParser class.

Thanks to TheOneMusic for his awesome contributions to this release!

- PLANNED FOR 0.5.0

    - Refactoring the parser classes to provide a
      parser for standard Python expressions using standard Python
      operators and builtins, and functions from the math module
      (may limit types to int and float). Will make this parser more
      of a safe drop-in replacement for "eval" without extra bells and
      whistles.

    - Better definition of custom operators, to permit support for
      proper definition of precedence of operations.

    - Update web demo to support selection of different parsers.

Plusminus 0.3.0

26 May 03:14
Compare
Choose a tag to compare
Plusminus 0.3.0 Pre-release
Pre-release
- Added syntax to clear a defined variable:

      a, b = 1, 2
      c = a + b    -> 3
      a =          -> clears variable a
      c = a + b    -> NameError

- Added support for nested sets, and better set display format.

      {{1, 2}, 99, 100}
      {99, 'z', 'a'} ∪ {'a', 't', 100} -> {99, 100, 'a', 't', 'z'}

- Set literals can be used as function arguments, if supported
  by the function.

      max({1, 2, 4})  -> 4
      min({1, 2, 4})  -> 1
      sin({1, 2, 4})  -> TypeError

- Added dict-like access API to set and get variables defined within
  a parser:

      for x in range(10):
          parser['x'] = x
          parser.evaluate("y = x * x")
          print(parser['y'])
          del parser['y']

- plusminus has been hardened against some possible attacks, using
  deep expression nesting or formula references:

  - To guard against expressions that are too deeply nested, a
    customizable maximum_expression_depth attribute has been added
    to parsers. Parsers customized with additional operators may need
    to limit the allowed depth. The default maximum depth is 6
    (reduced from 10 in 0.2.0).

        ((((((0)))))) -> 0
        (((((((0))))))) -> OverflowError: too deeply nested

    There is also a maximum_set_depth attribute for nested sets,
    also defaults to 6.

  - A similar performance issue can be raised if a formula chains
    to another formula to another formula, etc. too deeply.

        a @= b + b
        b @= c + c
        c @= d + d
        ...
        m @= n + n -> OverflowError: function variables nested too deeply

    A customizable parser attribute maximum_formula_depth will limit the number
    of formula indirections. The default value is 12.

  - An attack may try to define too many variables and crash an application
    by consuming excessive memory. A value to limit the number of variables and
    their respective memory usage was previously hard-coded. These are now
    part of the public API for parsers: max_number_of_vars (default = 1000)
    and max_var_memory (default = 10MB).

Plusminus 0.2.0

19 Apr 16:21
Compare
Choose a tag to compare
Plusminus 0.2.0 Pre-release
Pre-release

0.2.0 -

- Added set notation and arithmetic:
      {1, 2, 3} is the set of the integers 1, 2, and 3
      {} is the empty set
      a ∩ b is the intersection of sets a and b
      a ∪ b is the union of sets a and b
      a ∈ b a is an element of b (can also be written 'a in b')
      a ∉ b a is not an element of b (can also be written 'a not in b')

- Replaced "between", "within", and "in range from-to" operators
  to single "in" operator, taking an argument of the form:
      [1, 10] between 1 and 10 (including the values 1 and 10)
      [1, 10) between 1 and 10 (excluding the value 10)
      (1, 10] between 1 and 10 (excluding the value 1)
      (1, 10) between 1 and 10 (excluding the values 1 and 10)

- Custom functions can now take variable numbers of arguments,
  using ... for the arity. For example, here is a variant of
  hypot computing an n-dimensional distance:

      self.add_function("nhypot", ..., lambda *seq: sum(safe_pow(i, 2) for i in seq)**0.5)

- Updated the values returned from evaluating an assignment
  expression. If a single value is assigned, then a single
  value is returned. If multiple values are assigned, a tuple
  of the values is returned. (Previously, the underlying
  list of values was returned.)

- Guard against overly-nested ()'s (10 levels is the max).

- Changed signature of safe_pow, now takes multiple operands
  instead of a tuple of operands.

- New unit tests, thanks toonarmycaptain!

Plusminus 0.1.1

10 Feb 03:00
Compare
Choose a tag to compare
Plusminus 0.1.1 Pre-release
Pre-release
- Added useful customization methods to public API
  - safe_pow
  - safe_str_mult
  - constrained_factorial
  - ArithmeticParseException

- Modified example parsers to use these safe methods

- Moved many functions out of the base ArithmeticParser class and into
  BasicArithmeticParser, so that applications can choose to extend
  from the base class if trigonometric, etc. functions are not
  relevant to their particular domain.

- Moved example parsers into plusminus import tree, so that they can be
  imported and used:

      from plusminus.examples.example_parsers import DiceRollParser

      parser = DiceRollParser()
      print(parser.evaluate("3d20")

- Moved body of usage() out of bottle_repl and into the parser class
  itself so that repls can get basic usage text directly from the parser.

Plusminus 0.1

05 Feb 22:52
Compare
Choose a tag to compare
Plusminus 0.1 Pre-release
Pre-release

Initial release:

  • Core API classes and methods

    • ArithmeticParser
    • BasicArithmeticParser
  • examples

    • example_parsers.py
      • DiceRollerArithmeticParser
      • CombinatoricsArithmeticParser
      • BusinessArithmeticParser
      • DatetimeArithmeticParser
    • bottle_repl.py
    • console_repl.py
  • docs