{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "YfVGMp8AkODF",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "8055949d-83f1-464c-c111-0194926cd439"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m311.6/311.6 kB\u001b[0m \u001b[31m2.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m817.7/817.7 kB\u001b[0m \u001b[31m11.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m29.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m193.4/193.4 kB\u001b[0m \u001b[31m13.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m3.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m22.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m299.3/299.3 kB\u001b[0m \u001b[31m12.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m116.0/116.0 kB\u001b[0m \u001b[31m5.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.4/49.4 kB\u001b[0m \u001b[31m1.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m3.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m53.0/53.0 kB\u001b[0m \u001b[31m2.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m141.1/141.1 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip install openai langchain langchain-openai tiktoken langchain-experimental -q"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from getpass import getpass"
      ],
      "metadata": {
        "id": "lBznbmZ9nOa-"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Если используете ключ от OpenAI, запустите эту ячейку 👇"
      ],
      "metadata": {
        "id": "0dt0Sf3xnS3m"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "from langchain_openai import ChatOpenAI\n",
        "\n",
        "\n",
        "# os.environ['OPENAI_API_KEY'] = \"Введите ваш OpenAI API ключ\"\n",
        "os.environ['OPENAI_API_KEY'] = getpass(prompt='Введите ваш OpenAI API ключ')\n",
        "\n",
        "# Инициализируем языковую модель\n",
        "llm = ChatOpenAI(temperature=0.0)"
      ],
      "metadata": {
        "id": "a2ZTWMEynSrk",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "e08aae61-d88b-44e9-d27f-ebd267be803a"
      },
      "execution_count": null,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Введите ваш OpenAI API ключ··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Если используете ключ из курса, запустите эти ячейки 👇"
      ],
      "metadata": {
        "id": "S6LFfoYSnfVO"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!wget https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/notebooks/utils.py"
      ],
      "metadata": {
        "id": "5dTISH0jne2z",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "1c21d0c0-fa7a-42cb-f6aa-6fb84efdfc0c"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "--2024-04-29 14:31:01--  https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/notebooks/utils.py\n",
            "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.110.133, ...\n",
            "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.\n",
            "HTTP request sent, awaiting response... 200 OK\n",
            "Length: 10823 (11K) [text/plain]\n",
            "Saving to: ‘utils.py’\n",
            "\n",
            "\rutils.py              0%[                    ]       0  --.-KB/s               \rutils.py            100%[===================>]  10.57K  --.-KB/s    in 0s      \n",
            "\n",
            "2024-04-29 14:31:01 (99.0 MB/s) - ‘utils.py’ saved [10823/10823]\n",
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from utils import ChatOpenAI\n",
        "from getpass import getpass\n",
        "\n",
        "#course_api_key= \"Введите ваш API ключ, полученный в боте курса\"\n",
        "course_api_key = getpass(prompt='Введите ваш API ключ, полученный в боте курса')\n",
        "\n",
        "# инициализируем языковую модель\n",
        "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)"
      ],
      "metadata": {
        "id": "ATSJBycqnj9j",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "c7bff402-5fc0-49c4-c30a-c0d7366dba28"
      },
      "execution_count": null,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Введите ваш API ключ, полученный в боте курса··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "🥊PAL против математических задачек🧑‍🎓\n",
        "\n",
        "\n",
        "\n",
        "\n"
      ],
      "metadata": {
        "id": "AX_cKZihoXnP"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Подгрузим датасет"
      ],
      "metadata": {
        "id": "R9c5qsa-sU8Q"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import pandas as pd\n",
        "from tqdm import tqdm\n",
        "\n",
        "df = pd.read_csv(\"https://stepik.org/media/attachments/lesson/1282589/math_pal.csv\")"
      ],
      "metadata": {
        "id": "4sUfanNNoZUh"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# импортируйте PALChain из langchain_experimental и создайте цепь\n",
        "from langchain_experimental.pal_chain.base import PALChain\n",
        "\n",
        "pal_chain = PALChain.from_math_prompt(llm, verbose=True)"
      ],
      "metadata": {
        "id": "UKj1g552oZW1"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Сделайте предсказания. Чтобы избежать импортов библиотеки math, можо подавать в инпут значение числа \"пи\" 3.14159.\n",
        "Помните, что мы хотим получить число, а ЛЛМка будет выдавать строку."
      ],
      "metadata": {
        "id": "1QyOslrws8xM"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "answers = [] # Список, где будем хранить ответы модели\n",
        "\n",
        "for text_input in tqdm(df['task']):\n",
        "\n",
        "# далее будем подавать в инпут значение числа \"пи\", чтобы избежать импортов библиотеки math\n",
        "# также на выходе мы хотим получать число, а не строку\n",
        "\n",
        "    try:\n",
        "        answer = float(pal_chain.invoke(text_input+' if needed, pi=3.14159')['result'])\n",
        "    except ValueError:\n",
        "        answer = 0\n",
        "\n",
        "    answers.append(answer)\n",
        "\n",
        "\n",
        "    #break # Для отладки. Уберите, когда убедитесь, что на одном примере работает"
      ],
      "metadata": {
        "id": "aJCWxZshoZZO",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "6e3fa1f2-c11d-46f7-c746-68bfc382b345"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r  0%|          | 0/10 [00:00<?, ?it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:langchain_community.utilities.python:Python REPL can execute arbitrary code. Use with caution.\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Периметр прямоугольника со сторонами 1.5 м и 2 м. Ответ дай в сантиметрах.\"\"\"\n",
            "    side1 = 1.5  # in meters\n",
            "    side2 = 2  # in meters\n",
            "    perimeter_meters = 2 * (side1 + side2)\n",
            "    perimeter_cm = perimeter_meters * 100  # converting to centimeters\n",
            "    result = perimeter_cm\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 10%|█         | 1/10 [00:03<00:32,  3.61s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Find the sum of the areas of a circle with radius 5 cm and a circle with radius 3 cm.\"\"\"\n",
            "    radius1 = 5\n",
            "    radius2 = 3\n",
            "    pi = 3.14159\n",
            "    area1 = pi * (radius1 ** 2)\n",
            "    area2 = pi * (radius2 ** 2)\n",
            "    sum_areas = area1 + area2\n",
            "    result = sum_areas\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 20%|██        | 2/10 [00:06<00:24,  3.06s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Convert numbers 20 and 32 from decimal to binary and find the sum of ones.\"\"\"\n",
            "    num1 = bin(20)[2:]\n",
            "    num2 = bin(32)[2:]\n",
            "    sum_ones = num1.count('1') + num2.count('1')\n",
            "    result = sum_ones\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 30%|███       | 3/10 [00:08<00:18,  2.66s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Convert binary numbers 1101011010 and 101011 to decimal and calculate their sum.\"\"\"\n",
            "    binary1 = \"1101011010\"\n",
            "    binary2 = \"101011\"\n",
            "    \n",
            "    decimal1 = int(binary1, 2)\n",
            "    decimal2 = int(binary2, 2)\n",
            "    \n",
            "    sum_decimal = decimal1 + decimal2\n",
            "    result = sum_decimal\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 40%|████      | 4/10 [00:11<00:15,  2.63s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Найди объем цилиндра с радиусом 10 см и высотой 30 см, переведи результат в литры. if needed, pi=3.14159\"\"\"\n",
            "    radius = 10\n",
            "    height = 30\n",
            "    pi = 3.14159\n",
            "    volume = pi * radius**2 * height\n",
            "    volume_liters = volume / 1000  # converting cubic cm to liters\n",
            "    result = volume_liters\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 50%|█████     | 5/10 [00:14<00:14,  2.95s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Find the length of the arc of a circle with a radius of 20 m, formed by a central angle of 60°, then convert the result to centimeters. if needed, pi=3.14159\"\"\"\n",
            "    radius = 20\n",
            "    central_angle = 60\n",
            "    pi = 3.14159\n",
            "    arc_length = (central_angle/360) * 2 * pi * radius\n",
            "    arc_length_cm = arc_length * 100  # converting meters to centimeters\n",
            "    result = arc_length_cm\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 60%|██████    | 6/10 [00:17<00:11,  2.99s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Convert decimal number 1524 to binary and find the number of ones in its binary representation.\"\"\"\n",
            "    decimal_num = 1524\n",
            "    binary_num = bin(decimal_num)[2:]\n",
            "    count_ones = binary_num.count('1')\n",
            "    result = count_ones\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 70%|███████   | 7/10 [00:19<00:07,  2.64s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Найти объем куба со стороной 5 см, затем перевести результат в двоичную систему счисления.\"\"\"\n",
            "    side_length = 5\n",
            "    volume = side_length ** 3\n",
            "    volume_binary = bin(volume)[2:]  # convert volume to binary, [2:] to remove '0b' prefix\n",
            "    result = volume_binary\n",
            "    return result\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 80%|████████  | 8/10 [00:22<00:05,  2.63s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Находим площадь треугольника с заданными сторонами\"\"\"\n",
            "    a = 30\n",
            "    b = 40\n",
            "    c = int(\"110010\", 2)  # переводим число из двоичной системы в десятичную\n",
            "    s = (a + b + c) / 2\n",
            "    area = (s * (s - a) * (s - b) * (s - c)) ** 0.5\n",
            "    return area\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\r 90%|█████████ | 9/10 [00:25<00:02,  2.81s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new PALChain chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3mdef solution():\n",
            "    \"\"\"Найди объемы двух цилиндров с радиусами 8 см и 12 см и высотами 20 см и 25 см соответственно, затем сложи эти объемы и переведи сумму в литры. if needed, pi=3.14159\"\"\"\n",
            "    pi = 3.14159\n",
            "    radius1 = 8\n",
            "    radius2 = 12\n",
            "    height1 = 20\n",
            "    height2 = 25\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "100%|██████████| 10/10 [00:28<00:00,  2.86s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "df['answer'] = answers # запишем предсказания в датафрейм"
      ],
      "metadata": {
        "id": "qQJymxnZoZbh"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "df[['task', 'answer']].to_csv(\"5.6.7_solution.csv\", index=False) # сохраним решение в csv"
      ],
      "metadata": {
        "id": "FH7wqXK_oZeQ"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}