statistics.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. # pylint: disable=missing-module-docstring
  3. from __future__ import annotations
  4. from functools import reduce
  5. from operator import mul
  6. import babel
  7. import babel.numbers
  8. from flask_babel import gettext
  9. from searx.extended_types import sxng_request
  10. from searx.result_types import Answer
  11. from searx.result_types.answer import BaseAnswer
  12. from . import Answerer, AnswererInfo
  13. kw2func = [
  14. ("min", min),
  15. ("max", max),
  16. ("avg", lambda args: sum(args) / len(args)),
  17. ("sum", sum),
  18. ("prod", lambda args: reduce(mul, args, 1)),
  19. ("range", lambda args: max(args) - min(args)),
  20. ]
  21. class SXNGAnswerer(Answerer):
  22. """Statistics functions"""
  23. keywords = [kw for kw, _ in kw2func]
  24. def info(self):
  25. return AnswererInfo(
  26. name=gettext(self.__doc__),
  27. description=gettext("Compute {func} of the arguments".format(func='/'.join(self.keywords))),
  28. keywords=self.keywords,
  29. examples=["avg 123 548 2.04 24.2"],
  30. )
  31. def answer(self, query: str) -> list[BaseAnswer]:
  32. results = []
  33. parts = query.split()
  34. if len(parts) < 2:
  35. return results
  36. ui_locale = babel.Locale.parse(sxng_request.preferences.get_value('locale'), sep='-')
  37. try:
  38. args = [babel.numbers.parse_decimal(num, ui_locale, numbering_system="latn") for num in parts[1:]]
  39. except: # pylint: disable=bare-except
  40. # seems one of the args is not a float type, can't be converted to float
  41. return results
  42. for k, func in kw2func:
  43. if k == parts[0]:
  44. res = func(args)
  45. res = babel.numbers.format_decimal(res, locale=ui_locale)
  46. f_str = ', '.join(babel.numbers.format_decimal(arg, locale=ui_locale) for arg in args)
  47. results.append(Answer(answer=f"[{ui_locale}] {k}({f_str}) = {res} "))
  48. break
  49. return results