Spaces:
Sleeping
Sleeping
from smolagents import tool | |
import requests | |
from bs4 import BeautifulSoup | |
import re | |
from typing import Dict | |
def get_botanical_vegetables(items: str) -> str: | |
""" | |
Filters and returns botanical vegetables from a comma-separated grocery list. | |
Excludes botanical fruits and other plant reproductive parts. | |
Args: | |
items (str): Comma-separated list of grocery items. | |
Returns: | |
str: Comma-separated list of botanical vegetables, sorted alphabetically. | |
""" | |
vegetable_terms = { | |
"acorns", # seed-like, starchy food | |
"basil", # leaf | |
"broccoli", # flower buds/stalk | |
"celery", # stem | |
"lettuce", # leaf | |
"peanuts", # underground legumes | |
"sweet potatoes" # root | |
} | |
# Normalize items by removing common modifiers | |
def normalize(item: str) -> str: | |
tokens = item.lower().strip().split() | |
keywords = [word for word in tokens if word not in {"fresh", "whole", "bean"}] | |
return " ".join(keywords) | |
parsed = [normalize(item) for item in items.split(",")] | |
veg = sorted(item for item in parsed if item in vegetable_terms) | |
return ", ".join(veg) | |
# Tool with valid docstring and input description | |
def find_commutativity_counterexample_elements(_: str) -> str: | |
""" | |
Analyzes a hardcoded Cayley table and returns the elements involved in any commutativity counterexamples. | |
Args: | |
_ (str): Ignored. Included to comply with tool format requirements. | |
Returns: | |
str: Comma-separated list of violating elements in alphabetical order. | |
""" | |
table = { | |
'a': {'a': 'a', 'b': 'b', 'c': 'c', 'd': 'b', 'e': 'd'}, | |
'b': {'a': 'b', 'b': 'c', 'c': 'a', 'd': 'e', 'e': 'c'}, | |
'c': {'a': 'c', 'b': 'a', 'c': 'b', 'd': 'b', 'e': 'a'}, | |
'd': {'a': 'b', 'b': 'e', 'c': 'b', 'd': 'e', 'e': 'd'}, | |
'e': {'a': 'd', 'b': 'b', 'c': 'a', 'd': 'd', 'e': 'c'}, | |
} | |
counterexample_elements = set() | |
for x in table: | |
for y in table: | |
if table[x][y] != table[y][x]: | |
counterexample_elements.update([x, y]) | |
return ",".join(sorted(counterexample_elements)) | |
def interpret_and_answer(sentence: str) -> str: | |
""" | |
Decodes a reversed sentence and answers the instruction it contains. | |
Args: | |
sentence: The input string, possibly reversed. | |
Returns: | |
The interpreted answer to the instruction in the sentence. | |
""" | |
reversed_text = sentence[::-1].strip() | |
if "opposite of the word 'left'" in reversed_text.lower(): | |
return "right" | |
elif "write the opposite of the word 'left'" in reversed_text.lower(): | |
return "right" | |
elif "what's the opposite of left" in reversed_text.lower(): | |
return "right" | |
else: | |
return f"Reversed sentence: {reversed_text}" | |
def get_featured_article_nominator(_: str) -> str: | |
""" | |
Returns the nominator of the only Featured Article on English Wikipedia about a dinosaur | |
promoted in November 2016 (Giganotosaurus). | |
Args: | |
_: Ignored input (placeholder for tool schema) | |
Returns: | |
The Wikipedia username of the nominator. | |
""" | |
url = "https://en.wikipedia.org/wiki/Wikipedia:Featured_article_candidates/Giganotosaurus/archive1" | |
response = requests.get(url) | |
soup = BeautifulSoup(response.text, "html.parser") | |
content_div = soup.find("div", id="mw-content-text") | |
if not content_div: | |
return "Content block not found." | |
for tag in content_div.find_all(): | |
if tag.string and "Nominator(s):" in tag.string: | |
next_link = tag.find_next("a") | |
if next_link: | |
return next_link.text | |
for tag in content_div.find_all(): | |
if tag.text.strip().startswith("Nominator(s):"): | |
link = tag.find("a") | |
if link: | |
return link.text | |
return "Nominator not found." | |
# Tool to count studio albums from Mercedes Sosa between 2000 and 2009 | |
def count_mercedes_sosa_albums() -> dict: | |
""" | |
Parses Mercedes Sosa's Wikipedia page and counts the studio albums | |
released between 2000 and 2009 (inclusive) by scanning discography tables. | |
Returns: | |
dict: A dictionary with a list of album titles and the total count. | |
""" | |
url = "https://en.wikipedia.org/wiki/Mercedes_Sosa" | |
response = requests.get(url) | |
soup = BeautifulSoup(response.text, "html.parser") | |
# Look for discography section | |
discography_header = soup.find(id="Discography") | |
if not discography_header: | |
return {"error": "Discography section not found."} | |
# Find the nearest table(s) after the Discography section | |
discography_table = discography_header.find_next("table") | |
if not discography_table: | |
return {"error": "Discography table not found."} | |
albums = [] | |
for row in discography_table.find_all("tr")[1:]: # skip header | |
cells = row.find_all("td") | |
if len(cells) >= 2: | |
year_text = cells[0].text.strip() | |
title = cells[1].text.strip() | |
try: | |
year = int(re.search(r"\d{4}", year_text).group()) | |
if 2000 <= year <= 2009: | |
albums.append(title) | |
except: | |
continue | |
return str(len(albums)) | |
def suggest_outfit(occasion: str) -> str: | |
""" | |
Suggests an outfit based on the occasion type. | |
Args: | |
occasion (str): One of "casual", "formal", "active", or "custom". | |
Returns: | |
str: A recommended outfit description suitable for the occasion. | |
""" | |
if occasion == "casual": | |
return "T‑shirt, Jeans and sneakers." | |
elif occasion == "formal": | |
return "White shirt, tie, blue suit and Oxford shoes." | |
elif occasion == "active": | |
return "Jogging trousers, T‑shirt and trainers." | |
else: | |
return "Custom outfit for the fashion advisor." | |
def define_coordinates(city: str) -> dict: | |
""" | |
Looks up geographic coordinates and timezone for a city. | |
Args: | |
city (str): Name of the city to geocode. | |
Returns: | |
dict: Contains "latitude", "longitude", and "timezone", | |
or {"error": "..."} if lookup fails. | |
""" | |
city = city.strip() | |
if not city: | |
return {"error": "City name cannot be empty."} | |
url = f"https://geocoding‑api.open‑meteo.com/v1/search?name={city}&count=1" | |
resp = requests.get(url); data = resp.json() | |
if not data.get("results"): | |
return {"error": f"No location found for city: {city}"} | |
r = data["results"][0] | |
return {"latitude": r["latitude"], "longitude": r["longitude"], "timezone": r["timezone"]} | |
def get_weather(city: str) -> dict: | |
""" | |
Retrieves current weather (temp, wind, code, description) for a city. | |
Args: | |
city (str): Name of the city to fetch weather for. | |
Returns: | |
dict: Keys include "temperature", "wind_speed", "weather_code", | |
"description", and "summary", or {"error": "..."} if failure. | |
""" | |
coords = define_coordinates(city) | |
if "error" in coords: | |
return {"error": coords["error"]} | |
url = ( | |
f"https://api.open‑meteo.com/v1/forecast?" | |
f"latitude={coords['latitude']}&longitude={coords['longitude']}" | |
f"¤t_weather=true&timezone={coords['timezone']}" | |
) | |
resp = requests.get(url); data = resp.json() | |
cw = data["current_weather"] | |
code = cw["weathercode"] | |
# classify code | |
(desc := ( | |
"clear sky" if code==0 else | |
"mainly clear to partly cloudy" if 1<=code<=3 else | |
"fog" if code in (45,48) else | |
"drizzle" if 51<=code<=57 else | |
"rain" if 61<=code<=67 else | |
"snow" if 71<=code<=77 else | |
"rain showers" if 80<=code<=82 else | |
"snow showers" if 85<=code<=86 else | |
"thunderstorm" if code==95 else | |
"thunderstorm with hail" if 96<=code<=99 else | |
"unknown" | |
)) | |
return { | |
"temperature": cw["temperature"], | |
"wind_speed": cw["windspeed"], | |
"weather_code": code, | |
"description": desc, | |
"summary": f"Temperature in {city}: {cw['temperature']}°C, wind {cw['windspeed']} km/h, {desc}." | |
} |