add a function that lowercases all letters exept the first letter in a word. Python 3.12 code: import ctypes
import math
import re
from typing import Any, Dict, Union

import tkinter as tk
from tkinter import font as tkFont, ttk


# --- Conversion Functions ---


def kg_to_lb(kg: float) -> float:
    """Convert kilograms to pounds."""
    return kg / 0.45359237


def lb_to_kg(lb: float) -> float:
    """Convert pounds to kilograms."""
    return lb * 0.45359237


# --- Evaluation Function ---


def evaluate_expression(
    expression: str, use_degrees: bool = False
) -> Union[float, str]:
    """Safely evaluate a mathematical expression considering degree mode."""

    def convert_angle(func: Any, x: float) -> float:
        return func(math.radians(x)) if use_degrees else func(x)

    def inverse_convert_angle(func: Any, x: float) -> float:
        result = func(x)
        return math.degrees(result) if use_degrees else result

    safe_functions: Dict[str, Any] = {
        "sqrt": math.sqrt,
        "sin": lambda x: convert_angle(math.sin, x),
        "cos": lambda x: convert_angle(math.cos, x),
        "tan": lambda x: convert_angle(math.tan, x),
        "asin": lambda x: inverse_convert_angle(math.asin, x),
        "acos": lambda x: inverse_convert_angle(math.acos, x),
        "atan": lambda x: inverse_convert_angle(math.atan, x),
        "log": math.log10,
        "ln": math.log,
        "pi": math.pi,
        "e": math.e,
        "lb": kg_to_lb,
        "kg": lb_to_kg,
    }

    expression = expression.replace("^", "**")
    func_calls = re.findall(r"(\b\w+\b)\(([^)]+)\)", expression)

    for func, arg in func_calls:
        if func in ["asin", "acos"]:
            try:
                value = eval(arg, {"__builtins__": None}, safe_functions)
                if not -1 <= value <= 1:
                    raise ValueError(f"{func}(x) is undefined for |x| > 1")
            except Exception as e:
                return f"Error: {e}"

    try:
        result = eval(expression, {"__builtins__": None}, safe_functions)
        if isinstance(result, float) and abs(result) < 1e-10:
            result = 0.0
        return round(result, 2) if isinstance(result, (int, float)) else result
    except Exception as e:
        return f"Error: {e}"


# --- Calculator GUI Class ---


class CalculatorGUI:
    """Tkinter-based Calculator with Degrees/Radians toggle and history."""

    def __init__(self, master: tk.Tk) -> None:
        self.master = master
        self.use_degrees: tk.BooleanVar = tk.BooleanVar(value=False)
        self.set_dpi_awareness()
        self.setup_window()
        self.create_widgets()
        self.layout_widgets()
        self.configure_grid()

    def set_dpi_awareness(self) -> None:
        """Enable high-DPI support on Windows."""
        try:
            ctypes.windll.shcore.SetProcessDpiAwareness(1)
        except Exception:
            pass

    def setup_window(self) -> None:
        """Configure the main application window."""
        self.master.title("Calculator")
        self.master.geometry("1200x720")

    def create_widgets(self) -> None:
        """Initialize all GUI components."""
        self.font: tkFont.Font = tkFont.Font(family="Roboto Flex", size=16)
        self.expression_var: tk.StringVar = tk.StringVar()
        self.entry: ttk.Entry = ttk.Entry(
            self.master, textvariable=self.expression_var, font=self.font, width=50
        )
        self.entry.bind("<Return>", self.calculate)

        self.history_text: tk.Text = tk.Text(
            self.master,
            width=70,
            height=10,
            font=self.font,
            wrap="none",
            state=tk.DISABLED,
        )

        self.scrollbar: ttk.Scrollbar = ttk.Scrollbar(
            self.master, orient="vertical", command=self.history_text.yview
        )
        self.history_text.configure(yscrollcommand=self.scrollbar.set)

        self.create_toggle_button()

        supported_info: str = (
            "Functions: sqrt, sin, cos, tan, asin, acos, atan, log, ln\n"
            "Constants: pi, e\n"
            "Conversions: lb(kg), kg(lb)"
        )
        self.supported_label: ttk.Label = ttk.Label(
            self.master, text=supported_info, font=self.font
        )

    def create_toggle_button(self) -> None:
        """Create the Degrees/Radians toggle button."""
        style: ttk.Style = ttk.Style()
        style.configure("ToggleButton.TButton", font=self.font, padding=0)
        self.mode_button: ttk.Button = ttk.Button(
            self.master,
            text="Radians",
            command=self.toggle_mode,
            style="ToggleButton.TButton",
        )

    def layout_widgets(self) -> None:
        """Arrange widgets within the window."""
        self.entry.grid(row=0, column=0, columnspan=2, padx=5, pady=5, sticky="ew")
        self.history_text.grid(row=1, column=0, padx=5, pady=5, sticky="nsew")
        self.scrollbar.grid(row=1, column=1, padx=(0, 5), pady=5, sticky="ns")
        self.mode_button.grid(row=2, column=0, columnspan=2, padx=5, pady=5, sticky="w")
        self.supported_label.grid(
            row=3, column=0, columnspan=2, padx=5, pady=10, sticky="w"
        )

    def configure_grid(self) -> None:
        """Make the grid layout responsive."""
        self.master.columnconfigure(0, weight=1)
        self.master.columnconfigure(1, weight=0)
        self.master.rowconfigure(1, weight=1)

    def toggle_mode(self) -> None:
        """Switch between Degrees and Radians modes."""
        if self.use_degrees.get():
            self.use_degrees.set(False)
            self.mode_button.config(text="Radians")
        else:
            self.use_degrees.set(True)
            self.mode_button.config(text="Degrees")

    def calculate(self, event: tk.Event = None) -> None:
        """Evaluate the expression and update history."""
        expression: str = self.expression_var.get().strip()
        if not expression:
            return
        result: Union[float, str] = evaluate_expression(
            expression, use_degrees=self.use_degrees.get()
        )
        self.display_result(expression, result)
        self.expression_var.set("")

    def display_result(self, expression: str, result: Union[float, str]) -> None:
        """Append the calculation to the history log."""
        self.history_text.config(state=tk.NORMAL)
        mode: str = "Degrees" if self.use_degrees.get() else "Radians"
        self.history_text.insert(tk.END, f"[{mode}] {expression} = {result}\n")
        self.history_text.config(state=tk.DISABLED)
        self.history_text.see(tk.END)


# --- Main Function ---


def main() -> None:
    """Run the Calculator application."""
    root: tk.Tk = tk.Tk()
    CalculatorGUI(root)
    root.mainloop()


if __name__ == "__main__":
    main()