Calculator Bot Example
This example demonstrates a more complex use case of a mini app using SwiBots. The bot creates an advanced calculator with basic arithmetic, scientific functions, and calculation history.
Prerequisites
Before you begin, make sure you have:
- Installed SwiBots (
pip install swibots
) - Obtained a bot token from the Switch platform
- Installed the
math
module (usually comes pre-installed with Python)
The Code
Here's the complete code for our advanced calculator bot:
import logging
import math
from swibots import (
Client, BotContext, CommandEvent, CallbackQueryEvent, BotCommand,
AppPage, Text, Button, ButtonGroup,
ScreenType, TextSize, InlineKeyboardButton, InlineMarkup, regexp
)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
TOKEN = "YOUR_BOT_TOKEN_HERE"
app = Client(TOKEN, is_app=True, home_callback="show_calculator")
app.set_bot_commands([BotCommand("start", "Open the calculator", True)])
# Store calculation history
user_history = {}
def evaluate_expression(expression):
try:
# Replace '^' with '**' for exponentiation
expression = expression.replace('^', '**')
# Add math. prefix to mathematical functions
for func in ['sin', 'cos', 'tan', 'log', 'sqrt']:
expression = expression.replace(func, f'math.{func}')
return str(eval(expression, {"__builtins__": None}, {"math": math}))
except Exception as e:
return f"Error: {str(e)}"
@app.on_command("start")
async def start_command(ctx: BotContext[CommandEvent]):
await ctx.event.message.reply_text(
"Welcome to the Advanced Calculator! Click the button below to start calculating.",
inline_markup=InlineMarkup([[
InlineKeyboardButton("Open Calculator", callback_data="show_calculator", app=True)
]])
)
@app.on_callback_query(regexp("show_calculator"))
async def show_calculator(ctx: BotContext[CallbackQueryEvent]):
user_id = ctx.event.action_by_id
current_expression = user_history.get(user_id, {}).get('current', '')
calculator_buttons = [
["7", "8", "9", "/"],
["4", "5", "6", "*"],
["1", "2", "3", "-"],
["0", ".", "=", "+"],
["(", ")", "C", "←"],
["sin", "cos", "tan", "^"],
["log", "sqrt", "π", "e"],
]
button_groups = [
ButtonGroup([Button(btn, callback_data=f"calc_{btn}") for btn in row])
for row in calculator_buttons
]
page = AppPage(
screen=ScreenType.SCREEN,
components=[
Text("Advanced Calculator", size=TextSize.LARGE),
Text(current_expression or "0", size=TextSize.MEDIUM),
*button_groups,
Button("View History", callback_data="view_history"),
]
)
await ctx.event.answer(callback=page)
@app.on_callback_query(regexp("calc_"))
async def handle_calculation(ctx: BotContext[CallbackQueryEvent]):
user_id = ctx.event.action_by_id
button = ctx.event.callback_data.split("_")[1]
if user_id not in user_history:
user_history[user_id] = {'current': '', 'history': []}
current = user_history[user_id]['current']
if button == "=":
result = evaluate_expression(current)
user_history[user_id]['history'].append(f"{current} = {result}")
user_history[user_id]['current'] = result
elif button == "C":
user_history[user_id]['current'] = ''
elif button == "←":
user_history[user_id]['current'] = current[:-1]
elif button == "π":
user_history[user_id]['current'] += str(math.pi)
elif button == "e":
user_history[user_id]['current'] += str(math.e)
else:
user_history[user_id]['current'] += button
await show_calculator(ctx)
@app.on_callback_query(regexp("view_history"))
async def view_history(ctx: BotContext[CallbackQueryEvent]):
user_id = ctx.event.action_by_id
history = user_history.get(user_id, {}).get('history', [])
if not history:
await ctx.event.answer("No calculation history available.", show_alert=True)
return
page = AppPage(
screen=ScreenType.SCREEN,
components=[
Text("Calculation History", size=TextSize.LARGE),
Text("\n".join(history[-10:]), size=TextSize.MEDIUM),
Button("Back to Calculator", callback_data="show_calculator"),
]
)
await ctx.event.answer(callback=page)
if __name__ == "__main__":
app.run()
Features Demonstrated
This example showcases the following SwiBots features:
- Creating a complex mini app with advanced functionality
- Using various UI components:
- Text
- Buttons and ButtonGroups
- Implementing a calculator interface with multiple operations
- Maintaining user state (current expression and calculation history)
- Handling user actions for various calculator functions
- Integrating with Python's
math
module for advanced calculations
How It Works
- The bot starts with a welcome message and a button to open the calculator.
- The main calculator screen shows the current expression and buttons for various operations.
- Users can input numbers and perform various operations, including basic arithmetic and scientific functions.
- The calculator evaluates expressions and displays results.
- Users can view their calculation history.
This example demonstrates how to create a more complex, interactive mini app that provides practical functionality while showcasing various SwiBots features.
Running the Bot
To run the bot, save the complete code in a file (e.g., advanced_calculator_bot.py
) and execute it:
python advanced_calculator_bot.py
Note
This implementation uses Python's eval()
function, which can be dangerous if used with untrusted input. In a production environment, you should implement a safer method of evaluating mathematical expressions, such as using a parsing library or implementing your own expression evaluator.