Archived
1
0
Fork 0
This repository has been archived on 2024-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
akari-bot/modules/calc/__init__.py
Dianliang233 003784696b Wrap with async function
Finally now I can calc pi * (3 ** 2)
2023-01-19 17:09:56 +08:00

80 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from core.builtins.message import MessageSession
from core.component import on_command
from simpleeval import InvalidExpression, SimpleEval, DEFAULT_FUNCTIONS, DEFAULT_NAMES, DEFAULT_OPERATORS
import ast
import operator as op
import asyncio
import math
from core.exceptions import NoReportException
from .constant import consts
funcs = {}
for name in dir(math):
item = getattr(math, name)
if not name.startswith('_') and callable(item):
funcs[name] = item
s_eval = SimpleEval(
operators={
**DEFAULT_OPERATORS,
ast.BitOr: op.or_,
ast.BitAnd: op.and_,
ast.BitXor: op.xor,
ast.Invert: op.invert,
},
functions={**DEFAULT_FUNCTIONS, **funcs},
names={
**DEFAULT_NAMES, **consts,
'pi': math.pi,
'e': math.e,
'tau': math.tau,
'inf': math.inf, 'nan': math.nan,
},)
c = on_command('calc', developers=[
'Dianliang233'], desc='安全地计算 Python ast 表达式。',)
@c.handle('<math_expression>', options_desc={'+': '和/正数1 + 2 -> 3',
'-': '差/负数3 - 1 -> 2',
'/': '6 / 3 -> 2',
'//': '整除7 // 4 -> 1',
'*': '2 * 3 -> 6',
'**': 'x 的 y 次幂(由于性能问题,结果不得超过 4e+62 ** 3 -> 8',
'%': '取模5 % 2 -> 1',
'==': '等于1 == 1 -> True',
'<': '小于1 < 2 -> True',
'>': '大于2 > 1 -> True',
'<=': '小于等于1 <= 2 -> True',
'>>': 'x 右移 y 位(相当于 x / (2 ** y)y < 1000032 >> 5 -> 1',
'<<': 'x 左移 y 位(相当于 x * (2 ** y)y < 100001 << 5 -> 32',
'in': 'x 在 y 中:"hat" in "what" -> True',
'not': 'not True -> False',
'is': 'x 与 y 是同一个对象1 is 1 -> True',
'randint(x)': '小于 x 的随机整数randint(6) -> 5',
'rand()': '0 与 1 之间的随机浮点数rand() -> 0.5789015836448923',
'int()': '转换为整数int(1.5) -> 1',
'float()': '转换为浮点数float(1) -> 1.0',
'str()': '转换为字符串str(1) -> "1"',
'更多数学函数': 'https://docs.python.org/zh-cn/3/library/math.html'
})
async def _(msg: MessageSession):
try:
res = await asyncio.wait_for(async_eval(msg.parsed_msg["<math_expression>"]), 15)
await msg.finish(f'{(msg.parsed_msg["<math_expression>"])} = {str(res)}')
except InvalidExpression as e:
await msg.finish(f"表达式无效:{e}")
except asyncio.TimeoutError:
raise TimeoutException()
except Exception as e:
raise NoReportException(e)
async def async_eval(expr: str):
return s_eval.eval(expr)
class TimeoutException(NoReportException):
'''计算超时,最大计算时间为 15 秒。'''
pass