unni / tools_basic.py
Atomicflee's picture
Upload 11 files
948d678 verified
Raw History Blame Contribute Delete
2.94 kB
"""Offline/simple tools: exact calculator and weather."""
import ast
import operator
import requests
_OPS = {ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv,
ast.FloorDiv: operator.floordiv, ast.Mod: operator.mod, ast.Pow: operator.pow,
ast.USub: operator.neg, ast.UAdd: operator.pos}
def _eval(node):
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
return node.value
if isinstance(node, ast.BinOp) and type(node.op) in _OPS:
if isinstance(node.op, ast.Pow) and abs(_eval(node.right)) > 1000:
raise ValueError("exponent too large")
return _OPS[type(node.op)](_eval(node.left), _eval(node.right))
if isinstance(node, ast.UnaryOp) and type(node.op) in _OPS:
return _OPS[type(node.op)](_eval(node.operand))
raise ValueError("unsupported expression")
def calculator(expression: str) -> str:
"""Evaluate an arithmetic expression exactly. Supports + - * / // % ** and parentheses.
Args:
expression: The arithmetic expression, for example '(1500 * 18) / 100'.
"""
try:
expr = expression.replace("×", "*").replace("÷", "/").replace("^", "**").replace(",", "")
r = _eval(ast.parse(expr, mode="eval").body)
return str(round(r, 10) if isinstance(r, float) else r)
except Exception as e:
return f"Could not calculate: {e}"
def weather(place: str) -> str:
"""Get the current weather and a 3-day forecast for a town or city.
Args:
place: Town or city name, for example 'Aluva' or 'Kochi'.
"""
try:
g = requests.get("https://geocoding-api.open-meteo.com/v1/search", timeout=10,
params={"name": place, "count": 1}).json().get("results")
if not g:
return f"Place not found: {place}"
g = g[0]
w = requests.get("https://api.open-meteo.com/v1/forecast", timeout=10, params={
"latitude": g["latitude"], "longitude": g["longitude"], "timezone": "auto", "forecast_days": 3,
"current": "temperature_2m,relative_humidity_2m,precipitation,wind_speed_10m",
"daily": "temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max"}).json()
c, d = w["current"], w["daily"]
lines = [f"{g['name']}, {g.get('admin1', '')}, {g.get('country', '')}",
f"Now: {c['temperature_2m']}°C, humidity {c['relative_humidity_2m']}%, "
f"rain {c['precipitation']} mm, wind {c['wind_speed_10m']} km/h"]
for i, day in enumerate(d["time"]):
lines.append(f"{day}: {d['temperature_2m_min'][i]}–{d['temperature_2m_max'][i]}°C, "
f"rain {d['precipitation_sum'][i]} mm ({d['precipitation_probability_max'][i]}%)")
return "\n".join(lines)
except Exception as e:
return f"Weather lookup failed: {e}"